commit 6449a503576ef172d3f40ac708dfe4105c6d645d Author: Brandon <46827438+disclearing@users.noreply.github.com> Date: Thu May 25 00:58:23 2023 +0100 Sexy diff --git a/Anticheat-master/.gitignore b/Anticheat-master/.gitignore new file mode 100644 index 0000000..06fa4aa --- /dev/null +++ b/Anticheat-master/.gitignore @@ -0,0 +1,117 @@ +# User-specific stuff +.idea/ + +*.iml +*.ipr +*.iws + +# IntelliJ +out/ + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +target/ +<<<<<<< HEAD +======= +build/ +>>>>>>> fc8180f1c0e8a7687c5122fdae83d9ce32557278 + +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next + +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.flattened-pom.xml + +# Common working directory +run/ diff --git a/Anticheat-master/.gradle/6.1.1/executionHistory/executionHistory.bin b/Anticheat-master/.gradle/6.1.1/executionHistory/executionHistory.bin new file mode 100644 index 0000000..6c54aa1 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/executionHistory/executionHistory.bin differ diff --git a/Anticheat-master/.gradle/6.1.1/executionHistory/executionHistory.lock b/Anticheat-master/.gradle/6.1.1/executionHistory/executionHistory.lock new file mode 100644 index 0000000..9fa25c9 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/executionHistory/executionHistory.lock differ diff --git a/Anticheat-master/.gradle/6.1.1/fileChanges/last-build.bin b/Anticheat-master/.gradle/6.1.1/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/fileChanges/last-build.bin differ diff --git a/Anticheat-master/.gradle/6.1.1/fileContent/annotation-processors.bin b/Anticheat-master/.gradle/6.1.1/fileContent/annotation-processors.bin new file mode 100644 index 0000000..72bbabd Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/fileContent/annotation-processors.bin differ diff --git a/Anticheat-master/.gradle/6.1.1/fileContent/fileContent.lock b/Anticheat-master/.gradle/6.1.1/fileContent/fileContent.lock new file mode 100644 index 0000000..2c17db0 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/fileContent/fileContent.lock differ diff --git a/Anticheat-master/.gradle/6.1.1/fileHashes/fileHashes.bin b/Anticheat-master/.gradle/6.1.1/fileHashes/fileHashes.bin new file mode 100644 index 0000000..d3a7882 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/fileHashes/fileHashes.bin differ diff --git a/Anticheat-master/.gradle/6.1.1/fileHashes/fileHashes.lock b/Anticheat-master/.gradle/6.1.1/fileHashes/fileHashes.lock new file mode 100644 index 0000000..eb064af Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/fileHashes/fileHashes.lock differ diff --git a/Anticheat-master/.gradle/6.1.1/fileHashes/resourceHashesCache.bin b/Anticheat-master/.gradle/6.1.1/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000..e80dd15 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/fileHashes/resourceHashesCache.bin differ diff --git a/Anticheat-master/.gradle/6.1.1/gc.properties b/Anticheat-master/.gradle/6.1.1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/Anticheat-master/.gradle/6.1.1/javaCompile/classAnalysis.bin b/Anticheat-master/.gradle/6.1.1/javaCompile/classAnalysis.bin new file mode 100644 index 0000000..3244e84 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/javaCompile/classAnalysis.bin differ diff --git a/Anticheat-master/.gradle/6.1.1/javaCompile/jarAnalysis.bin b/Anticheat-master/.gradle/6.1.1/javaCompile/jarAnalysis.bin new file mode 100644 index 0000000..fd242b5 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/javaCompile/jarAnalysis.bin differ diff --git a/Anticheat-master/.gradle/6.1.1/javaCompile/javaCompile.lock b/Anticheat-master/.gradle/6.1.1/javaCompile/javaCompile.lock new file mode 100644 index 0000000..cee1c68 Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/javaCompile/javaCompile.lock differ diff --git a/Anticheat-master/.gradle/6.1.1/javaCompile/taskHistory.bin b/Anticheat-master/.gradle/6.1.1/javaCompile/taskHistory.bin new file mode 100644 index 0000000..dc4cb8a Binary files /dev/null and b/Anticheat-master/.gradle/6.1.1/javaCompile/taskHistory.bin differ diff --git a/Anticheat-master/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/Anticheat-master/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000..874a8b8 Binary files /dev/null and b/Anticheat-master/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/Anticheat-master/.gradle/buildOutputCleanup/cache.properties b/Anticheat-master/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..d56db49 --- /dev/null +++ b/Anticheat-master/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Tue Feb 02 07:05:59 EST 2021 +gradle.version=6.1.1 diff --git a/Anticheat-master/.gradle/buildOutputCleanup/outputFiles.bin b/Anticheat-master/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000..62b63c4 Binary files /dev/null and b/Anticheat-master/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/Anticheat-master/.gradle/checksums/checksums.lock b/Anticheat-master/.gradle/checksums/checksums.lock new file mode 100644 index 0000000..0706b5e Binary files /dev/null and b/Anticheat-master/.gradle/checksums/checksums.lock differ diff --git a/Anticheat-master/.gradle/checksums/md5-checksums.bin b/Anticheat-master/.gradle/checksums/md5-checksums.bin new file mode 100644 index 0000000..0ebaf6b Binary files /dev/null and b/Anticheat-master/.gradle/checksums/md5-checksums.bin differ diff --git a/Anticheat-master/.gradle/checksums/sha1-checksums.bin b/Anticheat-master/.gradle/checksums/sha1-checksums.bin new file mode 100644 index 0000000..2b7d111 Binary files /dev/null and b/Anticheat-master/.gradle/checksums/sha1-checksums.bin differ diff --git a/Anticheat-master/.gradle/vcs-1/gc.properties b/Anticheat-master/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/Anticheat-master/build.gradle b/Anticheat-master/build.gradle new file mode 100644 index 0000000..0fd6ad7 --- /dev/null +++ b/Anticheat-master/build.gradle @@ -0,0 +1,38 @@ +plugins { + id 'java' + id "com.github.johnrengelman.shadow" version "5.2.0" +} + +group 'cc.fyre.anticheat' +version '1.0-SNAPSHOT' + +sourceCompatibility = 1.8 + +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + + compile 'org.apache.commons:commons-math3:3.6.1' + compile 'io.github.retrooper:packetevents:1.7.9' + compileOnly 'cc.fyre.universe:spigot:1.0-SNAPSHOT' + compileOnly 'cc.fyre.proton:proton:1.0-SNAPSHOT' + compileOnly 'cc.fury.piston:piston:1.0-SNAPSHOT' + compileOnly 'cc.fyre.neutron:neutron:1.0-SNAPSHOT' + compileOnly 'org.mongodb:mongo-java-driver:3.10.2' + compileOnly 'com.google.code.gson:gson:2.8.6' + compileOnly 'net.valorhcf:vspigot-server:1.7.10-R0.1-SNAPSHOT' + + annotationProcessor 'org.projectlombok:lombok:1.16.10' +} + +shadowJar { + classifier = null + minimize() +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} \ No newline at end of file diff --git a/Anticheat-master/gradle/wrapper/gradle-wrapper.properties b/Anticheat-master/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..1b16c34 --- /dev/null +++ b/Anticheat-master/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/Anticheat-master/gradlew b/Anticheat-master/gradlew new file mode 100644 index 0000000..2fe81a7 --- /dev/null +++ b/Anticheat-master/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/Anticheat-master/gradlew.bat b/Anticheat-master/gradlew.bat new file mode 100644 index 0000000..9618d8d --- /dev/null +++ b/Anticheat-master/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/Anticheat-master/settings.gradle b/Anticheat-master/settings.gradle new file mode 100644 index 0000000..e63ab4f --- /dev/null +++ b/Anticheat-master/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'anticheat' + diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/Riot.java b/Anticheat-master/src/main/java/cc/fyre/riot/Riot.java new file mode 100644 index 0000000..62f5770 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/Riot.java @@ -0,0 +1,105 @@ +package cc.fyre.riot; + +import cc.fyre.proton.Proton; +import cc.fyre.riot.ban.BanManager; +import cc.fyre.riot.command.*; +import cc.fyre.riot.events.TickEvent; +import cc.fyre.riot.flag.FlagHandler; +import cc.fyre.riot.listener.GeneralListener; +import cc.fyre.riot.log.LogHandler; +import cc.fyre.riot.packet.RiotPacketProcessor; +import cc.fyre.riot.packet.packets.AlertLogPacket; +import cc.fyre.riot.packet.packets.ExemptPacket; +import cc.fyre.riot.packet.packets.WhitelistPacket; +import cc.fyre.riot.packet.listener.RiotPiginPacketListener; +import cc.fyre.riot.profile.ProfileHandler; +import cc.fyre.riot.timings.AntiCheatTimings; +import cc.fyre.riot.util.Magic; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.LongSerializationPolicy; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; + +import io.github.retrooper.packetevents.PacketEvents; +import io.github.retrooper.packetevents.event.PacketEvent; +import io.github.retrooper.packetevents.event.manager.EventManager; +import lombok.Getter; + +import org.bson.Document; +import org.bukkit.plugin.java.JavaPlugin; + +import org.bukkit.craftbukkit.v1_7_R4.entity.*; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.UUID; + +public class Riot extends JavaPlugin { + + @Getter private static Riot instance; + + @Getter private Gson gson; + @Getter private Magic magic; + + @Getter private MongoDatabase mongoDatabase; + + @Getter private LogHandler logHandler; + @Getter private BanManager banManager; + @Getter private FlagHandler flagHandler; + @Getter private ProfileHandler profileHandler; + @Getter private MongoCollection logsCollection; + + @Getter private AntiCheatTimings timings; + @Getter private ArrayList exempted = new ArrayList<>(); + + @Override + public void onEnable() { + instance = this; + + this.gson = new GsonBuilder().setLongSerializationPolicy(LongSerializationPolicy.STRING).create(); + this.magic = new Magic("Riot", "riot_packet_handler"); + + this.mongoDatabase = new MongoClient("51.79.73.197").getDatabase("riot"); + + this.logsCollection = this.mongoDatabase.getCollection("logs"); + + this.timings = new AntiCheatTimings(); + this.profileHandler = new ProfileHandler(this); + this.flagHandler = new FlagHandler(this); + this.logHandler = new LogHandler(this); + this.banManager = new BanManager(); + PacketEvents.get().init(this); + Proton.getInstance().getCommandHandler().registerAll(this); + PacketEvents.get().registerListener(new RiotPacketProcessor()); + /* Proton.getInstance().getCommandHandler().registerClass(FakeFlagCommand.class); + Proton.getInstance().getCommandHandler().registerClass(AlertCommand.class); + Proton.getInstance().getCommandHandler().registerClass(InfoCommand.class); + Proton.getInstance().getCommandHandler().registerClass(LogsCommand.class); + Proton.getInstance().getCommandHandler().registerClass(RecordClicksCommand.class); + Proton.getInstance().getCommandHandler().registerClass(ResetCommand.class); + Proton.getInstance().getCommandHandler().registerClass(TopCommand.class); + Proton.getInstance().getCommandHandler().registerClass(WhitelistPacket.class);*/ + Proton.getInstance().getPidginHandler().registerPacket(WhitelistPacket.class); + Proton.getInstance().getPidginHandler().registerPacket(AlertLogPacket.class); + Proton.getInstance().getPidginHandler().registerPacket(ExemptPacket.class); + Proton.getInstance().getPidginHandler().registerListener(new RiotPiginPacketListener()); + + this.getServer().getPluginManager().registerEvents(new GeneralListener(this),this); + } + + @Override + public void onDisable() { + this.getServer().getOnlinePlayers().forEach(it -> ((CraftPlayer)it).getHandle().playerConnection.networkManager.m.pipeline().remove(this.magic.getChannelHandlerName())); + PacketEvents.get().stop(); + } + @Override + public void onLoad() { + PacketEvents.create() + .getSettings() + .checkForUpdates(false); + PacketEvents.get().load(); + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/ban/BanManager.java b/Anticheat-master/src/main/java/cc/fyre/riot/ban/BanManager.java new file mode 100644 index 0000000..f7f7aa4 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/ban/BanManager.java @@ -0,0 +1,63 @@ +package cc.fyre.riot.ban; + +import cc.fyre.neutron.Neutron; +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.log.LogHandler; +import cc.fyre.riot.profile.Profile; + +import cc.fyre.universe.UniverseAPI; +import org.apache.commons.math3.analysis.UnivariateVectorFunction; +import org.bson.Document; + + +import org.bukkit.*; + +import javax.swing.*; +import java.util.*; + +public class BanManager +{ + private final Riot main; + private final LogHandler logHandler; + ArrayList queued = new ArrayList<>(); + public BanManager() { + this.main = Riot.getInstance(); + this.logHandler = this.main.getLogHandler(); + } + + public void ban(final Profile profile,final Check check) { + + if (profile.isKicked() && profile.getPlayer().isOp() && Riot.getInstance().getExempted().contains(profile.getUuid()) && + !profile.getPlayer().isOnline() && check.getName().contains("EXP")) { + return; + } + + + profile.setKicked(true); + if(!queued.contains(profile.getUuid()) && !Riot.getInstance().getExempted().contains(profile.getUuid())) { + queued.add(profile.getUuid()); + Bukkit.getScheduler().runTaskLater(Riot.getInstance(), () -> { + + if(!UniverseAPI.getServerName().contains("Dev-")) + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ban " + profile.getName() + " perm Cheating"); + + if (check != null) { + this.logHandler.log(profile, check, ""); + } + if (profile.getPlayer().isOnline()) { + Bukkit.broadcastMessage(""); + Bukkit.broadcastMessage(ChatColor.DARK_PURPLE + "[Riot] " + Neutron.getInstance().getProfileHandler().fromUuid(profile.getUuid()).getFancyName() + ChatColor.RED + " got caught " + + "lacking and was suspended from the network."); + Bukkit.broadcastMessage(""); + } + queued.remove(profile.getUuid()); + }, 20); + } + + } + + public void ban(final Profile profile) { + this.ban(profile, null); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/Check.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/Check.java new file mode 100644 index 0000000..231f7b7 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/Check.java @@ -0,0 +1,70 @@ +package cc.fyre.riot.check; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.Location; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; + +public abstract class Check { + + @Getter private final String name; + @Getter private final Profile profile; + + @Getter @Setter private int violations; + @Getter @Setter private int minViolations; + + public Check(String name,Profile profile) { + this.name = name; + this.profile = profile; + } + + public int incrementViolations(final int amount) { + return this.violations += amount; + } + + public int incrementViolations() { + return this.incrementViolations(1); + } + + public void decrementViolations() { + this.violations = Math.max(this.minViolations, this.violations - 1); + } + + public void flag(final String metadata) { + + if (this.profile.isKicked() && this.profile.getPlayer().isOp() && Riot.getInstance().getExempted().contains(profile.getUuid())) { + return; + } + + Riot.getInstance().getLogHandler().log(this.profile,this,metadata); + + Riot.getInstance().getFlagHandler().flag(this.profile,this,metadata); + } + + public void flag(String metadata,Object... args) { + this.flag(String.format(metadata,args)); + } + + public void flag() { + this.flag(null); + } + + public void ban() { + Riot.getInstance().getBanManager().ban(this.profile,this); + } + + public void onTeleport() {} + + public void onMove(Location from,Location to,boolean moved,boolean rotated) {} + + public void handleInboundPacket(Object message,long millis,long nanos) {} + + public void handleOutboundPacket(Object message,long millis,final long nanos) {} + public void handleInboundPacketEvent(Object message, byte packetId) {} + + public void onMouseLeftClick(int ticks) {} + public void onPlayerAttacked(Player attacker, Player damaged) {} + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/aim/AimA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/aim/AimA.java new file mode 100644 index 0000000..3318dde --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/aim/AimA.java @@ -0,0 +1,75 @@ +package cc.fyre.riot.check.checks.combat.aim; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.Location; + + + +import net.minecraft.server.v1_7_R4.*; + +public class AimA extends Check +{ + private static final double MULTIPLIER; + private float lastDeltaPitch; + private int lastAttackTicks; + private int total; + private int bad; + private float totalDeltaYaw; + + public AimA(final Profile profile) { + super("Aim A", profile); + this.lastDeltaPitch = Float.NaN; + this.lastAttackTicks = 6; + } + + @Override + public void onMove(final Location from,final Location to,final boolean moved,final boolean rotated) { + if (rotated) { + final float deltaYaw = Math.abs(to.getYaw() - from.getYaw()); + final float deltaPitch = Math.abs(to.getPitch() - from.getPitch()); + if (!Float.isNaN(this.lastDeltaPitch) && deltaPitch != 0.0f && deltaPitch <= 10.0f && Math.abs(from.getPitch()) != 90.0f && Math.abs(to.getPitch()) != 90.0f && this.lastAttackTicks <= 5) { + final long one = (long)(deltaPitch * AimA.MULTIPLIER); + final long two = (long)(this.lastDeltaPitch * AimA.MULTIPLIER); + final long gcd = this.gcd(one, two); + if (gcd <= 131072L) { + ++this.bad; + } + this.totalDeltaYaw += deltaYaw; + if (++this.total == 250) { + if (this.bad >= 100 && this.totalDeltaYaw >= 180.0f) { + this.flag("B: %s/250 Y: %.2f", this.bad, this.totalDeltaYaw); + } + this.total = 0; + this.bad = 0; + this.totalDeltaYaw = 0.0f; + } + } + this.lastDeltaPitch = deltaPitch; + } + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInUseEntity) { + final PacketPlayInUseEntity packet = (PacketPlayInUseEntity)message; + if (packet.c() == EnumEntityUseAction.ATTACK) { + this.lastAttackTicks = 0; + } + } + else if (message instanceof PacketPlayInFlying) { + ++this.lastAttackTicks; + } + } + + private long gcd(final long one, final long two) { + if (two <= 16384L) { + return one; + } + return this.gcd(two, one % two); + } + + static { + MULTIPLIER = Math.pow(2.0, 24.0); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/aim/AimB.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/aim/AimB.java new file mode 100644 index 0000000..468b9e9 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/aim/AimB.java @@ -0,0 +1,42 @@ +package cc.fyre.riot.check.checks.combat.aim; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.Location; + + + + +public class AimB extends Check +{ + public AimB(final Profile profile) { + super("Aim B", profile); + super.setMinViolations(-10); + super.setViolations(-10); + } + + @Override + public void onMove(final Location from,final Location to,final boolean moved,final boolean rotated) { + if (rotated) { + final float deltaYaw = Math.abs(to.getYaw() - from.getYaw()); + final float deltaPitch = Math.abs(to.getPitch() - from.getPitch()); + boolean flagged = false; + if (deltaYaw != 0.0f && Math.round(deltaYaw) == deltaYaw && this.incrementViolations(2) >= 0) { + this.flag("T: Yaw D: %s VL: %s", deltaYaw, this.getViolations()); + flagged = true; + } + if (deltaPitch != 0.0f && Math.round(deltaPitch) == deltaPitch && this.incrementViolations(2) >= 0) { + this.flag("T: Pitch D: %s VL: %s", deltaPitch, this.getViolations()); + flagged = true; + } + if (flagged) { + if (this.getViolations() >= 10) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerA.java new file mode 100644 index 0000000..7cb2118 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerA.java @@ -0,0 +1,16 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.left; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + +public class AutoClickerA extends Check { + public AutoClickerA(Profile profile) { + super("AutoClicker A", profile); + } + @Override + public void handleInboundPacket(Object message,long millis,long nanos) { + + } + + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerD.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerD.java new file mode 100644 index 0000000..8f78ee7 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerD.java @@ -0,0 +1,39 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.left; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + + +public class AutoClickerD extends Check +{ + private boolean chilling; + private int streak; + + public AutoClickerD(final Profile profile) { + super("Auto Clicker D", profile); + this.chilling = false; + this.streak = 0; + } + + @Override + public void onMouseLeftClick(final int ticks) { + if (!this.chilling) { + if (ticks == 0) { + this.chilling = true; + if (++this.streak >= 20) { + this.flag("S: %s", this.streak); + if (this.streak == 40) { + this.ban(); + } + } + } + else { + this.streak = 0; + } + } + else { + this.chilling = false; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerG.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerG.java new file mode 100644 index 0000000..242b303 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerG.java @@ -0,0 +1,50 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.left; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + +import net.minecraft.server.v1_7_R4.*; + +public class AutoClickerG extends Check +{ + private boolean sent; + private int streak; + + public AutoClickerG(final Profile profile) { + super("Auto Clicker G", profile); + this.sent = false; + this.streak = 0; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInBlockDig) { + final PacketPlayInBlockDig packet = (PacketPlayInBlockDig)message; + if (packet.g() == 0) { + this.sent = true; + } + else if (packet.g() == 1) { + if (this.sent) { + if (++this.streak >= 20 && this.streak % 5 == 0) { + this.flag("S: %s", this.streak); + if (this.streak == 60) { + this.ban(); + } + } + } + else { + this.streak = 0; + } + } + } + else if (message instanceof PacketPlayInFlying) { + this.sent = false; + } + else if (message instanceof PacketPlayInBlockPlace) { + final PacketPlayInBlockPlace packet2 = (PacketPlayInBlockPlace)message; + if (packet2.getFace() != 255) { + this.streak = 0; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerH.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerH.java new file mode 100644 index 0000000..b1ca483 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerH.java @@ -0,0 +1,40 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.left; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import org.apache.commons.math3.stat.descriptive.moment.*; + +public class AutoClickerH extends Check +{ + private final double[] delays; + private int index; + + public AutoClickerH(final Profile profile) { + super("Auto Clicker H", profile); + this.delays = new double[100]; + this.index = 0; + } + + @Override + public void onMouseLeftClick(final int ticks) { + if (ticks <= 8) { + this.delays[this.index++] = ticks; + if (this.index == this.delays.length) { + this.index = 0; + final double cps = 20.0 / new Mean().evaluate(this.delays); + getProfile().getClickTracker().setCps(cps); + if (cps >= 18.0) { + this.flag("CPS: %.1f", cps); + if (cps >= 24.0 && this.incrementViolations(4) >= 10) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerK.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerK.java new file mode 100644 index 0000000..b10f1b6 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerK.java @@ -0,0 +1,34 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.left; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import org.apache.commons.math3.stat.descriptive.moment.*; + +public class AutoClickerK extends Check +{ + private final double[] delays; + private int index; + + public AutoClickerK(final Profile profile) { + super("Auto Clicker K", profile); + this.delays = new double[500]; + this.index = 0; + } + + @Override + public void onMouseLeftClick(final int ticks) { + if (ticks <= 8) { + this.delays[this.index++] = ticks; + if (this.index == this.delays.length) { + this.index = 0; + final double cps = 20.0 / new Mean().evaluate(this.delays); + final double kurtosis = new Kurtosis().evaluate(this.delays); + if (kurtosis <= 0.0 && cps >= 8.0) { + this.flag("K: %.2f CPS: %.2f", kurtosis, cps); + } + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerO.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerO.java new file mode 100644 index 0000000..b1d952d --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerO.java @@ -0,0 +1,35 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.left; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import org.apache.commons.math3.stat.descriptive.moment.*; +import java.util.*; + +public class AutoClickerO extends Check +{ + private final double[] delays; + private int index; + + public AutoClickerO(final Profile profile) { + super("Auto Clicker O", profile); + this.delays = new double[500]; + this.index = 0; + } + + @Override + public void onMouseLeftClick(final int ticks) { + if (ticks <= 8) { + this.delays[this.index++] = ticks; + if (this.index == this.delays.length) { + this.index = 0; + final double cps = 20.0 / new Mean().evaluate(this.delays); + final long outliers = Arrays.stream(this.delays).filter(d -> d >= 4.0).count(); + if (outliers <= 5L && cps >= 6.0) { + this.flag("O: %s/%s CPS: %.2f", outliers, this.delays.length, cps); + } + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerS.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerS.java new file mode 100644 index 0000000..622ad7b --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerS.java @@ -0,0 +1,34 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.left; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import org.apache.commons.math3.stat.descriptive.moment.*; + +public class AutoClickerS extends Check +{ + private final double[] delays; + private int index; + + public AutoClickerS(final Profile profile) { + super("Auto Clicker S", profile); + this.delays = new double[100]; + this.index = 0; + } + + @Override + public void onMouseLeftClick(final int ticks) { + if (ticks <= 8) { + this.delays[this.index++] = ticks; + if (this.index == this.delays.length) { + this.index = 0; + final double cps = 20.0 / new Mean().evaluate(this.delays); + final double sd = new StandardDeviation().evaluate(this.delays); + if (sd <= 0.5 && cps >= 8.0) { + this.flag("SD: %.3f CPS: %.1f VL: %s", sd, cps, this.getViolations()); + } + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerZ.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerZ.java new file mode 100644 index 0000000..1ec5e50 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/left/AutoClickerZ.java @@ -0,0 +1,53 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.left; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + + +public class AutoClickerZ extends Check +{ + private boolean checking; + private boolean magic; + private int streak; + + public AutoClickerZ(final Profile profile) { + super("Auto Clicker Z", profile); + this.checking = false; + this.magic = false; + this.streak = 0; + super.setMinViolations(-25); + super.setViolations(-25); + } + + @Override + public void onMouseLeftClick(final int ticks) { + if (ticks > 8) { + this.checking = true; + this.magic = false; + this.streak = 0; + } + else if (this.checking) { + if (this.streak == 0 && ticks == 0) { + this.magic = true; + } + else if (ticks == 0) { + this.checking = false; + } + else if (++this.streak == 20) { + if (this.magic) { + if (this.incrementViolations(10) >= 0) { + this.flag("VL: %s", this.getViolations()); + if (this.getViolations() >= 60) { + this.ban(); + } + } + } + else { + this.decrementViolations(); + } + this.checking = false; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/right/AutoClickerRA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/right/AutoClickerRA.java new file mode 100644 index 0000000..b11ba6d --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/autoclicker/right/AutoClickerRA.java @@ -0,0 +1,15 @@ +package cc.fyre.riot.check.checks.combat.autoclicker.right; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + +public class AutoClickerRA extends Check { + public AutoClickerRA(Profile profile) { + super("AutoClicker RA", profile); + } + + @Override + public void handleInboundPacket(Object message, long millis, long nanos) { + + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/killaura/KillAuraA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/killaura/KillAuraA.java new file mode 100644 index 0000000..13de0d8 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/killaura/KillAuraA.java @@ -0,0 +1,51 @@ +package cc.fyre.riot.check.checks.combat.killaura; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import io.github.retrooper.packetevents.packettype.PacketType; +import io.github.retrooper.packetevents.packetwrappers.in.flying.WrappedPacketInFlying; +import io.github.retrooper.packetevents.packetwrappers.in.useentity.WrappedPacketInUseEntity; +import lombok.val; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +public class KillAuraA extends Check { + public KillAuraA(Profile profile) { + super("KillAura A (EXP)", profile); + } + + public Long lastUseEntity; + private int buffer; + + @Override + public void handleInboundPacketEvent(Object message, byte packetId) { + if (PacketType.Client.Util.isInstanceOfFlying(packetId)) { + WrappedPacketInFlying packetInFlying = new WrappedPacketInFlying(message); + if (this.lastUseEntity != null) { + double delay = System.currentTimeMillis() - this.lastUseEntity; + if (delay < 100.0 && delay > 40.0 && getProfile().getLastPacketDrop() != getProfile().getTotalTicks() + && !getProfile().isLagging(System.currentTimeMillis(), 250L)) { + if (++this.buffer > 3) { + this.flag( "Killaura A", "Post killaura\n delay=" + delay); + if(getViolations() >= 15) { + ban(); + } + this.lastUseEntity = null; + } + } else { + this.buffer = Math.max(this.buffer - 1, 0); + } + } + } else if (PacketType.Client.USE_ENTITY == packetId) { + if (System.currentTimeMillis() - getProfile().getLastFlying() < 10L) { + this.lastUseEntity = getProfile().getLastFlying(); + } else { + this.buffer = Math.max(this.buffer - 1, 0); + } + } + } +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/killaura/MultiAura.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/killaura/MultiAura.java new file mode 100644 index 0000000..c94b5b1 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/killaura/MultiAura.java @@ -0,0 +1,42 @@ +package cc.fyre.riot.check.checks.combat.killaura; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class MultiAura extends Check +{ + private int lastAttackedId; + + public MultiAura(final Profile profile) { + super("Multi Aura", profile); + this.lastAttackedId = -1; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + try { + if (message instanceof PacketPlayInUseEntity) { + final PacketPlayInUseEntity packet = (PacketPlayInUseEntity)message; + if (packet.c() == EnumEntityUseAction.ATTACK && this.lastAttackedId != -1 && packet.a != this.lastAttackedId) { + this.flag(); + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + this.lastAttackedId = packet.a; + } + else if (message instanceof PacketPlayInFlying) { + this.lastAttackedId = -1; + } + } + catch (Throwable $ex) { + throw $ex; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/reach/ReachA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/reach/ReachA.java new file mode 100644 index 0000000..884bada --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/reach/ReachA.java @@ -0,0 +1,94 @@ +package cc.fyre.riot.check.checks.combat.reach; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.profile.tracker.LocationHistoryTracker; +import cc.fyre.riot.util.MathUtil; + +import org.bukkit.entity.*; + +import org.bukkit.*; +import java.util.*; + +import net.minecraft.server.v1_7_R4.*; + +public class ReachA extends Check +{ + private int attackedId; + private final LocationHistoryTracker.SparkLocation location; + private boolean moved; + + public ReachA(final Profile profile) { + super("Reach", profile); + this.attackedId = -1; + this.location = new LocationHistoryTracker.SparkLocation(0.0, 0.0, 0.0); + this.moved = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInFlying) { + final PacketPlayInFlying packet = (PacketPlayInFlying)message; + if (packet.k()) { + this.location.setYaw(packet.g()); + this.location.setPitch(packet.h()); + } + final List locations = this.getProfile().getLocationHistoryTracker().locationHistoryMap.get(this.attackedId); + + final Player player = Riot.getInstance().getProfileHandler().findByEntityId(this.attackedId); + + if (player != null) { + + final Profile targetProfile = Riot.getInstance().getProfileHandler().getCache().get(player.getUniqueId()); + + if (targetProfile != null && targetProfile.getMovementTracker().ticksSinceVehicle > 200 && targetProfile.getMovementTracker().ticksSinceVehicle > 200 && this.attackedId != -1 && this.getProfile().getPlayer().getGameMode() == GameMode.SURVIVAL && !this.getProfile().getMovementTracker().teleporting && locations != null) { + final List checking = new ArrayList<>(); + final int size = locations.size(); + boolean fucked = false; + for (int i = 0; i < size; ++i) { + final LocationHistoryTracker.SparkLocation l = locations.get(i); + if (i == size - 1) { + fucked = true; + break; + } + checking.add(l); + if (l.getTicks() > 4) { + break; + } + } + if (!fucked) { + double dist = checking.stream().mapToDouble(t -> MathUtil.getHorizontalDistanceToHitBox(this.location, t)).min().orElse(0.0); + final int ticks = checking.stream().mapToInt(LocationHistoryTracker.SparkLocation::getTicks).max().orElse(0); + if (!this.moved) { + dist -= 0.03; + } + if (dist >= 3.03) { + this.incrementViolations(1200); + this.flag("D: %.6f T: %s S: %s VL: %s", dist, ticks, checking.size(), this.getViolations()); + if (this.getViolations() >= 6000) { + this.ban(); + } + } + } + } + + } + + this.attackedId = -1; + if (packet.j()) { + this.location.setX(packet.c()); + this.location.setY(packet.d()); + this.location.setZ(packet.e()); + this.moved = packet.j(); + } + this.decrementViolations(); + } + else if (message instanceof PacketPlayInUseEntity) { + final PacketPlayInUseEntity packet2 = (PacketPlayInUseEntity)message; + if (packet2.c() == EnumEntityUseAction.ATTACK && Riot.getInstance().getProfileHandler().getIdToUUID().containsKey(packet2.a)) { + this.attackedId = packet2.a; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/reach/ReachB.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/reach/ReachB.java new file mode 100644 index 0000000..ee483be --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/combat/reach/ReachB.java @@ -0,0 +1,120 @@ +package cc.fyre.riot.check.checks.combat.reach; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.profile.tracker.AttackTracker; +import cc.fyre.riot.util.*; +import io.github.retrooper.packetevents.packettype.PacketType; +import io.github.retrooper.packetevents.packetwrappers.in.flying.WrappedPacketInFlying; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; + +public class ReachB extends Check { + + private double buffer, bufferBox; + private Vec3 eyeLocation; + private Vec3 look, lookMouseDelayFix; + + public ReachB(final Profile playerData) { + super("Reach B (EXP)", playerData); + } + + @Override + public void handleInboundPacketEvent(Object message, byte packetId) { + + if (PacketType.Client.Util.isInstanceOfFlying(packetId)) { + WrappedPacketInFlying packet = new WrappedPacketInFlying(message); + AttackTracker attackTracker = getProfile().getAttackTracker(); + Player player = getProfile().getPlayer(); + + if (!player.getGameMode().equals(GameMode.CREATIVE) + && attackTracker.getLastTarget() != null + && !getProfile().isLagging(System.currentTimeMillis(), 200L) + && getProfile().getLocationHistoryTracker().getPastLocs().size() >= 10 + && attackTracker.getLastAttackTick() <= 1 + && getProfile().getTotalTicks() - getProfile().getLastPacketDrop() > 5 + && System.currentTimeMillis() - getProfile().getLastDelayedPacket() > 160L + && getProfile().getLocationHistoryTracker().lastServerPositionTick > 100 + + Math.min(MathUtil.getPingInTicks(getProfile().getConnectionTracker().transactionPing), 5)) { + + float sneak = getProfile().getMovementTracker().sneaking ? 1.54F : 1.62F; + + if (getProfile().getPlayer().getLocation() != null) { + eyeLocation = MathUtil.getPositionEyes(attackTracker.getAttackerX(), attackTracker.getAttackerY(), attackTracker.getAttackerZ(), sneak); + } + + if (packet.isLook()) { + lookMouseDelayFix = MathUtil.getVectorForRotation(attackTracker.getAttackerPitch(), packet.getYaw()); + look = MathUtil.getVectorForRotation(attackTracker.getAttackerPitch(), attackTracker.getAttackerYaw()); + } else { + lookMouseDelayFix = MathUtil.getVectorForRotation(attackTracker.getAttackerPitch(), attackTracker.getAttackerYaw()); + look = lookMouseDelayFix; + } + + Vec3 vec3 = eyeLocation; + Vec3 vec31 = look; + Vec3 vec311 = lookMouseDelayFix; + + // Bukkit.broadcastMessage("eyeL: " + eyeLocation); + // Bukkit.broadcastMessage("lMDF: " + lookMouseDelayFix); + // Bukkit.broadcastMessage("look: " + look); + + Vec3 vec32 = vec3.addVector(vec31.xCoord * 6.0D, vec31.yCoord * 6.0D, vec31.zCoord * 6.0D); + Vec3 vec322 = vec3.addVector(vec311.xCoord * 6.0D, vec311.yCoord * 6.0D, vec311.zCoord * 6.0D); + + AxisAlignedBB axisalignedbb = new AxisAlignedBB(0, 0, 0, 0, 0, 0); + boolean a = false; + + int nowTicks = getProfile().getTotalTicks(); + int pingTicks = MathUtil.getPingInTicks(getProfile().getConnectionTracker().transactionPing) + 3; + + double distance = -1; + int collided = 0, missed = 0; + + for (Pair pair : getProfile().getLocationHistoryTracker().getPastLocs()) { + if (Math.abs(nowTicks - pair.getY() - pingTicks) < 2) { + if (!a) { + axisalignedbb = pair.getX(); + a = true; + } else { + axisalignedbb.minX = Math.min(axisalignedbb.minX, pair.getX().minX); + axisalignedbb.maxX = Math.max(axisalignedbb.maxX, pair.getX().maxX); + axisalignedbb.minY = Math.min(axisalignedbb.minY, pair.getX().minY); + axisalignedbb.maxY = Math.max(axisalignedbb.maxY, pair.getX().maxY); + axisalignedbb.minZ = Math.min(axisalignedbb.minZ, pair.getX().minZ); + axisalignedbb.maxZ = Math.max(axisalignedbb.maxZ, pair.getX().maxZ); + } + + MovingObjectPosition movingobjectposition = axisalignedbb.calculateIntercept(vec3, vec32); + MovingObjectPosition movingobjectposition2 = axisalignedbb.calculateIntercept(vec3, vec322); + + if (movingobjectposition != null && movingobjectposition2 != null && !axisalignedbb.isVecInside(vec3)) { + double d3 = vec3.distanceTo(movingobjectposition.hitVec); + double d33 = vec3.distanceTo(movingobjectposition2.hitVec); + distance = Math.min(d3, d33); + if (distance > 3.03D) { + ++collided; + } + } else if (movingobjectposition == null && movingobjectposition2 == null && !axisalignedbb.isVecInside(vec3)) { + ++missed; + } + } + } + double maxDist = 3.0D; + // Bukkit.broadcastMessage("P: " + player.getName() + " R: " + distance + " C: " + collided); + if (distance > 3.03D && collided > 2) { + if ((buffer += 1.5) > 3.5) { + this.flag("Range: %.6f C: %s P: %s MX: %s VL: %s", distance, collided, maxDist, buffer); + if (getViolations() > 25) { + ban(); + } + } else { + buffer = Math.max(buffer - 0.5, 0); + } + } + EntityLocationHandler.updateFlyingLocations(getProfile(), packet); + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryA.java new file mode 100644 index 0000000..c4ffcdb --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryA.java @@ -0,0 +1,45 @@ +package cc.fyre.riot.check.checks.inventory; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class InventoryA extends Check +{ + private boolean swung; + private boolean opened; + + public InventoryA(final Profile profile) { + super("Inventory A", profile); + this.swung = false; + this.opened = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInArmAnimation) { + this.swung = true; + } + else if (message instanceof PacketPlayInClientCommand) { + final PacketPlayInClientCommand packet = (PacketPlayInClientCommand)message; + if (packet.c() == EnumClientCommand.OPEN_INVENTORY_ACHIEVEMENT) { + this.opened = true; + } + } + else if (message instanceof PacketPlayInFlying) { + if (this.swung && this.opened) { + this.flag(); + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + this.swung = false; + this.opened = false; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryB.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryB.java new file mode 100644 index 0000000..ae0bb07 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryB.java @@ -0,0 +1,42 @@ +package cc.fyre.riot.check.checks.inventory; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class InventoryB extends Check +{ + private boolean swung; + private boolean clicked; + + public InventoryB(final Profile profile) { + super("Inventory B", profile); + this.swung = false; + this.clicked = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInArmAnimation) { + this.swung = true; + } + else if (message instanceof PacketPlayInWindowClick) { + this.clicked = true; + } + else if (message instanceof PacketPlayInFlying) { + if (this.swung && this.clicked) { + this.flag(); + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + this.swung = false; + this.clicked = false; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryC.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryC.java new file mode 100644 index 0000000..4edf54f --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryC.java @@ -0,0 +1,42 @@ +package cc.fyre.riot.check.checks.inventory; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class InventoryC extends Check +{ + private boolean swung; + private boolean closed; + + public InventoryC(final Profile profile) { + super("Inventory C", profile); + this.swung = false; + this.closed = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInArmAnimation) { + this.swung = true; + } + else if (message instanceof PacketPlayInCloseWindow) { + this.closed = true; + } + else if (message instanceof PacketPlayInFlying) { + if (this.swung && this.closed) { + this.flag(); + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + this.swung = false; + this.closed = false; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryD.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryD.java new file mode 100644 index 0000000..5c1b12a --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/inventory/InventoryD.java @@ -0,0 +1,30 @@ +package cc.fyre.riot.check.checks.inventory; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class InventoryD extends Check +{ + private boolean check; + + public InventoryD(final Profile profile) { + super("Inventory D", profile); + this.check = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInWindowClick) { + this.check = true; + } + else if (message instanceof PacketPlayInFlying) { + if (this.check && this.getProfile().getMovementTracker().sprinting) { + this.flag(); + } + this.check = false; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceA.java new file mode 100644 index 0000000..b4e5028 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceA.java @@ -0,0 +1,28 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class BlockPlaceA extends Check +{ + public BlockPlaceA(final Profile profile) { + super("Block Place A", profile); + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInBlockPlace) { + final PacketPlayInBlockPlace packet = (PacketPlayInBlockPlace)message; + final float x = packet.h(); + final float y = packet.i(); + final float z = packet.j(); + if (x > 1.0f || y > 1.0f || z > 1.0f) { + this.flag("X: %.2f Y: %.2f Z: %.2f", x, y, z); + this.ban(); + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceB.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceB.java new file mode 100644 index 0000000..236d5d0 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceB.java @@ -0,0 +1,28 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class BlockPlaceB extends Check +{ + public BlockPlaceB(final Profile profile) { + super("Block Place B", profile); + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInBlockPlace) { + final PacketPlayInBlockPlace packet = (PacketPlayInBlockPlace)message; + final int face = packet.getFace(); + final float x = packet.h(); + final float y = packet.i(); + final float z = packet.j(); + if (face == 255 && (x != 0.0f || y != 0.0f || z != 0.0f)) { + this.flag("X: %.2f Y: %.2f Z: %.2f", x, y, z); + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceC.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceC.java new file mode 100644 index 0000000..c9edf7e --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/BlockPlaceC.java @@ -0,0 +1,72 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +import java.util.logging.*; + +import org.bukkit.*; +import org.bukkit.Material; +import org.bukkit.World; + +public class BlockPlaceC extends Check +{ + public BlockPlaceC(final Profile profile) { + super("Block Place C", profile); + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInBlockPlace) { + + final PacketPlayInBlockPlace packet = (PacketPlayInBlockPlace)message; + final int x = packet.c(); + final int y = packet.d(); + final int z = packet.e(); + final int face = packet.getFace(); + final float blockY = packet.i(); + + if (face == 255) { + return; + } + + final double deltaXZ; + + if ((deltaXZ = Math.hypot(this.getProfile().getMovementTracker().lastLocation.getX() - x, this.getProfile().getMovementTracker().lastLocation.getZ() - z)) > 20.0) { + Riot.getInstance().getLogger().log(Level.WARNING, this.getProfile().getName() + " block placed " + deltaXZ + " blocks away"); + return; + } + + if (face == 1 && blockY == 0.0f) { + + Bukkit.getScheduler().runTask(Riot.getInstance(),() -> { + + final World world = this.getProfile().getPlayer().getWorld(); + final Location location = new Location(world,x,y,z); + + if (!world.isChunkLoaded(location.getChunk())) { + Riot.getInstance().getLogger().log(Level.WARNING, this.getProfile().getName() + " checking in an unloaded chunk BlockPlaceC"); + } else { + + final Material material = world.getBlockAt(x,y,z).getType(); + + if (material != Material.GOLD_PLATE && material != Material.IRON_PLATE && material != Material.STONE_PLATE && material != Material.WOOD_PLATE && material != Material.WATER_LILY) { + + this.flag("B: " + material.name()); + + if (this.incrementViolations() == 40) { + this.ban(); + } + + } + } + + }); + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/CustomPayload.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/CustomPayload.java new file mode 100644 index 0000000..0ba64bf --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/CustomPayload.java @@ -0,0 +1,75 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; +import org.bukkit.Bukkit; + +public class CustomPayload extends Check +{ + public CustomPayload(final Profile profile) { + super("Custom Payload", profile); + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInCustomPayload) { + final PacketPlayInCustomPayload packet = (PacketPlayInCustomPayload)message; + final String tag = packet.c(); + final byte[] data = packet.e(); + + boolean ban = true; + switch (tag) { + case "CRYSTAL|6LAKS0TRIES": { + this.flag("C: Crystalware"); + break; + } + case "1946203560": { + this.flag("C: Vape v3.25 Crack (Ape)"); + break; + } + case "0SO1Lk2KASxzsd": { + this.flag("C: bspkrsCore Client"); + break; + } + case "LOLIMAHCKER": { + this.flag("C: Cracked Client"); + } + case "cock": { + this.flag("C: Cracked Client"); + } + case "customGuiOpenBspkrs": { + this.flag("C: Cracked Client"); + } + case "mincraftpvphcker": { + this.flag("C: Cracked Client"); + } + case "lmaohax": { + this.flag("C: Cracked Client"); + } + case "MCnetHandler": { + this.flag("C: Cracked Client"); + } + case "L0LIMAHCKER": { + this.flag("C: Cracked Client"); + } + default: { + ban = false; + break; + } + } + if (ban) { + Bukkit.getScheduler().runTaskLater(Riot.getInstance(),() -> { + + if (!this.getProfile().isLoggedOut()) { + this.ban(); + } + + },600L); + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/DoubleSneak.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/DoubleSneak.java new file mode 100644 index 0000000..ae90e33 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/DoubleSneak.java @@ -0,0 +1,47 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class DoubleSneak extends Check +{ + private boolean sent; + private boolean flagged; + + public DoubleSneak(final Profile profile) { + super("Double Sneak", profile); + this.sent = false; + this.flagged = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInEntityAction) { + final PacketPlayInEntityAction packet = (PacketPlayInEntityAction)message; + if (packet.d() == 1 || packet.d() == 2) { + if (!this.sent) { + this.sent = true; + } + else { + this.flag(); + this.flagged = true; + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + } + } + else if (message instanceof PacketPlayInFlying) { + this.sent = false; + if (!this.flagged) { + this.decrementViolations(); + } + else { + this.flagged = false; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/DoubleSprint.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/DoubleSprint.java new file mode 100644 index 0000000..eb0ea46 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/DoubleSprint.java @@ -0,0 +1,47 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class DoubleSprint extends Check +{ + private boolean sent; + private boolean flagged; + + public DoubleSprint(final Profile profile) { + super("Double Sprint", profile); + this.sent = false; + this.flagged = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInEntityAction) { + final PacketPlayInEntityAction packet = (PacketPlayInEntityAction)message; + if (packet.d() == 4 || packet.d() == 5) { + if (!this.sent) { + this.sent = true; + } + else { + this.flag(); + this.flagged = true; + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + } + } + else if (message instanceof PacketPlayInFlying) { + this.sent = false; + if (!this.flagged) { + this.decrementViolations(); + } + else { + this.flagged = false; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/NoPosition.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/NoPosition.java new file mode 100644 index 0000000..a8b890e --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/NoPosition.java @@ -0,0 +1,34 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class NoPosition extends Check +{ + private int streak; + + public NoPosition(final Profile profile) { + super("No Position", profile); + this.streak = 0; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInFlying) { + final PacketPlayInFlying packet = (PacketPlayInFlying)message; + if (packet.j()) { + this.streak = 0; + } + else if (++this.streak > 20) { + this.flag("S: %s", this.streak); + this.ban(); + } + } + else if (message instanceof PacketPlayInSteerVehicle) { + this.streak = 0; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/Pitch.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/Pitch.java new file mode 100644 index 0000000..8a8f58b --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/Pitch.java @@ -0,0 +1,26 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.Location; + + + + +public class Pitch extends Check +{ + public Pitch(final Profile profile) { + super("Pitch", profile); + } + + @Override + public void onMove(final Location from,final Location to,final boolean moved,final boolean rotated) { + if (rotated) { + final float pitch = to.getPitch(); + if (Math.abs(pitch) > 90.0f) { + this.flag("P: %.6f", pitch); + this.ban(); + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/PostFlyingPacket.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/PostFlyingPacket.java new file mode 100644 index 0000000..7d87060 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/PostFlyingPacket.java @@ -0,0 +1,42 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; +import java.util.*; + +public class PostFlyingPacket extends Check +{ + private final Set> packets; + + public PostFlyingPacket(final Profile profile) { + super("Post Flying Packet", profile); + this.packets = new HashSet>(); + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInFlying) { + this.packets.clear(); + } + else if (message instanceof PacketPlayInArmAnimation || message instanceof PacketPlayInUseEntity || message instanceof PacketPlayInBlockPlace || message instanceof PacketPlayInBlockDig || message instanceof PacketPlayInEntityAction || message instanceof PacketPlayInAbilities) { + this.packets.add(message.getClass()); + } + else if (message instanceof PacketPlayInTransaction) { + if (!this.packets.isEmpty() && this.getProfile().getConnectionTracker().hasRespondedToTransaction() && !this.getProfile().getMovementTracker().teleporting) { + final StringJoiner sj = new StringJoiner(", "); + this.packets.forEach(p -> sj.add(p.getSimpleName())); + this.flag("P: %s", sj.toString()); + this.packets.clear(); + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/SameSlotSwitch.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/SameSlotSwitch.java new file mode 100644 index 0000000..7f2da4d --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/SameSlotSwitch.java @@ -0,0 +1,29 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class SameSlotSwitch extends Check +{ + private int lastSlot; + + public SameSlotSwitch(final Profile profile) { + super("Same Slot Switch", profile); + this.lastSlot = Integer.MIN_VALUE; + } + + @Override + public void handleOutboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInHeldItemSlot) { + final PacketPlayInHeldItemSlot packetPlayInHeldItemSlot = (PacketPlayInHeldItemSlot)message; + if (this.lastSlot != Integer.MIN_VALUE && this.lastSlot == packetPlayInHeldItemSlot.c()) { + this.flag("S: %s", this.lastSlot); + this.ban(); + } + this.lastSlot = packetPlayInHeldItemSlot.c(); + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TestFlag.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TestFlag.java new file mode 100644 index 0000000..1e5b1f1 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TestFlag.java @@ -0,0 +1,13 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + +public class TestFlag extends Check { + + + + public TestFlag(final Profile profile) { + super("Test Flag", profile); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TimerA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TimerA.java new file mode 100644 index 0000000..2e7529a --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TimerA.java @@ -0,0 +1,71 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + + + +import java.util.logging.*; +import net.minecraft.server.v1_7_R4.*; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; + +public class TimerA extends Check +{ + private long lastFlying; + private long balance; + private int packets; + private boolean fucked; + + public TimerA(final Profile profile) { + super("Timer A", profile); + this.lastFlying = System.nanoTime(); + this.balance = 0L; + this.packets = 0; + this.fucked = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInFlying && this.getProfile().getConnectionTracker().hasRespondedToTransaction()) { + final long delay = nanos - this.lastFlying; + this.balance += 50000000L - delay; + ++this.packets; + if (this.balance <= -20000000000L) { + this.balance = -1000000000L; + this.fucked = true; + } + else if (this.balance >= 100000000L) { + if (this.packets <= 2000) { + if (!this.fucked) { + final double multiplier = 5.0E7 / (5.0E7 - this.balance / (double)this.packets); + this.flag("M: %.2f P: %s VL: %s", multiplier, this.packets, this.incrementViolations()); + if (this.getViolations() == 10) { + this.ban(); + } + } + else if (!this.getProfile().isKicked()) { + this.getProfile().setKicked(true); + + Bukkit.getScheduler().runTaskLater(Riot.getInstance(),() -> { + ((CraftPlayer)this.getProfile().getPlayer()).getHandle().playerConnection.disconnect("Disconnected"); + Riot.getInstance().getLogger().log(Level.WARNING, this.getProfile().getName() + " has been disconnected for fucking up Timer A"); + },1L); + } + } + this.balance = 0L; + this.packets = 0; + } + this.lastFlying = nanos; + } + } + + @Override + public void handleOutboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayOutPosition) { + this.balance -= 50000000L; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TimerB.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TimerB.java new file mode 100644 index 0000000..5daaac9 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/misc/TimerB.java @@ -0,0 +1,62 @@ +package cc.fyre.riot.check.checks.misc; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; +import org.apache.commons.math3.stat.descriptive.moment.*; + +public class TimerB extends Check +{ + private long lastFlying; + private long catchUpTime; + private final double[] delays; + private int index; + private int streak; + + public TimerB(final Profile profile) { + super("Timer B", profile); + this.lastFlying = System.nanoTime(); + this.catchUpTime = 0L; + this.delays = new double[40]; + this.index = 0; + this.streak = 0; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInFlying) { + final long delay = (nanos - this.lastFlying) / 1000000L; + if (delay >= 500L) { + this.catchUpTime = System.currentTimeMillis() + 2000L; + this.index = 0; + this.streak = 0; + } + if (System.currentTimeMillis() >= this.catchUpTime) { + this.delays[this.index++] = (double)delay; + if (this.index == this.delays.length) { + this.index = 0; + final double avg = new Mean().evaluate(this.delays); + final double sd = new StandardDeviation().evaluate(this.delays); + final double multiplier = 50.0 / avg; + if (avg <= 49.0) { + if (++this.streak >= 5) { + this.flag("M: %.2f SD: %.2f S: %s", multiplier, sd, this.streak); + } + } + else { + this.streak = 0; + } + } + } + this.lastFlying = nanos; + } + } + + @Override + public void onTeleport() { + this.index = 0; + this.streak = 0; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/KeepSprint.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/KeepSprint.java new file mode 100644 index 0000000..54f8b1e --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/KeepSprint.java @@ -0,0 +1,99 @@ +package cc.fyre.riot.check.checks.movement; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.ClientUtil; +import cc.fyre.riot.util.Location; +import cc.fyre.riot.Riot; + + + +import net.minecraft.server.v1_7_R4.*; +import org.bukkit.Bukkit; +import org.bukkit.entity.*; + +import org.bukkit.potion.*; + + +public class KeepSprint extends Check +{ + private static final double[] SPEED_POTION_VALUES; + private boolean attacked; + private double lastDeltaXZ; + + public KeepSprint(final Profile profile) { + super("Keep Sprint", profile); + this.attacked = false; + this.lastDeltaXZ = Double.NaN; + + super.setViolations(-50); + super.setMinViolations(-50); + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInUseEntity) { + + Bukkit.getScheduler().runTask(Riot.getInstance(),() -> { + + final PacketPlayInUseEntity packet = (PacketPlayInUseEntity) (message); + + if (packet.c() == EnumEntityUseAction.ATTACK) { + + final Player player = Riot.getInstance().getProfileHandler().findByEntityId(packet.a); + + if (player == null) { + return; + } + + this.attacked = true; + } + + }); + + } + } + + @Override + public void onMove(final Location from,final Location to,final boolean moved,final boolean rotated) { + + Bukkit.getScheduler().runTask(Riot.getInstance(),() -> { + + if (!moved) { + return; + } + + final double deltaXZ = Math.hypot(to.getX() - from.getX(), to.getZ() - from.getZ()); + final int speedPotionAmplifier = ClientUtil.getPotionAmplifier(this.getProfile().getPlayer(),PotionEffectType.SPEED) + 1; + + if (this.attacked && this.getProfile().getMovementTracker().sprinting && !Double.isNaN(this.lastDeltaXZ) && speedPotionAmplifier < KeepSprint.SPEED_POTION_VALUES.length) { + + final double speedMultiplier = deltaXZ / KeepSprint.SPEED_POTION_VALUES[speedPotionAmplifier]; + final double deltaMultiplier = deltaXZ / this.lastDeltaXZ; + + if (speedMultiplier >= 0.9) { + + if (deltaMultiplier >= 0.9 && deltaMultiplier <= 1.005) { + + if (this.incrementViolations(10) >= 0) { + this.flag("SM: %.4f DM: %.4f S: %s VL: %s", speedMultiplier, deltaMultiplier, speedPotionAmplifier, this.getViolations()); + + if (this.getViolations() >= 500) { + this.ban(); + } + } + + } else { + this.decrementViolations(); + } + } + this.lastDeltaXZ = deltaXZ; + } + this.attacked = false; + }); + } + + static { + SPEED_POTION_VALUES = new double[] { 0.2806, 0.3367, 0.3929, 0.449, 0.5051 }; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/falling/NoFallA.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/falling/NoFallA.java new file mode 100644 index 0000000..9d448cc --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/falling/NoFallA.java @@ -0,0 +1,67 @@ +package cc.fyre.riot.check.checks.movement.falling; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.BlockUtil; +import cc.fyre.riot.util.Location; +import io.github.retrooper.packetevents.packettype.PacketType; +import io.github.retrooper.packetevents.packetwrappers.in.flying.WrappedPacketInFlying; +import net.minecraft.util.com.google.common.math.DoubleMath; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; + +import java.util.logging.Level; + +public class NoFallA extends Check { + + private double buffer; + public NoFallA(final Profile profile) { + super("NoFallA (EXP)", profile); + } + + @Override + public void handleInboundPacketEvent(Object message, byte packetId) { + if (PacketType.Client.Util.isInstanceOfFlying(packetId)) { + WrappedPacketInFlying packetInFlying = new WrappedPacketInFlying(message); + if (packetInFlying.isPosition()) { + Player player = getProfile().getPlayer(); + + boolean onGround = BlockUtil.isOnGroundBB(player); + boolean lastOnGround = getProfile().lastOnGround; + getProfile().lastOnGround = onGround; + boolean lastLastOnGround = getProfile().lastLastOnGround; + getProfile().lastLastOnGround = lastOnGround; + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + this.buffer = Math.max(this.buffer - 0.75, 0.0); + return; + } + + if (!(packetInFlying.isOnGround() || getProfile().getTotalTicks() - getProfile().getLastPacketDrop() <= 10 || + BlockUtil.isOnBadJesusBlock(player) || onGround || lastOnGround || lastLastOnGround)) { + for (Entity ent : player.getNearbyEntities(3.0, 3.0, 3.0)) { + if (!(ent instanceof Boat)) continue; + return; + } + this.buffer += 1.0; + if (buffer > 5.0) { + flag("Spoofed Ground state"); + if(this.getViolations() >= 15) { + ban(); + } + } + + } else { + this.buffer = Math.max(this.buffer - 0.75, 0.0); + } + } + } + } +} + + + diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/fly/Fly.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/fly/Fly.java new file mode 100644 index 0000000..0ceeced --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/fly/Fly.java @@ -0,0 +1,82 @@ +package cc.fyre.riot.check.checks.movement.fly; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.BlockUtil; +import net.minecraft.util.com.google.common.math.DoubleMath; + + + +import cc.fyre.riot.util.Location; +import org.bukkit.*; + +import java.util.logging.*; +import org.bukkit.block.*; + + +public class Fly extends Check +{ + private double lastDeltaY; + private int streak; + + public Fly(final Profile profile) { + super("Fly", profile); + } + + @Override + public void onMove(final Location from,final Location to,final boolean moved,final boolean rotated) { + if (moved) { + + Bukkit.getScheduler().runTask(Riot.getInstance(),() -> { + + final double deltaY = to.getY() - from.getY(); + + if (deltaY != 0.0 && deltaY == this.lastDeltaY && deltaY > -3.92 && !DoubleMath.fuzzyEquals(deltaY, -0.098, 1.0E-5) && !this.getProfile().getPlayer().getAllowFlight() && this.getProfile().getMovementTracker().velocityList.stream().noneMatch(v -> DoubleMath.fuzzyEquals(deltaY, v.getY(), 1.25E-4)) && this.isInAir(this.getProfile().getPlayer().getWorld(), to)) { + if (++this.streak >= 2) { + boolean known = (DoubleMath.fuzzyEquals(Math.abs(deltaY), 0.1, 1.0E-5) || DoubleMath.fuzzyEquals(deltaY, 0.06, 1.0E-5) || DoubleMath.fuzzyEquals(deltaY, -0.17, 1.0E-5) || DoubleMath.fuzzyEquals(Math.abs(deltaY), 0.04, 1.0E-5) || DoubleMath.fuzzyEquals(deltaY, 0.1176, 1.0E-5) || DoubleMath.fuzzyEquals(deltaY, -0.15, 1.0E-5)); + this.flag("Y: %.5f S: %s K: %s", deltaY, this.streak, known); + if (this.streak == 20 && !known) { + this.ban(); + } + } + } else { + this.streak = 0; + } + + this.lastDeltaY = deltaY; + }); + + } + } + + @Override + public void onTeleport() { + this.streak = 0; + } + + public Boolean isInAir(final World world, final Location location) { + final int minX = (int)Math.floor(location.getX() - 0.3); + final int minY = (int)Math.floor(location.getY() - 0.5 - 1.0E-5); + final int minZ = (int)Math.floor(location.getZ() - 0.3); + final int maxX = (int)Math.floor(location.getX() + 0.3); + final int maxY = (int)Math.floor(location.getY() + 1.8); + final int maxZ = (int)Math.floor(location.getZ() + 0.3); + for (int x = minX; x <= maxX; ++x) { + for (int y = minY; y <= maxY; ++y) { + for (int z = minZ; z <= maxZ; ++z) { + final org.bukkit.Location loc = new org.bukkit.Location(world, (double)x, (double)y, (double)z); + final Block block = loc.getBlock(); + if (!world.isChunkLoaded(loc.getChunk())) { + Riot.getInstance().getLogger().log(Level.WARNING, this.getProfile().getName() + " checking in an unloaded chunk Fly#isInAir"); + return false; + } + if (!BlockUtil.TYPES.contains(block.getType())) { + return false; + } + } + } + } + return true; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/speed/Speed.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/speed/Speed.java new file mode 100644 index 0000000..715c228 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/speed/Speed.java @@ -0,0 +1,199 @@ +package cc.fyre.riot.check.checks.movement.speed; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.Velocity; + + + +import java.util.*; + +import org.bukkit.entity.Player; +import org.bukkit.potion.*; + +import java.util.logging.*; +import org.bukkit.*; +import org.bukkit.block.*; + +public class Speed extends Check +{ + private int fuckedTicks; + private int moreFuckedTicks; + private int reallyFuckedTicks; + private int speedAmplifier; + private int speedTicks; + + public Speed(final Profile profile) { + super("Speed", profile); + this.fuckedTicks = 0; + this.moreFuckedTicks = 0; + this.reallyFuckedTicks = 0; + this.speedAmplifier = 0; + this.speedTicks = 0; + super.setMinViolations(-200); + super.setViolations(-200); + } + + @Override + public void onMove(final cc.fyre.riot.util.Location from,final cc.fyre.riot.util.Location to,final boolean moved,final boolean rotated) { + if (moved) { + + Bukkit.getScheduler().runTask(Riot.getInstance(),() -> { + + final Velocity velocityMax = this.getProfile().getMovementTracker().velocityList.stream().max(Comparator.comparing(Velocity::getXz)).orElse(null); + + double maxDeltaXZ; + + final double deltaXZ = Math.hypot(to.getX() - from.getX(), to.getZ() - from.getZ()); + final double deltaY = to.getY() - from.getY(); + + final Player player = this.getProfile().getPlayer(); + + final PotionEffect speedEffect = player.getActivePotionEffects().stream().filter(p -> + p.getType().equals(PotionEffectType.SPEED)).findFirst().orElse(null); + + final int currentSpeedAmplifier = ((speedEffect == null) ? 0 : (speedEffect.getAmplifier() + 1)); + + if (currentSpeedAmplifier >= this.speedAmplifier) { + this.speedAmplifier = currentSpeedAmplifier; + this.speedTicks = 200; + } + + else if (this.speedTicks > 0 && --this.speedTicks == 0) { + this.speedAmplifier = currentSpeedAmplifier; + } + if (player.getAllowFlight() || player.getWalkSpeed() > 0.2f || player.isInsideVehicle()) { + this.reallyFuckedTicks = 200; + } + else if (this.reallyFuckedTicks > 0) { + --this.reallyFuckedTicks; + } + + final World world = player.getWorld(); + + if (this.isUnderBlock(player,world, to) || this.isFucked(player,world, to)) { + this.fuckedTicks = 20; + } + else if (this.fuckedTicks > 0) { + --this.fuckedTicks; + } + if (this.isOnIce(player,world, to)) { + this.moreFuckedTicks = 50; + } + else if (this.moreFuckedTicks > 0) { + --this.moreFuckedTicks; + } + if (this.reallyFuckedTicks == 0) { + maxDeltaXZ = 0.36; + if (deltaY >= 0.41999) { + maxDeltaXZ = 0.62; + } + else if (deltaY == 0.0) { + maxDeltaXZ = 0.42; + } + if (speedEffect != null) { + maxDeltaXZ += this.speedAmplifier * 0.06; + } + if (velocityMax != null) { + maxDeltaXZ += velocityMax.getXz(); + } + if (this.fuckedTicks > 0) { + maxDeltaXZ *= 2.0; + } + if (this.moreFuckedTicks > 0) { + maxDeltaXZ *= 2.0; + } + if (deltaXZ > maxDeltaXZ) { + if (this.incrementViolations(20) >= 0) { + this.flag("%.3f > %.3f VL: %s", deltaXZ, maxDeltaXZ, this.getViolations()); + + if (this.getViolations() >= 400) { + this.ban(); + } + } + } + else { + this.decrementViolations(); + } + } + }); + + } + } + + public Boolean isUnderBlock(Player player,final World world, final cc.fyre.riot.util.Location location) { + final int minX = (int)Math.floor(location.getX() - 0.4); + final int minY = (int)Math.floor(location.getY() + 1.8); + final int minZ = (int)Math.floor(location.getZ() - 0.4); + final int maxX = (int)Math.floor(location.getX() + 0.4); + final int maxY = (int)Math.floor(location.getY() + 2.0 + 1.0E-5); + final int maxZ = (int)Math.floor(location.getZ() + 0.4); + for (int x = minX; x <= maxX; ++x) { + for (int y = minY; y <= maxY; ++y) { + for (int z = minZ; z <= maxZ; ++z) { + final org.bukkit.Location loc = new org.bukkit.Location(world, (double)x, (double)y, (double)z); + if (!world.isChunkLoaded(loc.getChunk())) { + Riot.getInstance().getLogger().log(Level.WARNING, player.getName() + " checking in an unloaded chunk Speed#isUnderBlock"); + return true; + } + if (loc.getBlock().getType() != Material.AIR) { + return true; + } + } + } + } + return false; + } + + public Boolean isOnIce(Player player,final World world, final cc.fyre.riot.util.Location location) { + final int minX = (int)Math.floor(location.getX() - 0.4); + final int minY = (int)Math.floor(location.getY() - 1.0 - 1.0E-5); + final int minZ = (int)Math.floor(location.getZ() - 0.4); + final int maxX = (int)Math.floor(location.getX() + 0.4); + final int maxY = (int)Math.floor(location.getY()); + final int maxZ = (int)Math.floor(location.getZ() + 0.4); + for (int x = minX; x <= maxX; ++x) { + for (int y = minY; y <= maxY; ++y) { + for (int z = minZ; z <= maxZ; ++z) { + final org.bukkit.Location loc = new org.bukkit.Location(world, (double)x, (double)y, (double)z); + if (!world.isChunkLoaded(loc.getChunk())) { + Riot.getInstance().getLogger().log(Level.WARNING, player.getName() + " checking in an unloaded chunk Speed#isOnIce: " + loc.getX() + ", " + loc.getY() + ", " + loc.getZ()); + return true; + } + if (loc.getBlock().getType().name().contains("ICE")) { + return true; + } + } + } + } + return false; + } + + public Boolean isFucked(Player player,final World world, final cc.fyre.riot.util.Location location) { + final int minX = (int)Math.floor(location.getX() - 0.4); + final int minY = (int)Math.floor(location.getY() - 0.5 - 1.0E-5); + final int minZ = (int)Math.floor(location.getZ() - 0.4); + final int maxX = (int)Math.floor(location.getX() + 0.4); + final int maxY = (int)Math.floor(location.getY() + 2.0 + 1.0E-5); + final int maxZ = (int)Math.floor(location.getZ() + 0.4); + for (int x = minX; x <= maxX; ++x) { + for (int y = minY; y <= maxY; ++y) { + for (int z = minZ; z <= maxZ; ++z) { + final org.bukkit.Location loc = new org.bukkit.Location(world, (double)x, (double)y, (double)z); + final Block block = loc.getBlock(); + final Material material = block.getType(); + final String name = material.name(); + if (!world.isChunkLoaded(loc.getChunk())) { + Riot.getInstance().getLogger().log(Level.WARNING, player.getName() + " checking in an unloaded chunk Speed#isFucked"); + return true; + } + if (name.contains("STAIR") || name.contains("STEP")) { + return true; + } + } + } + } + return false; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/speed/SpeedB.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/speed/SpeedB.java new file mode 100644 index 0000000..24b7afd --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/speed/SpeedB.java @@ -0,0 +1,146 @@ +/*package cc.fyre.riot.check.checks.movement.speed; + +import cc.fyre.proton.util.PlayerUtils; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.BlockUtil; +import cc.fyre.riot.util.ClientUtil; +import cc.fyre.riot.util.Location; +import net.minecraft.server.v1_7_R4.PacketPlayInFlying; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class SpeedB extends Check { + + private double buffer, buffer2; + + public SpeedB(Profile profile) { + super("SpeedB", profile); + } + + @Override + public void handleInboundPacket(Object message,long millis,long nanos) { + if (message instanceof PacketPlayInFlying) { + Player player = getProfile().getPlayer(); + PacketPlayInFlying packet = (PacketPlayInFlying) message; + final boolean hasPos = packet.j(); + final boolean hasLook = packet.k(); + final double x = packet.c(); + final double y = packet.d(); + final double z = packet.e(); + final float yaw = packet.g(); + final float pitch = packet.h(); + final Location location = new Location(x, y, z, yaw, pitch); + if (!hasPos) { + location.setX(getProfile().getMovementTracker().lastLocation.getX()); + location.setY(getProfile().getMovementTracker().lastLocation.getY()); + location.setZ(getProfile().getMovementTracker().lastLocation.getZ()); + } + if (!hasLook) { + location.setYaw(getProfile().getMovementTracker().lastLocation.getYaw()); + location.setPitch(getProfile().getMovementTracker().lastLocation.getPitch()); + } + if(((PacketPlayInFlying) message).i()) { + float maxSpeed = (((PacketPlayInFlying) message).i() && !BlockUtil.isOnLily(player)) ? 0.3125f : 0.3585f; + float maxSpeed2 = (((PacketPlayInFlying) message).i() && !BlockUtil.isOnLily(player)) ? 0.6f : 1.0f; + + float speedLevel = ClientUtil.getPotionAmplifier(player, PotionEffectType.SPEED); + + + if (player.isFlying() + || player.getAllowFlight() + || getProfile().getTeleportLocation() != null + || player.getGameMode().equals(GameMode.CREATIVE) + || player.isInsideVehicle() + || event.getTimestamp() - playerData.getLastVehicle() < 2000L + || (playerData.getTotalTicks() - playerData.lastTeleportReset) < 25 + || playerData.getDeltaXZ() <= 0.01) return; + + + maxSpeed2 += getProfile().getMovementTracker().getGroundTicks() < 5 ? speedLevel * 0.07f : speedLevel * 0.0573f; + maxSpeed2 *= getProfile().getMovementTracker().iceTicks > 0 ? 4.4f : 1.0; + + maxSpeed += getProfile().getMovementTracker().getGroundTicks() < 5 ? speedLevel * 0.07f : speedLevel * 0.0573f; + maxSpeed *= getProfile().getMovementTracker().iceTicks > 0 ? 4.4f : 1.0; + + if(getProfile().getMovementTracker().iceTicks == 0) { + if(BlockUtil.isNearIce(player)) { + maxSpeed *= 4.4f; + maxSpeed2 *= 4.4f; + } + } + + maxSpeed *= getProfile().getMovementTracker().slimeTicks > 0 ? 1.25f : 1.0; + maxSpeed += BlockUtil.blockNearHead(player) ? 0.25 : 0.0; + + if(getProfile().getMovementTracker().getTotalTicks() - getProfile().getMovementTracker().getLastFlyTick() < 40) { + maxSpeed += 0.3; + maxSpeed2 += 0.3; + } + final PotionEffect speedEffect = player.getActivePotionEffects().stream().filter(p -> + p.getType().equals(PotionEffectType.SPEED)).findFirst().orElse(null); + + maxSpeed += (player.getWalkSpeed() - 0.2) * 2.5; + maxSpeed += (player.getFlySpeed() - 0.1) * 2.5; + + maxSpeed2 += (player.getWalkSpeed() - 0.2) * 2.5; + maxSpeed2 += (player.getFlySpeed() - 0.1) * 2.5; + + maxSpeed *= (BlockUtil.isOnStair(player) || BlockUtil.isOnStair2(player)) || BlockUtil.isOnSlab(player) ? 1.5f : 1.0; + + maxSpeed += getProfile().getMovementTracker().getVelocityHorizontal(); + maxSpeed2 += getProfile().getMovementTracker().getVelocityHorizontal(); + + if(getProfile().getMovementTracker().isUnderBlock()) + maxSpeed += 0.26; + double maxDeltaXZ; + + final double deltaXZ = Math.hypot(to.getX() - from.getX(), to.getZ() - from.getZ()); + final double deltaY = to.getY() - from.getY(); + + maxDeltaXZ = 0.36; + if (deltaY >= 0.41999) { + maxDeltaXZ = 0.62; + } + else if (deltaY == 0.0) { + maxDeltaXZ = 0.42; + } + if (speedEffect != null) { + maxDeltaXZ += this.speedAmplifier * 0.06; + } + if (velocityMax != null) { + maxDeltaXZ += velocityMax.getXz(); + } + if (this.fuckedTicks > 0) { + maxDeltaXZ *= 2.0; + } + if (this.moreFuckedTicks > 0) { + maxDeltaXZ *= 2.0; + } + + //Bukkit.broadcastMessage("§7[§c§lPOST-DEBUG§7] §fS: §c" + playerData.getDeltaXZ() + " §fM: §c" + maxSpeed); + + if (getProfile().deltaXZ > maxSpeed) { + if(++buffer > 15) { + buffer -= 2; + this.flag("%.3f > %.3f VL: %s", getProfile().deltaXZ, maxSpeed, this.getViolations()); + } + } else { + buffer -= buffer > 0 ? 1 : 0; + } + + if(playerData.deltaXZ > maxSpeed2 && !playerData.isLagging2(System.currentTimeMillis(), 100L)) { + if((buffer2 += 10) > 30) { + flag(player, "Speed B ", "§7* §6deltaXZ=§e" + playerData.deltaXZ + "\n§7* §6maxSpeed2=§e" + maxSpeed2, getBanVL("SpeedA"), 60000L); + } + } else { + buffer2 -= buffer2 > 0 ? 1 : 0; + } + } + } + } +}*/ \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/velocity/VerticalVelocity.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/velocity/VerticalVelocity.java new file mode 100644 index 0000000..9b27144 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/movement/velocity/VerticalVelocity.java @@ -0,0 +1,135 @@ +package cc.fyre.riot.check.checks.movement.velocity; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.BlockUtil; + + +import net.minecraft.server.v1_7_R4.*; + +import org.bukkit.*; + +import java.util.logging.*; + +import org.bukkit.World; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + +public class VerticalVelocity extends Check +{ + private boolean checking; + private short transactionId; + private double expectedMotionY; + private double highestMotionY; + private boolean taken; + private boolean received; + + public VerticalVelocity(final Profile profile) { + super("Vertical Velocity", profile); + super.setMinViolations(-50); + super.setViolations(-50); + } + + @Override + public void handleOutboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayOutEntityVelocity) { + final PacketPlayOutEntityVelocity packet = (PacketPlayOutEntityVelocity)message; + if (this.checking) { + return; + } + if (packet.a != this.getProfile().getPlayer().getEntityId()) { + return; + } + if (this.getProfile().getMovementTracker().ticksSinceVehicle <= 200) { + return; + } + final double y = packet.c / 8000.0; + if (y <= 0.03) { + return; + } + this.checking = true; + this.transactionId = this.getProfile().getConnectionTracker().sendTransaction(); + this.expectedMotionY = y; + } + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInTransaction) { + final PacketPlayInTransaction packet = (PacketPlayInTransaction)message; + if (this.checking && packet.d() == this.transactionId) { + this.received = true; + } + } + } + + @Override + public void onMove(final cc.fyre.riot.util.Location from,final cc.fyre.riot.util.Location to,final boolean moved,final boolean rotated) { + if (moved && this.checking) { + final double deltaY = to.getY() - from.getY(); + this.highestMotionY = Math.max(this.highestMotionY, deltaY); + if (this.highestMotionY >= this.expectedMotionY - 1.0E-5) { + this.taken = true; + } + } + if (this.received) { + boolean finalTaken = this.taken; + double finalHighestMotionY = this.highestMotionY; + double finalExpectedMotionY = this.expectedMotionY; + + Bukkit.getScheduler().runTask(Riot.getInstance(),() -> { + + final Player player = this.getProfile().getPlayer(); + + if (!finalTaken && Math.abs(finalHighestMotionY - 0.42D) > 1.0E-5D && !this.isFucked(player,player.getWorld(), from) && !this.isFucked(player,player.getWorld(), to)) { + if (this.incrementViolations(10) >= 0) { + this.flag("M: %.2f V: %.5f HV: %.20f FY: %.4f TY: %.4f",finalHighestMotionY / finalExpectedMotionY,finalExpectedMotionY,finalHighestMotionY,from.getY(),to.getY()); + } + } else { + this.decrementViolations(); + } + + this.checking = false; + this.highestMotionY = 0.0D; + this.taken = false; + this.received = false; + + }); + } + } + + @Override + public void onTeleport() { + this.checking = false; + this.highestMotionY = 0.0; + this.taken = false; + this.received = false; + } + + public Boolean isFucked(Player player,final World world,final cc.fyre.riot.util.Location location) { + final int minX = (int)Math.floor(location.getX() - 0.3); + final int minY = (int)Math.floor(location.getY()); + final int minZ = (int)Math.floor(location.getZ() - 0.3); + final int maxX = (int)Math.floor(location.getX() + 0.3); + final int maxY = (int)Math.floor(location.getY() + 2.0 + 1.0E-5); + final int maxZ = (int)Math.floor(location.getZ() + 0.3); + for (int x = minX; x <= maxX; ++x) { + for (int y = minY; y <= maxY; ++y) { + for (int z = minZ; z <= maxZ; ++z) { + final org.bukkit.Location loc = new org.bukkit.Location(world, (double)x, (double)y, (double)z); + if (!world.isChunkLoaded(loc.getChunk())) { + Riot.getInstance().getLogger().log(Level.WARNING,player.getName() + " checking in an unloaded chunk VerticalVelocity#isFucked"); + return true; + } + final Block block = loc.getBlock(); + if (!BlockUtil.TYPES.contains(block.getType())) { + return true; + } + } + } + } + return false; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/ActionAttack.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/ActionAttack.java new file mode 100644 index 0000000..956cf43 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/ActionAttack.java @@ -0,0 +1,48 @@ +package cc.fyre.riot.check.checks.order; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class ActionAttack extends Check +{ + private boolean sent; + private boolean flagged; + + public ActionAttack(final Profile profile) { + super("Action Attack", profile); + this.sent = false; + this.flagged = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInEntityAction) { + this.sent = true; + } + else if (message instanceof PacketPlayInUseEntity) { + final PacketPlayInUseEntity packet = (PacketPlayInUseEntity)message; + if (packet.c() == EnumEntityUseAction.ATTACK && this.sent) { + this.flag(); + this.flagged = true; + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + } + else if (message instanceof PacketPlayInFlying) { + this.sent = false; + if (!this.flagged) { + this.decrementViolations(); + } + else { + this.flagged = false; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/NoSwingAttack.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/NoSwingAttack.java new file mode 100644 index 0000000..f4bbb8e --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/NoSwingAttack.java @@ -0,0 +1,48 @@ +package cc.fyre.riot.check.checks.order; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class NoSwingAttack extends Check +{ + private boolean sent; + private boolean flagged; + + public NoSwingAttack(final Profile profile) { + super("No Swing Attack", profile); + this.sent = false; + this.flagged = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInArmAnimation) { + this.sent = true; + } + else if (message instanceof PacketPlayInUseEntity) { + final PacketPlayInUseEntity packet = (PacketPlayInUseEntity)message; + if (packet.c() == EnumEntityUseAction.ATTACK && !this.sent) { + this.flag(); + this.flagged = true; + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + } + else if (message instanceof PacketPlayInFlying) { + this.sent = false; + if (!this.flagged) { + this.decrementViolations(); + } + else { + this.flagged = false; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceAttack.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceAttack.java new file mode 100644 index 0000000..1fe8080 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceAttack.java @@ -0,0 +1,48 @@ +package cc.fyre.riot.check.checks.order; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class PlaceAttack extends Check +{ + private boolean sent; + private boolean flagged; + + public PlaceAttack(final Profile profile) { + super("Place Attack", profile); + this.sent = false; + this.flagged = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInBlockPlace) { + this.sent = true; + } + else if (message instanceof PacketPlayInUseEntity) { + final PacketPlayInUseEntity packet = (PacketPlayInUseEntity)message; + if (packet.c() == EnumEntityUseAction.ATTACK && this.sent) { + this.flag(); + this.flagged = true; + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + else { + this.decrementViolations(); + } + } + else if (message instanceof PacketPlayInFlying) { + this.sent = false; + if (!this.flagged) { + this.decrementViolations(); + } + else { + this.flagged = false; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceRelease.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceRelease.java new file mode 100644 index 0000000..5988223 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceRelease.java @@ -0,0 +1,46 @@ +package cc.fyre.riot.check.checks.order; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class PlaceRelease extends Check +{ + private boolean sent; + private boolean flagged; + + public PlaceRelease(final Profile profile) { + super("Place Release", profile); + this.sent = false; + this.flagged = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInBlockPlace) { + this.sent = true; + } + else if (message instanceof PacketPlayInBlockDig) { + final PacketPlayInBlockDig packet = (PacketPlayInBlockDig)message; + final int status = packet.g(); + if (status == 5 && this.sent) { + this.flag(); + this.flagged = true; + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + } + else if (message instanceof PacketPlayInFlying) { + this.sent = false; + if (!this.flagged) { + this.decrementViolations(); + } + else { + this.flagged = false; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceSlot.java b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceSlot.java new file mode 100644 index 0000000..0c1afe0 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/check/checks/order/PlaceSlot.java @@ -0,0 +1,44 @@ +package cc.fyre.riot.check.checks.order; + +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + + +import net.minecraft.server.v1_7_R4.*; + +public class PlaceSlot extends Check +{ + private boolean sent; + private boolean flagged; + + public PlaceSlot(final Profile profile) { + super("Place Slot", profile); + this.sent = false; + this.flagged = false; + } + + @Override + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + if (message instanceof PacketPlayInBlockPlace) { + this.sent = true; + } + else if (message instanceof PacketPlayInHeldItemSlot) { + if (this.sent) { + this.flag(); + this.flagged = true; + if (this.incrementViolations(200) >= 1000) { + this.ban(); + } + } + } + else if (message instanceof PacketPlayInFlying) { + this.sent = false; + if (!this.flagged) { + this.decrementViolations(); + } + else { + this.flagged = false; + } + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/AlertCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/AlertCommand.java new file mode 100644 index 0000000..1881c6c --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/AlertCommand.java @@ -0,0 +1,25 @@ +package cc.fyre.riot.command; + +import cc.fyre.proton.command.Command; +import cc.fyre.riot.Riot; + + +import org.bukkit.entity.*; +import org.bukkit.*; + +public class AlertCommand { + + public static final String PERMISSION = "command.riot.alerts"; + + + @Command(names = {"riot alerts","alerts"},permission = PERMISSION) + public static void execute(Player player) { + + boolean current = Riot.getInstance().getFlagHandler().getCache().getOrDefault(player.getUniqueId(),false); + + Riot.getInstance().getFlagHandler().getCache().put(player.getUniqueId(),!current); + + player.sendMessage(ChatColor.RED + "[" + ChatColor.YELLOW + "!" + ChatColor.RED + "] " + ChatColor.GRAY + "Alerts have been " + (!current ? ChatColor.GREEN + "enabled":ChatColor.RED + "disabled") + ChatColor.GRAY + "."); + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/BanCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/BanCommand.java new file mode 100644 index 0000000..3a206b2 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/BanCommand.java @@ -0,0 +1,18 @@ +package cc.fyre.riot.command; + + +import cc.fyre.proton.command.Command; +import cc.fyre.proton.command.param.Parameter; +import cc.fyre.riot.Riot; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.*; + +public class BanCommand { + + @Command(names = {"riot ban"},hidden = true,permission = "command.riot.ban") + public static void execute(CommandSender sender,@Parameter(name = "player")Player player) { + Riot.getInstance().getBanManager().ban(Riot.getInstance().getProfileHandler().getCache().get(player.getUniqueId())); + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/ExemptCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/ExemptCommand.java new file mode 100644 index 0000000..a13671d --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/ExemptCommand.java @@ -0,0 +1,25 @@ +package cc.fyre.riot.command; + +import cc.fyre.proton.Proton; +import cc.fyre.proton.command.Command; +import cc.fyre.proton.command.param.Parameter; +import cc.fyre.riot.Riot; +import cc.fyre.riot.packet.packets.AlertLogPacket; +import cc.fyre.riot.packet.packets.ExemptPacket; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +public class ExemptCommand { + + @Command(names = {"riot exempt"},permission = "riot.command.exempt") + public static void execute(Player player, @Parameter(name = "Player") Player target) { + boolean isExempted = Riot.getInstance().getExempted().contains(target.getUniqueId()); + if(isExempted) + Proton.getInstance().getPidginHandler().sendPacket(new ExemptPacket(target.getUniqueId().toString(), false)); + else + Proton.getInstance().getPidginHandler().sendPacket(new ExemptPacket(target.getUniqueId().toString(), true)); + player.sendMessage(isExempted ? ChatColor.RED + "You have UnExempeted " + target.getDisplayName() : ChatColor.GREEN + "You have Exempeted " + target.getDisplayName()); + target.sendMessage((isExempted ? ChatColor.GOLD + "You have been" + ChatColor.RED + " UnExempted " : + ChatColor.GOLD + "You have been " + ChatColor.GREEN + " Exempted ") + ChatColor.GOLD + "from All AC Checks"); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/InfoCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/InfoCommand.java new file mode 100644 index 0000000..a735d55 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/InfoCommand.java @@ -0,0 +1,68 @@ +package cc.fyre.riot.command; + +import cc.fyre.neutron.Neutron; +import cc.fyre.piston.Piston; +import cc.fyre.proton.command.Command; +import cc.fyre.proton.command.param.Parameter; +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.profile.Profile; + +import cc.fyre.universe.UniverseAPI; +import mkremins.fanciful.FancyMessage; +import org.apache.commons.lang.StringUtils; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.*; +import org.bukkit.*; + + +public class InfoCommand { + + @Command(names = {"riot info","info"},permission = "command.riot.info") + public static void execute(CommandSender sender,@Parameter(name = "player")Player player) { + + final Profile profile = Riot.getInstance().getProfileHandler().getCache().get(player.getUniqueId()); + cc.fyre.neutron.profile.Profile nProfile = Neutron.getInstance().getProfileHandler().fromUuid(player.getUniqueId()); + sender.sendMessage(" "); + sender.sendMessage(ChatColor.RED.toString() + ChatColor.STRIKETHROUGH.toString() + StringUtils.repeat("-",53)); + sender.sendMessage(ChatColor.YELLOW + "Riot lookup for " + nProfile.getFancyName()); + sender.sendMessage(ChatColor.RED.toString() + ChatColor.STRIKETHROUGH.toString() + StringUtils.repeat("-",53)); + sender.sendMessage(ChatColor.RED + "Player Information: "); + sender.sendMessage(" "); + new FancyMessage().text(ChatColor.YELLOW + "CPS: " + ChatColor.RED + getCPS(profile.getClickTracker().getCps())).tooltip(profile.getClickTracker().getCps()+"").send(sender); + sender.sendMessage(ChatColor.YELLOW + "Latency: " + ChatColor.RED + profile.getConnectionTracker().transactionPing + "ms" + ChatColor.YELLOW + " / " + ChatColor.RED + profile.getConnectionTracker().keepAlivePing + "ms"); + sender.sendMessage(ChatColor.YELLOW + "Client (Brand - Version): " + ChatColor.RED + + Piston.getInstance().getClientHandler().getPlayerClient(player).getName().replace("-", " ") + " v" + + Piston.getInstance().getClientHandler().getPlayerVerision(player).getVersion()); + sender.sendMessage(ChatColor.YELLOW + "Violations: " + ChatColor.RED + profile.getViolations()); + sender.sendMessage(ChatColor.RED.toString() + ChatColor.STRIKETHROUGH.toString() + StringUtils.repeat("-",53)); + } + @Command(names = {"riot info dev"},permission = "command.riot.info.dev", hidden = true) + public static void executeDev(CommandSender sender, @Parameter(name = "player")Player player) { + final Profile profile = Riot.getInstance().getProfileHandler().getCache().get(player.getUniqueId()); + if(UniverseAPI.getServerName().contains("Dev-")) { + StringBuilder sb = new StringBuilder(); + for(Check c : profile.getCheckList()) { + if(sb.length() != 0) + sb.append(", "); + sb.append((c.getName().contains("EXP") ? ChatColor.RED + c.getName() + ChatColor.RESET : c.getName())); + } + sender.sendMessage("Checks: " + sb.toString()); + sender.sendMessage("OnGround: " + profile.onGround); + sender.sendMessage("OnGroundPacket: " + profile.onGroundPacket); + sender.sendMessage("lastOnGround: " + profile.lastOnGround); + sender.sendMessage("lastGroundPacket: " + profile.lastOnGroundPacket); + sender.sendMessage("lastLastGround: " + profile.lastLastOnGround); + sender.sendMessage("lastLastGroundPacket: " + profile.lastLastOnGroundPacket); + } + } + + + private static String getCPS(double cps) { + String output = String.valueOf(cps); + return output.substring(0, Math.min(output.length(), 4)); + } + +} + + diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/LogsCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/LogsCommand.java new file mode 100644 index 0000000..3be1777 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/LogsCommand.java @@ -0,0 +1,89 @@ +package cc.fyre.riot.command; + +import cc.fyre.neutron.util.FormatUtil; +import cc.fyre.piston.Piston; +import cc.fyre.proton.Proton; +import cc.fyre.proton.command.Command; +import cc.fyre.proton.command.param.Parameter; +import cc.fyre.proton.util.TimeUtils; +import cc.fyre.riot.Riot; +import cc.fyre.riot.log.data.Log; + +import cc.fyre.riot.util.PageBuilder; +import com.mongodb.client.model.Filters; + +import com.mysql.jdbc.TimeUtil; +import mkremins.fanciful.FancyMessage; +import org.apache.commons.lang.StringUtils; +import org.bson.Document; +import org.bukkit.command.CommandSender; + +import org.bukkit.*; +import org.bukkit.entity.Player; + + +import java.util.*; +import java.util.stream.Collectors; + +public class LogsCommand +{ + + @Command(names = {"riot logs","logs"},permission = "command.riot.logs") + public static void execute(CommandSender sender, @Parameter(name = "player")UUID uuid, @Parameter(name = "page",defaultValue = "1")int page) { + + Bukkit.getScheduler().runTaskAsynchronously(Riot.getInstance(),() -> { + + final List logs = new ArrayList<>(); + + for (Document document : Riot.getInstance().getLogsCollection().find(Filters.eq("uuid",uuid.toString())).sort(Filters.eq("time",-1)).limit(10000)) { + logs.add(Riot.getInstance().getGson().fromJson(document.toJson(),Log.class)); + } + + logs.addAll(Riot.getInstance().getLogHandler().getQueue().stream().filter(it -> it.getUuid().equals(uuid) && !logs.contains(it)).collect(Collectors.toList())); + + final String displayName = Proton.getInstance().getUuidCache().name(uuid); + + new PageBuilder(15) { + + @Override + public FancyMessage getHeader(int i,int i1) { + return new FancyMessage(ChatColor.RED.toString() + ChatColor.STRIKETHROUGH.toString() + StringUtils.repeat("-",53)); + } + + @Override + public FancyMessage getFormat(Log log,int index) { + + String message = ChatColor.YELLOW.toString() + (index + 1) + ". " + ChatColor.RED + log.getFlag(); + + if (log.getMetadata() != null && log.getMetadata().isEmpty() && (!(sender instanceof Player)) || Riot.getInstance().getLogHandler().isWhitelisted(((Player) sender).getUniqueId())) { + message += " " + ChatColor.LIGHT_PURPLE + "[" + log.getMetadata() + "]"; + } + + message += " " + ChatColor.GOLD + "[" + log.getPing() + "ms]"; + message += " "; + message += ChatColor.YELLOW + "."; + + return new FancyMessage(message).tooltip(ChatColor.YELLOW + "Server: " + ChatColor.RED + log.getServer(), + ChatColor.YELLOW + "Client: " + ChatColor.RED + log.getClient().replace("_", ""), + ChatColor.YELLOW + "Version: " + ChatColor.RED + log.getVersion(), + ChatColor.YELLOW + "Time: " + ChatColor.RED + log.getTime() + " (EST)" + ); + // .tooltip(ChatColor.YELLOW + "Proxy: " + ChatColor.RED + log.getProxy()); + } + + @Override + public FancyMessage getFooter(int i,int index) { + return new FancyMessage(ChatColor.RED.toString() + ChatColor.STRIKETHROUGH.toString() + StringUtils.repeat("-",53)); + } + + @Override + public String getEmptyResultMessage() { + return ChatColor.RED + "No records found for " + displayName + ChatColor.RED + "."; + } + + }.send(sender,page,logs); + }); + + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/RecordClicksCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/RecordClicksCommand.java new file mode 100644 index 0000000..a0abe3e --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/RecordClicksCommand.java @@ -0,0 +1,111 @@ +package cc.fyre.riot.command; + +import cc.fyre.proton.command.Command; +import cc.fyre.proton.command.param.Parameter; +import cc.fyre.riot.Riot; +import cc.fyre.riot.profile.Profile; +import lombok.SneakyThrows; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.StringJoiner; + +public class RecordClicksCommand { + + @SneakyThrows + @Command(names = {"riot recordclicks","recordclicks"},hidden = true,permission = "command.riot.recordclicks") + public static void execute(Player sender,@Parameter(name = "player")Player player) { + + final Profile profile = Riot.getInstance().getProfileHandler().getCache().get(player.getUniqueId()); + + profile.getClickTracker().setRecording(!profile.getClickTracker().isRecording()); + + final String displayName = player.getName(); + + if (profile.getClickTracker().isRecording()) { + sender.sendMessage(ChatColor.GREEN + "Recording " + displayName + ChatColor.GREEN + "'s clicks.."); + } else { + player.sendMessage(ChatColor.GREEN + "Uploading " + player.getName() + "'s clicks..."); + final StringJoiner sj = new StringJoiner("\n"); + for (final int delay : profile.getClickTracker().getDelays()) { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < delay; ++i) { + sb.append("####################"); + } + sj.add(sb.toString()); + } + String response; + BufferedWriter writer = new BufferedWriter(new FileWriter(Riot.getInstance().getDataFolder().getAbsolutePath() + "\\save-" + System.currentTimeMillis())); + writer.write(sj.toString()); + + writer.close(); + + } + + } + + //TODO + /*2 + private final ProfileManager profileManager; + + public RecordClicksCommand() { + super("Record clicks", "", new String[] { "recordclicks" }); + this.profileManager = Trojan.getInstance().getProfileManager(); + } + + @Override + public void handle(final CommandContext ctx) { + final Player player = (Player)ctx.sender(); + final String arg = ctx.rawArg(1); + if (arg == null) { + player.sendMessage(ChatColor.RED + "Usage: /" + ctx.label() + " " + ctx.rawArg(0) + " "); + return; + } + final Player target = Bukkit.getPlayer(arg); + if (target == null) { + player.sendMessage(ChatColor.RED + "Could not find an online player with the name: " + arg); + return; + } + final Profile targetProfile = this.profileManager.getProfile(target); + targetProfile.clickTracker.recording = !targetProfile.clickTracker.recording; + if (targetProfile.clickTracker.recording) { + player.sendMessage(ChatColor.GREEN + "Started recording " + target.getName() + "'s clicks"); + } + else { + player.sendMessage(ChatColor.GREEN + "Uploading " + target.getName() + "'s clicks..."); + final StringJoiner sj = new StringJoiner("\n"); + for (final int delay : targetProfile.clickTracker.delays) { + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < delay; ++i) { + sb.append("####################"); + } + sj.add(sb.toString()); + } + final StringJoiner stringJoiner; + String response; + final Player player2; + Schedulers.async().run(() -> { + try { + response = WebUtils.postToTrojanWebsite(stringJoiner.toString()); + player2.sendMessage(ChatColor.GREEN + "https://trojan.valorhcf.net/" + response); + } + catch (IOException e) { + player2.sendMessage(ChatColor.RED + "An error occurred: " + e.getMessage()); + e.printStackTrace(); + } + return; + }); + targetProfile.clickTracker.delays.clear(); + } + } + + @Override + public boolean hasPermission(final Player player) { + return ServerUtils.isOperator(player); + }*/ +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/ResetCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/ResetCommand.java new file mode 100644 index 0000000..b43dd35 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/ResetCommand.java @@ -0,0 +1,39 @@ +package cc.fyre.riot.command; + +import cc.fyre.proton.command.Command; +import cc.fyre.proton.command.param.Parameter; +import cc.fyre.riot.Riot; +import cc.fyre.riot.log.data.Log; +import com.mongodb.client.model.Filters; +import mkremins.fanciful.FancyMessage; +import org.apache.commons.lang.StringUtils; +import org.bson.Document; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +public class ResetCommand { + + @Command(names = {"riot reset", "logs reset"}, permission = "command.riot.reset", hidden = true) + public static void execute(Player player, @Parameter(name = "target") UUID uuid) { + + Bukkit.getScheduler().runTaskAsynchronously(Riot.getInstance(),() -> { + + int logsAmount = 0; + + for (Document document : Riot.getInstance().getLogsCollection().find(Filters.eq("uuid",uuid.toString())).sort(Filters.eq("time",-1)).limit(10000)) { + Riot.getInstance().getLogHandler().getQueue().remove(Riot.getInstance().getGson().fromJson(document.toJson(),Log.class)); + Riot.getInstance().getLogsCollection().deleteOne(document); + logsAmount++; + } + + player.sendMessage(ChatColor.RED + "Deleted " + logsAmount + " logs for guy" + "."); + }); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/TopCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/TopCommand.java new file mode 100644 index 0000000..063806b --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/TopCommand.java @@ -0,0 +1,70 @@ +package cc.fyre.riot.command; + +import cc.fyre.proton.command.Command; +import cc.fyre.riot.Riot; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Map; + +public class TopCommand { + @Command(names = {"riot top"}, permission = "command.riot.top") + public static void execute(CommandSender sender) { + sender.sendMessage(ChatColor.RED.toString() + ChatColor.STRIKETHROUGH + "------------------------------"); + sender.sendMessage(ChatColor.YELLOW + "Riot Top Violations"); + sender.sendMessage(""); + LinkedHashMap sortedPlayerViolationsCount = getSortedPlayers(); + + int index = 0; + + for (Map.Entry teamEntry : sortedPlayerViolationsCount.entrySet()) { + + if (teamEntry.getKey() == null) { + continue; + } + + index++; + + if (11 <= index) { + break; + } + + Player player = teamEntry.getKey(); + + sender.sendMessage(ChatColor.GRAY + " " + player.getName() + ": " + ChatColor.WHITE + teamEntry.getValue()); + } + sender.sendMessage(ChatColor.RED.toString() + ChatColor.STRIKETHROUGH + "------------------------------"); + } + + public static LinkedHashMap getSortedPlayers() { + final Map playerViolationsCount = new HashMap<>(); + + for (Player player : Riot.getInstance().getServer().getOnlinePlayers()) { + if (!Riot.getInstance().getProfileHandler().getCache().containsKey(player.getUniqueId())) { + continue; + } + + playerViolationsCount.put(player, Riot.getInstance().getProfileHandler().getCache().get(player.getUniqueId()).getViolations()); + } + + return sortByValues(playerViolationsCount); + } + + public static LinkedHashMap sortByValues(Map map) { + final LinkedList> list = new LinkedList<>(map.entrySet()); + + list.sort((o1, o2) -> (o2.getValue().compareTo(o1.getValue()))); + + final LinkedHashMap sortedHashMap = new LinkedHashMap<>(); + + for (Map.Entry entry : list) { + sortedHashMap.put(entry.getKey(), entry.getValue()); + } + + return (sortedHashMap); + } +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/command/WhitelistCommand.java b/Anticheat-master/src/main/java/cc/fyre/riot/command/WhitelistCommand.java new file mode 100644 index 0000000..53aef68 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/command/WhitelistCommand.java @@ -0,0 +1,45 @@ +package cc.fyre.riot.command; + +import cc.fyre.neutron.Neutron; +import cc.fyre.neutron.profile.Profile; +import cc.fyre.proton.Proton; +import cc.fyre.proton.command.Command; +import cc.fyre.proton.command.param.Parameter; +import cc.fyre.riot.Riot; +import cc.fyre.riot.packet.packets.WhitelistPacket; +import cc.fyre.universe.UniverseAPI; +import com.google.gson.JsonObject; +import com.mongodb.client.model.Filters; +import org.bson.Document; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +/** + * @author xanderume@gmail.com + */ +public class WhitelistCommand { + + @Command(names = {"riot whitelist"},hidden = true,permission = "op") + public static void execute(CommandSender sender, @Parameter(name = "player")UUID player) { + + if (sender instanceof Player && !UniverseAPI.getServerName().contains("Dev-")) { + sender.sendMessage(ChatColor.RED + "This command cannot be executed in-game."); + return; + } + + Bukkit.getScheduler().runTaskAsynchronously(Riot.getInstance(),() -> { + + boolean whitelisted = Riot.getInstance().getLogHandler().isWhitelisted(player); + + Proton.getInstance().getPidginHandler().sendPacket(new WhitelistPacket(player.toString(), !whitelisted)); + Profile profile = Neutron.getInstance().getProfileHandler().fromUuid(player); + sender.sendMessage( profile.getFancyName() + (whitelisted ? ChatColor.RED:ChatColor.GREEN) + " has been " + (whitelisted ? "un-":"") + "whitelisted."); + }); + + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/events/TickEvent.java b/Anticheat-master/src/main/java/cc/fyre/riot/events/TickEvent.java new file mode 100644 index 0000000..be2d55b --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/events/TickEvent.java @@ -0,0 +1,18 @@ +package cc.fyre.riot.events; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +@Getter +@AllArgsConstructor +public class TickEvent extends Event { + private int currentTick; + private static final HandlerList HANDLERS_LIST = new HandlerList(); + @Override + public HandlerList getHandlers() { + return HANDLERS_LIST; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/flag/FlagHandler.java b/Anticheat-master/src/main/java/cc/fyre/riot/flag/FlagHandler.java new file mode 100644 index 0000000..4839f2d --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/flag/FlagHandler.java @@ -0,0 +1,94 @@ +package cc.fyre.riot.flag; + +import java.util.*; +import java.util.stream.Collectors; + +import cc.fyre.neutron.Neutron; +import cc.fyre.proton.Proton; +import cc.fyre.proton.pidgin.PidginHandler; +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.packet.packets.AlertLogPacket; +import cc.fyre.riot.packet.packets.WhitelistPacket; +import cc.fyre.riot.profile.Profile; +import cc.fyre.universe.Universe; +import cc.fyre.universe.UniverseAPI; +import lombok.Getter; + +import mkremins.fanciful.FancyMessage; +import org.bukkit.*; + +import net.md_5.bungee.api.chat.*; +import org.bukkit.entity.Player; +import org.bukkit.permissions.ServerOperator; + +public class FlagHandler { + + @Getter private final Map cache = new HashMap<>(); + + private Riot instance; + + public FlagHandler(Riot instance) { + this.instance = instance; + } + + public void flag(final Profile profile,final Check check,final String metadata) { + if(Riot.getInstance().getExempted().contains(profile.getUuid())) { + return; + } + final String displayName = profile.getName(); + + final String ping = ChatColor.GOLD + "[" + profile.getConnectionTracker().keepAlivePing + "ms]"; + + profile.setViolations(profile.getViolations()+1); + if(UniverseAPI.getServerName().contains("Dev")) { + this.instance.getServer().getOnlinePlayers().stream().filter(it -> Riot.getInstance().getFlagHandler().getCache().getOrDefault(it.getUniqueId(),false)).forEach(it -> { + it.sendMessage(ChatColor.DARK_PURPLE + "[Riot] " + ChatColor.GRAY + "(" + UniverseAPI.getServerName() + ") " + + displayName + ChatColor.GRAY + " failed " + ChatColor.RED + check.getName() + + ChatColor.GRAY + (metadata != null && this.instance.getLogHandler().isWhitelisted(it.getUniqueId()) ? " " + metadata:"") + " " + " " + ping); + }); + } else { + Bukkit.getScheduler().runTaskAsynchronously(Riot.getInstance(), () -> Proton.getInstance().getPidginHandler().sendPacket(new AlertLogPacket( + ChatColor.DARK_PURPLE + "[Riot] " + ChatColor.GRAY + "(" + UniverseAPI.getServerName() + ") " + ChatColor.DARK_PURPLE + + Neutron.getInstance().getProfileHandler().fromUuid(profile.getUuid()).getFancyName() + ChatColor.GRAY + " failed " + ChatColor.RED + check.getName() + + ChatColor.GRAY, (metadata == null ? " " : metadata), ping))); + } + + + /* this.instance.getServer().getOnlinePlayers().stream().filter(it -> Riot.getInstance().getFlagHandler().getCache().getOrDefault(it.getUniqueId(),false)).forEach(it -> { + it.sendMessage(ChatColor.DARK_PURPLE + "[Riot] " + ChatColor.GRAY + "(" + UniverseAPI.getServerName() + ") " + + displayName + ChatColor.GRAY + " failed " + ChatColor.RED + check.getName() + + ChatColor.GRAY + (metadata != null && this.instance.getLogHandler().isWhitelisted(it.getUniqueId()) ? " " + metadata:"") + " " + " " + ping); + });*/ + /* + final StringBuilder sb = new StringBuilder(); + sb.append(ChatColor.DARK_PURPLE).append("[Riot] ").append(ChatColor.WHITE).append(profile.getName()).append(ChatColor.GRAY).append(" failed ").append(ChatColor.RED).append(check.getName()); + if (metadata != null) { + sb.append(ChatColor.GRAY).append(" ").append("(").append(metadata).append(")"); + } + sb.append(ChatColor.GRAY).append(" (Ping: ").append(profile.getConnectionTracker().keepAlivePing).append(") "); + final TextComponent text = new TextComponent(TextComponent.fromLegacyText(sb.toString())); + text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(ChatColor.RED + "Click to teleport"))); + text.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/tp " + profile.getName())); + Bukkit.getOnlinePlayers().stream().filter(ServerOperator::isOp).filter(p -> !this.cache.get(p.getUniqueId())).forEach(p -> p.spigot().sendMessage(text));*/ + } + + /* + public void staffAlert(final Profile profile, final String checkName, final String metadata) { + final StringBuilder sb = new StringBuilder(); + sb.append(ChatColor.DARK_PURPLE).append("[Riot] ").append(ChatColor.WHITE).append(profile.getName()).append(ChatColor.GRAY).append(" failed ").append(ChatColor.RED).append(checkName); + if (metadata != null) { + sb.append(ChatColor.GRAY).append(" ").append("(").append(metadata).append(")"); + } + sb.append(ChatColor.GRAY).append(" (Ping: ").append(profile.getConnectionTracker().keepAlivePing).append(")"); + final TextComponent text = new TextComponent(TextComponent.fromLegacyText(sb.toString())); + text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(ChatColor.RED + "Click to teleport"))); + text.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/tp " + profile.getName())); + Bukkit.getOnlinePlayers().stream().filter(p -> !p.isOp()).filter(p -> p.hasPermission("trojan.staff")).filter(p -> !this.cache.get(p.getUniqueId())).forEach(p -> p.spigot().sendMessage((BaseComponent)text)); + } + + public void staffAlert(final Profile profile, final String checkName) { + this.staffAlert(profile, checkName, null); + }*/ + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/listener/GeneralListener.java b/Anticheat-master/src/main/java/cc/fyre/riot/listener/GeneralListener.java new file mode 100644 index 0000000..7176b25 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/listener/GeneralListener.java @@ -0,0 +1,94 @@ +package cc.fyre.riot.listener; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.packet.RiotChannelDuplexHandler; +import cc.fyre.riot.profile.Profile; +import lombok.AllArgsConstructor; + +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; +import org.bukkit.entity.*; + +import net.minecraft.util.io.netty.buffer.*; +import java.io.*; + +import net.minecraft.server.v1_7_R4.*; +import net.minecraft.util.io.netty.channel.*; +import org.bukkit.event.*; +import org.bukkit.event.player.*; +import org.bukkit.event.entity.*; + +@AllArgsConstructor +public class GeneralListener implements Listener { + + private final Riot instance; + + @EventHandler(priority = EventPriority.LOWEST) + private void onPlayerJoin(PlayerJoinEvent event) { + + this.instance.getProfileHandler().getCache().put(event.getPlayer().getUniqueId(),new Profile(event.getPlayer())); + this.instance.getProfileHandler().getIdToUUID().put(event.getPlayer().getEntityId(),event.getPlayer().getUniqueId()); + + Bukkit.getScheduler().runTaskAsynchronously(Riot.getInstance(),() -> { + + final EntityPlayer entityPlayer = ((CraftPlayer)event.getPlayer()).getHandle(); + + final Profile profile = this.instance.getProfileHandler().getCache().get(event.getPlayer().getUniqueId()); + final Channel channel = entityPlayer.playerConnection.networkManager.m; + + channel.pipeline().addBefore("packet_handler",this.instance.getMagic().getChannelHandlerName(),new RiotChannelDuplexHandler(profile)); + + Bukkit.getScheduler().runTaskLaterAsynchronously(Riot.getInstance(),() -> entityPlayer.playerConnection.sendPacket(new PacketPlayOutCustomPayload("stop ddosing",Unpooled.EMPTY_BUFFER)),20L); + + try { + final ByteArrayOutputStream byteOutPutStream = new ByteArrayOutputStream(); + final DataOutputStream outputStream = new DataOutputStream(byteOutPutStream); + + outputStream.writeByte(0); + outputStream.writeBoolean(false); + outputStream.writeBoolean(true); + outputStream.writeBoolean(true); + + byte[] payload = byteOutPutStream.toByteArray(); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutCustomPayload("schematica",payload)); + } catch (IOException e) { + e.printStackTrace(); + } + + }); + + } + + @EventHandler(priority = EventPriority.MONITOR) + private void onPlayerQuit(PlayerQuitEvent event) { + this.instance.getProfileHandler().getCache().remove(event.getPlayer().getUniqueId()); + this.instance.getProfileHandler().getIdToUUID().remove(event.getPlayer().getEntityId()); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onEntityDamageByEntity(final EntityDamageByEntityEvent event) { + + if (!(event.getEntity() instanceof Player)) { + return; + } + + if (!(event.getDamager() instanceof Player)) { + return; + } + + final Player player = (Player) event.getDamager(); + final Profile profile = this.instance.getProfileHandler().getCache().get(player.getUniqueId()); + + final long elapsed = System.currentTimeMillis() - profile.getConnectionTracker().lastTransaction; + + if (elapsed < 3000L) { + return; + } + + event.setCancelled(true); + + this.instance.getLogger().warning("Cancelled attack by " + player.getName() + " because they haven't responded to a transaction in " + elapsed + " ms"); + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/log/LogHandler.java b/Anticheat-master/src/main/java/cc/fyre/riot/log/LogHandler.java new file mode 100644 index 0000000..b5bfc17 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/log/LogHandler.java @@ -0,0 +1,81 @@ +package cc.fyre.riot.log; + +import java.time.format.*; +import java.util.concurrent.*; + +import cc.fyre.piston.Piston; +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.log.data.Log; +import cc.fyre.riot.log.listener.WhitelistListener; +import cc.fyre.riot.log.service.LogService; +import cc.fyre.riot.profile.Profile; +import cc.fyre.universe.UniverseAPI; +import com.mongodb.client.MongoCollection; +import lombok.Getter; +import org.bson.Document; + +import java.util.*; + + + +import java.time.*; + +public class LogHandler { + + private final Riot instance; + + @Getter private final Queue queue; + @Getter private final LogService service; + + @Getter private final List whitelisted; + + @Getter private final ZoneId zone = ZoneId.of("America/New_York"); + @Getter private final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS 'ET'"); + + @Getter private final MongoCollection collection; + @Getter private final MongoCollection whitelistCollection; + + public static final String WHITELIST_PACKET_ID = "RIOT_WHITELIST"; + + public LogHandler(Riot instance) { + this.instance = instance; + + this.queue = new ConcurrentLinkedQueue<>(); + this.whitelisted = new ArrayList<>(); + + this.collection = instance.getMongoDatabase().getCollection("logs"); + this.whitelistCollection = instance.getMongoDatabase().getCollection("whitelist"); + + this.service = new LogService(instance); + this.service.runTaskTimerAsynchronously(this.instance,20L,20L); + + this.whitelistCollection.find().iterator().forEachRemaining(it -> this.whitelisted.add(UUID.fromString(it.getString("uuid")))); + } + + public void log(Profile profile,Check check,String metadata) { + String client = "Unknown"; + String version = "Unknown"; + if(profile.getPlayer().isOnline()) { + client = Piston.getInstance().getClientHandler().getPlayerClient(profile.getPlayer()).getName(); + version = Piston.getInstance().getClientHandler().getPlayerVerision(profile.getPlayer()).getVersion(); + } + this.queue.add(new Log( + profile.getUuid(), + profile.getConnectionTracker().keepAlivePing, + check.getName(), + UniverseAPI.getServerName(), + metadata, + client, + version + + )); + + } + + public boolean isWhitelisted(UUID uuid) { + return this.whitelisted.contains(uuid); + } + + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/log/data/Log.java b/Anticheat-master/src/main/java/cc/fyre/riot/log/data/Log.java new file mode 100644 index 0000000..dd92e83 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/log/data/Log.java @@ -0,0 +1,40 @@ +package cc.fyre.riot.log.data; + +import cc.fyre.piston.client.data.Client; +import cc.fyre.piston.client.data.Version; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.UUID; + +/** + * @author xanderume@gmail.com + */ +@AllArgsConstructor +public class Log { + + @Getter private final UUID uuid; + @Getter private final Long ping; + @Getter private final String flag; + + @Getter private final String server; + //@Getter private final String proxy; + @Getter private final String metadata; + @Getter private final String client; + @Getter private final String version; + + @Getter private final long time = System.currentTimeMillis(); + + + public String getTime() { + SimpleDateFormat sdf = new SimpleDateFormat("MM/dd hh:mm aa"); + Date resultdate = new Date(time); + return sdf.format(resultdate); + + } + + +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/log/listener/WhitelistListener.java b/Anticheat-master/src/main/java/cc/fyre/riot/log/listener/WhitelistListener.java new file mode 100644 index 0000000..c0e1e92 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/log/listener/WhitelistListener.java @@ -0,0 +1,24 @@ +package cc.fyre.riot.log.listener; + + +import java.util.UUID; + +/** + * @author xanderume@gmail.com + */ +public class WhitelistListener { + +// @Parasite(id = LogHandler.WHITELIST_PACKET_ID) +// public void onWhitelist(JsonObject data) { +// +// final UUID uuid = UUID.fromString(data.get("uuid").getAsString()); +// +// if (Riot.getInstance().getLogHandler().getWhitelisted().contains(uuid)) { +// Riot.getInstance().getLogHandler().getWhitelisted().remove(uuid); +// return; +// } +// +// Riot.getInstance().getLogHandler().getWhitelisted().add(uuid); +// } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/log/service/LogService.java b/Anticheat-master/src/main/java/cc/fyre/riot/log/service/LogService.java new file mode 100644 index 0000000..380e940 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/log/service/LogService.java @@ -0,0 +1,44 @@ +package cc.fyre.riot.log.service; + +import lombok.AllArgsConstructor; +import cc.fyre.riot.Riot; +import cc.fyre.riot.log.data.Log; +import org.bson.Document; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author xanderume@gmail.com + */ +@AllArgsConstructor +public class LogService extends BukkitRunnable { + + private final Riot instance; + + @Override + public void run() { + + final List documents = new ArrayList<>(); + + for (int i = 0; i < this.instance.getLogHandler().getQueue().size(); i++) { + + final Log log = this.instance.getLogHandler().getQueue().poll(); + + if (log == null) { + break; + } + + documents.add(Document.parse(this.instance.getGson().toJson(log))); + } + + if (documents.isEmpty()) { + return; + } + + this.instance.getLogsCollection().insertMany(documents); + + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/packet/RiotChannelDuplexHandler.java b/Anticheat-master/src/main/java/cc/fyre/riot/packet/RiotChannelDuplexHandler.java new file mode 100644 index 0000000..12fe026 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/packet/RiotChannelDuplexHandler.java @@ -0,0 +1,56 @@ +package cc.fyre.riot.packet; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.profile.Profile; + +import java.util.logging.*; + +import lombok.AllArgsConstructor; +import net.minecraft.util.io.netty.channel.*; + +@AllArgsConstructor +public class RiotChannelDuplexHandler extends ChannelDuplexHandler { + + private final Profile profile; + + public void channelRead(ChannelHandlerContext ctx,Object message) throws Exception { + + final long nanos = System.nanoTime(); + final long millis = System.currentTimeMillis(); + + super.channelRead(ctx,message); + + if (!Riot.getInstance().isEnabled()) { + return; + } + + final long start = System.nanoTime(); + + try { + this.profile.handleInboundPacket(message,millis,nanos); + } catch (Exception rc) { + Riot.getInstance().getLogger().log(Level.SEVERE,"Could not handle inbound packet",rc); + } + + Riot.getInstance().getTimings().addTiming(System.nanoTime() - start); + } + + public void write(ChannelHandlerContext ctx,Object message,ChannelPromise promise) throws Exception { + + final long nanos = System.nanoTime(); + final long millis = System.currentTimeMillis(); + + super.write(ctx,message,promise); + + if (!Riot.getInstance().isEnabled()) { + return; + } + + try { + this.profile.handleOutboundPacket(message,millis,nanos); + } catch (Exception ex) { + Riot.getInstance().getLogger().log(Level.SEVERE,"Could not handle outbound packet",ex); + } + + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/packet/RiotPacketProcessor.java b/Anticheat-master/src/main/java/cc/fyre/riot/packet/RiotPacketProcessor.java new file mode 100644 index 0000000..d5c0606 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/packet/RiotPacketProcessor.java @@ -0,0 +1,125 @@ +package cc.fyre.riot.packet; + +import cc.fyre.neutron.Neutron; +import cc.fyre.proton.Proton; +import cc.fyre.riot.Riot; +import cc.fyre.riot.packet.packets.AlertLogPacket; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.AxisAlignedBB; +import cc.fyre.riot.util.BlockUtil; +import cc.fyre.riot.util.Pair; +import cc.fyre.universe.UniverseAPI; +import io.github.retrooper.packetevents.event.PacketEvent; +import io.github.retrooper.packetevents.event.PacketListener; +import io.github.retrooper.packetevents.event.PacketListenerDynamic; +import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent; +import io.github.retrooper.packetevents.event.priority.PacketEventPriority; +import io.github.retrooper.packetevents.packettype.PacketType; +import io.github.retrooper.packetevents.packetwrappers.in.flying.WrappedPacketInFlying; +import io.github.retrooper.packetevents.packetwrappers.in.useentity.WrappedPacketInUseEntity; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +public class RiotPacketProcessor extends PacketListenerDynamic { + + public RiotPacketProcessor() { + super(PacketEventPriority.HIGHEST); + } + + @Override + public void onPacketReceive(PacketReceiveEvent event) { + Player player = event.getPlayer(); + if(Riot.getInstance().getProfileHandler().getCache().containsKey(player.getUniqueId())) { + Profile profile = Riot.getInstance().getProfileHandler().getCache().get(player.getUniqueId()); + profile.TotalTicks++; + + if(event.getPacketId() == PacketType.Client.USE_ENTITY) { + WrappedPacketInUseEntity packet = new WrappedPacketInUseEntity(event.getNMSPacket()); + if(packet.getEntity() instanceof Player) { + Player target = (Player) packet.getEntity(); + if (target.isOnline()) { + profile.getAttackTracker().lastTarget = (Player) packet.getEntity(); + if (packet.getAction() == null) { + Bukkit.getScheduler().runTaskAsynchronously(Riot.getInstance(), () -> Proton.getInstance().getPidginHandler().sendPacket(new AlertLogPacket( + ChatColor.DARK_PURPLE + "[Riot] " + ChatColor.GRAY + "(" + UniverseAPI.getServerName() + ") " + ChatColor.DARK_PURPLE + + Neutron.getInstance().getProfileHandler().fromUuid(profile.getUuid()).getFancyName() + ChatColor.GRAY + " fucked with packets!" + + ChatColor.GRAY, " ", "-1"))); + return; + } + if (packet.getAction().equals(WrappedPacketInUseEntity.EntityUseAction.ATTACK)) { + profile.getAttackTracker().lastAttackTick = 0; + } + if (profile.getAttackTracker().getLastTarget() != null) { + if (packet.getEntity() != profile.getAttackTracker().getLastTarget()) { + profile.getLocationHistoryTracker().getPastLocs().clear(); + profile.getLocationHistoryTracker().getPastLocations().clear(); + } + } + profile.getAttackTracker().setLastTarget(target); + } + }else { + profile.getAttackTracker().setLastTarget(null); + } + + } + else if(PacketType.Client.Util.isInstanceOfFlying(event.getPacketId())) { + WrappedPacketInFlying packet = new WrappedPacketInFlying(event.getNMSPacket()); + long packetDiff = System.currentTimeMillis() - profile.getLastFlying(); + int nowTicks = profile.getTotalTicks(); + long now = System.currentTimeMillis(); + final boolean lagging = nowTicks - profile.LastPacketDrop < 2; + profile.getAttackTracker().lastAttackTick++; + profile.getLocationHistoryTracker().lastServerPositionTick++; + boolean delayed = nowTicks - profile.LastFlyingTicks > 2; + boolean onGround = packet.isOnGround(); + if (lagging) profile.setLastPacketDrop(profile.getTotalTicks()); + if (now - profile.getLastFlying() >= 110L) { + profile.setLastDelayedPacket(now); + } + if (packetDiff > 150L) { + profile.lastLag = now; + } + if(profile.getAttackTracker().getLastTarget() != null && profile.getAttackTracker().getLastTarget().isOnline()) { + Profile targetProfile = Riot.getInstance().getProfileHandler().getCache().get(profile.getAttackTracker().getLastTarget().getUniqueId()); + double x1 = (int) (targetProfile.getMovementTracker().lastLocation.getX() * 32.0D); + double y1 = (int) (targetProfile.getMovementTracker().lastLocation.getY() * 32.0D); + double z1 = (int) (targetProfile.getMovementTracker().lastLocation.getZ() * 32.0D); + double x2 = x1 / 32.0D; + double y2 = y1 / 32.0D; + double z2 = z1 / 32.0D; + + profile.setLastFlying(now); + profile.setLastFlyingTicks(nowTicks); + AxisAlignedBB box = getEntityBoundingBox(x2, y2, z2); + AxisAlignedBB box2 = getEntityBoundingBox(x2, y2, z2); + + AxisAlignedBB axisalignedbb = box.expand(0.03, 0.03, 0.03); + AxisAlignedBB axisalignedbb2 = box2.expand(0.23, 0.23, 0.23); + if (!profile.getMovementTracker().teleporting && !profile.getAttackTracker().lastTarget.isInsideVehicle() && !player.isInsideVehicle()) { + profile.getLocationHistoryTracker().getPastLocs().add(new Pair<>(axisalignedbb, profile.getTotalTicks())); + profile.getLocationHistoryTracker().getPastLocations().add(new Pair<>(axisalignedbb, profile.getTotalTicks())); + } else { + profile.getLocationHistoryTracker().getPastLocs().clear(); + profile.getLocationHistoryTracker().getPastLocations().clear(); + } + } + profile.lastLastOnGroundPacket = profile.lastOnGroundPacket; + profile.lastOnGroundPacket = profile.onGroundPacket; + profile.onGroundPacket = onGround; + profile.lastOnGround =profile.onGround; + profile.onGround = BlockUtil.isOnGroundBB(player); + + } + profile.handleInboundPacketEvent(event.getNMSPacket(), event.getPacketId()); + } + + } + + public static AxisAlignedBB getEntityBoundingBox(double x, double y, double z) { + float f = 0.6F / 2.0F; + float f1 = 1.8F; + return (new AxisAlignedBB(x - (double)f, y, z - (double)f, x + (double)f, y + (double)f1, z + (double)f)); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/packet/listener/RiotPiginPacketListener.java b/Anticheat-master/src/main/java/cc/fyre/riot/packet/listener/RiotPiginPacketListener.java new file mode 100644 index 0000000..55f8e60 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/packet/listener/RiotPiginPacketListener.java @@ -0,0 +1,22 @@ +package cc.fyre.riot.packet.listener; + +import cc.fyre.proton.pidgin.packet.handler.IncomingPacketHandler; +import cc.fyre.proton.pidgin.packet.listener.PacketListener; +import cc.fyre.riot.packet.packets.AlertLogPacket; +import cc.fyre.riot.packet.packets.ExemptPacket; +import cc.fyre.riot.packet.packets.WhitelistPacket; + +public class RiotPiginPacketListener implements PacketListener { + @IncomingPacketHandler + public void onUserWhitelisted(WhitelistPacket packet) { + packet.broadcast(); + } + @IncomingPacketHandler + public void onAlertLog(AlertLogPacket packet) { + packet.broadcast(); + } + @IncomingPacketHandler + public void onExemptPacket(ExemptPacket packet) { + packet.broadcast(); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/AlertLogPacket.java b/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/AlertLogPacket.java new file mode 100644 index 0000000..7d8722c --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/AlertLogPacket.java @@ -0,0 +1,52 @@ +package cc.fyre.riot.packet.packets; + +import cc.fyre.proton.pidgin.packet.Packet; +import cc.fyre.riot.Riot; +import cc.fyre.universe.UniverseAPI; +import com.google.gson.JsonObject; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class AlertLogPacket implements Packet { + @Getter + private JsonObject jsonObject; + public AlertLogPacket() { + } + public AlertLogPacket(JsonObject jsonObject) { + this.jsonObject = jsonObject; + } + public AlertLogPacket(String message, String metadata, String ping) { + this.jsonObject = new JsonObject(); + jsonObject.addProperty("message", message); + jsonObject.addProperty("metadata", metadata); + jsonObject.addProperty("ping", ping); + } + @Override + public int id() { + return 71; + } + + @Override + public JsonObject serialize() { + return this.jsonObject; + } + + @Override + public void deserialize(JsonObject jsonObject) { + this.jsonObject = jsonObject; + } + public void broadcast() { + String message = jsonObject.get("message").getAsString(); + String metadata = jsonObject.get("metadata").getAsString(); + String ping = jsonObject.get("ping").getAsString() ; + Riot.getInstance().getServer().getOnlinePlayers().stream().filter(it -> + Riot.getInstance().getFlagHandler().getCache().getOrDefault(it.getUniqueId(),false)).forEach(it -> { + it.sendMessage(message + (metadata != null && Riot.getInstance().getLogHandler().isWhitelisted(it.getUniqueId()) ? " " + metadata:"") + " " + ping); + }); + + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/ExemptPacket.java b/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/ExemptPacket.java new file mode 100644 index 0000000..4537a16 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/ExemptPacket.java @@ -0,0 +1,50 @@ +package cc.fyre.riot.packet.packets; + +import cc.fyre.proton.Proton; +import cc.fyre.proton.pidgin.packet.Packet; +import cc.fyre.riot.Riot; +import com.google.gson.JsonObject; +import lombok.Getter; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class ExemptPacket implements Packet { + @Getter + private JsonObject jsonObject; + public ExemptPacket(JsonObject jsonObject) { + this.jsonObject = jsonObject; + } + public ExemptPacket() { + } + public ExemptPacket(String uuid, boolean state) { + this.jsonObject = new JsonObject(); + jsonObject.addProperty("uuid", uuid); + jsonObject.addProperty("state", state); + } + @Override + public int id() { + return 72; + } + + @Override + public JsonObject serialize() { + return this.jsonObject; + } + + @Override + public void deserialize(JsonObject jsonObject) { + this.jsonObject = jsonObject; + } + public void broadcast() { + if(jsonObject.get("state").getAsBoolean()) { + Riot.getInstance().getExempted().add(UUID.fromString(jsonObject.get("uuid").getAsString())); + Riot.getInstance().getLogger().info("Exempt User"); + } else { + Riot.getInstance().getExempted().remove((UUID.fromString(jsonObject.get("uuid").getAsString()))); + Riot.getInstance().getLogger().info("UnExempt User"); + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/WhitelistPacket.java b/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/WhitelistPacket.java new file mode 100644 index 0000000..65ce8bf --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/packet/packets/WhitelistPacket.java @@ -0,0 +1,57 @@ +package cc.fyre.riot.packet.packets; + +import cc.fyre.proton.pidgin.packet.Packet; +import cc.fyre.riot.Riot; +import cc.fyre.riot.log.LogHandler; +import com.google.gson.JsonObject; +import lombok.Getter; +import org.apache.logging.log4j.core.helpers.UUIDUtil; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class WhitelistPacket implements Packet { + @Getter + private JsonObject jsonObject; + public WhitelistPacket(JsonObject jsonObject) { + this.jsonObject = jsonObject; + } + public WhitelistPacket() { + } + public WhitelistPacket(String uuid, boolean state) { + this.jsonObject = new JsonObject(); + System.out.println(uuid); + jsonObject.addProperty("uuid", uuid); + jsonObject.addProperty("state", state); + } + @Override + public int id() { + return 70; + } + + @Override + public JsonObject serialize() { + return this.jsonObject; + } + + @Override + public void deserialize(JsonObject jsonObject) { + this.jsonObject = jsonObject; + } + public void broadcast() { + UUID uuid = UUID.fromString(jsonObject.get("uuid").getAsString()); + Player player = Bukkit.getPlayer(uuid); + boolean whitelisted = jsonObject.get("state").getAsBoolean(); + if(player != null) { + player.sendMessage( ChatColor.GOLD + " You " + (!whitelisted ? ChatColor.RED:ChatColor.GREEN) + " have been " + (whitelisted ? "un-":"") + "whitelisted."); + } + if(whitelisted) { + Riot.getInstance().getLogHandler().getWhitelisted().add(uuid); + } else { + Riot.getInstance().getLogHandler().getWhitelisted().remove(uuid); + } + + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/profile/Profile.java b/Anticheat-master/src/main/java/cc/fyre/riot/profile/Profile.java new file mode 100644 index 0000000..5936376 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/profile/Profile.java @@ -0,0 +1,251 @@ +package cc.fyre.riot.profile; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.check.Check; +import cc.fyre.riot.check.checks.combat.aim.*; +import cc.fyre.riot.check.checks.combat.autoclicker.left.*; +import cc.fyre.riot.check.checks.combat.killaura.*; +import cc.fyre.riot.check.checks.combat.reach.ReachB; +import cc.fyre.riot.check.checks.inventory.*; +import cc.fyre.riot.check.checks.misc.*; +import cc.fyre.riot.check.checks.movement.*; +import cc.fyre.riot.check.checks.movement.falling.NoFallA; +import cc.fyre.riot.check.checks.movement.fly.*; +import cc.fyre.riot.check.checks.movement.speed.*; +import cc.fyre.riot.check.checks.movement.velocity.*; +import cc.fyre.riot.check.checks.order.*; +import cc.fyre.riot.profile.tracker.*; +import cc.fyre.riot.util.Location; +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.entity.*; + +import java.util.logging.*; +import java.util.*; +import net.minecraft.server.v1_7_R4.*; + + +public class Profile { + + @Getter private final UUID uuid; + @Getter private final String name; + + @Getter private final List checkList; + @Getter private final ClickTracker clickTracker; + @Getter private final ConnectionTracker connectionTracker; + @Getter private final LocationHistoryTracker locationHistoryTracker; + @Getter private final MovementTracker movementTracker; + @Getter private final PayloadTracker payloadTracker; + @Getter private final AttackTracker attackTracker; + + + @Getter @Setter private boolean kicked; + @Getter @Setter private boolean loggedOut; + @Getter @Setter private int violations; + @Getter @Setter public int LastPacketDrop; + @Getter @Setter public long LastDelayedPacket; + @Getter @Setter public long LastFlyingTicks; + @Getter @Setter public long LastFlying; + @Getter @Setter public int TotalTicks; + @Getter @Setter public long lastLag; + public float deltaXZ; + public boolean lastOnGround; + public boolean onGroundPacket; + public boolean lastLastOnGround; + public boolean onGround; + public boolean lastOnGroundPacket; + public boolean lastLastOnGroundPacket; + + public Profile(Player player) { + this.uuid = player.getUniqueId(); + this.name = player.getName(); + this.violations = 0; + this.LastPacketDrop = 0; + this.LastDelayedPacket = 0; + this.LastFlyingTicks = 0; + this.LastFlying = 0; + this.TotalTicks = 0; + + this.checkList = new ArrayList<>(); + this.clickTracker = new ClickTracker(this); + this.payloadTracker = new PayloadTracker(this); + this.movementTracker = new MovementTracker(this); + this.connectionTracker = new ConnectionTracker(this); + this.locationHistoryTracker = new LocationHistoryTracker(this); + this.attackTracker = new AttackTracker(this); + + this.kicked = false; + this.loggedOut = false; + this.lastLastOnGround = false; + this.onGround = false; + this.lastOnGroundPacket = false; + this.lastLastOnGroundPacket = false; + + this.checkList.addAll(Arrays.asList + //Aim + (new AimA(this), new AimB(this), + + //Auto-Clicker + new AutoClickerD(this), new AutoClickerG(this), new AutoClickerH(this), + new AutoClickerK(this), new AutoClickerO(this), new AutoClickerS(this), new AutoClickerZ(this), + + //Packet + new TimerA(this), new TimerB(this), new NoPosition(this), new Pitch(this), + new CustomPayload(this), new DoubleSneak(this), + new PostFlyingPacket(this), new SameSlotSwitch(this), + new BlockPlaceC(this), new BlockPlaceA(this), new BlockPlaceB(this), + + + //Movement / Invalid Direction + new Fly(this), new Speed(this), new DoubleSprint(this),new KeepSprint(this), + new VerticalVelocity(this), new NoFallA(this), + + //Order / Functions between packet order + new ActionAttack(this), new NoSwingAttack(this), + new PlaceAttack(this), new PlaceRelease(this), new PlaceSlot(this), + + //Combat / Invalid Swing Motion / Invalid Distance to range + new KillAuraA(this),new MultiAura(this), new ReachB(this), + + //Inventory + new InventoryA(this), new InventoryB(this), new InventoryC(this), + new InventoryD(this), + + //Debug / New checks and information + new TestFlag(this))); + + } + + public void handleInboundPacket(final Object message, final long millis, final long nanos) { + try { + + if (message instanceof PacketPlayInFlying) { + this.movementTracker.handleFlying((PacketPlayInFlying)message); + this.clickTracker.handleFlying(); + } else if (message instanceof PacketPlayInBlockDig) { + this.clickTracker.handleBlockDig((PacketPlayInBlockDig)message); + } else if (message instanceof PacketPlayInBlockPlace) { + this.clickTracker.handleBlockPlace(); + } else if (message instanceof PacketPlayInUseEntity) { + this.clickTracker.handleUseEntity((PacketPlayInUseEntity)message); + } else if (message instanceof PacketPlayInArmAnimation) { + this.clickTracker.handleArmAnimation(); + } else if (message instanceof PacketPlayInCustomPayload) { + this.payloadTracker.handleCustomPayload((PacketPlayInCustomPayload)message); + } else if (message instanceof PacketPlayInTransaction) { + this.connectionTracker.handleTransaction((PacketPlayInTransaction)message, millis); + this.movementTracker.handleTransaction((PacketPlayInTransaction)message); + this.locationHistoryTracker.handleTransaction((PacketPlayInTransaction)message); + } else if (message instanceof PacketPlayInKeepAlive) { + this.connectionTracker.handleKeepAlive((PacketPlayInKeepAlive)message, millis); + } else if (message instanceof PacketPlayInEntityAction) { + this.movementTracker.handleEntityAction((PacketPlayInEntityAction)message); + } + + } catch (Exception ex) { + Riot.getInstance().getLogger().log(Level.SEVERE,"Could not handle inbound packet",ex); + ex.printStackTrace(); + } + + this.checkList.forEach(it -> { + + try { + it.handleInboundPacket(message,millis,nanos); + } catch (Exception ex) { + Riot.getInstance().getLogger().log(Level.SEVERE,"Could not handle inbound packet for check " + it.getName(),ex); + } + + }); + + if (message instanceof PacketPlayInFlying) { + this.movementTracker.handleFlyingPost(); + this.locationHistoryTracker.handleFlyingPost(); + this.connectionTracker.handleFlyingPost(); + } + + } + public void handleInboundPacketEvent(final Object message, byte packetId) { + this.checkList.forEach(it -> { + + try { + it.handleInboundPacketEvent(message, packetId); + } catch (Exception ex) { + Riot.getInstance().getLogger().log(Level.SEVERE,"Could not handle inbound packet for check " + it.getName(),ex); + } + + }); + } + + public void handleOutboundPacket(final Object message, final long millis, final long nanos) { + + try { + + if (message instanceof PacketPlayOutPosition) { + this.movementTracker.handlePosition((PacketPlayOutPosition)message); + } else if (message instanceof PacketPlayOutEntityVelocity) { + this.movementTracker.handleEntityVelocity((PacketPlayOutEntityVelocity)message); + } else if (message instanceof PacketPlayOutExplosion) { + this.movementTracker.handleExplosion((PacketPlayOutExplosion)message); + } else if (message instanceof PacketPlayOutSpawnEntity) { + this.locationHistoryTracker.handleSpawnEntity((PacketPlayOutSpawnEntity)message); + } else if (message instanceof PacketPlayOutEntity) { + this.locationHistoryTracker.handleEntity((PacketPlayOutEntity)message); + } else if (message instanceof PacketPlayOutEntityTeleport) { + this.locationHistoryTracker.handleSpawnEntityTeleport((PacketPlayOutEntityTeleport)message); + } else if (message instanceof PacketPlayOutEntityDestroy) { + this.locationHistoryTracker.handleEntityDestroy((PacketPlayOutEntityDestroy)message); + } + + } catch (Exception ex) { + Riot.getInstance().getLogger().log(Level.SEVERE,"Could not handle inbound packet",ex); + ex.printStackTrace(); + } + + this.checkList.forEach(it -> { + + try { + it.handleOutboundPacket(message,millis,nanos); + } catch (Exception ex) { + Riot.getInstance().getLogger().log(Level.SEVERE,"Could not handle inbound packet for check " + it.getName(),ex); + } + + }); + + } + + public void onMove(Location from,Location to,boolean moved,boolean rotated) { + + this.checkList.forEach(it -> { + + try { + it.onMove(from,to,moved,rotated); + } catch (Exception ex) { + Riot.getInstance().getLogger().log(Level.SEVERE, "Could not handle onMove for check " + it.getName() + ":",ex); + } + + }); + + } + + public void onTeleport() { + this.checkList.forEach(Check::onTeleport); + } + + public void onServerTick() { + this.connectionTracker.onServerTick(); + } + + public void onMouseLeftClick(final int ticks) { + this.checkList.forEach(c -> c.onMouseLeftClick(ticks)); + } + + public Player getPlayer() { + return Riot.getInstance().getServer().getPlayer(this.uuid); + } + + public boolean isLagging(long currentTime, long length) { + return currentTime - lastLag < length; + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/profile/ProfileHandler.java b/Anticheat-master/src/main/java/cc/fyre/riot/profile/ProfileHandler.java new file mode 100644 index 0000000..512638f --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/profile/ProfileHandler.java @@ -0,0 +1,33 @@ +package cc.fyre.riot.profile; + +import lombok.Getter; +import net.minecraft.server.v1_7_R4.MinecraftServer; +import cc.fyre.riot.Riot; +import org.bukkit.entity.*; +import java.util.*; + +public class ProfileHandler { + + @Getter private final Map cache = new HashMap<>(); + @Getter private final Map idToUUID = new HashMap<>(); + + private final Riot instance; + + public ProfileHandler(Riot instance) { + this.instance = instance; + + MinecraftServer.PRE_ENTITY_TRACKER_RUNNABLE_LIST.add(() -> this.cache.values().forEach(it -> it.getLocationHistoryTracker().preEntityTracker())); + + instance.getServer().getScheduler().runTaskTimer(instance,() -> this.cache.values().forEach(Profile::onServerTick),1L,1L); + } + + public Player findByEntityId(int id) { + + if (!this.idToUUID.containsKey(id)) { + return null; + } + + return this.instance.getServer().getPlayer(this.idToUUID.get(id)); + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/AttackTracker.java b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/AttackTracker.java new file mode 100644 index 0000000..2931ef3 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/AttackTracker.java @@ -0,0 +1,29 @@ +package cc.fyre.riot.profile.tracker; + +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.Location; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +@Getter @Setter +public class AttackTracker { + private final Profile profile; + public Player lastTarget; + public int lastAttackTick; + public float attackerPitch, attackerYaw; + public double attackerX, attackerY, attackerZ; + public int lastPosition; + public int lastPosition2; + public double attackerX2, attackerY2, attackerZ2; + public float attackerYaw2, attackerPitch2; + + public AttackTracker(final Profile profile) { + this.profile = profile; + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/ClickTracker.java b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/ClickTracker.java new file mode 100644 index 0000000..61066f9 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/ClickTracker.java @@ -0,0 +1,79 @@ +package cc.fyre.riot.profile.tracker; + +import cc.fyre.riot.profile.Profile; +import lombok.Getter; + +import java.util.*; + +import lombok.Setter; +import net.minecraft.server.v1_7_R4.*; + +public class ClickTracker { + + @Getter private final Profile profile; + + @Getter private boolean digging; + @Getter private boolean placing; + @Getter @Setter private boolean recording; + + @Getter private int animations; + @Getter private int lastClickTicks; + @Getter @Setter private double cps; + + @Getter private List delays; + + public ClickTracker(Profile profile) { + this.profile = profile; + this.delays = new ArrayList<>(); + this.recording = false; + this.animations = 0; + this.cps = 0; + this.lastClickTicks = 10; + } + + public void handleArmAnimation() { + this.animations++; + } + + public void handleBlockDig(PacketPlayInBlockDig packet) { + + if (packet.g() != 0) { + return; + } + + this.digging = true; + } + + public void handleUseEntity(final PacketPlayInUseEntity packet) { + + if (packet.c() != EnumEntityUseAction.ATTACK) { + return; + } + + this.digging = false; + } + + public void handleBlockPlace() { + this.placing = true; + } + + public void handleFlying() { + if (!this.digging && !this.placing) { + + for (int i = 0; i < this.animations; ++i) { + + if (this.recording && this.lastClickTicks <= 20) { + this.delays.add(this.lastClickTicks); + } + + this.profile.onMouseLeftClick(this.lastClickTicks); + this.lastClickTicks = 0; + } + + } + + this.placing = false; + this.animations = 0; + this.lastClickTicks++; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/ConnectionTracker.java b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/ConnectionTracker.java new file mode 100644 index 0000000..845a4a4 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/ConnectionTracker.java @@ -0,0 +1,117 @@ +package cc.fyre.riot.profile.tracker; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.profile.Profile; + +import java.util.*; + + +import java.util.logging.*; +import net.minecraft.server.v1_7_R4.*; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer; + +public class ConnectionTracker { + + public static final Object LOCK; + private final Profile profile; + public int ticks; + private short transactionId; + private final Map transactionMap; + public long transactionPing; + public long lastTransaction; + private int keepAliveId; + private final Map keepAliveMap; + public long keepAlivePing; + + public ConnectionTracker(final Profile profile) { + this.transactionId = -32768; + this.transactionMap = new HashMap(); + this.transactionPing = -1L; + this.lastTransaction = System.currentTimeMillis(); + this.keepAliveId = 0; + this.keepAliveMap = new HashMap(); + this.keepAlivePing = -1L; + this.profile = profile; + } + + public void handleTransaction(final PacketPlayInTransaction packet, final long millis) { + synchronized (ConnectionTracker.LOCK) { + if (packet.c() == 0) { + final Long time = this.transactionMap.remove(packet.d()); + if (time != null) { + this.transactionPing = millis - time; + this.lastTransaction = System.currentTimeMillis(); + } + } + } + } + + public void handleKeepAlive(final PacketPlayInKeepAlive packet, final long millis) { + synchronized (ConnectionTracker.LOCK) { + final Long time = this.keepAliveMap.remove(packet.c()); + if (time != null) { + this.keepAlivePing = millis - time; + } + } + } + + public void onServerTick() { + synchronized (ConnectionTracker.LOCK) { + + final EntityPlayer entityPlayer = ((CraftPlayer)this.profile.getPlayer()).getHandle(); + + if (this.ticks % 10 == 0) { + this.keepAliveMap.put(this.keepAliveId, System.currentTimeMillis()); + + entityPlayer.playerConnection.sendPacket(new PacketPlayOutKeepAlive(this.keepAliveId)); + + ++this.keepAliveId; + } + + if (this.ticks % 20 == 0) { + this.transactionMap.values().stream().filter(time -> System.currentTimeMillis() - time >= 20000L).findFirst().ifPresent(time -> { + + Bukkit.getScheduler().runTaskLater(Riot.getInstance(),() -> { + entityPlayer.playerConnection.disconnect("Disconnected"); + Riot.getInstance().getLogger().log(Level.WARNING,entityPlayer.getName() + " has been disconnected for not responding to a transaction within " + (System.currentTimeMillis() - time) + " ms"); + },1L); + + }); + } + } + } + + public short sendTransaction() { + synchronized (ConnectionTracker.LOCK) { + final short transactionId = this.transactionId; + + this.transactionId = (short)(transactionId + 1); + + if (this.transactionId == 0) { + this.transactionId = -32768; + } + + this.transactionMap.put(transactionId, System.currentTimeMillis()); + + ((CraftPlayer)this.profile.getPlayer()).getHandle().playerConnection.sendPacket(new PacketPlayOutTransaction(0,transactionId,false)); + + return transactionId; + + } + } + + public boolean hasRespondedToTransaction() { + return this.transactionPing != -1L; + } + + public void handleFlyingPost() { + synchronized (ConnectionTracker.LOCK) { + ++this.ticks; + } + } + + static { + LOCK = new Object(); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/LocationHistoryTracker.java b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/LocationHistoryTracker.java new file mode 100644 index 0000000..974dca7 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/LocationHistoryTracker.java @@ -0,0 +1,129 @@ +package cc.fyre.riot.profile.tracker; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.AxisAlignedBB; +import cc.fyre.riot.util.EvictingList; +import cc.fyre.riot.util.Pair; +import lombok.Getter; +import lombok.Setter; + + +import java.util.*; + +import net.minecraft.server.v1_7_R4.*; +import org.bukkit.Bukkit; + +public class LocationHistoryTracker +{ + private final Profile profile; + public short lastServerPositionTick; + private short transactionId; + public final Map> locationHistoryMap; + public final Map lastLocationMap; + @Getter private final EvictingList> pastLocs = new EvictingList<>(20); + @Getter private final EvictingList> pastLocations = new EvictingList<>(30); + + public LocationHistoryTracker(final Profile profile) { + this.transactionId = -1; + this.locationHistoryMap = new HashMap<>(); + this.lastLocationMap = new HashMap<>(); + this.profile = profile; + } + + public void preEntityTracker() { + this.transactionId = this.profile.getConnectionTracker().sendTransaction(); + } + + public void handleFlyingPost() { + this.locationHistoryMap.values().forEach(l -> l.stream().filter(SparkLocation::isReceived).forEach(SparkLocation::incrementTicks)); + } + + public void handleTransaction(final PacketPlayInTransaction packet) { + this.locationHistoryMap.values().forEach(l -> l.stream().filter(l2 -> l2.getTransactionId() == packet.d()).forEach(l2 -> l2.setReceived(true))); + } + + public void handleSpawnEntity(final PacketPlayOutSpawnEntity packet) { + final int entityId = packet.a; + final double x = packet.b / 32.0; + final double y = packet.c / 32.0; + final double z = packet.d / 32.0; + final SparkLocation location = new SparkLocation(x, y, z); + location.transactionId = this.transactionId; + final List locations = this.locationHistoryMap.computeIfAbsent(Integer.valueOf(entityId), e -> new ArrayList()); + if (locations.size() == 200) { + locations.remove(199); + } + locations.add(0, location); + this.lastLocationMap.put(entityId, location); + } + + public void handleEntity(final PacketPlayOutEntity packet) { + if (packet instanceof PacketPlayOutRelEntityMove || packet instanceof PacketPlayOutRelEntityMoveLook) { + final int entityId = packet.a; + final double x = packet.b / 32.0; + final double y = packet.c / 32.0; + final double z = packet.d / 32.0; + final SparkLocation lastLocation = this.lastLocationMap.get(entityId); + if (lastLocation != null) { + final SparkLocation location = new SparkLocation(lastLocation.x + x, lastLocation.y + y, lastLocation.z + z); + location.transactionId = this.transactionId; + final List locations = this.locationHistoryMap.computeIfAbsent(entityId,e -> new ArrayList<>()); + if (locations.size() == 200) { + locations.remove(199); + } + locations.add(0, location); + this.lastLocationMap.put(entityId, location); + + } + } + } + + public void handleSpawnEntityTeleport(final PacketPlayOutEntityTeleport packet) { + final int entityId = packet.a; + final double x = packet.b / 32.0; + final double y = packet.c / 32.0; + final double z = packet.d / 32.0; + final SparkLocation location = new SparkLocation(x, y, z); + location.transactionId = this.transactionId; + final List locations = this.locationHistoryMap.computeIfAbsent(entityId,e -> new ArrayList<>()); + if (locations.size() == 200) { + locations.remove(199); + } + locations.add(0, location); + this.lastLocationMap.put(entityId, location); + } + + public void handleEntityDestroy(final PacketPlayOutEntityDestroy packet) { + for (final int entityId : packet.a) { + this.locationHistoryMap.remove(entityId); + this.lastLocationMap.remove(entityId); + } + } + + + public static class SparkLocation { + + @Getter @Setter private double x; + @Getter @Setter private double y; + @Getter @Setter private double z; + + @Getter @Setter private float yaw; + @Getter @Setter private float pitch; + + @Getter @Setter private int ticks; + @Getter @Setter private boolean received; + + @Getter @Setter private short transactionId; + + public SparkLocation(final double x, final double y, final double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public void incrementTicks() { + ++this.ticks; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/MovementTracker.java b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/MovementTracker.java new file mode 100644 index 0000000..6ca1fc0 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/MovementTracker.java @@ -0,0 +1,148 @@ +package cc.fyre.riot.profile.tracker; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.util.Location; +import cc.fyre.riot.util.Velocity; + + +import java.util.*; + +import java.util.logging.*; + +import io.github.retrooper.packetevents.packetwrappers.in.entityaction.WrappedPacketInEntityAction; +import net.minecraft.server.v1_7_R4.*; + +public class MovementTracker +{ + private final Profile profile; + public Location lastLocation; + public boolean sprinting; + public boolean sneaking; + public final List velocityList; + private final List teleportIdList; + public boolean teleporting; + private boolean teleported; + public int ticksSinceTeleported; + public int ticksSinceVehicle; + + public MovementTracker(final Profile profile) { + this.lastLocation = new Location(Double.NaN, Double.NaN, Double.NaN, Float.NaN, Float.NaN); + this.sprinting = false; + this.velocityList = new ArrayList<>(); + this.teleportIdList = new ArrayList<>(); + this.teleporting = false; + this.teleported = false; + this.ticksSinceTeleported = 1000; + this.ticksSinceVehicle = 1000; + this.profile = profile; + } + + public void handleFlying(final PacketPlayInFlying packet) { + ++this.ticksSinceTeleported; + ++this.ticksSinceVehicle; + + if (this.profile.getPlayer().isInsideVehicle()) { + this.ticksSinceVehicle = 0; + } + + this.velocityList.stream().filter(Velocity::isReceived).forEach(v -> v.setTicks(v.getTicks() - 1)); + this.velocityList.removeIf(v -> v.getTicks() == 0); + final boolean hasPos = packet.j(); + final boolean hasLook = packet.k(); + final double x = packet.c(); + final double y = packet.d(); + final double z = packet.e(); + final float yaw = packet.g(); + final float pitch = packet.h(); + final Location location = new Location(x, y, z, yaw, pitch); + if (!hasPos) { + location.setX(this.lastLocation.getX()); + location.setY(this.lastLocation.getY()); + location.setZ(this.lastLocation.getZ()); + } + if (!hasLook) { + location.setYaw(this.lastLocation.getYaw()); + location.setPitch(this.lastLocation.getPitch()); + } + final boolean moved = !Double.isNaN(this.lastLocation.getX()) && !Double.isNaN(location.getX()) && (this.lastLocation.getX() != location.getX() || this.lastLocation.getY() != location.getY() || this.lastLocation.getZ() != location.getZ()); + final boolean rotated = !Double.isNaN(this.lastLocation.getYaw()) && !Double.isNaN(location.getPitch()) && (this.lastLocation.getYaw() != location.getPitch() || this.lastLocation.getPitch() != location.getPitch()); + final double deltaXZ; + if (moved && !this.teleporting && (deltaXZ = Math.hypot(this.lastLocation.getX() - location.getX(), this.lastLocation.getZ() - location.getZ())) > 20.0) { +// Riot.getInstance().getLogger().log(Level.WARNING, this.profile.getName() + " moved " + deltaXZ + " blocks"); + return; + } + if (moved && (Math.abs(x) > 3000.0 || Math.abs(z) > 3000.0)) { +// Riot.getInstance().getLogger().log(Level.WARNING, this.profile.getName() + " moved to " + x + ", " + z); + return; + } + if ((moved || rotated) && !this.teleporting) { + this.profile.onMove(this.lastLocation, location, moved, rotated); + } + this.lastLocation = location; + } + + public void handlePosition(final PacketPlayOutPosition packet) { + this.teleportIdList.add(this.profile.getConnectionTracker().sendTransaction()); + this.teleporting = true; + } + + public void handleTransaction(final PacketPlayInTransaction packet) { + final Short id = packet.d(); + if (this.teleportIdList.remove(id)) { + this.teleported = true; + } + this.velocityList.stream().filter(v -> v.getTransactionId() == id).forEach(v -> v.setReceived(true)); + } + + public void handleEntityVelocity(final PacketPlayOutEntityVelocity packet) { + if (packet.a == this.profile.getPlayer().getEntityId()) { + final double x = packet.b / 8000.0; + final double y = packet.c / 8000.0; + final double z = packet.d / 8000.0; + final double length = Math.sqrt(Math.pow(x, 2.0) + Math.pow(y, 2.0) + Math.pow(z, 2.0)); + final int ticks = (int)(length * 20.0 + 20.0); + final short id = this.profile.getConnectionTracker().sendTransaction(); + this.velocityList.add(new Velocity(x, y, z, ticks, id)); + } + } + + public void handleExplosion(final PacketPlayOutExplosion packet) { + final double x = packet.f; + final double y = packet.g; + final double z = packet.h; + final double length = Math.sqrt(Math.pow(x, 2.0) + Math.pow(y, 2.0) + Math.pow(z, 2.0)); + final int ticks = (int)(length * 20.0 + 20.0); + final short id = this.profile.getConnectionTracker().sendTransaction(); + this.velocityList.add(new Velocity(x, y, z, ticks, id)); + } + + public void handleEntityAction(final PacketPlayInEntityAction packet) { + if (packet.d() == 4) { + this.sprinting = true; + } + else if (packet.d() == 5) { + this.sprinting = false; + } + final WrappedPacketInEntityAction action = new WrappedPacketInEntityAction(packet); + switch (action.getAction()) { + case START_SPRINTING: + sneaking = true; + break; + case STOP_SPRINTING: + sneaking = false; + break; + } + } + + public void handleFlyingPost() { + if (this.teleported) { + this.teleported = false; + if (this.teleportIdList.isEmpty()) { + this.teleporting = false; + } + this.ticksSinceTeleported = 0; + this.profile.onTeleport(); + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/PayloadTracker.java b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/PayloadTracker.java new file mode 100644 index 0000000..a307abb --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/profile/tracker/PayloadTracker.java @@ -0,0 +1,119 @@ +package cc.fyre.riot.profile.tracker; + +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.Riot; + +import java.util.*; +import net.minecraft.server.v1_7_R4.*; + + +import org.bukkit.Bukkit; + +public class PayloadTracker +{ + private final Profile profile; + public Set clientInformation; + private boolean known; + private int payloads; + + public PayloadTracker(final Profile profile) { + this.clientInformation = new HashSet(); + this.known = false; + this.profile = profile; + } + + public void handleCustomPayload(final PacketPlayInCustomPayload packet) { + final String tag = packet.c(); + final byte[] data = packet.e(); + final String text = (data == null) ? "" : new String(data); + if (tag.equals("MC|Brand")) { + if (text.contains("vanilla")) { + this.add("Vanilla"); + } + if (text.contains("LiteLoader")) { + this.add("LiteLoader"); + } + if (text.contains("forge")) { + this.add("Forge"); + } + if (text.contains("lunarclient")) { + this.add("Lunar Client"); + } + if (text.contains("PLC")) { + this.add("PvPLounge Client"); + } + if (text.contains("hyperium")) { + this.add("Hyperium Client"); + } + if (text.contains("cheatbreaker")) { + this.add("CheatBreaker"); + } + } + if (tag.equals("REGISTER")) { + if (text.contains("CC")) { + this.add("Cosmic Client"); + } + if (text.contains("OCMC")) { + this.add("OCMC"); + } + if (text.contains("FALCUN-CLIENT")) { + this.add("Falcun Client"); + } + if (text.toLowerCase().contains("5zig")) { + this.add("5zig Mod"); + } + if (text.contains("WDL|INIT")) { + this.add("World Downloader"); + } + if (text.contains("WECUI")) { + this.add("WorldEdit CUI"); + } + if (text.contains("Lunar-Client")) { + this.add("Lunar Client"); + } + } + if (tag.equals("LMC")) { + this.add("LabyMod"); + } + if (tag.equals("WDL|INIT")) { + this.add("WorldDownloader"); + } + if (tag.equals("WECUI")) { + this.add("WorldEdit CUI"); + } + if (tag.equals("CB-Client")) { + this.add("CheatBreaker"); + } + if (tag.equals("Lunar-Client")) { + this.add("Lunar Client"); + } + if (tag.equals("CTWRequest")) { + this.add("CTW (Pixel Client?)"); + } + if (tag.equals("OCMC")) { + this.add("OCMC"); + } + if (!tag.equals("MC|BEdit") && !tag.equals("MC|BSign") && !tag.equals("MC|TrSel") && !tag.equals("MC|Beacon") && !tag.equals("MC|ItemName") && (!tag.equals("REGISTER") || !text.startsWith("FML")) && !this.known && ++this.payloads <= 5) { + + Bukkit.getScheduler().runTaskAsynchronously(Riot.getInstance(),() -> { + + final String message = String.format("Name: %s\nTag: %s\nText: %s", this.profile.getPlayer().getName(), tag, text); + + /*TODO? + try { + WebUtils.postMessageToWebhook("https://discordapp.com/api/webhooks/769336044369477633/Df8hFoxvADTApAOkNJWxgBKWByejYZoetYThOVlVGWmWQ4h6h_eK550X3-Ki9-yO5MQz", message); + } catch (IOException ex) { + ex.printStackTrace(); + }*/ + + }); + + } + this.known = false; + } + + private void add(final String info) { + this.known = true; + this.clientInformation.add(info); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/timings/AntiCheatTimings.java b/Anticheat-master/src/main/java/cc/fyre/riot/timings/AntiCheatTimings.java new file mode 100644 index 0000000..d69894d --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/timings/AntiCheatTimings.java @@ -0,0 +1,57 @@ +package cc.fyre.riot.timings; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.minecraft.util.com.google.common.collect.*; +import cc.fyre.riot.Riot; +import org.bukkit.Bukkit; + +public class AntiCheatTimings { + + private int events; + private long time; + private final EvictingQueue lastTwentyTicks; + + public AntiCheatTimings() { + this.lastTwentyTicks = EvictingQueue.create(20); + + Bukkit.getScheduler().runTaskTimer(Riot.getInstance(),() -> { + + synchronized (this) { + this.lastTwentyTicks.add(new Timings(this.events,this.time)); + this.reset(); + } + + },1L,1L); + } + + public void reset() { + this.time = 0L; + this.events = 0; + } + + public synchronized void addTiming(final long timing) { + ++this.events; + this.time += timing; + } + + public synchronized Timings getLastTwentyTicks() { + int events = 0; + long time = 0L; + + for (final Timings tick : this.lastTwentyTicks) { + events += tick.getEvents(); + time += tick.getTime(); + } + + return new Timings(events, time); + } + + @AllArgsConstructor + public static class Timings { + + @Getter private final int events; + @Getter private final long time; + + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/AxisAlignedBB.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/AxisAlignedBB.java new file mode 100644 index 0000000..df84cac --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/AxisAlignedBB.java @@ -0,0 +1,410 @@ +package cc.fyre.riot.util; + +import net.minecraft.server.v1_7_R4.EnumFacing; +import org.bukkit.event.block.BlockPlaceEvent; + +public class AxisAlignedBB +{ + public double minX; + public double minY; + public double minZ; + public double maxX; + public double maxY; + public double maxZ; + + public AxisAlignedBB(double x1, double y1, double z1, double x2, double y2, double z2) + { + this.minX = Math.min(x1, x2); + this.minY = Math.min(y1, y2); + this.minZ = Math.min(z1, z2); + this.maxX = Math.max(x1, x2); + this.maxY = Math.max(y1, y2); + this.maxZ = Math.max(z1, z2); + } + + + private String nej(boolean value) { + return value ? "%%__TIMESTAMP__%%" : "%%__USER__%%"; + } + + /** + * Adds the coordinates to the bounding box extending it if the point lies outside the current ranges. Args: x, y, z + */ + public AxisAlignedBB addCoord(double x, double y, double z) + { + double d0 = this.minX; + double d1 = this.minY; + double d2 = this.minZ; + double d3 = this.maxX; + double d4 = this.maxY; + double d5 = this.maxZ; + + if (x < 0.0D) + { + d0 += x; + } + else if (x > 0.0D) + { + d3 += x; + } + + if (y < 0.0D) + { + d1 += y; + } + else if (y > 0.0D) + { + d4 += y; + } + + if (z < 0.0D) + { + d2 += z; + } + else if (z > 0.0D) + { + d5 += z; + } + + return new AxisAlignedBB(d0, d1, d2, d3, d4, d5); + } + + /** + * Returns a bounding box expanded by the specified vector (if negative numbers are given it will shrink). Args: x, + * y, z + */ + public AxisAlignedBB expand(double x, double y, double z) + { + double d0 = this.minX - x; + double d1 = this.minY - y; + double d2 = this.minZ - z; + double d3 = this.maxX + x; + double d4 = this.maxY + y; + double d5 = this.maxZ + z; + return new AxisAlignedBB(d0, d1, d2, d3, d4, d5); + } + + public AxisAlignedBB union(AxisAlignedBB other) + { + double d0 = Math.min(this.minX, other.minX); + double d1 = Math.min(this.minY, other.minY); + double d2 = Math.min(this.minZ, other.minZ); + double d3 = Math.max(this.maxX, other.maxX); + double d4 = Math.max(this.maxY, other.maxY); + double d5 = Math.max(this.maxZ, other.maxZ); + return new AxisAlignedBB(d0, d1, d2, d3, d4, d5); + } + + /** + * returns an AABB with corners x1, y1, z1 and x2, y2, z2 + */ + public static AxisAlignedBB fromBounds(double x1, double y1, double z1, double x2, double y2, double z2) + { + double d0 = Math.min(x1, x2); + double d1 = Math.min(y1, y2); + double d2 = Math.min(z1, z2); + double d3 = Math.max(x1, x2); + double d4 = Math.max(y1, y2); + double d5 = Math.max(z1, z2); + return new AxisAlignedBB(d0, d1, d2, d3, d4, d5); + } + + /** + * Offsets the current bounding box by the specified coordinates. Args: x, y, z + */ + public AxisAlignedBB offset(double x, double y, double z) + { + return new AxisAlignedBB(this.minX + x, this.minY + y, this.minZ + z, this.maxX + x, this.maxY + y, this.maxZ + z); + } + + /** + * if instance and the argument bounding boxes overlap in the Y and Z dimensions, calculate the offset between them + * in the X dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateXOffset(AxisAlignedBB other, double offsetX) + { + if (other.maxY > this.minY && other.minY < this.maxY && other.maxZ > this.minZ && other.minZ < this.maxZ) + { + if (offsetX > 0.0D && other.maxX <= this.minX) + { + double d1 = this.minX - other.maxX; + + if (d1 < offsetX) + { + offsetX = d1; + } + } + else if (offsetX < 0.0D && other.minX >= this.maxX) + { + double d0 = this.maxX - other.minX; + + if (d0 > offsetX) + { + offsetX = d0; + } + } + + return offsetX; + } + else + { + return offsetX; + } + } + + /** + * if instance and the argument bounding boxes overlap in the X and Z dimensions, calculate the offset between them + * in the Y dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateYOffset(AxisAlignedBB other, double offsetY) + { + if (other.maxX > this.minX && other.minX < this.maxX && other.maxZ > this.minZ && other.minZ < this.maxZ) + { + if (offsetY > 0.0D && other.maxY <= this.minY) + { + double d1 = this.minY - other.maxY; + + if (d1 < offsetY) + { + offsetY = d1; + } + } + else if (offsetY < 0.0D && other.minY >= this.maxY) + { + double d0 = this.maxY - other.minY; + + if (d0 > offsetY) + { + offsetY = d0; + } + } + + return offsetY; + } + else + { + return offsetY; + } + } + + /** + * if instance and the argument bounding boxes overlap in the Y and X dimensions, calculate the offset between them + * in the Z dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the + * calculated offset. Otherwise return the calculated offset. + */ + public double calculateZOffset(AxisAlignedBB other, double offsetZ) + { + if (other.maxX > this.minX && other.minX < this.maxX && other.maxY > this.minY && other.minY < this.maxY) + { + if (offsetZ > 0.0D && other.maxZ <= this.minZ) + { + double d1 = this.minZ - other.maxZ; + + if (d1 < offsetZ) + { + offsetZ = d1; + } + } + else if (offsetZ < 0.0D && other.minZ >= this.maxZ) + { + double d0 = this.maxZ - other.minZ; + + if (d0 > offsetZ) + { + offsetZ = d0; + } + } + + return offsetZ; + } + else + { + return offsetZ; + } + } + + /** + * Returns whether the given bounding box intersects with this one. Args: axisAlignedBB + */ + public boolean intersectsWith(AxisAlignedBB other) + { + return other.maxX > this.minX && other.minX < this.maxX ? (other.maxY > this.minY && other.minY < this.maxY ? other.maxZ > this.minZ && other.minZ < this.maxZ : false) : false; + } + + /** + * Returns if the supplied Vec3D is completely inside the bounding box + */ + public boolean isVecInside(Vec3 vec) + { + return vec.xCoord > this.minX && vec.xCoord < this.maxX ? (vec.yCoord > this.minY && vec.yCoord < this.maxY ? vec.zCoord > this.minZ && vec.zCoord < this.maxZ : false) : false; + } + + /** + * Returns the average length of the edges of the bounding box. + */ + public double getAverageEdgeLength() + { + double d0 = this.maxX - this.minX; + double d1 = this.maxY - this.minY; + double d2 = this.maxZ - this.minZ; + return (d0 + d1 + d2) / 3.0D; + } + + /** + * Returns a bounding box that is inset by the specified amounts + */ + public AxisAlignedBB contract(double x, double y, double z) + { + double d0 = this.minX + x; + double d1 = this.minY + y; + double d2 = this.minZ + z; + double d3 = this.maxX - x; + double d4 = this.maxY - y; + double d5 = this.maxZ - z; + return new AxisAlignedBB(d0, d1, d2, d3, d4, d5); + } + + public MovingObjectPosition calculateIntercept(Vec3 vecA, Vec3 vecB) + { + Vec3 vec3 = vecA.getIntermediateWithXValue(vecB, this.minX); + Vec3 vec31 = vecA.getIntermediateWithXValue(vecB, this.maxX); + Vec3 vec32 = vecA.getIntermediateWithYValue(vecB, this.minY); + Vec3 vec33 = vecA.getIntermediateWithYValue(vecB, this.maxY); + Vec3 vec34 = vecA.getIntermediateWithZValue(vecB, this.minZ); + Vec3 vec35 = vecA.getIntermediateWithZValue(vecB, this.maxZ); + + if (!this.isVecInYZ(vec3)) + { + vec3 = null; + } + + if (!this.isVecInYZ(vec31)) + { + vec31 = null; + } + + if (!this.isVecInXZ(vec32)) + { + vec32 = null; + } + + if (!this.isVecInXZ(vec33)) + { + vec33 = null; + } + + if (!this.isVecInXY(vec34)) + { + vec34 = null; + } + + if (!this.isVecInXY(vec35)) + { + vec35 = null; + } + + Vec3 vec36 = null; + + if (vec3 != null) + { + vec36 = vec3; + } + + if (vec31 != null && (vec36 == null || vecA.squareDistanceTo(vec31) < vecA.squareDistanceTo(vec36))) + { + vec36 = vec31; + } + + if (vec32 != null && (vec36 == null || vecA.squareDistanceTo(vec32) < vecA.squareDistanceTo(vec36))) + { + vec36 = vec32; + } + + if (vec33 != null && (vec36 == null || vecA.squareDistanceTo(vec33) < vecA.squareDistanceTo(vec36))) + { + vec36 = vec33; + } + + if (vec34 != null && (vec36 == null || vecA.squareDistanceTo(vec34) < vecA.squareDistanceTo(vec36))) + { + vec36 = vec34; + } + + if (vec35 != null && (vec36 == null || vecA.squareDistanceTo(vec35) < vecA.squareDistanceTo(vec36))) + { + vec36 = vec35; + } + + if (vec36 == null) + { + return null; + } + else + { + EnumFacing enumfacing = null; + + if (vec36 == vec3) + { + enumfacing = EnumFacing.WEST; + } + else if (vec36 == vec31) + { + enumfacing = EnumFacing.EAST; + } + else if (vec36 == vec32) + { + enumfacing = EnumFacing.DOWN; + } + else if (vec36 == vec33) + { + enumfacing = EnumFacing.UP; + } + else if (vec36 == vec34) + { + enumfacing = EnumFacing.NORTH; + } + else + { + enumfacing = EnumFacing.SOUTH; + } + + return new MovingObjectPosition(vec36, enumfacing); + } + } + + /** + * Checks if the specified vector is within the YZ dimensions of the bounding box. Args: Vec3D + */ + private boolean isVecInYZ(Vec3 vec) + { + return vec == null ? false : vec.yCoord >= this.minY && vec.yCoord <= this.maxY && vec.zCoord >= this.minZ && vec.zCoord <= this.maxZ; + } + + /** + * Checks if the specified vector is within the XZ dimensions of the bounding box. Args: Vec3D + */ + private boolean isVecInXZ(Vec3 vec) + { + return vec == null ? false : vec.xCoord >= this.minX && vec.xCoord <= this.maxX && vec.zCoord >= this.minZ && vec.zCoord <= this.maxZ; + } + + /** + * Checks if the specified vector is within the XY dimensions of the bounding box. Args: Vec3D + */ + private boolean isVecInXY(Vec3 vec) + { + return vec == null ? false : vec.xCoord >= this.minX && vec.xCoord <= this.maxX && vec.yCoord >= this.minY && vec.yCoord <= this.maxY; + } + + public String toString() + { + return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + " -> " + this.maxX + ", " + this.maxY + ", " + this.maxZ + "]"; + } + + public boolean func_181656_b() + { + return Double.isNaN(this.minX) || Double.isNaN(this.minY) || Double.isNaN(this.minZ) || Double.isNaN(this.maxX) || Double.isNaN(this.maxY) || Double.isNaN(this.maxZ); + } +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/BlockPos.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/BlockPos.java new file mode 100644 index 0000000..7aef4a8 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/BlockPos.java @@ -0,0 +1,362 @@ +package cc.fyre.riot.util; + + +import net.minecraft.util.com.google.common.collect.AbstractIterator; + +import java.util.Iterator; + +public class BlockPos extends Vec3i +{ + /** The BlockPos with all coordinates 0 */ + public static final BlockPos ORIGIN = new BlockPos(0, 0, 0); + private static final int NUM_X_BITS = 1 + MathHelper.calculateLogBaseTwo(MathHelper.roundUpToPowerOfTwo(30000000)); + private static final int NUM_Z_BITS = NUM_X_BITS; + private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS; + private static final int Y_SHIFT = 0 + NUM_Z_BITS; + private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS; + private static final long X_MASK = (1L << NUM_X_BITS) - 1L; + private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L; + private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L; + + public BlockPos(int x, int y, int z) + { + super(x, y, z); + } + + public BlockPos(double x, double y, double z) + { + super(x, y, z); + } + + public BlockPos(Vec3 source) + { + this(source.xCoord, source.yCoord, source.zCoord); + } + + public BlockPos(Vec3i source) + { + this(source.getX(), source.getY(), source.getZ()); + } + + /** + * Add the given coordinates to the coordinates of this BlockPos + */ + public BlockPos add(double x, double y, double z) + { + return x == 0.0D && y == 0.0D && z == 0.0D ? this : new BlockPos((double)this.getX() + x, (double)this.getY() + y, (double)this.getZ() + z); + } + + /** + * Add the given coordinates to the coordinates of this BlockPos + */ + public BlockPos add(int x, int y, int z) + { + return x == 0 && y == 0 && z == 0 ? this : new BlockPos(this.getX() + x, this.getY() + y, this.getZ() + z); + } + + /** + * Add the given Vector to this BlockPos + */ + public BlockPos add(Vec3i vec) + { + return vec.getX() == 0 && vec.getY() == 0 && vec.getZ() == 0 ? this : new BlockPos(this.getX() + vec.getX(), this.getY() + vec.getY(), this.getZ() + vec.getZ()); + } + + /** + * Subtract the given Vector from this BlockPos + */ + public BlockPos subtract(Vec3i vec) + { + return vec.getX() == 0 && vec.getY() == 0 && vec.getZ() == 0 ? this : new BlockPos(this.getX() - vec.getX(), this.getY() - vec.getY(), this.getZ() - vec.getZ()); + } + + /** + * Offset this BlockPos 1 block up + */ + public BlockPos up() + { + return this.up(1); + } + + /** + * Offset this BlockPos n blocks up + */ + public BlockPos up(int n) + { + return this.offset(EnumFacing.UP, n); + } + + /** + * Offset this BlockPos 1 block down + */ + public BlockPos down() + { + return this.down(1); + } + + /** + * Offset this BlockPos n blocks down + */ + public BlockPos down(int n) + { + return this.offset(EnumFacing.DOWN, n); + } + + /** + * Offset this BlockPos 1 block in northern direction + */ + public BlockPos north() + { + return this.north(1); + } + + /** + * Offset this BlockPos n blocks in northern direction + */ + public BlockPos north(int n) + { + return this.offset(EnumFacing.NORTH, n); + } + + /** + * Offset this BlockPos 1 block in southern direction + */ + public BlockPos south() + { + return this.south(1); + } + + /** + * Offset this BlockPos n blocks in southern direction + */ + public BlockPos south(int n) + { + return this.offset(EnumFacing.SOUTH, n); + } + + /** + * Offset this BlockPos 1 block in western direction + */ + public BlockPos west() + { + return this.west(1); + } + + /** + * Offset this BlockPos n blocks in western direction + */ + public BlockPos west(int n) + { + return this.offset(EnumFacing.WEST, n); + } + + /** + * Offset this BlockPos 1 block in eastern direction + */ + public BlockPos east() + { + return this.east(1); + } + + /** + * Offset this BlockPos n blocks in eastern direction + */ + public BlockPos east(int n) + { + return this.offset(EnumFacing.EAST, n); + } + + /** + * Offset this BlockPos 1 block in the given direction + */ + public BlockPos offset(EnumFacing facing) + { + return this.offset(facing, 1); + } + + /** + * Offsets this BlockPos n blocks in the given direction + */ + public BlockPos offset(EnumFacing facing, int n) + { + return n == 0 ? this : new BlockPos(this.getX() + facing.getFrontOffsetX() * n, this.getY() + facing.getFrontOffsetY() * n, this.getZ() + facing.getFrontOffsetZ() * n); + } + + /** + * Calculate the cross product of this and the given Vector + */ + public BlockPos crossProduct(Vec3i vec) + { + return new BlockPos(this.getY() * vec.getZ() - this.getZ() * vec.getY(), this.getZ() * vec.getX() - this.getX() * vec.getZ(), this.getX() * vec.getY() - this.getY() * vec.getX()); + } + + /** + * Serialize this BlockPos into a long value + */ + public long toLong() + { + return ((long)this.getX() & X_MASK) << X_SHIFT | ((long)this.getY() & Y_MASK) << Y_SHIFT | ((long)this.getZ() & Z_MASK) << 0; + } + + /** + * Create a BlockPos from a serialized long value (created by toLong) + */ + public static BlockPos fromLong(long serialized) + { + int i = (int)(serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS); + int j = (int)(serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS); + int k = (int)(serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS); + return new BlockPos(i, j, k); + } + + public static Iterable getAllInBox(BlockPos from, BlockPos to) + { + final BlockPos blockpos = new BlockPos(Math.min(from.getX(), to.getX()), Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ())); + final BlockPos blockpos1 = new BlockPos(Math.max(from.getX(), to.getX()), Math.max(from.getY(), to.getY()), Math.max(from.getZ(), to.getZ())); + return new Iterable() + { + public Iterator iterator() + { + return new AbstractIterator() + { + private BlockPos lastReturned = null; + protected BlockPos computeNext() + { + if (this.lastReturned == null) + { + this.lastReturned = blockpos; + return this.lastReturned; + } + else if (this.lastReturned.equals(blockpos1)) + { + return (BlockPos)this.endOfData(); + } + else + { + int i = this.lastReturned.getX(); + int j = this.lastReturned.getY(); + int k = this.lastReturned.getZ(); + + if (i < blockpos1.getX()) + { + ++i; + } + else if (j < blockpos1.getY()) + { + i = blockpos.getX(); + ++j; + } + else if (k < blockpos1.getZ()) + { + i = blockpos.getX(); + j = blockpos.getY(); + ++k; + } + + this.lastReturned = new BlockPos(i, j, k); + return this.lastReturned; + } + } + }; + } + }; + } + + public static Iterable getAllInBoxMutable(BlockPos from, BlockPos to) + { + final BlockPos blockpos = new BlockPos(Math.min(from.getX(), to.getX()), Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ())); + final BlockPos blockpos1 = new BlockPos(Math.max(from.getX(), to.getX()), Math.max(from.getY(), to.getY()), Math.max(from.getZ(), to.getZ())); + return new Iterable() + { + public Iterator iterator() + { + return new AbstractIterator() + { + private BlockPos.MutableBlockPos theBlockPos = null; + protected BlockPos.MutableBlockPos computeNext() + { + if (this.theBlockPos == null) + { + this.theBlockPos = new BlockPos.MutableBlockPos(blockpos.getX(), blockpos.getY(), blockpos.getZ()); + return this.theBlockPos; + } + else if (this.theBlockPos.equals(blockpos1)) + { + return (BlockPos.MutableBlockPos)this.endOfData(); + } + else + { + int i = this.theBlockPos.getX(); + int j = this.theBlockPos.getY(); + int k = this.theBlockPos.getZ(); + + if (i < blockpos1.getX()) + { + ++i; + } + else if (j < blockpos1.getY()) + { + i = blockpos.getX(); + ++j; + } + else if (k < blockpos1.getZ()) + { + i = blockpos.getX(); + j = blockpos.getY(); + ++k; + } + + this.theBlockPos.x = i; + this.theBlockPos.y = j; + this.theBlockPos.z = k; + return this.theBlockPos; + } + } + }; + } + }; + } + + public static final class MutableBlockPos extends BlockPos + { + private int x; + private int y; + private int z; + + public MutableBlockPos() + { + this(0, 0, 0); + } + + public MutableBlockPos(int x_, int y_, int z_) + { + super(0, 0, 0); + this.x = x_; + this.y = y_; + this.z = z_; + } + + public int getX() + { + return this.x; + } + + public int getY() + { + return this.y; + } + + public int getZ() + { + return this.z; + } + + public BlockPos.MutableBlockPos func_181079_c(int p_181079_1_, int p_181079_2_, int p_181079_3_) + { + this.x = p_181079_1_; + this.y = p_181079_2_; + this.z = p_181079_3_; + return this; + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/BlockUtil.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/BlockUtil.java new file mode 100644 index 0000000..9541f74 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/BlockUtil.java @@ -0,0 +1,728 @@ +package cc.fyre.riot.util; + +import cc.fyre.riot.Riot; +import cc.fyre.riot.profile.Profile; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import net.minecraft.server.v1_7_R4.Blocks; +import org.bukkit.*; +import net.minecraft.server.v1_7_R4.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; + +import java.util.*; + +public class BlockUtil { + + public static final Set TYPES = new ImmutableSet.Builder() + .add(Material.AIR) + .add(Material.RED_ROSE) + .add(Material.LONG_GRASS) + .add(Material.DOUBLE_PLANT) + .add(Material.YELLOW_FLOWER) + .build(); + public static final Set ICEBLOCKS = new ImmutableSet.Builder() + .add(Material.ICE.getId()) + .add(Material.PACKED_ICE.getId()) + .build(); + public static final Set LIQUIDS = new ImmutableSet.Builder() + .add(8) + .add(9) + .add(10) + .add(11) + .build(); + public static boolean isUnderBlock(org.bukkit.Location location, Set blocks, int down) { + double posX = location.getX(); + double posZ = location.getZ(); + double fracX = posX % 1.0 > 0.0 ? Math.abs(posX % 1.0) : 1.0 - Math.abs(posX % 1.0); + double fracZ = posZ % 1.0 > 0.0 ? Math.abs(posZ % 1.0) : 1.0 - Math.abs(posZ % 1.0); + int blockX = location.getBlockX(); + int blockY = location.getBlockY() - down; + int blockZ = location.getBlockZ(); + World world = location.getWorld(); + if (blocks.contains(world.getBlockAt(blockX, blockY, blockZ).getTypeId())) { + return true; + } + return false; + } + public static boolean isOnIce(org.bukkit.Location location, int down) { + return isUnderBlock(location, ICEBLOCKS, down); + } + public static boolean isOnLiquid(org.bukkit.Location location, int down) { + return BlockUtil.isUnderBlock(location, LIQUIDS, down); + } + public static double getHorizontalDistance(Location to, Location from) { + double x = Math.abs(Math.abs(to.getX()) - Math.abs(from.getX())); + double z = Math.abs(Math.abs(to.getZ()) - Math.abs(from.getZ())); + + return Math.sqrt(x * x + z * z); + } + + public static boolean isOnGroundBB(Player player) { + + if(!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) return true; + + Profile profile = Riot.getInstance().getProfileHandler().getCache().get(player.getUniqueId()); + + if(profile.getPlayer().getLocation() == null) return true; + + if(!player.getLocation().getWorld().isChunkLoaded(profile.getPlayer().getLocation().getBlockX() >> 4, profile.getPlayer().getLocation().getBlockZ() >> 4)) return true; + + final BoundingBox boundingBox = new BoundingBox(profile.getPlayer().getLocation().getX(), profile.getPlayer().getLocation().getY(), profile.getPlayer().getLocation().getZ()); + boundingBox.expand(0.5, 0.07, 0.5).move(0.0, -0.55, 0.0); + + final World world = player.getWorld(); + + final boolean touchingAir = boundingBox.checkBlocks(world, material -> material == Material.AIR); + final boolean touchingIllegalBlock = boundingBox.checkBlocks(world, material -> material.toString().contains("LILY") || material == Material.BREWING_STAND || material.toString().contains("SKULL")); + + if (touchingAir && !touchingIllegalBlock) { + return false; + } else { + return true; + } + } + + public static boolean isOnIce(Player p) { + if (!p.getLocation().getWorld().isChunkLoaded(p.getLocation().getBlockX() >> 4, p.getLocation().getBlockZ() >> 4)) { + return false; + } + return p.getLocation().getBlock().getRelative(BlockFace.DOWN).toString().contains("ICE") || p.getLocation().clone().add(0, -0.5, 0).getBlock().toString().contains("ICE"); + } + + public static boolean isOnSoulSand(Player p) { + if (!p.getLocation().getWorld().isChunkLoaded(p.getLocation().getBlockX() >> 4, p.getLocation().getBlockZ() >> 4)) { + return false; + } + return p.getLocation().getBlock().getRelative(BlockFace.DOWN).toString().contains("SOUL"); + } + + public static boolean isOnStair(Player p) { + if (!p.getLocation().getWorld().isChunkLoaded(p.getLocation().getBlockX() >> 4, p.getLocation().getBlockZ() >> 4)) { + return false; + } + + if (p.getLocation().getBlock().getRelative(BlockFace.DOWN).toString().contains("STAIR") + || p.getLocation().clone().add(0, -0.5, 0).getBlock().getRelative(BlockFace.DOWN).toString().contains("STAIR") + || p.getLocation().clone().add(0, -0.25, 0).getBlock().getRelative(BlockFace.DOWN).toString().contains("STAIR")) { + return true; + } + return false; + } + + public static boolean isOnStair2(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.05, x)).toString().contains("STAIR") + || getThreadSafe(loc.clone().add(z, -0.75, x)).toString().contains("STAIR") + || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("STAIR") + || getThreadSafe(loc.clone().add(z, -0.3, x)).toString().contains("STAIR") + || getThreadSafe(loc.clone().add(z, -0.5, x)).toString().contains("STAIR") + || getThreadSafe(loc.clone().add(z, -0.25, x)).toString().contains("STAIR")) { + return true; + } + } + } + return false; + } + + public static boolean isOnWall(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.05, x)).toString().contains("WALL") + || getThreadSafe(loc.clone().add(z, -0.75, x)).toString().contains("WALL") + || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("WALL") + || getThreadSafe(loc.clone().add(z, -0.3, x)).toString().contains("WALL") + || getThreadSafe(loc.clone().add(z, -0.5, x)).toString().contains("WALL") + || getThreadSafe(loc.clone().add(z, -0.25, x)).toString().contains("WALL")) { + return true; + } + } + } + return false; + } + + public static boolean isOnFence(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.05, x)).toString().contains("FENCE") + || getThreadSafe(loc.clone().add(z, -0.75, x)).toString().contains("FENCE") + || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("FENCE") + || getThreadSafe(loc.clone().add(z, -0.3, x)).toString().contains("FENCE") + || getThreadSafe(loc.clone().add(z, -0.5, x)).toString().contains("FENCE") + || getThreadSafe(loc.clone().add(z, -0.25, x)).toString().contains("FENCE")) { + return true; + } + } + } + return false; + } + + public static boolean isOnSkull(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.05, x)).toString().contains("SKULL") || getThreadSafe(loc.clone().add(z, -0.05, x)).toString().contains("HEAD") + || getThreadSafe(loc.clone().add(z, -0.75, x)).toString().contains("SKULL") || getThreadSafe(loc.clone().add(z, -0.75, x)).toString().contains("HEAD") + || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("SKULL") || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("HEAD") + || getThreadSafe(loc.clone().add(z, -0.3, x)).toString().contains("SKULL") || getThreadSafe(loc.clone().add(z, -0.3, x)).toString().contains("HEAD") + || getThreadSafe(loc.clone().add(z, -0.5, x)).toString().contains("SKULL") ||getThreadSafe(loc.clone().add(z, -0.5, x)).toString().contains("HEAD") + || getThreadSafe(loc.clone().add(z, -0.25, x)).toString().contains("SKULL") || getThreadSafe(loc.clone().add(z, -0.25, x)).toString().contains("HEAD")) { + return true; + } + } + } + return false; + } + + public static boolean isOnPot(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.05, x)).toString().contains("POT") + || getThreadSafe(loc.clone().add(z, -0.75, x)).toString().contains("POT") + || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("POT") + || getThreadSafe(loc.clone().add(z, -0.3, x)).toString().contains("POT") + || getThreadSafe(loc.clone().add(z, -0.5, x)).toString().contains("POT") + || getThreadSafe(loc.clone().add(z, -0.25, x)).toString().contains("POT")) { + return true; + } + } + } + return false; + } + + public static boolean isOnSlab(Player p) { + + if (!p.getLocation().getWorld().isChunkLoaded(p.getLocation().getBlockX() >> 4, p.getLocation().getBlockZ() >> 4)) { + return false; + } + + if (p.getLocation().getBlock().getRelative(BlockFace.DOWN).toString().contains("STEP") + || p.getLocation().getBlock().getRelative(BlockFace.DOWN).toString().contains("SLAB") + + || p.getLocation().clone().add(0, -0.1, 0).toString().contains("STEP") + || p.getLocation().clone().add(0, -0.1, 0).getBlock().toString().contains("SLAB") + + || getThreadSafe(p.getLocation()).toString().contains("STEP") + || getThreadSafe(p.getLocation()).toString().contains("SLAB")) { + return true; + } + return false; + } + + public static void pullback(org.bukkit.Location lastLastLocation, final org.bukkit.Location location, final Player player) { + lastLastLocation.setPitch(location.getPitch()); + lastLastLocation.setYaw(location.getYaw()); + player.teleport(lastLastLocation, PlayerTeleportEvent.TeleportCause.UNKNOWN); + } + + public static boolean isOnBadJesusBlock(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.01, x)).toString().contains("LILY") + || getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("DAYLIGHT") + || getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("STAIR") + || getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("CAMP") + || getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("STEP") + || getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("TRAP") + || getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("PATH") + || getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("REDSTONE") + || getThreadSafe(loc.clone().add(z, -0.01, x)).toString().contains("CARPET")) { + return true; + } + } + } + return false; + } + + public static boolean isOnLily(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("LILY") + || getThreadSafe(loc.clone().add(z, -0.01, x)).toString().contains("LILY") + || getThreadSafe(loc.clone().add(z, -0.005, x)).toString().contains("LILY") + || getThreadSafe(loc.clone().add(z, -0.05, x)).toString().contains("LILY")) { + return true; + } + } + } + return false; + } + + public static boolean isOnCarpet(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.09, x)).toString().contains("CARPET") + || getThreadSafe(loc.clone().add(z, 0, x)).toString().contains("CARPET") + || getThreadSafe(loc.clone().add(z, -0.01, x)).toString().contains("CARPET") + || getThreadSafe(loc.clone().add(z, -0.015, x)).toString().contains("CARPET") + || getThreadSafe(loc.clone().add(z, -0.015, x)).toString().contains("CARPET") + || getThreadSafe(loc.clone().add(z, -0.03, x)).toString().contains("CARPET") + || getThreadSafe(loc.clone().add(z, -0.03, x)).toString().contains("SNOW") + || getThreadSafe(loc.clone().add(z, -0.05, x)).toString().contains("CARPET")) { + return true; + } + } + } + return false; + } + + public static boolean isNearLiquid(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, 0, x)).toString().contains("WATER") || getThreadSafe(loc.clone().add(z, 0, x)).toString().contains("LAVA") || getThreadSafe(loc.clone().add(z, -0.5, x)).toString().contains("LAVA") || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("BUBBLE")) { + return true; + } else if (getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("WATER") || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("LAVA") || getThreadSafe(loc.clone().add(z, -0.25, x)).toString().contains("LAVA") || getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("BUBBLE")) { + return true; + } + } + } + return false; + } + + public static boolean isNearTrapdoor(org.bukkit.Location location) { + double expand = 0.45; + + if (!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) { + return false; + } + + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(location.clone().add(x, -0.16, z)).toString().toLowerCase().contains("trapdoor")) { + return true; + } else if (getThreadSafe(location.clone().add(x, -0.1, z)).toString().contains("TRAPDOOR")) { + return true; + } + else if (getThreadSafe(location.clone().add(x, 1.90, z)).toString().contains("TRAPDOOR")) { + return true; + } + else if (getThreadSafe(location.clone().add(x, -0.012500048, z)).toString().contains("TRAPDOOR")) { + return true; + } + else if (getThreadSafe(location.clone().add(x, -0.18750, z)).toString().contains("TRAPDOOR")) { + return true; + } + else if (getThreadSafe(location.clone().add(x, -0.2, z)).toString().contains("TRAPDOOR")) { + return true; + } + } + + } + return false; + } + + public static boolean isOnFlyABad(Player player) { + org.bukkit.Location loc = player.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(loc.clone().add(z, -0.125, x)).toString().contains("DAYLIGHT")) { + return true; + } else if (getThreadSafe(loc.clone().add(z, -0.1, x)).toString().contains("TRAP")) { + return true; + } + } + } + return false; + } + + public static boolean isNearSlime(org.bukkit.Location location) { + + if (!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.4; + + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(location.clone().add(x, -0.1, z)).toString().contains("SLIME")) { + return true; + } + if (getThreadSafe(location.clone().add(x, -0.2, z)).toString().contains("SLIME")) { + return true; + } + + } + + } + return false; + } + + public static boolean isLandingSoonOnSlime(org.bukkit.Location location) { + + if (!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(location.clone().add(x, -0.75, z)).toString().contains("SLIME")) { + return true; + } + if (getThreadSafe(location.clone().add(x, -1, z)).toString().contains("SLIME")) { + return true; + } + if (getThreadSafe(location.clone().add(x, -2, z)).toString().contains("SLIME")) { + return true; + } + + } + + } + return false; + } + + public static boolean isInWeb(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(player.getLocation().clone().add(z, 0, x)).toString().contains("WEB")) { + return true; + }else if (getThreadSafe(player.getLocation().clone().add(z, +1.6, x)).toString().contains("WEB")) { + return true; + } + } + } + return false; + } + + public static boolean isNearGround(org.bukkit.Location location) { + + if (!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(location.clone().add(x, -0.5001, z)).isSolid()) { + return true; + } + } + + } + return false; + } + + public static boolean isNearPiston(org.bukkit.Location location) { + + if (!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) { + return false; + } + + double expand = 5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(location.clone().add(x, 0, z)).toString().contains("PISTON")) { + return true; + } + } + + } + return false; + } + + + public static boolean isAboveLiquid(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + org.bukkit.Location water1 = player.getLocation().clone(); + org.bukkit.Location water2 = player.getLocation().clone(); + org.bukkit.Location air = player.getLocation().clone(); + water1.setZ(water1.getZ() + 0.3); + water1.setY(water1.getY()); + water1.setX(water1.getX() + 0.3); + + water2.setZ(water2.getZ() - 0.3); + water2.setY(water2.getY()); + water2.setX(water2.getX() - 0.3); + + air.setY(air.getY() + 0.1); + + return water1.getBlock().getRelative(BlockFace.DOWN).isLiquid() + && water2.getBlock().getRelative(BlockFace.DOWN).isLiquid() + && getThreadSafe(air) == Material.AIR; + } + + + public static boolean isNextToWall(Player p) { + org.bukkit.Location loc = p.getLocation(); + + if (!loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return false; + } + + org.bukkit.Location xp = new org.bukkit.Location(loc.getWorld(), loc.getX() + 0.5, loc.getY(), loc.getZ()); + org.bukkit.Location xn = new org.bukkit.Location(loc.getWorld(), loc.getX() - 0.5, loc.getY(), loc.getZ()); + org.bukkit.Location zp = new org.bukkit.Location(loc.getWorld(), loc.getX(), loc.getY(), loc.getZ() + 0.5); + org.bukkit.Location zn = new org.bukkit.Location(loc.getWorld(), loc.getX(), loc.getY(), loc.getZ() - 0.5); + + if(getThreadSafe(xp) == null || getThreadSafe(xn) == null || getThreadSafe(zp) == null || getThreadSafe(zn) == null) { + return false; + } + + return getThreadSafe(xp).isSolid() || getThreadSafe(xn).isSolid() || getThreadSafe(zp).isSolid() || getThreadSafe(zn).isSolid(); + } + + public static boolean blockNearHead(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 0.3; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(player.getLocation().clone().add(z, 2, x)).isSolid()) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 1.5001, x)).isSolid()) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 1.5001, x)).toString().contains("SKULL") || getThreadSafe(player.getLocation().clone().add(z, 1.5001, x)).toString().contains("HEAD")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 1.75, x)).toString().contains("SKULL") || getThreadSafe(player.getLocation().clone().add(z, 1.75, x)).toString().contains("HEAD")) { + return true; + } + } + } + return false; + } + + public static boolean isNearWall(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 1; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if(getThreadSafe(player.getLocation().clone().add(z, 0, x)) == null) { + return false; + } else if (getThreadSafe(player.getLocation().clone().add(z, 0, x)).isSolid()) { + return true; + } + } + } + return false; + } + + public static boolean isNearScaffolding(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 1; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(player.getLocation().clone().add(z, 0, x)).toString().contains("SCAFFOLD")) { + return true; + } + } + } + return false; + } + + public static boolean isNearAnvil(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 0.5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(player.getLocation().clone().add(z, 0, x)).toString().contains("ANVIL")) { + return true; + } + } + } + return false; + } + + public static boolean isNearHoney(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 0.5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + //Bukkit.broadcastMessage(getThreadSafe(player.getLocation().clone().add(z, 0, x)).toString()); + if (getThreadSafe(player.getLocation().clone().add(z, 0, x)).toString().contains("HONEY")) { + return true; + } + } + } + return false; + } + + public static boolean isNearWeb(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 0.5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(player.getLocation().clone().add(z, 0, x)).toString().contains("WEB")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 0.5, x)).toString().contains("WEB")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 0.75, x)).toString().contains("WEB")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 1, x)).toString().contains("WEB")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 1.3, x)).toString().contains("WEB")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 1.5, x)).toString().contains("WEB")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 1.75, x)).toString().contains("WEB")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, 2, x)).toString().contains("WEB")) { + return true; + } + } + } + return false; + } + + public static boolean isNearIce(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 0.5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(player.getLocation().clone().add(z, -0.5, x)).toString().contains("ICE")) { + return true; + } else if (getThreadSafe(player.getLocation().clone().add(z, -0.25, x)).toString().contains("ICE")) { + return true; + } + } + } + return false; + } + + public static boolean isNearClimbable(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + double expand = 0.5; + for (double x = -expand; x <= expand; x += expand) { + for (double z = -expand; z <= expand; z += expand) { + if (getThreadSafe(player.getLocation().clone().add(z, 0, x)).toString().contains("LADDER") || getThreadSafe(player.getLocation().clone().add(z, player.getLocation().getY(), x)).toString().contains("VINE")) { + return true; + } + } + } + return false; + } + + + public static boolean isClimbableBlock(Player player) { + + if (!player.getLocation().getWorld().isChunkLoaded(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4)) { + return false; + } + + return getThreadSafe(player.getLocation()).toString().contains("LADDER") || getThreadSafe(player.getLocation()).toString().contains("VINE"); + } + + public static double getBlockFriction(Player player) { + return isNearIce(player) ? 0.98 : 0.60; + } + + public static Material getThreadSafe(org.bukkit.Location loc) { + if (loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + return loc.getBlock().getType(); + } + return Material.AIR; + } + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/BoundingBox.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/BoundingBox.java new file mode 100644 index 0000000..04f0376 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/BoundingBox.java @@ -0,0 +1,273 @@ +package cc.fyre.riot.util; + +import cc.fyre.riot.profile.Profile; +import lombok.Getter; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + + +@Getter +public final class BoundingBox { + + private double minX, minY, minZ; + + private double maxX, maxY, maxZ; + + private boolean worldLoaded; + + private long timestamp; + + public BoundingBox(final Location position) { + this(position.getX(), position.getY(), position.getZ()); + } + public BoundingBox(final Vector position) { + this(position.getX(), position.getY(), position.getZ()); + } + + public BoundingBox(final double x, final double y, final double z) { + this(x, x, y, y, z, z); + + timestamp = System.currentTimeMillis(); + } + + public BoundingBox(double minX, double maxX, double minY, double maxY, double minZ, double maxZ) { + if (minX < maxX) { + this.minX = minX; + this.maxX = maxX; + } else { + this.minX = maxX; + this.maxX = minX; + } + if (minY < maxY) { + this.minY = minY; + this.maxY = maxY; + } else { + this.minY = maxY; + this.maxY = minY; + } + if (minZ < maxZ) { + this.minZ = minZ; + this.maxZ = maxZ; + } else { + this.minZ = maxZ; + this.maxZ = minZ; + } + } + + public double distance(final Location location) { + return Math.sqrt(Math.min(Math.pow(location.getX() - this.minX, 2), Math.pow(location.getX() - this.maxX, 2)) + Math.min(Math.pow(location.getZ() - this.minZ, 2), Math.pow(location.getZ() - this.maxZ, 2))); + } + + public double distance(final double x, final double z) { + + final double dx = Math.min(Math.pow(x - minX, 2), Math.pow(x - maxX, 2)); + final double dz = Math.min(Math.pow(z - minZ, 2), Math.pow(z - maxZ, 2)); + + return Math.sqrt(dx + dz); + } + + public double distance(final BoundingBox box) { + + final double dx = Math.min(Math.pow(box.minX - minX, 2), Math.pow(box.maxX - maxX, 2)); + final double dz = Math.min(Math.pow(box.minZ - minZ, 2), Math.pow(box.maxZ - maxZ, 2)); + + return Math.sqrt(dx + dz); + } + + public double angle(final World world, final BoundingBox box) { + final Vector homeVector = new Vector(minX, minY, minZ); + final Vector outVector = new Vector(box.minX, box.minY, box.minZ); + + return outVector.subtract(homeVector).setY(0).angle(outVector.toLocation(world).getDirection().setY(0)); + } + + public Vector getDirection(final World world) { + return new Location(world, minX, minY, minZ).getDirection(); + } + + public BoundingBox add(final BoundingBox box) { + + this.minX += box.minX; + this.minY += box.minY; + this.minZ += box.minZ; + + this.maxX += box.maxX; + this.maxY += box.maxY; + this.maxZ += box.maxZ; + + return this; + } + + public BoundingBox move(final double x, final double y, final double z) { + + this.minX += x; + this.minY += y; + this.minZ += z; + + this.maxX += x; + this.maxY += y; + this.maxZ += z; + + return this; + } + + public BoundingBox expand(final double x, final double y, final double z) { + + this.minX -= x; + this.minY -= y; + this.minZ -= z; + + this.maxX += x; + this.maxY += y; + this.maxZ += z; + + return this; + } + + public BoundingBox expandMin(final double x, final double y, final double z) { + this.minX += x; + this.minY += y; + this.minZ += z; + return this; + } + + public BoundingBox expandMax(double x, double y, double z) { + this.maxX += x; + this.maxY += y; + this.maxZ += z; + + return this; + } + + + public boolean checkBlocks(final World world, final Predicate predicate) { + final int first = (int) Math.floor(this.minX); + final int second = (int) Math.ceil(this.maxX); + final int third = (int) Math.floor(this.minY); + final int forth = (int) Math.ceil(this.maxY); + final int fifth = (int) Math.floor(this.minZ); + final int sixth = (int) Math.ceil(this.maxZ); + + final ArrayList list = new ArrayList<>(); + worldLoaded = true; + + Location locMin = new Location(world, first, third, fifth); + Location locMax = new Location(world, second, forth, sixth); + + if(!locMin.getWorld().isChunkLoaded(locMin.getBlockX() >> 4, locMin.getBlockZ() >> 4) || !locMax.getWorld().isChunkLoaded(locMax.getBlockX() >> 4, locMax.getBlockZ() >> 4)) { + worldLoaded = false; + } + + if(worldLoaded) list.add(world.getBlockAt(first, third, fifth)); + + for (int i = first; i < second; ++i) { + for (int j = third; j < forth; ++j) { + for (int k = fifth; k < sixth; ++k) { + + Location locShit = new Location(world, i, j, k); + if(locShit.getWorld().isChunkLoaded(locShit.getBlockX() >> 4, locShit.getBlockZ() >> 4)) { + list.add(world.getBlockAt(i, j, k)); + } else { + worldLoaded = false; + } + } + } + } + + return list.stream().allMatch(block -> predicate.test(block.getType())); + } + + public List getCollidingBlocks(Profile profile) { + + final List blocks = new ArrayList<>(); + + final int xFloor = (int) Math.floor(minX); + final int xCeil = (int) Math.ceil(maxX); + + final int yFloor = (int) Math.floor(minY); + final int yCeil = (int) Math.ceil(maxY); + + final int zFloor = (int) Math.floor(minZ); + final int zCeil = (int) Math.ceil(maxZ); + + for (int x = xFloor; x < xCeil; x++) { + + for (int y = yFloor; y < yCeil; y++) { + + for (int z = zFloor; z < zCeil; z++) { + + final Location loc = new Location(profile.getPlayer().getWorld(), x, y, z); + + if (loc.getWorld().isChunkLoaded(loc.getBlockX() >> 4, loc.getBlockZ() >> 4)) { + final Block b = loc.getBlock(); + blocks.add(b); + } + + } + + } + + } + + return blocks; + } + + public double getCenterX() { + return (this.minX + this.maxX) / 2.0; + } + + public double getCenterY() { + return (this.minY + this.maxY) / 2.0; + } + + public double getCenterZ() { + return (this.minZ + this.maxZ) / 2.0; + } + + public long getTimestamp() { + return timestamp; + } +} + +final class BlockPosition { + + private int x, y, z; + + + public BlockPosition(final int x, final int y, final int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public int getX() { + return x; + } + + public void setX(final int x) { + this.x = x; + } + + public int getY() { + return y; + } + + public void setY(final int y) { + this.y = y; + } + + public int getZ() { + return z; + } + + public void setZ(final int z) { + this.z = z; + } +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/ClientUtil.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/ClientUtil.java new file mode 100644 index 0000000..30e0b98 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/ClientUtil.java @@ -0,0 +1,21 @@ +package cc.fyre.riot.util; + +import org.bukkit.entity.*; +import org.bukkit.potion.*; +import java.util.*; + +public class ClientUtil { + + public static int getPotionAmplifier(Player player,PotionEffectType type) { + + for (final PotionEffect effect : player.getActivePotionEffects()) { + + if (effect.getType().equals(type)) { + return effect.getAmplifier(); + } + + } + + return -1; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/EntityLocationHandler.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/EntityLocationHandler.java new file mode 100644 index 0000000..ce4dace --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/EntityLocationHandler.java @@ -0,0 +1,42 @@ +package cc.fyre.riot.util; + +import cc.fyre.riot.profile.Profile; +import io.github.retrooper.packetevents.packetwrappers.in.flying.WrappedPacketInFlying; + +public class EntityLocationHandler { + public static void updateFlyingLocations(Profile profile, WrappedPacketInFlying flying) { + if(flying.isLook()) { + profile.getAttackTracker().lastPosition = 0; + profile.getAttackTracker().attackerX = flying.getX(); + profile.getAttackTracker().attackerY = flying.getY(); + profile.getAttackTracker().attackerZ = flying.getZ(); + } + + if(!flying.isPosition()) { + profile.getAttackTracker().lastPosition++; + } + + if(flying.isLook()) { + profile.getAttackTracker().attackerYaw = flying.getYaw(); + profile.getAttackTracker().attackerPitch = flying.getPitch(); + } + } + + public static void updateFlyingLocations2(Profile profile, WrappedPacketInFlying flying) { + if(flying.isLook()) { + profile.getAttackTracker().lastPosition2 = 0; + profile.getAttackTracker().attackerX2 = flying.getX(); + profile.getAttackTracker().attackerY2 = flying.getY(); + profile.getAttackTracker().attackerZ2 = flying.getZ(); + } + + if(!flying.isPosition()) { + profile.getAttackTracker().lastPosition2++; + } + + if(flying.isLook()) { + profile.getAttackTracker().attackerYaw2 = flying.getYaw(); + profile.getAttackTracker().attackerPitch2 = flying.getPitch(); + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/EnumFacing.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/EnumFacing.java new file mode 100644 index 0000000..1cb0992 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/EnumFacing.java @@ -0,0 +1,604 @@ +package cc.fyre.riot.util; + + + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterators; +import com.google.common.collect.Maps; +import java.util.Iterator; +import java.util.Map; +import java.util.Random; + +public enum EnumFacing implements IStringSerializable +{ + DOWN("DOWN", 0, 0, 1, -1, "down", EnumFacing.AxisDirection.NEGATIVE, EnumFacing.Axis.Y, new Vec3i(0, -1, 0)), + UP("UP", 1, 1, 0, -1, "up", EnumFacing.AxisDirection.POSITIVE, EnumFacing.Axis.Y, new Vec3i(0, 1, 0)), + NORTH("NORTH", 2, 2, 3, 2, "north", EnumFacing.AxisDirection.NEGATIVE, EnumFacing.Axis.Z, new Vec3i(0, 0, -1)), + SOUTH("SOUTH", 3, 3, 2, 0, "south", EnumFacing.AxisDirection.POSITIVE, EnumFacing.Axis.Z, new Vec3i(0, 0, 1)), + WEST("WEST", 4, 4, 5, 1, "west", EnumFacing.AxisDirection.NEGATIVE, EnumFacing.Axis.X, new Vec3i(-1, 0, 0)), + EAST("EAST", 5, 5, 4, 3, "east", EnumFacing.AxisDirection.POSITIVE, EnumFacing.Axis.X, new Vec3i(1, 0, 0)); + + /** Ordering index for D-U-N-S-W-E */ + private final int index; + + /** Index of the opposite Facing in the VALUES array */ + private final int opposite; + + /** Ordering index for the HORIZONTALS field (S-W-N-E) */ + private final int horizontalIndex; + private final String name; + private final EnumFacing.Axis axis; + private final EnumFacing.AxisDirection axisDirection; + + /** Normalized Vector that points in the direction of this Facing */ + private final Vec3i directionVec; + + /** All facings in D-U-N-S-W-E order */ + public static final EnumFacing[] VALUES = new EnumFacing[6]; + + /** All Facings with horizontal axis in order S-W-N-E */ + private static final EnumFacing[] HORIZONTALS = new EnumFacing[4]; + private static final Map NAME_LOOKUP = Maps.newHashMap(); + private static final EnumFacing[] $VALUES = new EnumFacing[]{DOWN, UP, NORTH, SOUTH, WEST, EAST}; + private static final String __OBFID = "CL_00001201"; + + private EnumFacing(String p_i17_3_, int p_i17_4_, int p_i17_5_, int p_i17_6_, int p_i17_7_, String p_i17_8_, EnumFacing.AxisDirection p_i17_9_, EnumFacing.Axis p_i17_10_, Vec3i p_i17_11_) + { + this.index = p_i17_5_; + this.horizontalIndex = p_i17_7_; + this.opposite = p_i17_6_; + this.name = p_i17_8_; + this.axis = p_i17_10_; + this.axisDirection = p_i17_9_; + this.directionVec = p_i17_11_; + } + + /** + * Get the Index of this Facing (0-5). The order is D-U-N-S-W-E + */ + public int getIndex() + { + return this.index; + } + + /** + * Get the index of this horizontal facing (0-3). The order is S-W-N-E + */ + public int getHorizontalIndex() + { + return this.horizontalIndex; + } + + /** + * Get the AxisDirection of this Facing. + */ + public EnumFacing.AxisDirection getAxisDirection() + { + return this.axisDirection; + } + + /** + * Get the opposite Facing (e.g. DOWN => UP) + */ + public EnumFacing getOpposite() + { + return VALUES[this.opposite]; + } + + /** + * Rotate this Facing around the given axis clockwise. If this facing cannot be rotated around the given axis, + * returns this facing without rotating. + */ + public EnumFacing rotateAround(EnumFacing.Axis axis) + { + switch (EnumFacing.EnumFacing$1.field_179515_a[axis.ordinal()]) + { + case 1: + if (this != WEST && this != EAST) + { + return this.rotateX(); + } + + return this; + + case 2: + if (this != UP && this != DOWN) + { + return this.rotateY(); + } + + return this; + + case 3: + if (this != NORTH && this != SOUTH) + { + return this.rotateZ(); + } + + return this; + + default: + throw new IllegalStateException("Unable to get CW facing for axis " + axis); + } + } + + /** + * Rotate this Facing around the Y axis clockwise (NORTH => EAST => SOUTH => WEST => NORTH) + */ + public EnumFacing rotateY() + { + switch (EnumFacing.EnumFacing$1.field_179513_b[this.ordinal()]) + { + case 1: + return EAST; + + case 2: + return SOUTH; + + case 3: + return WEST; + + case 4: + return NORTH; + + default: + throw new IllegalStateException("Unable to get Y-rotated facing of " + this); + } + } + + /** + * Rotate this Facing around the X axis (NORTH => DOWN => SOUTH => UP => NORTH) + */ + private EnumFacing rotateX() + { + switch (EnumFacing.EnumFacing$1.field_179513_b[this.ordinal()]) + { + case 1: + return DOWN; + + case 2: + case 4: + default: + throw new IllegalStateException("Unable to get X-rotated facing of " + this); + + case 3: + return UP; + + case 5: + return NORTH; + + case 6: + return SOUTH; + } + } + + /** + * Rotate this Facing around the Z axis (EAST => DOWN => WEST => UP => EAST) + */ + private EnumFacing rotateZ() + { + switch (EnumFacing.EnumFacing$1.field_179513_b[this.ordinal()]) + { + case 2: + return DOWN; + + case 3: + default: + throw new IllegalStateException("Unable to get Z-rotated facing of " + this); + + case 4: + return UP; + + case 5: + return EAST; + + case 6: + return WEST; + } + } + + /** + * Rotate this Facing around the Y axis counter-clockwise (NORTH => WEST => SOUTH => EAST => NORTH) + */ + public EnumFacing rotateYCCW() + { + switch (EnumFacing.EnumFacing$1.field_179513_b[this.ordinal()]) + { + case 1: + return WEST; + + case 2: + return NORTH; + + case 3: + return EAST; + + case 4: + return SOUTH; + + default: + throw new IllegalStateException("Unable to get CCW facing of " + this); + } + } + + /** + * Returns a offset that addresses the block in front of this facing. + */ + public int getFrontOffsetX() + { + return this.axis == EnumFacing.Axis.X ? this.axisDirection.getOffset() : 0; + } + + public int getFrontOffsetY() + { + return this.axis == EnumFacing.Axis.Y ? this.axisDirection.getOffset() : 0; + } + + /** + * Returns a offset that addresses the block in front of this facing. + */ + public int getFrontOffsetZ() + { + return this.axis == EnumFacing.Axis.Z ? this.axisDirection.getOffset() : 0; + } + + /** + * Same as getName, but does not override the method from Enum. + */ + public String getName2() + { + return this.name; + } + + public EnumFacing.Axis getAxis() + { + return this.axis; + } + + /** + * Get the facing specified by the given name + */ + public static EnumFacing byName(String name) + { + return name == null ? null : (EnumFacing)NAME_LOOKUP.get(name.toLowerCase()); + } + + /** + * Get a Facing by it's index (0-5). The order is D-U-N-S-W-E. Named getFront for legacy reasons. + */ + public static EnumFacing getFront(int index) + { + return VALUES[MathHelper.abs_int(index % VALUES.length)]; + } + + /** + * Get a Facing by it's horizontal index (0-3). The order is S-W-N-E. + */ + public static EnumFacing getHorizontal(int p_176731_0_) + { + return HORIZONTALS[MathHelper.abs_int(p_176731_0_ % HORIZONTALS.length)]; + } + + /** + * Get the Facing corresponding to the given angle (0-360). An angle of 0 is SOUTH, an angle of 90 would be WEST. + */ + public static EnumFacing fromAngle(double angle) + { + return getHorizontal(MathHelper.floor_double(angle / 90.0D + 0.5D) & 3); + } + + /** + * Choose a random Facing using the given Random + */ + public static EnumFacing random(Random rand) + { + return values()[rand.nextInt(values().length)]; + } + + public static EnumFacing getFacingFromVector(float p_176737_0_, float p_176737_1_, float p_176737_2_) + { + EnumFacing enumfacing = NORTH; + float f = Float.MIN_VALUE; + + for (EnumFacing enumfacing1 : values()) + { + float f1 = p_176737_0_ * (float)enumfacing1.directionVec.getX() + p_176737_1_ * (float)enumfacing1.directionVec.getY() + p_176737_2_ * (float)enumfacing1.directionVec.getZ(); + + if (f1 > f) + { + f = f1; + enumfacing = enumfacing1; + } + } + + return enumfacing; + } + + public String toString() + { + return this.name; + } + + public String getName() + { + return this.name; + } + + public static EnumFacing func_181076_a(EnumFacing.AxisDirection p_181076_0_, EnumFacing.Axis p_181076_1_) + { + for (EnumFacing enumfacing : values()) + { + if (enumfacing.getAxisDirection() == p_181076_0_ && enumfacing.getAxis() == p_181076_1_) + { + return enumfacing; + } + } + + throw new IllegalArgumentException("No such direction: " + p_181076_0_ + " " + p_181076_1_); + } + + /** + * Get a normalized Vector that points in the direction of this Facing. + */ + public Vec3i getDirectionVec() + { + return this.directionVec; + } + + static { + for (EnumFacing enumfacing : values()) + { + VALUES[enumfacing.index] = enumfacing; + + if (enumfacing.getAxis().isHorizontal()) + { + HORIZONTALS[enumfacing.horizontalIndex] = enumfacing; + } + + NAME_LOOKUP.put(enumfacing.getName2().toLowerCase(), enumfacing); + } + } + + static final class EnumFacing$1 { + static final int[] field_179515_a; + static final int[] field_179513_b; + static final int[] field_179514_c = new int[EnumFacing.Plane.values().length]; + private static final String __OBFID = "CL_00002322"; + + static { + try { + field_179514_c[EnumFacing.Plane.HORIZONTAL.ordinal()] = 1; + } + catch (NoSuchFieldError var11) + { + ; + } + + try { + field_179514_c[EnumFacing.Plane.VERTICAL.ordinal()] = 2; + } + catch (NoSuchFieldError var10) + { + ; + } + + field_179513_b = new int[EnumFacing.values().length]; + + try { + field_179513_b[EnumFacing.NORTH.ordinal()] = 1; + } + catch (NoSuchFieldError var9) + { + ; + } + + try { + field_179513_b[EnumFacing.EAST.ordinal()] = 2; + } + catch (NoSuchFieldError var8) + { + ; + } + + try { + field_179513_b[EnumFacing.SOUTH.ordinal()] = 3; + } + catch (NoSuchFieldError var7) + { + ; + } + + try { + field_179513_b[EnumFacing.WEST.ordinal()] = 4; + } + catch (NoSuchFieldError var6) + { + ; + } + + try { + field_179513_b[EnumFacing.UP.ordinal()] = 5; + } + catch (NoSuchFieldError var5) + { + ; + } + + try { + field_179513_b[EnumFacing.DOWN.ordinal()] = 6; + } + catch (NoSuchFieldError var4) + { + ; + } + + field_179515_a = new int[EnumFacing.Axis.values().length]; + + try { + field_179515_a[EnumFacing.Axis.X.ordinal()] = 1; + } + catch (NoSuchFieldError var3) + { + ; + } + + try { + field_179515_a[EnumFacing.Axis.Y.ordinal()] = 2; + } + catch (NoSuchFieldError var2) + { + ; + } + + try { + field_179515_a[EnumFacing.Axis.Z.ordinal()] = 3; + } + catch (NoSuchFieldError var1) + { + ; + } + } + } + + public static enum Axis implements Predicate, IStringSerializable { + X("X", 0, "x", EnumFacing.Plane.HORIZONTAL), + Y("Y", 1, "y", EnumFacing.Plane.VERTICAL), + Z("Z", 2, "z", EnumFacing.Plane.HORIZONTAL); + + private static final Map NAME_LOOKUP = Maps.newHashMap(); + private final String name; + private final EnumFacing.Plane plane; + private static final EnumFacing.Axis[] $VALUES = new EnumFacing.Axis[]{X, Y, Z}; + private static final String __OBFID = "CL_00002321"; + + private Axis(String p_i14_3_, int p_i14_4_, String p_i14_5_, EnumFacing.Plane p_i14_6_) + { + this.name = p_i14_5_; + this.plane = p_i14_6_; + } + + public static EnumFacing.Axis byName(String name) + { + return name == null ? null : (EnumFacing.Axis)NAME_LOOKUP.get(name.toLowerCase()); + } + + public String getName2() + { + return this.name; + } + + public boolean isVertical() + { + return this.plane == EnumFacing.Plane.VERTICAL; + } + + public boolean isHorizontal() + { + return this.plane == EnumFacing.Plane.HORIZONTAL; + } + + public String toString() + { + return this.name; + } + + public boolean apply(EnumFacing p_apply_1_) + { + return p_apply_1_ != null && p_apply_1_.getAxis() == this; + } + + public EnumFacing.Plane getPlane() + { + return this.plane; + } + + public String getName() + { + return this.name; + } + + public boolean apply(Object p_apply_1_) + { + return this.apply((EnumFacing)p_apply_1_); + } + + static { + for (EnumFacing.Axis enumfacing$axis : values()) + { + NAME_LOOKUP.put(enumfacing$axis.getName2().toLowerCase(), enumfacing$axis); + } + } + } + + public static enum AxisDirection { + POSITIVE("POSITIVE", 0, 1, "Towards positive"), + NEGATIVE("NEGATIVE", 1, -1, "Towards negative"); + + private final int offset; + private final String description; + private static final EnumFacing.AxisDirection[] $VALUES = new EnumFacing.AxisDirection[]{POSITIVE, NEGATIVE}; + private static final String __OBFID = "CL_00002320"; + + private AxisDirection(String p_i15_3_, int p_i15_4_, int p_i15_5_, String p_i15_6_) + { + this.offset = p_i15_5_; + this.description = p_i15_6_; + } + + public int getOffset() + { + return this.offset; + } + + public String toString() + { + return this.description; + } + } + + public static enum Plane implements Predicate, Iterable { + HORIZONTAL("HORIZONTAL", 0), + VERTICAL("VERTICAL", 1); + + private static final EnumFacing.Plane[] $VALUES = new EnumFacing.Plane[]{HORIZONTAL, VERTICAL}; + private static final String __OBFID = "CL_00002319"; + + private Plane(String p_i16_3_, int p_i16_4_) + { + } + + public EnumFacing[] facings() + { + switch (EnumFacing.EnumFacing$1.field_179514_c[this.ordinal()]) + { + case 1: + return new EnumFacing[] {EnumFacing.NORTH, EnumFacing.EAST, EnumFacing.SOUTH, EnumFacing.WEST}; + case 2: + return new EnumFacing[] {EnumFacing.UP, EnumFacing.DOWN}; + default: + throw new Error("Someone\'s been tampering with the universe!"); + } + } + + public EnumFacing random(Random rand) + { + EnumFacing[] aenumfacing = this.facings(); + return aenumfacing[rand.nextInt(aenumfacing.length)]; + } + + public boolean apply(EnumFacing p_apply_1_) + { + return p_apply_1_ != null && p_apply_1_.getAxis().getPlane() == this; + } + + public Iterator iterator() + { + return Iterators.forArray(this.facings()); + } + + public boolean apply(Object p_apply_1_) + { + return this.apply((EnumFacing)p_apply_1_); + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/EvictingList.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/EvictingList.java new file mode 100644 index 0000000..ddb7899 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/EvictingList.java @@ -0,0 +1,31 @@ +package cc.fyre.riot.util; + +import java.util.Collection; +import java.util.LinkedList; + +public class EvictingList extends LinkedList { + + public static String user = "%%USER%%"; + public static String username = "%%USERNAME%%"; + + private int maxSize; + + public EvictingList(int maxSize) { + this.maxSize = maxSize; + } + + public EvictingList(Collection c, int maxSize) { + super(c); + this.maxSize = maxSize; + } + + public int getMaxSize() { + return maxSize; + } + + @Override + public boolean add(T t) { + if (size() >= getMaxSize()) removeFirst(); + return super.add(t); + } +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/IStringSerializable.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/IStringSerializable.java new file mode 100644 index 0000000..9ec3e87 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/IStringSerializable.java @@ -0,0 +1,5 @@ +package cc.fyre.riot.util; + +public interface IStringSerializable { + String getName(); +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/Location.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/Location.java new file mode 100644 index 0000000..0ff1173 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/Location.java @@ -0,0 +1,32 @@ +package cc.fyre.riot.util; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.Player; + +@AllArgsConstructor +public class Location { + + @Getter @Setter private double x; + @Getter @Setter private double y; + @Getter @Setter private double z; + + @Getter @Setter private float yaw; + @Getter @Setter private float pitch; + + @Getter private final long time = System.currentTimeMillis(); + + public Location(final double x,final double y,final double z) { + this(x,y,z,0.0F,0.0F); + } + + @Override + public String toString() { + return String.format("x=%.5f y=%.5f z=%.5f",this.x,this.y,this.z); + } + + public org.bukkit.Location toBLocation(Player player) { + return new org.bukkit.Location(player.getWorld(), x, y, z); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/Magic.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/Magic.java new file mode 100644 index 0000000..f66795c --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/Magic.java @@ -0,0 +1,12 @@ +package cc.fyre.riot.util; + +import lombok.Getter; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class Magic { + + @Getter private final String name; + @Getter private final String channelHandlerName; + +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/MathHelper.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/MathHelper.java new file mode 100644 index 0000000..3ec6605 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/MathHelper.java @@ -0,0 +1,592 @@ +package cc.fyre.riot.util; + +import java.util.Random; +import java.util.UUID; + +public class MathHelper +{ + public static final float SQRT_2 = sqrt_float(2.0F); + private static final int SIN_BITS = 12; + private static final int SIN_MASK = 4095; + private static final int SIN_COUNT = 4096; + public static final float PI = (float)Math.PI; + public static final float PI2 = ((float)Math.PI * 2F); + public static final float PId2 = ((float)Math.PI / 2F); + private static final float radFull = ((float)Math.PI * 2F); + private static final float degFull = 360.0F; + private static final float radToIndex = 651.8986F; + private static final float degToIndex = 11.377778F; + public static final float deg2Rad = 0.017453292F; + private static final float[] SIN_TABLE_FAST = new float[4096]; + public static boolean fastMath = false; + + /** + * A table of sin values computed from 0 (inclusive) to 2*pi (exclusive), with steps of 2*PI / 65536. + */ + private static final float[] SIN_TABLE = new float[65536]; + + /** + * Though it looks like an array, this is really more like a mapping. Key (index of this array) is the upper 5 bits + * of the result of multiplying a 32-bit unsigned integer by the B(2, 5) De Bruijn sequence 0x077CB531. Value + * (value stored in the array) is the unique index (from the right) of the leftmost one-bit in a 32-bit unsigned + * integer that can cause the upper 5 bits to get that value. Used for highly optimized "find the log-base-2 of + * this number" calculations. + */ + private static final int[] multiplyDeBruijnBitPosition; + private static final double field_181163_d; + private static final double[] field_181164_e; + private static final double[] field_181165_f; + private static final String __OBFID = "CL_00001496"; + + /** + * sin looked up in a table + */ + public static float sin(float p_76126_0_) + { + return fastMath ? SIN_TABLE_FAST[(int)(p_76126_0_ * 651.8986F) & 4095] : SIN_TABLE[(int)(p_76126_0_ * 10430.378F) & 65535]; + } + + /** + * cos looked up in the sin table with the appropriate offset + */ + public static float cos(float value) + { + return fastMath ? SIN_TABLE_FAST[(int)((value + ((float)Math.PI / 2F)) * 651.8986F) & 4095] : SIN_TABLE[(int)(value * 10430.378F + 16384.0F) & 65535]; + } + + public static float sqrt_float(float value) + { + return (float)Math.sqrt((double)value); + } + + public static float sqrt_double(double value) + { + return (float)Math.sqrt(value); + } + + /** + * Returns the greatest integer less than or equal to the float argument + */ + public static int floor_float(float value) + { + int i = (int)value; + return value < (float)i ? i - 1 : i; + } + + /** + * returns par0 cast as an int, and no greater than Integer.MAX_VALUE-1024 + */ + public static int truncateDoubleToInt(double value) + { + return (int)(value + 1024.0D) - 1024; + } + + /** + * Returns the greatest integer less than or equal to the double argument + */ + public static int floor_double(double value) + { + int i = (int)value; + return value < (double)i ? i - 1 : i; + } + + /** + * Long version of floor_double + */ + public static long floor_double_long(double value) + { + long i = (long)value; + return value < (double)i ? i - 1L : i; + } + + public static float sqrt(double var0) { + return (float)Math.sqrt(var0); + } + + public static int func_154353_e(double value) + { + return (int)(value >= 0.0D ? value : -value + 1.0D); + } + + public static float abs(float value) + { + return value >= 0.0F ? value : -value; + } + + /** + * Returns the unsigned value of an int. + */ + public static int abs_int(int value) + { + return value >= 0 ? value : -value; + } + + public static int ceiling_float_int(float value) + { + int i = (int)value; + return value > (float)i ? i + 1 : i; + } + + public static int ceiling_double_int(double value) + { + int i = (int)value; + return value > (double)i ? i + 1 : i; + } + + /** + * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and + * third parameters. + */ + public static int clamp_int(int num, int min, int max) + { + return num < min ? min : (num > max ? max : num); + } + + /** + * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and + * third parameters + */ + public static float clamp_float(float num, float min, float max) + { + return num < min ? min : (num > max ? max : num); + } + + public static double clamp_double(double num, double min, double max) + { + return num < min ? min : (num > max ? max : num); + } + + public static double denormalizeClamp(double p_151238_0_, double p_151238_2_, double p_151238_4_) + { + return p_151238_4_ < 0.0D ? p_151238_0_ : (p_151238_4_ > 1.0D ? p_151238_2_ : p_151238_0_ + (p_151238_2_ - p_151238_0_) * p_151238_4_); + } + + /** + * Maximum of the absolute value of two numbers. + */ + public static double abs_max(double p_76132_0_, double p_76132_2_) + { + if (p_76132_0_ < 0.0D) + { + p_76132_0_ = -p_76132_0_; + } + + if (p_76132_2_ < 0.0D) + { + p_76132_2_ = -p_76132_2_; + } + + return p_76132_0_ > p_76132_2_ ? p_76132_0_ : p_76132_2_; + } + + /** + * Buckets an integer with specifed bucket sizes. Args: i, bucketSize + */ + public static int bucketInt(int p_76137_0_, int p_76137_1_) + { + return p_76137_0_ < 0 ? -((-p_76137_0_ - 1) / p_76137_1_) - 1 : p_76137_0_ / p_76137_1_; + } + + public static int getRandomIntegerInRange(Random p_76136_0_, int p_76136_1_, int p_76136_2_) + { + return p_76136_1_ >= p_76136_2_ ? p_76136_1_ : p_76136_0_.nextInt(p_76136_2_ - p_76136_1_ + 1) + p_76136_1_; + } + + public static float randomFloatClamp(Random p_151240_0_, float p_151240_1_, float p_151240_2_) + { + return p_151240_1_ >= p_151240_2_ ? p_151240_1_ : p_151240_0_.nextFloat() * (p_151240_2_ - p_151240_1_) + p_151240_1_; + } + + public static double getRandomDoubleInRange(Random p_82716_0_, double p_82716_1_, double p_82716_3_) + { + return p_82716_1_ >= p_82716_3_ ? p_82716_1_ : p_82716_0_.nextDouble() * (p_82716_3_ - p_82716_1_) + p_82716_1_; + } + + public static double average(long[] values) + { + long i = 0L; + + for (long j : values) + { + i += j; + } + + return (double)i / (double)values.length; + } + + public static boolean epsilonEquals(float p_180185_0_, float p_180185_1_) + { + return abs(p_180185_1_ - p_180185_0_) < 1.0E-5F; + } + + public static int normalizeAngle(int p_180184_0_, int p_180184_1_) + { + return (p_180184_0_ % p_180184_1_ + p_180184_1_) % p_180184_1_; + } + + /** + * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check + */ + public static float wrapAngleTo180_float(float value) + { + value = value % 360.0F; + + if (value >= 180.0F) + { + value -= 360.0F; + } + + if (value < -180.0F) + { + value += 360.0F; + } + + return value; + } + + /** + * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check + */ + public static double wrapAngleTo180_double(double value) + { + value = value % 360.0D; + + if (value >= 180.0D) + { + value -= 360.0D; + } + + if (value < -180.0D) + { + value += 360.0D; + } + + return value; + } + + /** + * parses the string as integer or returns the second parameter if it fails + */ + public static int parseIntWithDefault(String p_82715_0_, int p_82715_1_) + { + try + { + return Integer.parseInt(p_82715_0_); + } + catch (Throwable var3) + { + return p_82715_1_; + } + } + + /** + * parses the string as integer or returns the second parameter if it fails. this value is capped to par2 + */ + public static int parseIntWithDefaultAndMax(String p_82714_0_, int p_82714_1_, int p_82714_2_) + { + return Math.max(p_82714_2_, parseIntWithDefault(p_82714_0_, p_82714_1_)); + } + + /** + * parses the string as double or returns the second parameter if it fails. + */ + public static double parseDoubleWithDefault(String p_82712_0_, double p_82712_1_) + { + try + { + return Double.parseDouble(p_82712_0_); + } + catch (Throwable var4) + { + return p_82712_1_; + } + } + + public static double parseDoubleWithDefaultAndMax(String p_82713_0_, double p_82713_1_, double p_82713_3_) + { + return Math.max(p_82713_3_, parseDoubleWithDefault(p_82713_0_, p_82713_1_)); + } + + /** + * Returns the input value rounded up to the next highest power of two. + */ + public static int roundUpToPowerOfTwo(int value) + { + int i = value - 1; + i = i | i >> 1; + i = i | i >> 2; + i = i | i >> 4; + i = i | i >> 8; + i = i | i >> 16; + return i + 1; + } + + /** + * Is the given value a power of two? (1, 2, 4, 8, 16, ...) + */ + private static boolean isPowerOfTwo(int value) + { + return value != 0 && (value & value - 1) == 0; + } + + /** + * Uses a B(2, 5) De Bruijn sequence and a lookup table to efficiently calculate the log-base-two of the given + * value. Optimized for cases where the input value is a power-of-two. If the input value is not a power-of-two, + * then subtract 1 from the return value. + */ + private static int calculateLogBaseTwoDeBruijn(int value) + { + value = isPowerOfTwo(value) ? value : roundUpToPowerOfTwo(value); + return multiplyDeBruijnBitPosition[(int)((long)value * 125613361L >> 27) & 31]; + } + + /** + * Efficiently calculates the floor of the base-2 log of an integer value. This is effectively the index of the + * highest bit that is set. For example, if the number in binary is 0...100101, this will return 5. + */ + public static int calculateLogBaseTwo(int value) + { + return calculateLogBaseTwoDeBruijn(value) - (isPowerOfTwo(value) ? 0 : 1); + } + + public static int func_154354_b(int p_154354_0_, int p_154354_1_) + { + if (p_154354_1_ == 0) + { + return 0; + } + else if (p_154354_0_ == 0) + { + return p_154354_1_; + } + else + { + if (p_154354_0_ < 0) + { + p_154354_1_ *= -1; + } + + int i = p_154354_0_ % p_154354_1_; + return i == 0 ? p_154354_0_ : p_154354_0_ + p_154354_1_ - i; + } + } + + public static int func_180183_b(float p_180183_0_, float p_180183_1_, float p_180183_2_) + { + return func_180181_b(floor_float(p_180183_0_ * 255.0F), floor_float(p_180183_1_ * 255.0F), floor_float(p_180183_2_ * 255.0F)); + } + + public static int func_180181_b(int p_180181_0_, int p_180181_1_, int p_180181_2_) + { + int i = (p_180181_0_ << 8) + p_180181_1_; + i = (i << 8) + p_180181_2_; + return i; + } + + public static int func_180188_d(int p_180188_0_, int p_180188_1_) + { + int i = (p_180188_0_ & 16711680) >> 16; + int j = (p_180188_1_ & 16711680) >> 16; + int k = (p_180188_0_ & 65280) >> 8; + int l = (p_180188_1_ & 65280) >> 8; + int i1 = (p_180188_0_ & 255) >> 0; + int j1 = (p_180188_1_ & 255) >> 0; + int k1 = (int)((float)i * (float)j / 255.0F); + int l1 = (int)((float)k * (float)l / 255.0F); + int i2 = (int)((float)i1 * (float)j1 / 255.0F); + return p_180188_0_ & -16777216 | k1 << 16 | l1 << 8 | i2; + } + + public static double func_181162_h(double p_181162_0_) + { + return p_181162_0_ - Math.floor(p_181162_0_); + } + + /*public static long getPositionRandom(Vec3i pos) + { + return getCoordinateRandom(pos.getX(), pos.getY(), pos.getZ()); + }*/ + + public static long getCoordinateRandom(int x, int y, int z) + { + long i = (long)(x * 3129871) ^ (long)z * 116129781L ^ (long)y; + i = i * i * 42317861L + i * 11L; + return i; + } + + public static UUID getRandomUuid(Random rand) + { + long i = rand.nextLong() & -61441L | 16384L; + long j = rand.nextLong() & 4611686018427387903L | Long.MIN_VALUE; + return new UUID(i, j); + } + + public static double func_181160_c(double p_181160_0_, double p_181160_2_, double p_181160_4_) + { + return (p_181160_0_ - p_181160_2_) / (p_181160_4_ - p_181160_2_); + } + + public static double func_181159_b(double p_181159_0_, double p_181159_2_) + { + double d0 = p_181159_2_ * p_181159_2_ + p_181159_0_ * p_181159_0_; + + if (Double.isNaN(d0)) + { + return Double.NaN; + } + else + { + boolean flag = p_181159_0_ < 0.0D; + + if (flag) + { + p_181159_0_ = -p_181159_0_; + } + + boolean flag1 = p_181159_2_ < 0.0D; + + if (flag1) + { + p_181159_2_ = -p_181159_2_; + } + + boolean flag2 = p_181159_0_ > p_181159_2_; + + if (flag2) + { + double d1 = p_181159_2_; + p_181159_2_ = p_181159_0_; + p_181159_0_ = d1; + } + + double d9 = func_181161_i(d0); + p_181159_2_ = p_181159_2_ * d9; + p_181159_0_ = p_181159_0_ * d9; + double d2 = field_181163_d + p_181159_0_; + int i = (int)Double.doubleToRawLongBits(d2); + double d3 = field_181164_e[i]; + double d4 = field_181165_f[i]; + double d5 = d2 - field_181163_d; + double d6 = p_181159_0_ * d4 - p_181159_2_ * d5; + double d7 = (6.0D + d6 * d6) * d6 * 0.16666666666666666D; + double d8 = d3 + d7; + + if (flag2) + { + d8 = (Math.PI / 2D) - d8; + } + + if (flag1) + { + d8 = Math.PI - d8; + } + + if (flag) + { + d8 = -d8; + } + + return d8; + } + } + + public static double func_181161_i(double p_181161_0_) + { + double d0 = 0.5D * p_181161_0_; + long i = Double.doubleToRawLongBits(p_181161_0_); + i = 6910469410427058090L - (i >> 1); + p_181161_0_ = Double.longBitsToDouble(i); + p_181161_0_ = p_181161_0_ * (1.5D - d0 * p_181161_0_ * p_181161_0_); + return p_181161_0_; + } + + public static int func_181758_c(float p_181758_0_, float p_181758_1_, float p_181758_2_) + { + int i = (int)(p_181758_0_ * 6.0F) % 6; + float f = p_181758_0_ * 6.0F - (float)i; + float f1 = p_181758_2_ * (1.0F - p_181758_1_); + float f2 = p_181758_2_ * (1.0F - f * p_181758_1_); + float f3 = p_181758_2_ * (1.0F - (1.0F - f) * p_181758_1_); + float f4; + float f5; + float f6; + + switch (i) + { + case 0: + f4 = p_181758_2_; + f5 = f3; + f6 = f1; + break; + + case 1: + f4 = f2; + f5 = p_181758_2_; + f6 = f1; + break; + + case 2: + f4 = f1; + f5 = p_181758_2_; + f6 = f3; + break; + + case 3: + f4 = f1; + f5 = f2; + f6 = p_181758_2_; + break; + + case 4: + f4 = f3; + f5 = f1; + f6 = p_181758_2_; + break; + + case 5: + f4 = p_181758_2_; + f5 = f1; + f6 = f2; + break; + + default: + throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + p_181758_0_ + ", " + p_181758_1_ + ", " + p_181758_2_); + } + + int j = clamp_int((int)(f4 * 255.0F), 0, 255); + int k = clamp_int((int)(f5 * 255.0F), 0, 255); + int l = clamp_int((int)(f6 * 255.0F), 0, 255); + return j << 16 | k << 8 | l; + } + + static + { + for (int i = 0; i < 65536; ++i) + { + SIN_TABLE[i] = (float)Math.sin((double)i * Math.PI * 2.0D / 65536.0D); + } + + for (int j = 0; j < 4096; ++j) + { + SIN_TABLE_FAST[j] = (float)Math.sin((double)(((float)j + 0.5F) / 4096.0F * ((float)Math.PI * 2F))); + } + + for (int l = 0; l < 360; l += 90) + { + SIN_TABLE_FAST[(int)((float)l * 11.377778F) & 4095] = (float)Math.sin((double)((float)l * 0.017453292F)); + } + + multiplyDeBruijnBitPosition = new int[] {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; + field_181163_d = Double.longBitsToDouble(4805340802404319232L); + field_181164_e = new double[257]; + field_181165_f = new double[257]; + + for (int k = 0; k < 257; ++k) + { + double d1 = (double)k / 256.0D; + double d0 = Math.asin(d1); + field_181165_f[k] = Math.cos(d0); + field_181164_e[k] = d0; + } + } +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/MathUtil.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/MathUtil.java new file mode 100644 index 0000000..3967151 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/MathUtil.java @@ -0,0 +1,160 @@ +package cc.fyre.riot.util; + +import cc.fyre.riot.profile.Profile; +import cc.fyre.riot.profile.tracker.LocationHistoryTracker; +import org.bukkit.util.Vector; + +import java.util.Collection; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + + +public class MathUtil { + + public static double getHorizontalDistanceToHitBox(final LocationHistoryTracker.SparkLocation from, final LocationHistoryTracker.SparkLocation to) { + + final double nearestX = clamp(from.getX(), to.getX() - 0.4, to.getX() + 0.4); + final double nearestZ = clamp(from.getZ(), to.getZ() - 0.4, to.getZ() + 0.4); + final double distX = from.getX() - nearestX; + final double distZ = from.getZ() - nearestZ; + + double toReturn = Math.hypot(distX, distZ); + + if (Math.abs(from.getPitch()) != 90.0f) { + toReturn /= Math.cos(Math.toRadians(from.getPitch())); + } + + return toReturn; + } + + //https://github.com/funkemunky/Atlas/blob/master/AtlasParent/Atlas/src/main/java/cc/funkemunky/api/utils/MathUtils.java + public static double getHorizontalDistance(Location from, Location to) { + double deltaX = to.getX() - from.getX(), deltaZ = to.getZ() - from.getZ(); + return sqrt(deltaX * deltaX + deltaZ * deltaZ); + } + + public static double sqrt(double number) { + if (number == 0) return 0; + double t; + double squareRoot = number / 2; + + do { + t = squareRoot; + squareRoot = (t + (number / t)) / 2; + } while ((t - squareRoot) != 0); + + return squareRoot; + } + + public static long gcd(final long limit, final long a, final long b) { + try { + if (b <= limit) { + return a; + } + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + } + return gcd(limit, b, a % b); + } + + public static long gcd(long a, long b) { + if (b <= 16384) { + return a; + } + return gcd(b, a % b); + } + + public static double gcd(final double limit, final double a, final double b) { + try { + if (b <= limit) { + return a; + } + } catch (IllegalArgumentException ex) { + ex.printStackTrace(); + } + return gcd(limit, b, a % b); + } + + public static T getMode(Collection collect) { + Map repeated = new HashMap<>(); + + //Sorting each value by how to repeat into a map. + collect.forEach(val -> { + int number = repeated.getOrDefault(val, 0); + + repeated.put(val, number + 1); + }); + + //Calculating the largest value to the key, which would be the mode. + return (T) repeated.keySet().stream() + .map(key -> new Tuple<>(key, repeated.get(key))) //We map it into a Tuple for easier sorting. + .max(Comparator.comparing(tup -> tup.b(), Comparator.naturalOrder())) + .orElseThrow(NullPointerException::new).a(); + } + + public static long getGcd(long current, long previous) { + return previous <= 0b100000000000000 ? current : MathUtil.getGcd(previous, MathUtil.getDelta(current, previous)); + } + + private static long getDelta(long alpha, long beta) { + return alpha % beta; + } + + public static Vector getDirection(double yaw, double pitch) { + Vector vector = new Vector(); + vector.setY(-Math.sin(Math.toRadians(pitch))); + double xz = Math.cos(Math.toRadians(pitch)); + vector.setX(-xz * Math.sin(Math.toRadians(yaw))); + vector.setZ(xz * Math.cos(Math.toRadians(yaw))); + return vector; + } + + public static float sqrt(float number) { + if(number == 0) return 0; + float t; + + float squareRoot = number / 2; + + do { + t = squareRoot; + squareRoot = (t + (number / t)) / 2; + } while ((t - squareRoot) != 0); + + return squareRoot; + } + + public static double clamp(final double val, final double min, final double max) { + return Math.max(min, Math.min(max, val)); + } + public static int pingFormula(long ping) { + return (int) Math.ceil(ping / 50.0); + } + public static Vec3 getPositionEyes(double x, double y, double z, float eyeHeight) { + return new Vec3(x, y + (double)eyeHeight, z); + } + + public Vec3 getLook(float partialTicks, Profile profile) { + if (partialTicks == 1.0F) { + return getVectorForRotation(profile.getPlayer().getLocation().getPitch(), profile.getPlayer().getLocation().getYaw()); + } else { + float f = profile.getMovementTracker().lastLocation.getPitch() + (profile.getPlayer().getLocation().getPitch() - + profile.getMovementTracker().lastLocation.getPitch()) * partialTicks; + float f1 = profile.getMovementTracker().lastLocation.getYaw() + + (profile.getMovementTracker().lastLocation.getYaw() - profile.getMovementTracker().lastLocation.getYaw()) * partialTicks; + return getVectorForRotation(f, f1); + } + } + + public static final Vec3 getVectorForRotation(float pitch, float yaw) { + float f = MathHelper.cos(-yaw * 0.017453292F - (float)Math.PI); + float f1 = MathHelper.sin(-yaw * 0.017453292F - (float)Math.PI); + float f2 = -MathHelper.cos(-pitch * 0.017453292F); + float f3 = MathHelper.sin(-pitch * 0.017453292F); + return new Vec3(f1 * f2, f3, f * f2); + } + + public static int getPingInTicks(long ping) { + return (int) Math.floor(ping / 50.); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/MovingObjectPosition.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/MovingObjectPosition.java new file mode 100644 index 0000000..7e7fac2 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/MovingObjectPosition.java @@ -0,0 +1,61 @@ +package cc.fyre.riot.util; + +import net.minecraft.server.v1_7_R4.EnumFacing; +import org.bukkit.entity.Entity; + +public class MovingObjectPosition +{ + private BlockPos blockPos; + + /** What type of ray trace hit was this? 0 = block, 1 = entity */ + public MovingObjectPosition.MovingObjectType typeOfHit; + public EnumFacing sideHit; + + /** The vector position of the hit */ + public Vec3 hitVec; + + /** The hit entity */ + public Entity entityHit; + + public MovingObjectPosition(Vec3 hitVecIn, EnumFacing facing, BlockPos blockPosIn) + { + this(MovingObjectPosition.MovingObjectType.BLOCK, hitVecIn, facing, blockPosIn); + } + + public MovingObjectPosition(Vec3 p_i45552_1_, EnumFacing facing) + { + this(MovingObjectPosition.MovingObjectType.BLOCK, p_i45552_1_, facing, BlockPos.ORIGIN); + } + + public MovingObjectPosition(MovingObjectPosition.MovingObjectType typeOfHitIn, Vec3 hitVecIn, EnumFacing sideHitIn, BlockPos blockPosIn) + { + this.typeOfHit = typeOfHitIn; + this.blockPos = blockPosIn; + this.sideHit = sideHitIn; + this.hitVec = new Vec3(hitVecIn.xCoord, hitVecIn.yCoord, hitVecIn.zCoord); + } + + public MovingObjectPosition(Entity entityHitIn, Vec3 hitVecIn) + { + this.typeOfHit = MovingObjectPosition.MovingObjectType.ENTITY; + this.entityHit = entityHitIn; + this.hitVec = hitVecIn; + } + + public BlockPos getBlockPos() + { + return this.blockPos; + } + + public String toString() + { + return "HitResult{type=" + this.typeOfHit + ", blockpos=" + this.blockPos + ", f=" + this.sideHit + ", pos=" + this.hitVec + ", entity=" + this.entityHit + '}'; + } + + public static enum MovingObjectType + { + MISS, + BLOCK, + ENTITY; + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/PageBuilder.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/PageBuilder.java new file mode 100644 index 0000000..4fc7cca --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/PageBuilder.java @@ -0,0 +1,48 @@ +package cc.fyre.riot.util; + +import mkremins.fanciful.FancyMessage; +import org.bukkit.command.CommandSender; + +import java.util.Collection; +import java.util.List; + +public abstract class PageBuilder { + + private int resultsPerPage; + + public PageBuilder(final int resultsPerPage) { + this.resultsPerPage = resultsPerPage; + if (this.resultsPerPage <= 0) { + this.resultsPerPage = 10; + } + } + + public abstract FancyMessage getFormat(final Log log, final int index); + public abstract FancyMessage getHeader(final int page, final int maxPages); + public abstract FancyMessage getFooter(final int page, final int maxPages); + public abstract String getEmptyResultMessage(); + + public void send(final CommandSender sender, final int page, final Collection results) { + this.send(sender, page, results); + } + + public void send(final CommandSender sender, final int page, final List results) { + if (results.isEmpty()) { + sender.sendMessage(this.getEmptyResultMessage()); + return; + } + final int maxPages = results.size() / this.resultsPerPage + 1; + final int currentPage = (page <= 0) ? 1 : (Math.min(page, maxPages)); + final FancyMessage header = this.getHeader(currentPage, maxPages); + if (header != null) { + header.send(sender); + } + for (int i = this.resultsPerPage * (currentPage - 1); i < this.resultsPerPage * currentPage && i < results.size(); ++i) { + this.getFormat(results.get(i), i).send(sender); + } + final FancyMessage footer = this.getFooter(currentPage, maxPages); + if (footer != null) { + footer.send(sender); + } + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/Pair.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/Pair.java new file mode 100644 index 0000000..0aba041 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/Pair.java @@ -0,0 +1,13 @@ +package cc.fyre.riot.util; + +import lombok.*; + +@Getter @Setter +@NoArgsConstructor +@AllArgsConstructor +public class Pair { + + private X x; + private Y y; + +} \ No newline at end of file diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/Tuple.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/Tuple.java new file mode 100644 index 0000000..5ed3880 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/Tuple.java @@ -0,0 +1,20 @@ +package cc.fyre.riot.util; + +public class Tuple { + private A a; + private B b; + + public Tuple(A var1, B var2) { + this.a = var1; + this.b = var2; + } + + public A a() { + return this.a; + } + + public B b() { + return this.b; + } +} + diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/Vec3.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/Vec3.java new file mode 100644 index 0000000..9a30dc0 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/Vec3.java @@ -0,0 +1,214 @@ +package cc.fyre.riot.util; + + +public class Vec3 +{ + /** X coordinate of Vec3D */ + public final double xCoord; + + /** Y coordinate of Vec3D */ + public final double yCoord; + + /** Z coordinate of Vec3D */ + public final double zCoord; + + public Vec3(double x, double y, double z) + { + if (x == -0.0D) + { + x = 0.0D; + } + + if (y == -0.0D) + { + y = 0.0D; + } + + if (z == -0.0D) + { + z = 0.0D; + } + + this.xCoord = x; + this.yCoord = y; + this.zCoord = z; + } + + + + /** + * Returns a new vector with the result of the specified vector minus this. + */ + public Vec3 subtractReverse(Vec3 vec) + { + return new Vec3(vec.xCoord - this.xCoord, vec.yCoord - this.yCoord, vec.zCoord - this.zCoord); + } + + private String dirt(boolean value) { + return value ? "%%__TIMESTAMP__%%" : "%%__USER__%%"; + } + + /** + * Normalizes the vector to a length of 1 (except if it is the zero vector) + */ + public Vec3 normalize() + { + double d0 = (double)MathHelper.sqrt_double(this.xCoord * this.xCoord + this.yCoord * this.yCoord + this.zCoord * this.zCoord); + return d0 < 1.0E-4D ? new Vec3(0.0D, 0.0D, 0.0D) : new Vec3(this.xCoord / d0, this.yCoord / d0, this.zCoord / d0); + } + + public double dotProduct(Vec3 vec) + { + return this.xCoord * vec.xCoord + this.yCoord * vec.yCoord + this.zCoord * vec.zCoord; + } + + /** + * Returns a new vector with the result of this vector x the specified vector. + */ + public Vec3 crossProduct(Vec3 vec) + { + return new Vec3(this.yCoord * vec.zCoord - this.zCoord * vec.yCoord, this.zCoord * vec.xCoord - this.xCoord * vec.zCoord, this.xCoord * vec.yCoord - this.yCoord * vec.xCoord); + } + + public Vec3 subtract(Vec3 vec) + { + return this.subtract(vec.xCoord, vec.yCoord, vec.zCoord); + } + + public Vec3 subtract(double x, double y, double z) + { + return this.addVector(-x, -y, -z); + } + + public Vec3 add(Vec3 vec) + { + return this.addVector(vec.xCoord, vec.yCoord, vec.zCoord); + } + + /** + * Adds the specified x,y,z vector components to this vector and returns the resulting vector. Does not change this + * vector. + */ + public Vec3 addVector(double x, double y, double z) + { + return new Vec3(this.xCoord + x, this.yCoord + y, this.zCoord + z); + } + + /** + * Euclidean distance between this and the specified vector, returned as double. + */ + public double distanceTo(Vec3 vec) + { + double d0 = vec.xCoord - this.xCoord; + double d1 = vec.yCoord - this.yCoord; + double d2 = vec.zCoord - this.zCoord; + return (double)MathHelper.sqrt_double(d0 * d0 + d1 * d1 + d2 * d2); + } + + /** + * The square of the Euclidean distance between this and the specified vector. + */ + public double squareDistanceTo(Vec3 vec) + { + double d0 = vec.xCoord - this.xCoord; + double d1 = vec.yCoord - this.yCoord; + double d2 = vec.zCoord - this.zCoord; + return d0 * d0 + d1 * d1 + d2 * d2; + } + + /** + * Returns the length of the vector. + */ + public double lengthVector() + { + return (double)MathHelper.sqrt_double(this.xCoord * this.xCoord + this.yCoord * this.yCoord + this.zCoord * this.zCoord); + } + + /** + * Returns a new vector with x value equal to the second parameter, along the line between this vector and the + * passed in vector, or null if not possible. + */ + public Vec3 getIntermediateWithXValue(Vec3 vec, double x) + { + double d0 = vec.xCoord - this.xCoord; + double d1 = vec.yCoord - this.yCoord; + double d2 = vec.zCoord - this.zCoord; + + if (d0 * d0 < 1.0000000116860974E-7D) + { + return null; + } + else + { + double d3 = (x - this.xCoord) / d0; + return d3 >= 0.0D && d3 <= 1.0D ? new Vec3(this.xCoord + d0 * d3, this.yCoord + d1 * d3, this.zCoord + d2 * d3) : null; + } + } + + /** + * Returns a new vector with y value equal to the second parameter, along the line between this vector and the + * passed in vector, or null if not possible. + */ + public Vec3 getIntermediateWithYValue(Vec3 vec, double y) + { + double d0 = vec.xCoord - this.xCoord; + double d1 = vec.yCoord - this.yCoord; + double d2 = vec.zCoord - this.zCoord; + + if (d1 * d1 < 1.0000000116860974E-7D) + { + return null; + } + else + { + double d3 = (y - this.yCoord) / d1; + return d3 >= 0.0D && d3 <= 1.0D ? new Vec3(this.xCoord + d0 * d3, this.yCoord + d1 * d3, this.zCoord + d2 * d3) : null; + } + } + + /** + * Returns a new vector with z value equal to the second parameter, along the line between this vector and the + * passed in vector, or null if not possible. + */ + public Vec3 getIntermediateWithZValue(Vec3 vec, double z) + { + double d0 = vec.xCoord - this.xCoord; + double d1 = vec.yCoord - this.yCoord; + double d2 = vec.zCoord - this.zCoord; + + if (d2 * d2 < 1.0000000116860974E-7D) + { + return null; + } + else + { + double d3 = (z - this.zCoord) / d2; + return d3 >= 0.0D && d3 <= 1.0D ? new Vec3(this.xCoord + d0 * d3, this.yCoord + d1 * d3, this.zCoord + d2 * d3) : null; + } + } + + public String toString() + { + return "(" + this.xCoord + ", " + this.yCoord + ", " + this.zCoord + ")"; + } + + public Vec3 rotatePitch(float pitch) + { + float f = MathHelper.cos(pitch); + float f1 = MathHelper.sin(pitch); + double d0 = this.xCoord; + double d1 = this.yCoord * (double)f + this.zCoord * (double)f1; + double d2 = this.zCoord * (double)f - this.yCoord * (double)f1; + return new Vec3(d0, d1, d2); + } + + public Vec3 rotateYaw(float yaw) + { + float f = MathHelper.cos(yaw); + float f1 = MathHelper.sin(yaw); + double d0 = this.xCoord * (double)f + this.zCoord * (double)f1; + double d1 = this.yCoord; + double d2 = this.zCoord * (double)f - this.xCoord * (double)f1; + return new Vec3(d0, d1, d2); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/Vec3i.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/Vec3i.java new file mode 100644 index 0000000..4284e70 --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/Vec3i.java @@ -0,0 +1,126 @@ +package cc.fyre.riot.util; + +import net.minecraft.util.com.google.common.base.Objects; + +public class Vec3i implements Comparable { + /** The Null vector constant (0, 0, 0) */ + public static final Vec3i NULL_VECTOR = new Vec3i(0, 0, 0); + + /** X coordinate */ + private final int x; + + /** Y coordinate */ + private final int y; + + /** Z coordinate */ + private final int z; + + public Vec3i(int xIn, int yIn, int zIn) + { + this.x = xIn; + this.y = yIn; + this.z = zIn; + } + + public Vec3i(double xIn, double yIn, double zIn) + { + this(MathHelper.floor_double(xIn), MathHelper.floor_double(yIn), MathHelper.floor_double(zIn)); + } + + private String pig(boolean value) { + return value ? "%%__TIMESTAMP__%%" : "%%__USER__%%"; + } + + public boolean equals(Object p_equals_1_) + { + if (this == p_equals_1_) + { + return true; + } + else if (!(p_equals_1_ instanceof Vec3i)) + { + return false; + } + else + { + Vec3i vec3i = (Vec3i)p_equals_1_; + return this.getX() != vec3i.getX() ? false : (this.getY() != vec3i.getY() ? false : this.getZ() == vec3i.getZ()); + } + } + + public int hashCode() + { + return (this.getY() + this.getZ() * 31) * 31 + this.getX(); + } + + public int compareTo(Vec3i p_compareTo_1_) + { + return this.getY() == p_compareTo_1_.getY() ? (this.getZ() == p_compareTo_1_.getZ() ? this.getX() - p_compareTo_1_.getX() : this.getZ() - p_compareTo_1_.getZ()) : this.getY() - p_compareTo_1_.getY(); + } + + /** + * Get the X coordinate + */ + public int getX() + { + return this.x; + } + + /** + * Get the Y coordinate + */ + public int getY() + { + return this.y; + } + + /** + * Get the Z coordinate + */ + public int getZ() + { + return this.z; + } + + /** + * Calculate the cross product of this and the given Vector + */ + public Vec3i crossProduct(Vec3i vec) + { + return new Vec3i(this.getY() * vec.getZ() - this.getZ() * vec.getY(), this.getZ() * vec.getX() - this.getX() * vec.getZ(), this.getX() * vec.getY() - this.getY() * vec.getX()); + } + + /** + * Calculate squared distance to the given coordinates + */ + public double distanceSq(double toX, double toY, double toZ) + { + double d0 = (double)this.getX() - toX; + double d1 = (double)this.getY() - toY; + double d2 = (double)this.getZ() - toZ; + return d0 * d0 + d1 * d1 + d2 * d2; + } + + /** + * Compute square of distance from point x, y, z to center of this Block + */ + public double distanceSqToCenter(double xIn, double yIn, double zIn) + { + double d0 = (double)this.getX() + 0.5D - xIn; + double d1 = (double)this.getY() + 0.5D - yIn; + double d2 = (double)this.getZ() + 0.5D - zIn; + return d0 * d0 + d1 * d1 + d2 * d2; + } + + /** + * Calculate squared distance to the given Vector + */ + public double distanceSq(Vec3i to) + { + return this.distanceSq((double)to.getX(), (double)to.getY(), (double)to.getZ()); + } + + public String toString() { + return Objects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString(); + } +} diff --git a/Anticheat-master/src/main/java/cc/fyre/riot/util/Velocity.java b/Anticheat-master/src/main/java/cc/fyre/riot/util/Velocity.java new file mode 100644 index 0000000..d75dbed --- /dev/null +++ b/Anticheat-master/src/main/java/cc/fyre/riot/util/Velocity.java @@ -0,0 +1,33 @@ +package cc.fyre.riot.util; + +import lombok.Getter; +import lombok.Setter; + +public class Velocity { + + @Getter private final double x; + @Getter private final double y; + @Getter private final double z; + @Getter private final double xz; + + @Getter @Setter private int ticks; + @Getter @Setter private boolean received; + + @Getter private short transactionId; + + public Velocity(final double x,final double y,final double z) { + this.x = x; + this.y = y; + this.z = z; + this.xz = Math.hypot(x,z); + } + + public Velocity(final double x,final double y,final double z,final int ticks,final short transactionId) { + this.x = x; + this.y = y; + this.z = z; + this.xz = Math.hypot(x,z); + this.ticks = ticks; + this.transactionId = transactionId; + } +} diff --git a/Anticheat-master/src/main/resources/plugin.yml b/Anticheat-master/src/main/resources/plugin.yml new file mode 100644 index 0000000..0978a65 --- /dev/null +++ b/Anticheat-master/src/main/resources/plugin.yml @@ -0,0 +1,4 @@ +name: Riot +main: cc.fyre.riot.Riot +version: 1.0-SNAPSHOT +depend: [Proton, Neutron] \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/LICENCE.txt b/MythicSpigot-master/TacoSpigot-API/LICENCE.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/LICENCE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/MythicSpigot-master/TacoSpigot-API/README.md b/MythicSpigot-master/TacoSpigot-API/README.md new file mode 100644 index 0000000..e69d02e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/README.md @@ -0,0 +1,27 @@ +Bukkit +====== +A plugin API for [Minecraft](https://minecraft.net/) servers, currently maintained by [SpigotMC](http://www.spigotmc.org/). + +Bug Reporting +------------- +The development team is very open to both bug and feature requests / suggestions. You can submit these on the [JIRA Issue Tracker](http://hub.spigotmc.org/jira/). + +Compilation +----------- +Bukkit is a Java program which uses [Maven 3](http://maven.apache.org/) for compilation. To compile fresh from Git, simply perform the following steps: + +* Install Maven and Git using your preferred installation methods. +* `git clone https://hub.spigotmc.org/stash/scm/spigot/bukkit.git`. +* `mvn clean install`. + +Some IDEs such as [NetBeans](https://netbeans.org/) can perform these steps for you. Any Maven capable Java IDE can be used to develop with Bukkit, however the current team's personal preference is to use NetBeans. + +Contributing +------------ +Contributions of all sorts are welcome. To manage community contributions, we use the pull request functionality of Stash. In to gain access to Stash and create a pull request, you will first need to perform the following steps: + +* Create an account on [JIRA](http://hub.spigotmc.org/jira/). +* Fill in the [SpigotMC CLA](http://www.spigotmc.org/go/cla) and wait up to 24 hours for your Stash account to be activated. Please ensure that your username and email addresses match. +* Log into Stash using your JIRA credentials. + +Once you have performed these steps you can create a fork, push your code changes, and then submit it for review. diff --git a/MythicSpigot-master/TacoSpigot-API/api.iml b/MythicSpigot-master/TacoSpigot-API/api.iml new file mode 100644 index 0000000..ece0932 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/api.iml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/pom.xml b/MythicSpigot-master/TacoSpigot-API/pom.xml new file mode 100644 index 0000000..9079700 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/pom.xml @@ -0,0 +1,176 @@ + + + 4.0.0 + + + me.levansj01.mythicspigot + parent + dev-SNAPSHOT + + + me.levansj01.mythicspigot + api + 1.8.8-R0.2-SNAPSHOT + jar + + MythicSpigot-API + https://github.com/TacoSpigot + An enhanced plugin API for Minecraft servers. + + + + -Xdoclint:none + 1.8 + 1.8 + UTF-8 + + + + + + destroystokyo-releases + https://repo.destroystokyo.com/content/repositories/releases/ + + + destroystokyo-snapshots + https://repo.destroystokyo.com/content/repositories/snapshots/ + + + + + + + spigotmc-public + https://hub.spigotmc.org/nexus/content/groups/public/ + + + + + + net.sf.trove4j + trove4j + 3.0.3 + + provided + + + commons-lang + commons-lang + 2.6 + compile + + + com.googlecode.json-simple + json-simple + 1.1.1 + jar + compile + + + + com.google.guava + guava + 17.0 + compile + + + + net.jafama + jafama + 2.1.0 + + + com.google.code.gson + gson + 2.2.4 + + + org.avaje + ebean + 2.8.1 + compile + + + org.yaml + snakeyaml + 1.15 + compile + + + net.md-5 + bungeecord-chat + 1.8-SNAPSHOT + jar + compile + + + + + junit + junit + 4.12 + test + + + org.hamcrest + hamcrest-library + 1.3 + test + + + net.jafama + jafama + 2.3.2 + compile + + + jline + jline + 2.12.1 + compile + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + true + 1.8 + 1.8 + + + + + org.codehaus.plexus + plexus-compiler-eclipse + 2.5.0-spigotmc + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + + package + + shade + + + + + + false + + true + + + + + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/cc/ghast/progress/ProgressBar.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/cc/ghast/progress/ProgressBar.java new file mode 100644 index 0000000..ec817c3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/cc/ghast/progress/ProgressBar.java @@ -0,0 +1,48 @@ +package cc.ghast.progress; + +import jline.console.ConsoleReader; + +/** + * @author Ghast + * @since 29-Apr-20 + */ +public class ProgressBar { + private final int total; + private final ConsoleReader reader; + private int remain; + + + public ProgressBar(int total, ConsoleReader reader) { + this.total = total; + this.remain = 0; + this.reader = reader; + } + + public void progressPercentage(){ + progressPercentage(1); + } + + public void progressPercentage(int add) { + remain += add; + if (remain > total) { + throw new IllegalArgumentException(); + } + int maxBareSize = 10; // 10unit for 100% + int remainProcent = ((100 * remain) / total) / maxBareSize; + char defaultChar = '-'; + String icon = "*"; + String bare = new String(new char[maxBareSize]).replace('\0', defaultChar) + "]"; + StringBuilder bareDone = new StringBuilder(); + bareDone.append("["); + for (int i = 0; i < remainProcent; i++) { + bareDone.append(icon); + } + + + String bareRemain = bare.substring(remainProcent, bare.length()); + System.out.print("\r" + bareDone + bareRemain + " " + remainProcent * 10 + "%"); + if (remain == total) { + System.out.print("\n"); + } + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/FullServerTickHandler.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/FullServerTickHandler.java new file mode 100644 index 0000000..cb4e7ba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/FullServerTickHandler.java @@ -0,0 +1,79 @@ +package co.aikar.timings; + +import static co.aikar.timings.TimingsManager.*; + +public class FullServerTickHandler extends TimingHandler { + static final TimingIdentifier IDENTITY = new TimingIdentifier("Minecraft", "Full Server Tick", null, false); + final TimingData minuteData; + double avgFreeMemory = -1D; + double avgUsedMemory = -1D; + FullServerTickHandler() { + super(IDENTITY); + minuteData = new TimingData(id); + + TIMING_MAP.put(IDENTITY, this); + } + + @Override + public void startTiming() { + if (TimingsManager.needsFullReset) { + TimingsManager.resetTimings(); + } else if (TimingsManager.needsRecheckEnabled) { + TimingsManager.recheckEnabled(); + } + super.startTiming(); + } + + @Override + public void stopTiming() { + super.stopTiming(); + if (!enabled) { + return; + } + if (TimingHistory.timedTicks % 20 == 0) { + final Runtime runtime = Runtime.getRuntime(); + double usedMemory = runtime.totalMemory() - runtime.freeMemory(); + double freeMemory = runtime.maxMemory() - usedMemory; + if (this.avgFreeMemory == -1) { + this.avgFreeMemory = freeMemory; + } else { + this.avgFreeMemory = (this.avgFreeMemory * (59 / 60D)) + (freeMemory * (1 / 60D)); + } + + if (this.avgUsedMemory == -1) { + this.avgUsedMemory = usedMemory; + } else { + this.avgUsedMemory = (this.avgUsedMemory * (59 / 60D)) + (usedMemory * (1 / 60D)); + } + } + + long start = System.nanoTime(); + TimingsManager.tick(); + long diff = System.nanoTime() - start; + CURRENT = TIMINGS_TICK; + TIMINGS_TICK.addDiff(diff); + // addDiff for TIMINGS_TICK incremented this, bring it back down to 1 per tick. + record.curTickCount--; + minuteData.curTickTotal = record.curTickTotal; + minuteData.curTickCount = 1; + boolean violated = isViolated(); + minuteData.processTick(violated); + TIMINGS_TICK.processTick(violated); + processTick(violated); + + + if (TimingHistory.timedTicks % 1200 == 0) { + MINUTE_REPORTS.add(new TimingHistory.MinuteReport()); + TimingHistory.resetTicks(false); + minuteData.reset(); + } + if (TimingHistory.timedTicks % Timings.getHistoryInterval() == 0) { + TimingsManager.HISTORY.add(new TimingHistory()); + TimingsManager.resetTimings(); + } + } + + boolean isViolated() { + return record.curTickTotal > 50000000; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/NullTimingHandler.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/NullTimingHandler.java new file mode 100644 index 0000000..0a54002 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/NullTimingHandler.java @@ -0,0 +1,71 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +public final class NullTimingHandler implements Timing { + @Override + public double getAverage() { + return 0; + } + + @Override + public void startTiming() { + + } + + @Override + public void stopTiming() { + + } + + @Override + public void startTimingIfSync() { + + } + + @Override + public void stopTimingIfSync() { + + } + + @Override + public void abort() { + + } + + @Override + public void stopTimingAsync() { + + } + + @Override + public TimingHandler getTimingHandler() { + return null; + } + + @Override + public void close() { + + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimedEventExecutor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimedEventExecutor.java new file mode 100644 index 0000000..e3da034 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimedEventExecutor.java @@ -0,0 +1,81 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.EventException; +import org.bukkit.event.Listener; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.Plugin; + +import java.lang.reflect.Method; + +public class TimedEventExecutor implements EventExecutor { + + private final EventExecutor executor; + private final Timing timings; + + /** + * Wraps an event executor and associates a timing handler to it. + * + * @param executor + * @param plugin + * @param method + * @param eventClass + */ + public TimedEventExecutor(EventExecutor executor, Plugin plugin, Method method, Class eventClass) { + this.executor = executor; + String id; + + if (method == null) { + if (executor.getClass().getEnclosingClass() != null) { // Oh Skript, how we love you + method = executor.getClass().getEnclosingMethod(); + } + } + + if (method != null) { + id = method.getDeclaringClass().getName(); + } else { + id = executor.getClass().getName(); + } + + + final String eventName = eventClass.getSimpleName(); + boolean verbose = "BlockPhysicsEvent".equals(eventName) || "Drain".equals(eventName) || "Fill".equals(eventName); + this.timings = Timings.ofSafe(plugin.getName(), (verbose ? "## " : "") + + "Event: " + id + " (" + eventName + ")", null); + } + + @Override + public void execute(Listener listener, Event event) throws EventException { + if (event.isAsynchronous() || !Timings.timingsEnabled || !Bukkit.isPrimaryThread()) { + executor.execute(listener, event); + return; + } + timings.startTiming(); + executor.execute(listener, event); + timings.stopTiming(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/Timing.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/Timing.java new file mode 100644 index 0000000..d4d3371 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/Timing.java @@ -0,0 +1,76 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +/** + * Provides an ability to time sections of code within the Minecraft Server + */ +public interface Timing extends AutoCloseable { + /** + * Starts timing the execution until {@link #stopTiming()} is called. + */ + public void startTiming(); + + /** + *

Stops timing and records the data. Propagates the data up to group handlers.

+ * + * Will automatically be called when this Timing is used with try-with-resources + */ + public void stopTiming(); + + public void stopTimingAsync(); + + public double getAverage(); + + /** + * Starts timing the execution until {@link #stopTiming()} is called. + * + * But only if we are on the primary thread. + */ + public void startTimingIfSync(); + + /** + *

Stops timing and records the data. Propagates the data up to group handlers.

+ * + *

Will automatically be called when this Timing is used with try-with-resources

+ * + * But only if we are on the primary thread. + */ + public void stopTimingIfSync(); + + /** + * Stops timing and disregards current timing data. + */ + public void abort(); + + /** + * Used internally to get the actual backing Handler in the case of delegated Handlers + * + * @return TimingHandler + */ + TimingHandler getTimingHandler(); + + @Override + void close(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingData.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingData.java new file mode 100644 index 0000000..b62e428 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingData.java @@ -0,0 +1,105 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import com.google.common.base.Function; + +import java.util.List; + +import static co.aikar.util.JSONUtil.toArray; + +/** + *

Lightweight object for tracking timing data

+ * + * This is broken out to reduce memory usage + */ +class TimingData { + static Function LOADER = new Function() { + @Override + public TimingData apply(Integer input) { + return new TimingData(input); + } + }; + int id; + int count = 0; + int lagCount = 0; + long totalTime = 0; + long lagTotalTime = 0; + + int curTickCount = 0; + int curTickTotal = 0; + + TimingData(int id) { + this.id = id; + } + + TimingData(TimingData data) { + this.id = data.id; + this.totalTime = data.totalTime; + this.lagTotalTime = data.lagTotalTime; + this.count = data.count; + this.lagCount = data.lagCount; + } + + void add(long diff) { + ++curTickCount; + curTickTotal += diff; + } + + void processTick(boolean violated) { + totalTime += curTickTotal; + count += curTickCount; + if (violated) { + lagTotalTime += curTickTotal; + lagCount += curTickCount; + } + curTickTotal = 0; + curTickCount = 0; + } + + void reset() { + count = 0; + lagCount = 0; + curTickTotal = 0; + curTickCount = 0; + totalTime = 0; + lagTotalTime = 0; + } + + protected TimingData clone() { + return new TimingData(this); + } + + public List export() { + List list = toArray( + id, + count, + totalTime); + if (lagCount > 0) { + list.add(lagCount); + list.add(lagTotalTime); + } + return list; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java new file mode 100644 index 0000000..6db7740 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHandler.java @@ -0,0 +1,214 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import gnu.trove.map.hash.TIntObjectHashMap; +import org.bukkit.Bukkit; +import co.aikar.util.LoadingIntMap; +import co.aikar.util.LoadingMap; +import co.aikar.util.MRUMapCache; + +import java.util.Map; +import java.util.logging.Level; + +public class TimingHandler implements Timing { + + private static int idPool = 1; + final int id = idPool++; + + final String name; + final boolean verbose; + + final TIntObjectHashMap children = new LoadingIntMap(TimingData.LOADER); + + final TimingData record; + final TimingHandler groupHandler; + + int count, total; + long start = 0; + int timingDepth = 0; + boolean added; + boolean timed; + boolean enabled; + TimingHandler parent; + + TimingHandler(TimingIdentifier id) { + if (id.name.startsWith("##")) { + verbose = true; + this.name = id.name.substring(3); + } else { + this.name = id.name; + verbose = false; + } + + this.record = new TimingData(this.id); + this.groupHandler = id.groupHandler; + + TimingIdentifier.getGroup(id.group).handlers.add(this); + checkEnabled(); + } + + final void checkEnabled() { + enabled = Timings.timingsEnabled && (!verbose || Timings.verboseEnabled); + } + + void processTick(boolean violated) { + if (timingDepth != 0 || record.curTickCount == 0) { + timingDepth = 0; + start = 0; + return; + } + + record.processTick(violated); + for (TimingData handler : children.valueCollection()) { + handler.processTick(violated); + } + } + + @Override + public double getAverage() { + if (count < 20) return 0; + return total / count; + } + + @Override + public void startTimingIfSync() { + if (Bukkit.isPrimaryThread()) { + startTiming(); + } + } + + @Override + public void stopTimingIfSync() { + if (Bukkit.isPrimaryThread()) { + stopTiming(); + } + } + + public void startTiming() { + if (enabled && ++timingDepth == 1) { + start = System.nanoTime(); + parent = TimingsManager.CURRENT; + TimingsManager.CURRENT = this; + } + } + + public void stopTiming() { + if (enabled && --timingDepth == 0 && start != 0) { + if (!Bukkit.isPrimaryThread()) { + Bukkit.getLogger().log(Level.SEVERE, "stopTiming called async for " + name); + new Throwable().printStackTrace(); + start = 0; + return; + } + addDiff(System.nanoTime() - start); + start = 0; + } + } + + public void stopTimingAsync() { + if (enabled && --timingDepth == 0 && start != 0) { + addDiff(System.nanoTime() - start); + start = 0; + } + } + + @Override + public void abort() { + if (enabled && timingDepth > 0) { + start = 0; + } + } + + void addDiff(long diff) { + total += diff; + count++; + if (count > 20) { + count--; + total -= ((double) total / (double) count); + } + + if (TimingsManager.CURRENT == this) { + TimingsManager.CURRENT = parent; + if (parent != null) { + parent.children.get(id).add(diff); + } + } + record.add(diff); + if (!added) { + added = true; + timed = true; + TimingsManager.HANDLERS.add(this); + } + if (groupHandler != null) { + groupHandler.addDiff(diff); + groupHandler.children.get(id).add(diff); + } + } + + /** + * Reset this timer, setting all values to zero. + * + * @param full + */ + void reset(boolean full) { + record.reset(); + if (full) { + timed = false; + } + start = 0; + timingDepth = 0; + added = false; + children.clear(); + checkEnabled(); + } + + @Override + public TimingHandler getTimingHandler() { + return this; + } + + @Override + public boolean equals(Object o) { + return (this == o); + } + + @Override + public int hashCode() { + return id; + } + + /** + * This is simply for the Closeable interface so it can be used with + * try-with-resources () + */ + @Override + public void close() { + stopTimingIfSync(); + } + + public boolean isSpecial() { + return this == TimingsManager.FULL_SERVER_TICK || this == TimingsManager.TIMINGS_TICK; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHistory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHistory.java new file mode 100644 index 0000000..edc10ac --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHistory.java @@ -0,0 +1,277 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import com.google.common.base.Function; +import com.google.common.collect.Sets; +import net.jafama.FastMath; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import co.aikar.util.LoadingMap; +import co.aikar.util.MRUMapCache; + +import java.lang.management.ManagementFactory; +import java.util.Collection; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static co.aikar.timings.TimingsManager.FULL_SERVER_TICK; +import static co.aikar.timings.TimingsManager.MINUTE_REPORTS; +import static co.aikar.util.JSONUtil.*; + +@SuppressWarnings({"deprecation", "SuppressionAnnotation"}) +public class TimingHistory { + public static long lastMinuteTime; + public static long timedTicks; + public static long playerTicks; + public static long entityTicks; + public static long tileEntityTicks; + public static long activatedEntityTicks; + static int worldIdPool = 1; + static Map worldMap = LoadingMap.newHashMap(new Function() { + @Override + public Integer apply(String input) { + return worldIdPool++; + } + }); + final long endTime; + final long startTime; + final long totalTicks; + final long totalTime; // Represents all time spent running the server this history + final MinuteReport[] minuteReports; + + final TimingHistoryEntry[] entries; + final Set tileEntityTypeSet = Sets.newHashSet(); + final Set entityTypeSet = Sets.newHashSet(); + final Map worlds; + + TimingHistory() { + this.endTime = System.currentTimeMillis() / 1000; + this.startTime = TimingsManager.historyStart / 1000; + if (timedTicks % 1200 != 0 || MINUTE_REPORTS.isEmpty()) { + this.minuteReports = MINUTE_REPORTS.toArray(new MinuteReport[MINUTE_REPORTS.size() + 1]); + this.minuteReports[this.minuteReports.length - 1] = new MinuteReport(); + } else { + this.minuteReports = MINUTE_REPORTS.toArray(new MinuteReport[MINUTE_REPORTS.size()]); + } + long ticks = 0; + for (MinuteReport mp : this.minuteReports) { + ticks += mp.ticksRecord.timed; + } + this.totalTicks = ticks; + this.totalTime = FULL_SERVER_TICK.record.totalTime; + this.entries = new TimingHistoryEntry[TimingsManager.HANDLERS.size()]; + + int i = 0; + for (TimingHandler handler : TimingsManager.HANDLERS) { + entries[i++] = new TimingHistoryEntry(handler); + } + + final Map entityCounts = MRUMapCache.of(LoadingMap.of( + new EnumMap(EntityType.class), Counter.LOADER + )); + final Map tileEntityCounts = MRUMapCache.of(LoadingMap.of( + new EnumMap(Material.class), Counter.LOADER + )); + // Information about all loaded chunks/entities + this.worlds = toObjectMapper(Bukkit.getWorlds(), new Function() { + @Override + public JSONPair apply(World world) { + return pair( + worldMap.get(world.getName()), + toArrayMapper(world.getLoadedChunks(), new Function() { + @Override + public Object apply(Chunk chunk) { + entityCounts.clear(); + tileEntityCounts.clear(); + + for (Entity entity : chunk.getEntities()) { + entityCounts.get(entity.getType()).increment(); + } + + for (BlockState tileEntity : chunk.getTileEntities()) { + tileEntityCounts.get(tileEntity.getBlock().getType()).increment(); + } + + if (tileEntityCounts.isEmpty() && entityCounts.isEmpty()) { + return null; + } + return toArray( + chunk.getX(), + chunk.getZ(), + toObjectMapper(entityCounts.entrySet(), + new Function, JSONPair>() { + @Override + public JSONPair apply(Map.Entry entry) { + entityTypeSet.add(entry.getKey()); + return pair( + String.valueOf(entry.getKey().getTypeId()), + entry.getValue().count() + ); + } + } + ), + toObjectMapper(tileEntityCounts.entrySet(), + new Function, JSONPair>() { + @Override + public JSONPair apply(Map.Entry entry) { + tileEntityTypeSet.add(entry.getKey()); + return pair( + String.valueOf(entry.getKey().getId()), + entry.getValue().count() + ); + } + } + ) + ); + } + }) + ); + } + }); + } + + public static void resetTicks(boolean fullReset) { + if (fullReset) { + // Non full is simply for 1 minute reports + timedTicks = 0; + } + lastMinuteTime = System.nanoTime(); + playerTicks = 0; + tileEntityTicks = 0; + entityTicks = 0; + activatedEntityTicks = 0; + } + + Object export() { + return createObject( + pair("s", startTime), + pair("e", endTime), + pair("tk", totalTicks), + pair("tm", totalTime), + pair("w", worlds), + pair("h", toArrayMapper(entries, new Function() { + @Override + public Object apply(TimingHistoryEntry entry) { + TimingData record = entry.data; + if (record.count == 0) { + return null; + } + return entry.export(); + } + })), + pair("mp", toArrayMapper(minuteReports, new Function() { + @Override + public Object apply(MinuteReport input) { + return input.export(); + } + })) + ); + } + + static class MinuteReport { + final long time = System.currentTimeMillis() / 1000; + + final TicksRecord ticksRecord = new TicksRecord(); + final PingRecord pingRecord = new PingRecord(); + final TimingData fst = TimingsManager.FULL_SERVER_TICK.minuteData.clone(); + final double tps = 1E9 / ( System.nanoTime() - lastMinuteTime ) * ticksRecord.timed; + final double usedMemory = TimingsManager.FULL_SERVER_TICK.avgUsedMemory; + final double freeMemory = TimingsManager.FULL_SERVER_TICK.avgFreeMemory; + final double loadAvg = ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage(); + + public List export() { + return toArray( + time, + FastMath.round(tps * 100D) / 100D, + FastMath.round(pingRecord.avg * 100D) / 100D, + fst.export(), + toArray(ticksRecord.timed, + ticksRecord.player, + ticksRecord.entity, + ticksRecord.activatedEntity, + ticksRecord.tileEntity + ), + usedMemory, + freeMemory, + loadAvg + ); + } + } + + static class TicksRecord { + final long timed; + final long player; + final long entity; + final long tileEntity; + final long activatedEntity; + + TicksRecord() { + timed = timedTicks - (TimingsManager.MINUTE_REPORTS.size() * 1200); + player = playerTicks; + entity = entityTicks; + tileEntity = tileEntityTicks; + activatedEntity = activatedEntityTicks; + } + + } + + static class PingRecord { + final double avg; + + PingRecord() { + final Collection onlinePlayers = Bukkit.getOnlinePlayers(); + int totalPing = 0; + for (Player player : onlinePlayers) { + totalPing += player.spigot().getPing(); + } + avg = onlinePlayers.isEmpty() ? 0 : totalPing / onlinePlayers.size(); + } + } + + static class Counter { + int count = 0; + @SuppressWarnings({"rawtypes", "SuppressionAnnotation"}) + static Function LOADER = new LoadingMap.Feeder() { + @Override + public Counter apply() { + return new Counter(); + } + }; + public int increment() { + return ++count; + } + public int count() { + return count; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHistoryEntry.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHistoryEntry.java new file mode 100644 index 0000000..eac4e21 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingHistoryEntry.java @@ -0,0 +1,59 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import com.google.common.base.Function; + +import java.util.List; + +import static co.aikar.util.JSONUtil.toArrayMapper; + +class TimingHistoryEntry { + final TimingData data; + final TimingData[] children; + + TimingHistoryEntry(TimingHandler handler) { + this.data = handler.record.clone(); + children = new TimingData[handler.children.size()]; + int i = 0; + for (TimingData child : handler.children.valueCollection()) { + children[i++] = child.clone(); + } + } + + List export() { + List result = data.export(); + if (children.length > 0) { + result.add( + toArrayMapper(children, new Function() { + @Override + public Object apply(TimingData child) { + return child.export(); + } + }) + ); + } + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingIdentifier.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingIdentifier.java new file mode 100644 index 0000000..623dda4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingIdentifier.java @@ -0,0 +1,102 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import com.google.common.base.Function; +import co.aikar.util.LoadingMap; +import co.aikar.util.MRUMapCache; + +import java.util.ArrayDeque; +import java.util.Map; + +/** + *

Used as a basis for fast HashMap key comparisons for the Timing Map.

+ * + * This class uses interned strings giving us the ability to do an identity check instead of equals() on the strings + */ +final class TimingIdentifier { + /** + * Holds all groups. Autoloads on request for a group by name. + */ + static final Map GROUP_MAP = MRUMapCache.of( + LoadingMap.newIdentityHashMap(new Function() { + @Override + public TimingGroup apply(String group) { + return new TimingGroup(group); + } + }, 64) + ); + static final TimingGroup DEFAULT_GROUP = getGroup("Minecraft"); + final String group; + final String name; + final TimingHandler groupHandler; + final boolean protect; + private final int hashCode; + + TimingIdentifier(String group, String name, Timing groupHandler, boolean protect) { + this.group = group != null ? group.intern() : DEFAULT_GROUP.name; + this.name = name.intern(); + this.groupHandler = groupHandler != null ? groupHandler.getTimingHandler() : null; + this.protect = protect; + this.hashCode = (31 * this.group.hashCode()) + this.name.hashCode(); + } + + static TimingGroup getGroup(String groupName) { + if (groupName == null) { + return DEFAULT_GROUP; + } + + return GROUP_MAP.get(groupName.intern()); + } + + // We are using .intern() on the strings so it is guaranteed to be an identity comparison. + @SuppressWarnings("StringEquality") + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + + TimingIdentifier that = (TimingIdentifier) o; + return group == that.group && name == that.name; + } + + @Override + public int hashCode() { + return hashCode; + } + + static class TimingGroup { + + private static int idPool = 1; + final int id = idPool++; + + final String name; + ArrayDeque handlers = new ArrayDeque(64); + + private TimingGroup(String name) { + this.name = name; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/Timings.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/Timings.java new file mode 100644 index 0000000..8d28a7d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/Timings.java @@ -0,0 +1,274 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import com.google.common.base.Preconditions; +import com.google.common.collect.EvictingQueue; +import net.jafama.FastMath; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; + +import java.util.Queue; +import java.util.logging.Level; + +@SuppressWarnings("UnusedDeclaration") +public final class Timings { + + private static final int MAX_HISTORY_FRAMES = 12; + public static final Timing NULL_HANDLER = new NullTimingHandler(); + static boolean timingsEnabled = false; + static boolean verboseEnabled = false; + private static int historyInterval = -1; + private static int historyLength = -1; + + private Timings() {} + + /** + * Returns a Timing for a plugin corresponding to a name. + * + * @param plugin Plugin to own the Timing + * @param name Name of Timing + * @return Handler + */ + public static Timing of(Plugin plugin, String name) { + Timing pluginHandler = null; + if (plugin != null) { + pluginHandler = ofSafe(plugin.getName(), "Combined Total", TimingsManager.PLUGIN_GROUP_HANDLER); + } + return of(plugin, name, pluginHandler); + } + + /** + *

Returns a handler that has a groupHandler timer handler. Parent timers should not have their + * start/stop methods called directly, as the children will call it for you.

+ * + * Parent Timers are used to group multiple subsections together and get a summary of them combined + * Parent Handler can not be changed after first call + * + * @param plugin Plugin to own the Timing + * @param name Name of Timing + * @param groupHandler Parent handler to mirror .start/stop calls to + * @return Timing Handler + */ + public static Timing of(Plugin plugin, String name, Timing groupHandler) { + Preconditions.checkNotNull(plugin, "Plugin can not be null"); + return TimingsManager.getHandler(plugin.getName(), name, groupHandler, true); + } + + /** + * Returns a Timing object after starting it, useful for Java7 try-with-resources. + * + * try (Timing ignored = Timings.ofStart(plugin, someName)) { + * // timed section + * } + * + * @param plugin Plugin to own the Timing + * @param name Name of Timing + * @return Timing Handler + */ + public static Timing ofStart(Plugin plugin, String name) { + return ofStart(plugin, name, null); + } + + /** + * Returns a Timing object after starting it, useful for Java7 try-with-resources. + * + * try (Timing ignored = Timings.ofStart(plugin, someName, groupHandler)) { + * // timed section + * } + * + * @param plugin Plugin to own the Timing + * @param name Name of Timing + * @param groupHandler Parent handler to mirror .start/stop calls to + * @return Timing Handler + */ + public static Timing ofStart(Plugin plugin, String name, Timing groupHandler) { + Timing timing = of(plugin, name, groupHandler); + timing.startTimingIfSync(); + return timing; + } + + /** + * Gets whether or not the Spigot Timings system is enabled + * + * @return Enabled or not + */ + public static boolean isTimingsEnabled() { + return timingsEnabled; + } + + /** + *

Sets whether or not the Spigot Timings system should be enabled

+ * + * Calling this will reset timing data. + * + * @param enabled Should timings be reported + */ + public static void setTimingsEnabled(boolean enabled) { + timingsEnabled = enabled; + reset(); + } + + /** + *

Sets whether or not the Timings should monitor at Verbose level.

+ * + *

When Verbose is disabled, high-frequency timings will not be available.

+ * + * @return Enabled or not + */ + public static boolean isVerboseTimingsEnabled() { + return timingsEnabled; + } + + /** + * Sets whether or not the Timings should monitor at Verbose level. + *

+ * When Verbose is disabled, high-frequency timings will not be available. + * Calling this will reset timing data. + * + * @param enabled Should high-frequency timings be reported + */ + public static void setVerboseTimingsEnabled(boolean enabled) { + verboseEnabled = enabled; + TimingsManager.needsRecheckEnabled = true; + } + + /** + *

Gets the interval between Timing History report generation.

+ * + * Defaults to 5 minutes (6000 ticks) + * + * @return Interval in ticks + */ + public static int getHistoryInterval() { + return historyInterval; + } + + /** + *

Sets the interval between Timing History report generations.

+ * + *

Defaults to 5 minutes (6000 ticks)

+ * + * This will recheck your history length, so lowering this value will lower your + * history length if you need more than 60 history windows. + * + * @param interval Interval in ticks + */ + public static void setHistoryInterval(int interval) { + historyInterval = FastMath.max(20*60, interval); + // Recheck the history length with the new Interval + if (historyLength != -1) { + setHistoryLength(historyLength); + } + } + + /** + * Gets how long in ticks Timings history is kept for the server. + * + * Defaults to 1 hour (72000 ticks) + * + * @return Duration in Ticks + */ + public static int getHistoryLength() { + return historyLength; + } + + /** + * Sets how long Timing History reports are kept for the server. + * + * Defaults to 1 hours(72000 ticks) + * + * This value is capped at a maximum of getHistoryInterval() * MAX_HISTORY_FRAMES (12) + * + * Will not reset Timing Data but may truncate old history if the new length is less than old length. + * + * @param length Duration in ticks + */ + public static void setHistoryLength(int length) { + // Cap at 12 History Frames, 1 hour at 5 minute frames. + int maxLength = historyInterval * MAX_HISTORY_FRAMES; + // For special cases of servers with special permission to bypass the max. + // This max helps keep data file sizes reasonable for processing on Aikar's Timing parser side. + // Setting this will not help you bypass the max unless Aikar has added an exception on the API side. + if (System.getProperty("timings.bypassMax") != null) { + maxLength = Integer.MAX_VALUE; + } + historyLength = FastMath.max(FastMath.min(maxLength, length), historyInterval); + Queue oldQueue = TimingsManager.HISTORY; + int frames = (getHistoryLength() / getHistoryInterval()); + if (length > maxLength) { + Bukkit.getLogger().log(Level.WARNING, "Timings Length too high. Requested " + length + ", max is " + maxLength + ". To get longer history, you must increase your interval. Set Interval to " + FastMath.ceil(length / MAX_HISTORY_FRAMES) + " to achieve this length."); + } + TimingsManager.HISTORY = EvictingQueue.create(frames); + TimingsManager.HISTORY.addAll(oldQueue); + } + + /** + * Resets all Timing Data + */ + public static void reset() { + TimingsManager.reset(); + } + + /** + * Generates a report and sends it to the specified command sender. + * + * If sender is null, ConsoleCommandSender will be used. + * @param sender The sender to send to, or null to use the ConsoleCommandSender + */ + public static void generateReport(CommandSender sender) { + if (sender == null) { + sender = Bukkit.getConsoleSender(); + } + TimingsExport.reportTimings(sender); + } + + /* + ================= + Protected API: These are for internal use only in Bukkit/CraftBukkit + These do not have isPrimaryThread() checks in the startTiming/stopTiming + ================= + */ + + static TimingHandler ofSafe(String name) { + return ofSafe(null, name, null); + } + + static Timing ofSafe(Plugin plugin, String name) { + Timing pluginHandler = null; + if (plugin != null) { + pluginHandler = ofSafe(plugin.getName(), "Combined Total", TimingsManager.PLUGIN_GROUP_HANDLER); + } + return ofSafe(plugin != null ? plugin.getName() : "Minecraft - Invalid Plugin", name, pluginHandler); + } + + static TimingHandler ofSafe(String name, Timing groupHandler) { + return ofSafe(null, name, groupHandler); + } + + static TimingHandler ofSafe(String groupName, String name, Timing groupHandler) { + return TimingsManager.getHandler(groupName, name, groupHandler, false); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsCommand.java new file mode 100644 index 0000000..3dba3aa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsCommand.java @@ -0,0 +1,110 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.Validate; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.defaults.BukkitCommand; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.List; + + +public class TimingsCommand extends BukkitCommand { + public static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("report", "reset", "on", "off", "paste", "verbon", "verboff"); + + public TimingsCommand(String name) { + super(name); + this.description = "Manages Spigot Timings data to see performance of the server."; + this.usageMessage = "/timings "; + this.setPermission("bukkit.command.timings"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) { + return true; + } + if (args.length < 1) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return true; + } + final String arg = args[0]; + if ("on".equalsIgnoreCase(arg)) { + Timings.setTimingsEnabled(true); + sender.sendMessage("Enabled Timings & Reset"); + return true; + } else if ("off".equalsIgnoreCase(arg)) { + Timings.setTimingsEnabled(false); + sender.sendMessage("Disabled Timings"); + return true; + } + + if (!Timings.isTimingsEnabled()) { + sender.sendMessage("Please enable timings by typing /timings on"); + return true; + } + if ("verbon".equalsIgnoreCase(arg)) { + Timings.setVerboseTimingsEnabled(true); + sender.sendMessage("Enabled Verbose Timings"); + return true; + } else if ("verboff".equalsIgnoreCase(arg)) { + Timings.setVerboseTimingsEnabled(false); + sender.sendMessage("Disabled Verbose Timings"); + return true; + } else if ("reset".equalsIgnoreCase(arg)) { + TimingsManager.reset(); + sender.sendMessage("Timings reset"); + } else if ("cost".equals(arg)) { + sender.sendMessage("Timings cost: " + TimingsExport.getCost()); + } else if ( + "paste".equalsIgnoreCase(arg) || + "report".equalsIgnoreCase(arg) || + "get".equalsIgnoreCase(arg) || + "merged".equalsIgnoreCase(arg) || + "separate".equalsIgnoreCase(arg) + ) { + TimingsExport.reportTimings(sender); + } else { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + } + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], TIMINGS_SUBCOMMANDS, + new ArrayList(TIMINGS_SUBCOMMANDS.size())); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsExport.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsExport.java new file mode 100644 index 0000000..fe19ea0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsExport.java @@ -0,0 +1,373 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import com.google.common.base.Function; +import com.google.common.collect.Sets; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.RemoteConsoleCommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.MemorySection; +import org.bukkit.entity.EntityType; +import org.bukkit.plugin.Plugin; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.lang.management.OperatingSystemMXBean; +import java.lang.management.RuntimeMXBean; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.zip.GZIPOutputStream; + +import static co.aikar.timings.TimingsManager.HISTORY; +import static co.aikar.util.JSONUtil.*; + +@SuppressWarnings({"rawtypes", "SuppressionAnnotation"}) +class TimingsExport extends Thread { + + private final CommandSender sender; + private final Map out; + private final TimingHistory[] history; + + TimingsExport(CommandSender sender, Map out, TimingHistory[] history) { + super("Timings paste thread"); + this.sender = sender; + this.out = out; + this.history = history; + } + + + /** + * Builds an XML report of the timings to be uploaded for parsing. + * + * @param sender Who to report to + */ + static void reportTimings(CommandSender sender) { + Map parent = createObject( + // Get some basic system details about the server + pair("version", Bukkit.getVersion()), + pair("maxplayers", Bukkit.getMaxPlayers()), + pair("start", TimingsManager.timingStart / 1000), + pair("end", System.currentTimeMillis() / 1000), + pair("sampletime", (System.currentTimeMillis() - TimingsManager.timingStart) / 1000) + ); + if (!TimingsManager.privacy) { + appendObjectData(parent, + pair("server", Bukkit.getServerName()), + pair("motd", Bukkit.getServer().getMotd()), + pair("online-mode", Bukkit.getServer().getOnlineMode()), + pair("icon", Bukkit.getServer().getServerIcon().getData()) + ); + } + + final Runtime runtime = Runtime.getRuntime(); + RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); + + parent.put("system", createObject( + pair("timingcost", getCost()), + pair("name", System.getProperty("os.name")), + pair("version", System.getProperty("os.version")), + pair("jvmversion", System.getProperty("java.version")), + pair("arch", System.getProperty("os.arch")), + pair("maxmem", runtime.maxMemory()), + pair("cpu", runtime.availableProcessors()), + pair("runtime", ManagementFactory.getRuntimeMXBean().getUptime()), + pair("flags", StringUtils.join(runtimeBean.getInputArguments(), " ")), + pair("gc", toObjectMapper(ManagementFactory.getGarbageCollectorMXBeans(), new Function() { + @Override + public JSONPair apply(GarbageCollectorMXBean input) { + return pair(input.getName(), toArray(input.getCollectionCount(), input.getCollectionTime())); + } + })) + ) + ); + + Set tileEntityTypeSet = Sets.newHashSet(); + Set entityTypeSet = Sets.newHashSet(); + + int size = HISTORY.size(); + TimingHistory[] history = new TimingHistory[size + 1]; + int i = 0; + for (TimingHistory timingHistory : HISTORY) { + tileEntityTypeSet.addAll(timingHistory.tileEntityTypeSet); + entityTypeSet.addAll(timingHistory.entityTypeSet); + history[i++] = timingHistory; + } + + history[i] = new TimingHistory(); // Current snapshot + tileEntityTypeSet.addAll(history[i].tileEntityTypeSet); + entityTypeSet.addAll(history[i].entityTypeSet); + + + Map handlers = createObject(); + for (TimingIdentifier.TimingGroup group : TimingIdentifier.GROUP_MAP.values()) { + for (TimingHandler id : group.handlers) { + if (!id.timed && !id.isSpecial()) { + continue; + } + handlers.put(id.id, toArray( + group.id, + id.name + )); + } + } + + parent.put("idmap", createObject( + pair("groups", toObjectMapper( + TimingIdentifier.GROUP_MAP.values(), new Function() { + @Override + public JSONPair apply(TimingIdentifier.TimingGroup group) { + return pair(group.id, group.name); + } + })), + pair("handlers", handlers), + pair("worlds", toObjectMapper(TimingHistory.worldMap.entrySet(), new Function, JSONPair>() { + @Override + public JSONPair apply(Map.Entry input) { + return pair(input.getValue(), input.getKey()); + } + })), + pair("tileentity", + toObjectMapper(tileEntityTypeSet, new Function() { + @Override + public JSONPair apply(Material input) { + return pair(input.getId(), input.name()); + } + })), + pair("entity", + toObjectMapper(entityTypeSet, new Function() { + @Override + public JSONPair apply(EntityType input) { + return pair(input.getTypeId(), input.name()); + } + })) + )); + + // Information about loaded plugins + + parent.put("plugins", toObjectMapper(Bukkit.getPluginManager().getPlugins(), + new Function() { + @Override + public JSONPair apply(Plugin plugin) { + return pair(plugin.getName(), createObject( + pair("version", plugin.getDescription().getVersion()), + pair("description", String.valueOf(plugin.getDescription().getDescription()).trim()), + pair("website", plugin.getDescription().getWebsite()), + pair("authors", StringUtils.join(plugin.getDescription().getAuthors(), ", ")) + )); + } + })); + + + + // Information on the users Config + + parent.put("config", createObject( + pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)), + pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)), + pair("paperspigot", mapAsJSON(Bukkit.spigot().getPaperSpigotConfig(), null)) + )); + + new TimingsExport(sender, parent, history).start(); + } + + static long getCost() { + // Benchmark the users System.nanotime() for cost basis + int passes = 100; + TimingHandler SAMPLER1 = Timings.ofSafe("Timings Sampler 1"); + TimingHandler SAMPLER2 = Timings.ofSafe("Timings Sampler 2"); + TimingHandler SAMPLER3 = Timings.ofSafe("Timings Sampler 3"); + TimingHandler SAMPLER4 = Timings.ofSafe("Timings Sampler 4"); + TimingHandler SAMPLER5 = Timings.ofSafe("Timings Sampler 5"); + TimingHandler SAMPLER6 = Timings.ofSafe("Timings Sampler 6"); + + long start = System.nanoTime(); + for (int i = 0; i < passes; i++) { + SAMPLER1.startTiming(); + SAMPLER2.startTiming(); + SAMPLER3.startTiming(); + SAMPLER3.stopTiming(); + SAMPLER4.startTiming(); + SAMPLER5.startTiming(); + SAMPLER6.startTiming(); + SAMPLER6.stopTiming(); + SAMPLER5.stopTiming(); + SAMPLER4.stopTiming(); + SAMPLER2.stopTiming(); + SAMPLER1.stopTiming(); + } + long timingsCost = (System.nanoTime() - start) / passes / 6; + SAMPLER1.reset(true); + SAMPLER2.reset(true); + SAMPLER3.reset(true); + SAMPLER4.reset(true); + SAMPLER5.reset(true); + SAMPLER6.reset(true); + return timingsCost; + } + + private static JSONObject mapAsJSON(ConfigurationSection config, String parentKey) { + + JSONObject object = new JSONObject(); + for (String key : config.getKeys(false)) { + String fullKey = (parentKey != null ? parentKey + "." + key : key); + if (fullKey.equals("database") || fullKey.equals("settings.bungeecord-addresses") || TimingsManager.hiddenConfigs.contains(fullKey)) { + continue; + } + final Object val = config.get(key); + + object.put(key, valAsJSON(val, fullKey)); + } + return object; + } + + private static Object valAsJSON(Object val, final String parentKey) { + if (!(val instanceof MemorySection)) { + if (val instanceof List) { + Iterable v = (Iterable) val; + return toArrayMapper(v, new Function() { + @Override + public Object apply(Object input) { + return valAsJSON(input, parentKey); + } + }); + } else { + return val.toString(); + } + } else { + return mapAsJSON((ConfigurationSection) val, parentKey); + } + } + + @SuppressWarnings("CallToThreadRun") + @Override + public synchronized void start() { + if (sender instanceof RemoteConsoleCommandSender) { + sender.sendMessage(ChatColor.RED + "Warning: Timings report done over RCON will cause lag spikes."); + sender.sendMessage(ChatColor.RED + "You should use " + ChatColor.YELLOW + + "/timings report" + ChatColor.RED + " in game or console."); + run(); + } else { + super.start(); + } + } + + @Override + public void run() { + sender.sendMessage(ChatColor.GREEN + "Preparing Timings Report..."); + + + out.put("data", toArrayMapper(history, new Function() { + @Override + public Object apply(TimingHistory input) { + return input.export(); + } + })); + + + String response = null; + try { + HttpURLConnection con = (HttpURLConnection) new URL("http://timings.aikar.co/post").openConnection(); + con.setDoOutput(true); + con.setRequestProperty("User-Agent", "Spigot/" + Bukkit.getServerName() + "/" + InetAddress.getLocalHost().getHostName()); + con.setRequestMethod("POST"); + con.setInstanceFollowRedirects(false); + + OutputStream request = new GZIPOutputStream(con.getOutputStream()) {{ + this.def.setLevel(7); + }}; + + request.write(JSONValue.toJSONString(out).getBytes("UTF-8")); + request.close(); + + response = getResponse(con); + + if (con.getResponseCode() != 302) { + sender.sendMessage( + ChatColor.RED + "Upload Error: " + con.getResponseCode() + ": " + con.getResponseMessage()); + sender.sendMessage(ChatColor.RED + "Check your logs for more information"); + if (response != null) { + Bukkit.getLogger().log(Level.SEVERE, response); + } + return; + } + + String location = con.getHeaderField("Location"); + sender.sendMessage(ChatColor.GREEN + "View Timings Report: " + location); + if (!(sender instanceof ConsoleCommandSender)) { + Bukkit.getLogger().log(Level.INFO, "View Timings Report: " + location); + } + + if (response != null && !response.isEmpty()) { + Bukkit.getLogger().log(Level.INFO, "Timing Response: " + response); + } + } catch (IOException ex) { + sender.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information"); + if (response != null) { + Bukkit.getLogger().log(Level.SEVERE, response); + } + Bukkit.getLogger().log(Level.SEVERE, "Could not paste timings", ex); + } + } + + private String getResponse(HttpURLConnection con) throws IOException { + InputStream is = null; + try { + is = con.getInputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + byte[] b = new byte[1024]; + int bytesRead; + while ((bytesRead = is.read(b)) != -1) { + bos.write(b, 0, bytesRead); + } + return bos.toString(); + + } catch (IOException ex) { + sender.sendMessage(ChatColor.RED + "Error uploading timings, check your logs for more information"); + Bukkit.getLogger().log(Level.WARNING, con.getResponseMessage(), ex); + return null; + } finally { + if (is != null) { + is.close(); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsManager.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsManager.java new file mode 100644 index 0000000..67c39df --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/TimingsManager.java @@ -0,0 +1,194 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import com.google.common.base.Function; +import com.google.common.collect.EvictingQueue; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.Command; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.PluginClassLoader; +import co.aikar.util.LoadingMap; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +public final class TimingsManager { + static final Map TIMING_MAP = + Collections.synchronizedMap(LoadingMap.newHashMap( + new Function() { + @Override + public TimingHandler apply(TimingIdentifier id) { + return (id.protect ? + new UnsafeTimingHandler(id) : + new TimingHandler(id) + ); + } + }, + 256, .5F + )); + public static final FullServerTickHandler FULL_SERVER_TICK = new FullServerTickHandler(); + public static final TimingHandler TIMINGS_TICK = Timings.ofSafe("Timings Tick", FULL_SERVER_TICK); + public static final Timing PLUGIN_GROUP_HANDLER = Timings.ofSafe("Plugins"); + public static List hiddenConfigs = new ArrayList(); + public static boolean privacy = false; + + static final Collection HANDLERS = new ArrayDeque(); + static final ArrayDeque MINUTE_REPORTS = new ArrayDeque(); + + static EvictingQueue HISTORY = EvictingQueue.create(12); + static TimingHandler CURRENT; + static long timingStart = 0; + static long historyStart = 0; + static boolean needsFullReset = false; + static boolean needsRecheckEnabled = false; + + private TimingsManager() {} + + /** + * Resets all timing data on the next tick + */ + static void reset() { + needsFullReset = true; + } + + /** + * Ticked every tick by CraftBukkit to count the number of times a timer + * caused TPS loss. + */ + static void tick() { + if (Timings.timingsEnabled) { + boolean violated = FULL_SERVER_TICK.isViolated(); + + for (TimingHandler handler : HANDLERS) { + if (handler.isSpecial()) { + // We manually call this + continue; + } + handler.processTick(violated); + } + + TimingHistory.playerTicks += Bukkit.getOnlinePlayers().size(); + TimingHistory.timedTicks++; + // Generate TPS/Ping/Tick reports every minute + } + } + static void stopServer() { + Timings.timingsEnabled = false; + recheckEnabled(); + } + static void recheckEnabled() { + synchronized (TIMING_MAP) { + for (TimingHandler timings : TIMING_MAP.values()) { + timings.checkEnabled(); + } + } + needsRecheckEnabled = false; + } + static void resetTimings() { + if (needsFullReset) { + // Full resets need to re-check every handlers enabled state + // Timing map can be modified from async so we must sync on it. + synchronized (TIMING_MAP) { + for (TimingHandler timings : TIMING_MAP.values()) { + timings.reset(true); + } + } + Bukkit.getLogger().log(Level.INFO, "Timings Reset"); + HISTORY.clear(); + needsFullReset = false; + needsRecheckEnabled = false; + timingStart = System.currentTimeMillis(); + } else { + // Soft resets only need to act on timings that have done something + // Handlers can only be modified on main thread. + for (TimingHandler timings : HANDLERS) { + timings.reset(false); + } + } + + HANDLERS.clear(); + MINUTE_REPORTS.clear(); + + TimingHistory.resetTicks(true); + historyStart = System.currentTimeMillis(); + } + + static TimingHandler getHandler(String group, String name, Timing parent, boolean protect) { + return TIMING_MAP.get(new TimingIdentifier(group, name, parent, protect)); + } + + + /** + *

Due to access restrictions, we need a helper method to get a Command TimingHandler with String group

+ * + * Plugins should never call this + * + * @param pluginName Plugin this command is associated with + * @param command Command to get timings for + * @return TimingHandler + */ + public static Timing getCommandTiming(String pluginName, Command command) { + Plugin plugin = null; + final Server server = Bukkit.getServer(); + if (!("minecraft".equals(pluginName) || "bukkit".equals(pluginName) || "Spigot".equals(pluginName) || + server == null)) { + plugin = server.getPluginManager().getPlugin(pluginName); + if (plugin == null) { + // Plugin is passing custom fallback prefix, try to look up by class loader + plugin = getPluginByClassloader(command.getClass()); + } + } + if (plugin == null) { + return Timings.ofSafe("Command: " + pluginName + ":" + command.getTimingName()); + } + + return Timings.ofSafe(plugin, "Command: " + pluginName + ":" + command.getTimingName()); + } + + /** + * Looks up the class loader for the specified class, and if it is a PluginClassLoader, return the + * Plugin that created this class. + * + * @param clazz Class to check + * @return Plugin if created by a plugin + */ + public static Plugin getPluginByClassloader(Class clazz) { + if (clazz == null) { + return null; + } + final ClassLoader classLoader = clazz.getClassLoader(); + if (classLoader instanceof PluginClassLoader) { + PluginClassLoader pluginClassLoader = (PluginClassLoader) classLoader; + return pluginClassLoader.getPlugin(); + } + return null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/UnsafeTimingHandler.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/UnsafeTimingHandler.java new file mode 100644 index 0000000..e3b0ed8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/timings/UnsafeTimingHandler.java @@ -0,0 +1,51 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.timings; + +import org.bukkit.Bukkit; + +class UnsafeTimingHandler extends TimingHandler { + + UnsafeTimingHandler(TimingIdentifier id) { + super(id); + } + + private static void checkThread() { + if (!Bukkit.isPrimaryThread()) { + throw new IllegalStateException("Calling Timings from Async Operation"); + } + } + + @Override + public void startTiming() { + checkThread(); + super.startTiming(); + } + + @Override + public void stopTiming() { + checkThread(); + super.stopTiming(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/JSONUtil.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/JSONUtil.java new file mode 100644 index 0000000..5fdf7c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/JSONUtil.java @@ -0,0 +1,123 @@ +package co.aikar.util; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Provides Utility methods that assist with generating JSON Objects + */ +@SuppressWarnings({"rawtypes", "SuppressionAnnotation"}) +public final class JSONUtil { + private JSONUtil() {} + + /** + * Creates a key/value "JSONPair" object + * @param key + * @param obj + * @return + */ + public static JSONPair pair(String key, Object obj) { + return new JSONPair(key, obj); + } + + public static JSONPair pair(long key, Object obj) { + return new JSONPair(String.valueOf(key), obj); + } + + /** + * Creates a new JSON object from multiple JsonPair key/value pairs + * @param data + * @return + */ + public static Map createObject(JSONPair... data) { + return appendObjectData(new LinkedHashMap(), data); + } + + /** + * This appends multiple key/value Obj pairs into a JSON Object + * @param parent + * @param data + * @return + */ + public static Map appendObjectData(Map parent, JSONPair... data) { + for (JSONPair JSONPair : data) { + parent.put(JSONPair.key, JSONPair.val); + } + return parent; + } + + /** + * This builds a JSON array from a set of data + * @param data + * @return + */ + public static List toArray(Object... data) { + return Lists.newArrayList(data); + } + + /** + * These help build a single JSON array using a mapper function + * @param collection + * @param mapper + * @param + * @return + */ + public static List toArrayMapper(E[] collection, Function mapper) { + return toArrayMapper(Lists.newArrayList(collection), mapper); + } + + public static List toArrayMapper(Iterable collection, Function mapper) { + List array = Lists.newArrayList(); + for (E e : collection) { + Object object = mapper.apply(e); + if (object != null) { + array.add(object); + } + } + return array; + } + + /** + * These help build a single JSON Object from a collection, using a mapper function + * @param collection + * @param mapper + * @param + * @return + */ + public static Map toObjectMapper(E[] collection, Function mapper) { + return toObjectMapper(Lists.newArrayList(collection), mapper); + } + + public static Map toObjectMapper(Iterable collection, Function mapper) { + Map object = Maps.newLinkedHashMap(); + for (E e : collection) { + JSONPair JSONPair = mapper.apply(e); + if (JSONPair != null) { + object.put(JSONPair.key, JSONPair.val); + } + } + return object; + } + + /** + * Simply stores a key and a value, used internally by many methods below. + */ + @SuppressWarnings("PublicInnerClass") + public static class JSONPair { + final String key; + final Object val; + + JSONPair(String key, Object val) { + this.key = key; + this.val = val; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/LoadingIntMap.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/LoadingIntMap.java new file mode 100644 index 0000000..8d0f269 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/LoadingIntMap.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015. Starlis LLC / dba Empire Minecraft + * + * This source code is proprietary software and must not be redistributed without Starlis LLC's approval + * + */ +package co.aikar.util; + + +import com.google.common.base.Function; +import gnu.trove.map.hash.TIntObjectHashMap; + +/** + * Allows you to pass a Loader function that when a key is accessed that doesn't exist, + * automatically loads the entry into the map by calling the loader Function. + * + * .get() Will only return null if the Loader can return null. + * + * You may pass any backing Map to use. + * + * This class is not thread safe and should be wrapped with Collections.synchronizedMap on the OUTSIDE of the LoadingMap if needed. + * + * Do not wrap the backing map with Collections.synchronizedMap. + * + * @param Value + */ +public class LoadingIntMap extends TIntObjectHashMap { + private final Function loader; + + /** + * Initializes an auto loading map using specified loader and backing map + * @param loader The loader + */ + public LoadingIntMap(Function loader) { + this.loader = loader; + } + + + @Override + public V get(int key) { + V res = super.get(key); + if (res == null) { + res = loader.apply(key); + if (res != null) { + put(key, res); + } + } + return res; + } + + /** + * Due to java stuff, you will need to cast it to (Function) for some cases + * @param + */ + public abstract static class Feeder implements Function { + @Override + public T apply(Object input) { + return apply(); + } + + public abstract T apply(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/LoadingMap.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/LoadingMap.java new file mode 100644 index 0000000..a9f2919 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/LoadingMap.java @@ -0,0 +1,332 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.util; + + +import com.google.common.base.Function; +import org.bukkit.Material; +import co.aikar.timings.TimingHistory; +import org.w3c.dom.css.Counter; + +import java.lang.reflect.Constructor; +import java.util.AbstractMap; +import java.util.Collection; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.Set; + +/** + * Allows you to pass a Loader function that when a key is accessed that doesn't exists, + * automatically loads the entry into the map by calling the loader Function. + * + * .get() Will only return null if the Loader can return null. + * + * You may pass any backing Map to use. + * + * This class is not thread safe and should be wrapped with Collections.synchronizedMap on the OUTSIDE of the LoadingMap if needed. + * + * Do not wrap the backing map with Collections.synchronizedMap. + * + * @param Key + * @param Value + */ +public class LoadingMap extends AbstractMap { + private final Map backingMap; + private final Function loader; + + /** + * Initializes an auto loading map using specified loader and backing map + * @param backingMap + * @param loader + */ + public LoadingMap(Map backingMap, Function loader) { + this.backingMap = backingMap; + this.loader = loader; + } + + /** + * Creates a new LoadingMap with the specified map and loader + * @param backingMap + * @param loader + * @param + * @param + * @return + */ + public static Map of(Map backingMap, Function loader) { + return new LoadingMap(backingMap, loader); + } + + /** + * Creates a LoadingMap with an auto instantiating loader. + * + * Will auto construct class of of Value when not found + * + * Since this uses Reflection, It is more effecient to define your own static loader + * than using this helper, but if performance is not critical, this is easier. + * + * @param backingMap Actual map being used. + * @param keyClass Class used for the K generic + * @param valueClass Class used for the V generic + * @param Key Type of the Map + * @param Value Type of the Map + * @return Map that auto instantiates on .get() + */ + public static Map newAutoMap(Map backingMap, final Class keyClass, + final Class valueClass) { + return new LoadingMap(backingMap, new AutoInstantiatingLoader(keyClass, valueClass)); + } + /** + * Creates a LoadingMap with an auto instantiating loader. + * + * Will auto construct class of of Value when not found + * + * Since this uses Reflection, It is more effecient to define your own static loader + * than using this helper, but if performance is not critical, this is easier. + * + * @param backingMap Actual map being used. + * @param valueClass Class used for the V generic + * @param Key Type of the Map + * @param Value Type of the Map + * @return Map that auto instantiates on .get() + */ + public static Map newAutoMap(Map backingMap, + final Class valueClass) { + return newAutoMap(backingMap, null, valueClass); + } + + /** + * @see #newAutoMap + * + * new Auto initializing map using a HashMap. + * @param keyClass + * @param valueClass + * @param + * @param + * @return + */ + public static Map newHashAutoMap(final Class keyClass, final Class valueClass) { + return newAutoMap(new HashMap(), keyClass, valueClass); + } + + /** + * @see #newAutoMap + * + * new Auto initializing map using a HashMap. + * @param valueClass + * @param + * @param + * @return + */ + public static Map newHashAutoMap(final Class valueClass) { + return newHashAutoMap(null, valueClass); + } + + /** + * @see #newAutoMap + * + * new Auto initializing map using a HashMap. + * + * @param keyClass + * @param valueClass + * @param initialCapacity + * @param loadFactor + * @param + * @param + * @return + */ + public static Map newHashAutoMap(final Class keyClass, final Class valueClass, int initialCapacity, float loadFactor) { + return newAutoMap(new HashMap(initialCapacity, loadFactor), keyClass, valueClass); + } + + /** + * @see #newAutoMap + * + * new Auto initializing map using a HashMap. + * + * @param valueClass + * @param initialCapacity + * @param loadFactor + * @param + * @param + * @return + */ + public static Map newHashAutoMap(final Class valueClass, int initialCapacity, float loadFactor) { + return newHashAutoMap(null, valueClass, initialCapacity, loadFactor); + } + + /** + * Initializes an auto loading map using a HashMap + * @param loader + * @param + * @param + * @return + */ + public static Map newHashMap(Function loader) { + return new LoadingMap(new HashMap(), loader); + } + + /** + * Initializes an auto loading map using a HashMap + * @param loader + * @param initialCapacity + * @param loadFactor + * @param + * @param + * @return + */ + public static Map newHashMap(Function loader, int initialCapacity, float loadFactor) { + return new LoadingMap(new HashMap(initialCapacity, loadFactor), loader); + } + + /** + * Initializes an auto loading map using an Identity HashMap + * @param loader + * @param + * @param + * @return + */ + public static Map newIdentityHashMap(Function loader) { + return new LoadingMap(new IdentityHashMap(), loader); + } + + /** + * Initializes an auto loading map using an Identity HashMap + * @param loader + * @param initialCapacity + * @param + * @param + * @return + */ + public static Map newIdentityHashMap(Function loader, int initialCapacity) { + return new LoadingMap(new IdentityHashMap(initialCapacity), loader); + } + + @Override + public int size() {return backingMap.size();} + + @Override + public boolean isEmpty() {return backingMap.isEmpty();} + + @Override + public boolean containsKey(Object key) {return backingMap.containsKey(key);} + + @Override + public boolean containsValue(Object value) {return backingMap.containsValue(value);} + + @Override + public V get(Object key) { + V res = backingMap.get(key); + if (res == null && key != null) { + res = loader.apply((K) key); + if (res != null) { + backingMap.put((K) key, res); + } + } + return res; + } + + public V put(K key, V value) {return backingMap.put(key, value);} + + @Override + public V remove(Object key) {return backingMap.remove(key);} + + public void putAll(Map m) {backingMap.putAll(m);} + + @Override + public void clear() {backingMap.clear();} + + @Override + public Set keySet() {return backingMap.keySet();} + + @Override + public Collection values() {return backingMap.values();} + + @Override + public boolean equals(Object o) {return backingMap.equals(o);} + + @Override + public int hashCode() {return backingMap.hashCode();} + + @Override + public Set> entrySet() { + return backingMap.entrySet(); + } + + public LoadingMap clone() { + return new LoadingMap(backingMap, loader); + } + + private static class AutoInstantiatingLoader implements Function { + final Constructor constructor; + private final Class valueClass; + + AutoInstantiatingLoader(Class keyClass, Class valueClass) { + try { + this.valueClass = valueClass; + if (keyClass != null) { + constructor = valueClass.getConstructor(keyClass); + } else { + constructor = null; + } + } catch (NoSuchMethodException e) { + throw new IllegalStateException( + valueClass.getName() + " does not have a constructor for " + (keyClass != null ? keyClass.getName() : null)); + } + } + + @Override + public V apply(K input) { + try { + return (constructor != null ? constructor.newInstance(input) : valueClass.newInstance()); + } catch (Exception e) { + throw new ExceptionInInitializerError(e); + } + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object object) { + return false; + } + } + + /** + * Due to java stuff, you will need to cast it to (Function) for some cases + * @param + */ + public abstract static class Feeder implements Function { + @Override + public T apply(Object input) { + return apply(); + } + + public abstract T apply(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/MRUMapCache.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/MRUMapCache.java new file mode 100644 index 0000000..3a288d2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/co/aikar/util/MRUMapCache.java @@ -0,0 +1,100 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package co.aikar.util; + +import java.util.AbstractMap; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +/** + * Implements a Most Recently Used cache in front of a backing map, to quickly access the last accessed result. + * @param + * @param + */ +public class MRUMapCache extends AbstractMap { + final Map backingMap; + Object cacheKey; + V cacheValue; + public MRUMapCache(final Map backingMap) { + this.backingMap = backingMap; + } + + public int size() {return backingMap.size();} + + public boolean isEmpty() {return backingMap.isEmpty();} + + public boolean containsKey(Object key) { + return key != null && key.equals(cacheKey) || backingMap.containsKey(key); + } + + public boolean containsValue(Object value) { + return value != null && value == cacheValue || backingMap.containsValue(value); + } + + public V get(Object key) { + if (cacheKey != null && cacheKey.equals(key)) { + return cacheValue; + } + cacheKey = key; + return cacheValue = backingMap.get(key); + } + + public V put(K key, V value) { + cacheKey = key; + return cacheValue = backingMap.put(key, value); + } + + public V remove(Object key) { + if (key != null && key.equals(cacheKey)) { + cacheKey = null; + } + return backingMap.remove(key); + } + + public void putAll(Map m) {backingMap.putAll(m);} + + public void clear() { + cacheKey = null; + cacheValue = null; + backingMap.clear(); + } + + public Set keySet() {return backingMap.keySet();} + + public Collection values() {return backingMap.values();} + + public Set> entrySet() {return backingMap.entrySet();} + + /** + * Wraps the specified map with a most recently used cache + * @param map + * @param + * @param + * @return + */ + public static Map of(Map map) { + return new MRUMapCache(map); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/MythicConfiguration.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/MythicConfiguration.java new file mode 100644 index 0000000..d2d020a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/MythicConfiguration.java @@ -0,0 +1,220 @@ +package me.levansj01.mythicspigot; + +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.logging.Level; + +public class MythicConfiguration { + private static final YamlConfiguration config = new YamlConfiguration(); + private static final File file = new File("mythic.yml"); + private static boolean error; + + public static void load() { + error = false; + // Load configuration + if(file.exists()) { + try { + config.load(file); + } catch (IOException|InvalidConfigurationException e) { + MythicCore.getLogger().log(Level.SEVERE, "Failed to load configuration, ", e); + error = true; + } + } + + config.options().copyHeader(true).copyDefaults(true) + .header("---------------------------\n" + + "MythicSpigot configuration" + + "\n---------------------------"); + + load("", MythicConfiguration.class.getDeclaredClasses()); + try { + config.save(file); + } catch (IOException e) { + MythicCore.getLogger().log(Level.SEVERE, "Failed to load configuration, ", e); + error = true; + } + + if(!error) MythicCore.getLogger().info("Successfully loaded configuration"); + } + + public static void load(String prefix, Class... search) { + for(Class clazz: search) { + String clazzName = alt(clazz.getSimpleName()), clazzPath = prefix + "." + clazzName; + for(Field field: clazz.getDeclaredFields()) { + if(!Modifier.isStatic(field.getModifiers())) continue; + + Object value; + try { + value = field.get(null); + } catch (IllegalAccessException e) { + MythicCore.getLogger().log(Level.SEVERE, "Could not load field " + field.getName() + ", ", e); + error = true; + continue; + } + String fieldPath = clazzPath + "." + field.getName(); + config.addDefault(fieldPath, value); + value = config.get(fieldPath, value); + try { + field.set(null, value); + } catch (IllegalAccessException e) { + MythicCore.getLogger().log(Level.SEVERE, "Could not save field " + field.getName() + ", ", e); + error = true; + continue; + } + } + load(clazzPath, clazz.getDeclaredClasses()); + } + } + + public static String alt(String string) { + return Character.toLowerCase(string.charAt(0)) + string.substring(1); + } + + + public static class Options { + public static class Server { + public static boolean + preventCrash = true, + asyncCatcher = false, + snooper, + optimalPacketTick = true, + entityCollisions = false, + mobAi = false; + + public static int maxSleepMillis = 60; + + public static class Exploits { + public static boolean bookPages; + } + + public static class Players { + public static boolean + save = true, + sendLatency; + } + + public static int loginsPerTick = 1; + } + + public static class World { + public static boolean + weather, + checkDifficulty, + time = true, + daylightCycle, + tickPending = true, + tickBlocks = true, + antiXray, + tickVillage, + tickPortals = true, + blockActions = true, + tickTiles = true, + tickPendingTiles = true, + checkEntityCubes, + tickChunkBlocks = true; + + public static int maxRandomTick = 1, + nearbyChunkRadius = 1; + + public static class Mobs { + public static boolean spawn; + } + + public static class Chunks { + public static boolean unload = true, + save = true; + } + + public static class Physics { + public static boolean enabled = true; + + public static class Limits { + public static boolean enabled = true; + + public static int + ticks = 400, + amount = 100000; + } + } + } + + public static class Tracking { + public static int updateTicks = 2, + minimumDistance = 4; + + public static class Hide { + public static boolean projectiles = true, + items = true; + } + } + + public static class Potions { + public static int minimumTicks = 4; + } + + public static class Enderpearls { + public static boolean pearlPassFineCancel = false, + pearlPassFine = false, + pearlParticles = false, + pearlAntiGlitch = true, + pearlSuffocationPrevention = true; + + public static int pearlMaxPass = 1; + + public static class Taliban { + public static boolean pearlThroughCobweb = false, + pearlThroughFenceGates = false, + pearlThroughString = false, + pearlThroughSlab = false, + pearlThroughStairs = false, + pearlCobbleWall = false, + pearlCriticalBlock = false, + damagePearls = true; + } + } + + + public static class Combat { + public static class DamageTicks { + + public static boolean durabilityFix = true; + + public static class ProjectilesBypass { + public static boolean enabled = true, + velocity = true, + limitDamage = true, + resetTicks = false; + } + } + +// public static class Potions { +// public static float +// potDistance = 0.5F, +// potSpeed = 1.0F, +// potOffY = -20.0F; +// } + + } + + public static class PacketProcessing { + public static class Flying { + public static boolean moveEvent, + reduceMoveEvent; + } + + public static class ArmAnimation { + public static int ticksPerEvent = 5, + ticksPerAnimation = 1; + } + } + + public static class AntiPhase { + public static boolean enabled = true; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/MythicCore.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/MythicCore.java new file mode 100644 index 0000000..9bc5182 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/MythicCore.java @@ -0,0 +1,48 @@ +package me.levansj01.mythicspigot; + +import lombok.Getter; +import me.levansj01.mythicspigot.command.MythicCommand; +import me.levansj01.mythicspigot.command.impl.KB; +import me.levansj01.mythicspigot.command.impl.ReloadSpigot; +import me.levansj01.mythicspigot.command.impl.TPS; +import me.levansj01.mythicspigot.command.impl.Version; +import me.levansj01.mythicspigot.kb.KBProfileManager; +import me.levansj01.mythicspigot.logger.MythicLogger; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.SimpleCommandMap; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@Getter +public class MythicCore { + @Getter + private static final MythicLogger logger = new MythicLogger(); + @Getter + private static final MythicCore core = new MythicCore(); + + private final KBProfileManager kBManager = new KBProfileManager(); + private final MythicCommand[] commands = { + new ReloadSpigot(), + new Version(), + new TPS(), + new KB() + }; + + public void load() { + MythicConfiguration.load(); + kBManager.load(); + registerCommands(); + } + + private void registerCommands() { + SimpleCommandMap commandMap = (SimpleCommandMap) Bukkit.getCommandMap(); + Map knownCommands = commandMap.getKnownCommands(); + for(MythicCommand command: commands) { + knownCommands.put(command.getName(), command); + for(String alias: command.getAliases()) knownCommands.put(alias, command); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/CommandInformation.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/CommandInformation.java new file mode 100644 index 0000000..2163862 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/CommandInformation.java @@ -0,0 +1,13 @@ +package me.levansj01.mythicspigot.command; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(value = RetentionPolicy.RUNTIME) +public @interface CommandInformation { + String name(); + String desc() default ""; + String[] aliases() default {}; + boolean perm() default true; + String usage() default ""; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/MythicBaseCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/MythicBaseCommand.java new file mode 100644 index 0000000..4fbd0ba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/MythicBaseCommand.java @@ -0,0 +1,119 @@ +package me.levansj01.mythicspigot.command; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import lombok.Getter; +import net.md_5.bungee.api.ChatColor; +import org.apache.commons.lang.WordUtils; +import org.bukkit.command.CommandSender; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class MythicBaseCommand extends MythicCommand { + private final List argsList = Lists.newArrayList(); + private final Map argMap = Maps.newHashMap(); + private final HelpArg helpArg = new HelpArg(); + + public MythicBaseCommand() { + super(); + + Class clazz = getClass(); + for(Class innerClass: clazz.getDeclaredClasses()) { + if(CommandArg.class.isAssignableFrom(innerClass)) { + CommandArg arg; + try { + Constructor constructor = innerClass.asSubclass(CommandArg.class).getDeclaredConstructor(getClass()); + constructor.setAccessible(true); + arg = constructor.newInstance(this); + } catch (InstantiationException|IllegalAccessException|NoSuchMethodException|InvocationTargetException e) { + e.printStackTrace(); + continue; + } + + register(arg); + } + } + register(helpArg); + Collections.reverse(argsList); + } + + private void register(CommandArg arg) { + argsList.add(arg); + argMap.put(arg.getName().toLowerCase(), arg); + for(String alias: arg.getAliases()) argMap.put(alias.toLowerCase(), arg); + } + + public void execute(CommandSender sender, String[] args) { + CommandArg arg; + if(args.length == 0 || (arg = argMap.get(args[0].toLowerCase())) == null) { + arg = helpArg; + } + + if(arg.hasAccess(sender)) { + String[] newArgs; + if(args.length > 1) { + newArgs = new String[args.length - 1]; + System.arraycopy(args, 1, newArgs, 0, newArgs.length); + } else newArgs = new String[0]; + + arg.execute(sender, newArgs); + } else sender.sendMessage(getPermissionMessage()); + } + + public String getPermissionMessage() { + String msg = super.getPermissionMessage(); + if(msg == null) msg = 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 msg; + } + + @CommandInformation( + name = "help", + aliases = "?", + desc = "Displays help information", + perm = false + ) + public class HelpArg extends CommandArg { + public void execute(CommandSender sender, String[] args) { + String name = MythicBaseCommand.this.getName(); + sender.sendMessage(ChatColor.AQUA + WordUtils.capitalize(name) + " Help: "); + argsList.stream().filter(arg -> arg.hasAccess(sender)) + .forEach(arg -> sender.sendMessage(ChatColor.AQUA + "/" + name + " " + arg.getName() + " " + arg.getUsage() + ChatColor.GRAY + " " + arg.getDesc())); + } + } + + @Getter + public abstract class CommandArg { + private final String name; + private final String desc; + private final String usage; + private final String perm; + private final String[] aliases; + + public CommandArg() { + Class clazz = getClass(); + if(clazz.isAnnotationPresent(CommandInformation.class)) { + CommandInformation info = clazz.getAnnotation(CommandInformation.class); + + name = info.name(); + desc = info.desc(); + usage = info.usage(); + aliases = info.aliases(); + perm = info.perm() ? MythicBaseCommand.this.getPermission() + ".arg." + name : null; + } else throw new IllegalArgumentException(CommandInformation.class.getName() + " not present in " + clazz.getName()); + } + + public boolean hasAccess(CommandSender sender) { + return perm == null || sender.hasPermission(perm); + } + + public void sendInvalidUsage(CommandSender sender) { + sender.sendMessage(ChatColor.RED + "Invalid usage, /" + MythicBaseCommand.this.getName() + " " + name + " " + usage); + } + + public abstract void execute(CommandSender sender, String[] args); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/MythicCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/MythicCommand.java new file mode 100644 index 0000000..76a5845 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/MythicCommand.java @@ -0,0 +1,35 @@ +package me.levansj01.mythicspigot.command; + +import lombok.Getter; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public abstract class MythicCommand extends Command { + @Getter private final List aliases; + + public MythicCommand() { + super(""); + Class clazz = getClass(); + if(clazz.isAnnotationPresent(CommandInformation.class)) { + CommandInformation info = clazz.getAnnotation(CommandInformation.class); + + setName(info.name()); + setDescription(info.desc()); + setUsage("/" + info.name() + " " + info.usage()); + setAliases(aliases = new ArrayList<>(Arrays.asList(info.aliases()))); + setPermission(info.perm() ? "mythicspigot.command." + info.name() : null); + + } else throw new IllegalArgumentException(CommandInformation.class.getName() + " not present in " + clazz.getName()); + } + + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + if(testPermission(sender)) execute(sender, args); + return true; + } + + public abstract void execute(CommandSender sender, String[] args); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/KB.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/KB.java new file mode 100644 index 0000000..674a17a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/KB.java @@ -0,0 +1,246 @@ +package me.levansj01.mythicspigot.command.impl; + +import me.levansj01.mythicspigot.MythicCore; +import me.levansj01.mythicspigot.command.CommandInformation; +import me.levansj01.mythicspigot.command.MythicBaseCommand; +import me.levansj01.mythicspigot.kb.KBOption; +import me.levansj01.mythicspigot.kb.KBProfile; +import me.levansj01.mythicspigot.kb.KBProfileManager; +import me.levansj01.mythicspigot.kb.KBSet; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.command.CommandSender; + +@CommandInformation( + name = "kb", + aliases = { "knockback", "kbmod", "knockbackmod", "kbprofile", "knockbackprofile", "kbp" }, + desc = "Manages knockback profiles" +) +public class KB extends MythicBaseCommand { + private KBProfileManager getKBManager() { + return MythicCore.getCore().getKBManager(); + } + + private BaseComponent[] getInfo(String name, KBProfile kb) { + KBSet player = kb.getPlayer(), rod = kb.getRod(), arrow = kb.getProjectile(); + return new ComponentBuilder(name) + .event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText( + String.format("%sDefault\n" + + "%sFriction:%s H=%s V=%s %sBase:%s H=%s, V=%s\n" + + "%sRods\n" + + "%sFriction:%s H=%s V=%s %sBase:%s H=%s, V=%s\n" + + "%sOther Projectiles\n" + + "%sFriction:%s H=%s V=%s %sBase:%s H=%s, V=%s\n\n" + + "%sOther Settings\n" + + "%sCrit:%s H=%s, V=%s\n" + + "%sBack Stab:%s H=%s, V=%s\n" + + "%sWTap:%s H=%s, V=%s\n" + + "%sSprint Slowdown:%s H=%s\n" + + "%sMax:%s V=%s\n" + + "%sHit Delay:%s V=%s\n" + + "%sDefault:%s %s", + ChatColor.AQUA, + ChatColor.DARK_AQUA, ChatColor.GRAY, player.getFriction().getHorizontal(), player.getFriction().getVertical(), + ChatColor.DARK_AQUA, ChatColor.GRAY, player.getBase().getHorizontal(), player.getBase().getVertical(), + ChatColor.AQUA, + ChatColor.DARK_AQUA, ChatColor.GRAY, rod.getFriction().getHorizontal(), rod.getFriction().getVertical(), + ChatColor.DARK_AQUA, ChatColor.GRAY, rod.getBase().getHorizontal(), rod.getBase().getVertical(), + ChatColor.AQUA, + ChatColor.DARK_AQUA, ChatColor.GRAY, arrow.getFriction().getHorizontal(), arrow.getFriction().getVertical(), + ChatColor.DARK_AQUA, ChatColor.GRAY, arrow.getBase().getHorizontal(), arrow.getBase().getVertical(), + ChatColor.AQUA, + ChatColor.DARK_AQUA, ChatColor.GRAY, kb.getCrit().getHorizontal(), kb.getCrit().getVertical(), + ChatColor.DARK_AQUA, ChatColor.GRAY, kb.getBackStab().getHorizontal(), kb.getBackStab().getVertical(), + ChatColor.DARK_AQUA, ChatColor.GRAY, kb.getWTap().getHorizontal(), kb.getWTap().getVertical(), + ChatColor.DARK_AQUA, ChatColor.GRAY, kb.getSlow(), + ChatColor.DARK_AQUA, ChatColor.GRAY, kb.getMaxY(), + ChatColor.DARK_AQUA, ChatColor.GRAY, kb.getHitDelay(), + ChatColor.DARK_AQUA, ChatColor.GRAY, kb.isDefaultProfile() + ) + ))) + .create(); + } + + @CommandInformation( + name = "list", + aliases = { "ls", "show" }, + desc = "Lists all KB profiles", + perm = false + ) + class List extends CommandArg { + public void execute(CommandSender sender, String[] args) { + sender.sendMessage(ChatColor.AQUA + "KB Profiles: " + ChatColor.GRAY + "(Hover!!!)"); + getKBManager().getProfileMap().forEach((name, kb) -> sender.sendMessage(getInfo("- " + name, kb))); + } + } + + @CommandInformation( + name = "set", + desc = "Sets a KB profile", + usage = "(name) (friction[H,V]) (base[H,V]) (wTap[H,V]) (backstab[H,V]) (crit[H,V]) (slow) (maxY)", + aliases = "create" + ) + class Set extends CommandArg { + public void execute(CommandSender sender, String[] args) { + if(args.length != 7) { + sendInvalidUsage(sender); + return; + } + + KBProfile kb = getKBManager().getProfileMap().computeIfAbsent(args[0], name -> getKBManager().getVanillaProfile().copy()); + KBSet player = kb.getPlayer(); + try { + player.setFriction(parse(args[1])); + player.setBase(parse(args[2])); + kb.setWTap(parse(args[3])); + kb.setBackStab(parse(args[4])); + kb.setCrit(parse(args[5])); + kb.setSlow(Double.parseDouble(args[6])); + kb.setMaxY(Double.parseDouble(args[7])); + } catch (NumberFormatException e) { + sendInvalidUsage(sender); + return; + } + + getKBManager().save(); + sender.sendMessage(getInfo(ChatColor.GREEN + "Successfully updated KB Profile " + args[0], kb)); + } + + private KBOption parse(String arg) throws NumberFormatException { + String[] split = arg.split(","); + if(split.length != 2) throw new NumberFormatException(); + return new KBOption<>(Double.parseDouble(split[0]), Double.parseDouble(split[1])); + } + } + + @CommandInformation( + name = "setrod", + desc = "Sets a KB profile's rod set", + usage = "(name) (friction[H,V]) (base[H,V])", + aliases = "setrods" + ) + class SetRod extends CommandArg { + public void execute(CommandSender sender, String[] args) { + if(args.length != 3) { + sendInvalidUsage(sender); + return; + } + + KBProfile kb = getKBManager().getProfileMap().computeIfAbsent(args[0], name -> getKBManager().getVanillaProfile().copy()); + KBSet rod = kb.getRod(); + try { + rod.setFriction(parse(args[1])); + rod.setBase(parse(args[2])); + } catch (NumberFormatException e) { + sendInvalidUsage(sender); + return; + } + + getKBManager().save(); + sender.sendMessage(getInfo(ChatColor.GREEN + "Successfully updated KB Profile " + args[0] + "'s rod set", kb)); + } + + private KBOption parse(String arg) throws NumberFormatException { + String[] split = arg.split(","); + if(split.length != 2) throw new NumberFormatException(); + return new KBOption<>(Double.parseDouble(split[0]), Double.parseDouble(split[1])); + } + } + + @CommandInformation( + name = "setprojectile", + desc = "Sets a KB profile's projectile set", + usage = "(name) (friction[H,V]) (base[H,V])", + aliases = "setprojectiles" + ) + class SetArrow extends CommandArg { + public void execute(CommandSender sender, String[] args) { + if(args.length != 3) { + sendInvalidUsage(sender); + return; + } + + KBProfile kb = getKBManager().getProfileMap().computeIfAbsent(args[0], name -> getKBManager().getVanillaProfile().copy()); + KBSet projectile = kb.getProjectile(); + try { + projectile.setFriction(parse(args[1])); + projectile.setBase(parse(args[2])); + } catch (NumberFormatException e) { + sendInvalidUsage(sender); + return; + } + + getKBManager().save(); + sender.sendMessage(getInfo(ChatColor.GREEN + "Successfully updated KB Profile " + args[0] + "'s projectile set", kb)); + } + + private KBOption parse(String arg) throws NumberFormatException { + String[] split = arg.split(","); + if(split.length != 2) throw new NumberFormatException(); + return new KBOption<>(Double.parseDouble(split[0]), Double.parseDouble(split[1])); + } + } + + @CommandInformation( + name = "default", + desc = "Makes a KB profile default", + usage = "(name)", + aliases = "setdefault" + ) + class Default extends CommandArg { + public void execute(CommandSender sender, String[] args) { + if(args.length != 1) { + sendInvalidUsage(sender); + return; + } + + KBProfile kb = getKBManager().getProfileMap().get(args[0]); + if(kb == null) { + sender.sendMessage(ChatColor.RED + "No profile found with name " + args[0]); + return; + } + if(kb.isDefaultProfile()) { + sender.sendMessage(ChatColor.RED + "This profile is already default"); + return; + } + getKBManager().getDefaultProfile().setDefaultProfile(false); + kb.setDefaultProfile(true); + getKBManager().setDefaultProfile(kb); + getKBManager().save(); + + sender.sendMessage(ChatColor.GREEN + "Successfully set default profile to " + args[0]); + } + } + + @CommandInformation( + name = "remove", + desc = "Removes a KB profile", + usage = "(name)", + aliases = { "rm", "del", "delete" } + ) + class Remove extends CommandArg { + public void execute(CommandSender sender, String[] args) { + if(args.length != 1) { + sendInvalidUsage(sender); + return; + } + + KBProfile kb = getKBManager().getProfileMap().get(args[0]); + if(kb == null) { + sender.sendMessage(ChatColor.RED + "No profile found with name " + args[0]); + return; + } + if(kb.isDefaultProfile()) { + sender.sendMessage(ChatColor.RED + "You may not remove a default profile"); + return; + } + + getKBManager().removeProfile(args[0]); + + sender.sendMessage(ChatColor.GREEN + "Successfully removed profile " + args[0]); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/ReloadSpigot.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/ReloadSpigot.java new file mode 100644 index 0000000..421020a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/ReloadSpigot.java @@ -0,0 +1,20 @@ +package me.levansj01.mythicspigot.command.impl; + +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.command.CommandInformation; +import me.levansj01.mythicspigot.command.MythicCommand; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +@CommandInformation( + name = "reloadspigot", + aliases = {"reloadmythic", "rlspigot", "rlmythic"}, + desc = "Reloads the MythicSpigot configuration" +) +public class ReloadSpigot extends MythicCommand { + public void execute(CommandSender sender, String[] args) { + long then = System.currentTimeMillis(); + MythicConfiguration.load(); + sender.sendMessage(ChatColor.GREEN + "Successfully reloaded configuration in " + (System.currentTimeMillis() - then) + "ms"); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/TPS.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/TPS.java new file mode 100644 index 0000000..5dbd2a4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/TPS.java @@ -0,0 +1,25 @@ +package me.levansj01.mythicspigot.command.impl; + +import me.levansj01.mythicspigot.command.CommandInformation; +import me.levansj01.mythicspigot.command.MythicCommand; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import java.util.Arrays; +import java.util.stream.Collectors; + +@CommandInformation( + name = "tps", + aliases = "tickspersecond", + desc = "Displays performance information" +) +public class TPS extends MythicCommand { + public void execute(CommandSender sender, String[] args) { + double[] tps = org.bukkit.Bukkit.spigot().getTPS(); + sender.sendMessage(ChatColor.AQUA + "TPS from last 1m, 5m, 15m: " + ChatColor.WHITE + Arrays.stream(tps).mapToObj(this::format).collect(Collectors.joining(", "))); + } + + public String format(double tps) { + return String.format("%.2f", tps); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/Version.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/Version.java new file mode 100644 index 0000000..e5c8632 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/command/impl/Version.java @@ -0,0 +1,59 @@ +package me.levansj01.mythicspigot.command.impl; + +import com.google.common.base.Joiner; +import me.levansj01.mythicspigot.command.CommandInformation; +import me.levansj01.mythicspigot.command.MythicCommand; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@CommandInformation( + name = "version", + aliases = {"ver", "about", "mythic"}, + desc = "Displays version information about the server", + perm = false +) +public class Version extends MythicCommand { + public void execute(CommandSender sender, String[] args) { + if(args.length == 0) { + // String git = Bukkit.getVersion().replace("TacoSpigot", "mySpigot"); // Some plugins recognise TacoSpigot, so just replace it here + sender.sendMessage("This server is powered by " + org.bukkit.ChatColor.DARK_PURPLE + "mySpigot"); + } else { + if (!sender.hasPermission("group.admin")) { + sender.sendMessage("This server is powered by " + org.bukkit.ChatColor.DARK_PURPLE + "mySpigot"); + return; + } + PluginManager pluginManager = Bukkit.getPluginManager(); + Plugin plugin = pluginManager.getPlugin(args[0]); + if(plugin == null && !args[0].isEmpty()) { + plugin = Arrays.stream(pluginManager.getPlugins()) + .filter(p -> StringUtil.startsWithIgnoreCase(p.getName(), args[0])) + .findFirst().orElse(null); + } + + if(plugin == null) { + sender.sendMessage(ChatColor.RED + "Unable to find a plugin with the name \"" + args[0] + "\""); + return; + } + + PluginDescriptionFile desc = plugin.getDescription(); + + sender.sendMessage(ChatColor.AQUA + desc.getFullName() + " Information: "); + if(desc.getDescription() != null) sender.sendMessage(ChatColor.AQUA + "Description: " + ChatColor.WHITE + desc.getDescription()); + sender.sendMessage(ChatColor.AQUA + "Version: " + ChatColor.WHITE + desc.getVersion()); + if(desc.getWebsite() != null && !desc.getWebsite().isEmpty()) sender.sendMessage(ChatColor.AQUA + "Site: " + ChatColor.WHITE + desc.getWebsite()); + if(desc.getAuthors() != null && !desc.getAuthors().isEmpty()) sender.sendMessage(ChatColor.AQUA + "Author(s): " + ChatColor.WHITE + Joiner.on(", ").join(desc.getAuthors())); + sender.sendMessage(ChatColor.AQUA + "Plugin Class: " + ChatColor.WHITE + desc.getMain()); + if(desc.getCommands() != null && !desc.getCommands().isEmpty()) sender.sendMessage(ChatColor.AQUA + "Commands: " + ChatColor.WHITE + Joiner.on(", ").join(desc.getCommands().keySet())); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBOption.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBOption.java new file mode 100644 index 0000000..714de58 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBOption.java @@ -0,0 +1,31 @@ +package me.levansj01.mythicspigot.kb; + +import com.google.common.collect.Maps; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.Map; + +@AllArgsConstructor +@Getter +public class KBOption { + private T horizontal, vertical; + + @SuppressWarnings("unchecked") + public KBOption(ConfigurationSection map) { + horizontal = (T) map.get("horizontal"); + vertical = (T) map.get("vertical"); + } + + public Map save() { + Map map = Maps.newLinkedHashMap(); + map.put("horizontal", horizontal); + map.put("vertical", vertical); + return map; + } + + public KBOption copy() { + return new KBOption (horizontal, vertical); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBProfile.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBProfile.java new file mode 100644 index 0000000..60bea97 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBProfile.java @@ -0,0 +1,77 @@ +package me.levansj01.mythicspigot.kb; + +import com.google.common.collect.Maps; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FishHook; +import org.bukkit.entity.Projectile; + +import java.util.Map; + +@AllArgsConstructor +@Data +public class KBProfile { + private KBSet player, rod, projectile; + private KBOption wTap, backStab, crit; + private double slow, maxY; + private int hitDelay; + private boolean cactus, fire, poison, wither; + private boolean defaultProfile; + + @SuppressWarnings("unchecked") + public KBProfile(ConfigurationSection map) { + player = new KBSet(map); + + if(map.isConfigurationSection("rod")) rod = new KBSet(map.getConfigurationSection("rod")); + else rod = player.copy(); + if(map.isConfigurationSection("projectile")) projectile = new KBSet(map.getConfigurationSection("projectile")); + else projectile = player.copy(); + + cactus = (Boolean) map.get("cactus"); + fire = (Boolean) map.get("fire"); + poison = (Boolean) map.get("poison"); + wither = (Boolean) map.get("wither"); + + backStab = new KBOption<>(map.getConfigurationSection("backStab")); + wTap = new KBOption<>(map.getConfigurationSection("wTap")); + crit = new KBOption<>(map.getConfigurationSection("crit")); + slow = ((Number) map.get("slow")).doubleValue(); + maxY = ((Number) map.get("maxY")).doubleValue(); + hitDelay = ((Number) map.get("hitDelay")).intValue(); + defaultProfile = (Boolean) map.get("default"); + } + + public Map save() { + Map map = Maps.newLinkedHashMap(); + player.save(map); + map.put("rod", rod.save()); + map.put("projectile", projectile.save()); + map.put("cactus", cactus); + map.put("fire", fire); + map.put("poison", poison); + map.put("wither", wither); + map.put("wTap", wTap.save()); + map.put("backStab", backStab.save()); + map.put("crit", crit.save()); + map.put("slow", slow); + map.put("maxY", maxY); + map.put("hitDelay", hitDelay); + map.put("default", defaultProfile); + return map; + } + + public KBProfile copy() { + return new KBProfile(player.copy(), rod.copy(), projectile.copy(), wTap.copy(), backStab.copy(), crit.copy(), slow, maxY, hitDelay, false, false, false, false, false); + } + + public KBSet get(Entity entity) { + if(entity instanceof FishHook) { + return rod; + } else if(entity instanceof Projectile) { + return projectile; + } + return player; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBProfileManager.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBProfileManager.java new file mode 100644 index 0000000..1701985 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBProfileManager.java @@ -0,0 +1,104 @@ +package me.levansj01.mythicspigot.kb; + +import com.google.common.collect.Maps; +import lombok.Getter; +import lombok.Setter; +import me.levansj01.mythicspigot.MythicCore; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.Optional; +import java.util.logging.Level; + +@Getter @Setter +public class KBProfileManager { + private final YamlConfiguration config = new YamlConfiguration(); + private final File file = new File("kbprofile.yml"); + private final Map profileMap = Maps.newHashMap(); + private final KBProfile vanillaProfile = new KBProfile( + KBSet.DEFAULT.copy(), + KBSet.DEFAULT.copy(), + KBSet.DEFAULT.copy(), + new KBOption<>(1.0, 0.1), + new KBOption<>(0.0, 0.0), + new KBOption<>(0.0, 0.0), + 0.6, 0.4000000059604645D, 20, false, false, false, false, false + ); + private KBProfile defaultProfile; + + public void load() { + if(file.exists()) { + try { + config.load(file); + } catch (IOException | InvalidConfigurationException e) { + MythicCore.getLogger().log(Level.SEVERE, "Failed to load kb profile config, " + e); + } + } + profileMap.clear(); + ConfigurationSection section = config.getConfigurationSection("profiles"); + if(section != null) { + for (String profileName : section.getKeys(false)) { + ConfigurationSection profileSection = section.getConfigurationSection(profileName); + KBProfile profile = new KBProfile(profileSection); + profileMap.put(profileName, profile); + if (profile.isDefaultProfile()) { + defaultProfile = profile; + } + MythicCore.getLogger().info("Loaded " + profileName + " KB Profile" + (profile.isDefaultProfile() ? " (Default Profile)" : "")); + } + } + + if (defaultProfile == null) { + MythicCore.getLogger().info("Default profile not found, creating default profile..."); + defaultProfile = vanillaProfile.copy(); + defaultProfile.setDefaultProfile(true); + addProfile("default", defaultProfile); + } + } + + /** + * Gets a KB Profie + * @param name name of KB profile + * @return the KB profile, null if it does not exist + */ + public KBProfile getProfile(String name) { + return profileMap.get(name); + } + + /** + * Removes a KB Profile + * @param name name of KB profile + * @return whether the KB profile was removed + */ + public boolean removeProfile(String name) { + if(profileMap.remove(name) != null) { + save(); + return true; + } + return false; + } + + /** + * Adds a KB profile + * @param name name of KB profile + * @param profile KB profile + */ + public void addProfile(String name, KBProfile profile) { + profileMap.put(name, profile); + save(); + } + + public void save() { + config.set("profiles", null); + profileMap.forEach((profileName, profile) -> config.set("profiles." + profileName, profile.save())); + try { + config.save(file); + } catch (IOException e) { + MythicCore.getLogger().log(Level.SEVERE, "Failed to save kb profile config, " + e); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBSet.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBSet.java new file mode 100644 index 0000000..be3650a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/kb/KBSet.java @@ -0,0 +1,39 @@ +package me.levansj01.mythicspigot.kb; + +import com.google.common.collect.Maps; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.Map; + +@AllArgsConstructor +@Getter +@Setter +public class KBSet { + public static final KBSet DEFAULT = new KBSet(new KBOption<>(0.5, 0.5), new KBOption<>(0.4, 0.4)); + + private KBOption friction, base; + + public KBSet(ConfigurationSection map) { + friction = new KBOption<>(map.getConfigurationSection("friction")); + base = new KBOption<>(map.getConfigurationSection("base")); + } + + public Map save() { + Map map = Maps.newHashMap(); + save(map); + return map; + } + + public void save(Map map) { + map.put("friction", friction.save()); + map.put("base", base.save()); + } + + public KBSet copy() { + return new KBSet(friction.copy(), base.copy()); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/logger/MythicLogger.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/logger/MythicLogger.java new file mode 100644 index 0000000..b344932 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/me/levansj01/mythicspigot/logger/MythicLogger.java @@ -0,0 +1,21 @@ +package me.levansj01.mythicspigot.logger; + +import me.levansj01.mythicspigot.MythicCore; + +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +public class MythicLogger extends Logger { + public MythicLogger() { + super(MythicCore.class.getCanonicalName(), null); + setParent(Logger.getLogger("Minecraft")); + setLevel(Level.ALL); + } + + @Override + public void log(LogRecord record) { + record.setMessage("[MythicSpigot] " + record.getMessage()); + super.log(record); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/net/techcable/tacospigot/event/entity/ArrowCollideEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/net/techcable/tacospigot/event/entity/ArrowCollideEvent.java new file mode 100644 index 0000000..04c6f6f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/net/techcable/tacospigot/event/entity/ArrowCollideEvent.java @@ -0,0 +1,60 @@ +package net.techcable.tacospigot.event.entity; + +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; + +/** + * Called when an arrow collides with an entity + *

+ * This event is called before {@link org.bukkit.event.entity.EntityDamageByEntityEvent}, and cancelling it will allow the arrow to continue flying + */ +public class ArrowCollideEvent extends EntityEvent implements Cancellable { + private final Entity collidedWith; + + /** + * Get the entity the arrow collided wit + * + * @return the entity + */ + public Entity getCollidedWith() { + return collidedWith; + } + + public ArrowCollideEvent(Arrow what, Entity collidedWith) { + super(what); + this.collidedWith = collidedWith; + } + + /** + * Get the arrow that collided + * + * @return the arrow that collided + */ + public Arrow getEntity() { + return (Arrow) super.getEntity(); + } + + private static final HandlerList handlerList = new HandlerList(); + public static HandlerList getHandlerList() { + return handlerList; + } + + @Override + public HandlerList getHandlers() { + return handlerList; + } + + private boolean cancelled = false; + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/net/techcable/tacospigot/event/entity/SpawnerPreSpawnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/net/techcable/tacospigot/event/entity/SpawnerPreSpawnEvent.java new file mode 100644 index 0000000..efed50a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/net/techcable/tacospigot/event/entity/SpawnerPreSpawnEvent.java @@ -0,0 +1,71 @@ +package net.techcable.tacospigot.event.entity; + +import com.google.common.base.Preconditions; + +import org.bukkit.Location; +import org.bukkit.entity.EntityType; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import static com.google.common.base.Preconditions.*; + +/** + * Fired before a mob spawns and entity data as calculated. + *

This is a more preformat alternative to {@link org.bukkit.event.entity.SpawnerSpawnEvent}

+ */ +public class SpawnerPreSpawnEvent extends Event implements Cancellable { + + private final Location location; + private final EntityType spawnedType; + + public SpawnerPreSpawnEvent(Location location, EntityType spawnedType) { + this.location = checkNotNull(location, "Null location").clone(); // Defensive copy + this.spawnedType = checkNotNull(spawnedType, "Null spawned type"); + } + + /** + * Get the location of the spawner where the entity is being spawned + * + * @return the spawner's location + */ + public Location getLocation() { + return location.clone(); // Defensive copy + } + + /** + * Get the type of entity being spawned + * + * @return the type being spawned + */ + public EntityType getSpawnedType() { + return spawnedType; + } + + // Cancellable + + private boolean cancelled; + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + // handlers + + private static final HandlerList handlerList = new HandlerList(); + + @Override + public HandlerList getHandlers() { + return handlerList; + } + + public static HandlerList getHandlerList() { + return handlerList; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Achievement.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Achievement.java new file mode 100644 index 0000000..ee874ee --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Achievement.java @@ -0,0 +1,70 @@ +package org.bukkit; + +/** + * Represents an achievement, which may be given to players. + */ +public enum Achievement { + OPEN_INVENTORY, + MINE_WOOD (OPEN_INVENTORY), + BUILD_WORKBENCH (MINE_WOOD), + BUILD_PICKAXE (BUILD_WORKBENCH), + BUILD_FURNACE (BUILD_PICKAXE), + ACQUIRE_IRON (BUILD_FURNACE), + BUILD_HOE (BUILD_WORKBENCH), + MAKE_BREAD (BUILD_HOE), + BAKE_CAKE (BUILD_HOE), + BUILD_BETTER_PICKAXE (BUILD_PICKAXE), + COOK_FISH (BUILD_FURNACE), + ON_A_RAIL (ACQUIRE_IRON), + BUILD_SWORD (BUILD_WORKBENCH), + KILL_ENEMY (BUILD_SWORD), + KILL_COW (BUILD_SWORD), + FLY_PIG (KILL_COW), + SNIPE_SKELETON (KILL_ENEMY), + GET_DIAMONDS (ACQUIRE_IRON), + NETHER_PORTAL (GET_DIAMONDS), + GHAST_RETURN (NETHER_PORTAL), + GET_BLAZE_ROD (NETHER_PORTAL), + BREW_POTION (GET_BLAZE_ROD), + END_PORTAL (GET_BLAZE_ROD), + THE_END (END_PORTAL), + ENCHANTMENTS (GET_DIAMONDS), + OVERKILL (ENCHANTMENTS), + BOOKCASE (ENCHANTMENTS), + EXPLORE_ALL_BIOMES (END_PORTAL), + SPAWN_WITHER (THE_END), + KILL_WITHER (SPAWN_WITHER), + FULL_BEACON (KILL_WITHER), + BREED_COW (KILL_COW), + DIAMONDS_TO_YOU (GET_DIAMONDS), + OVERPOWERED (BUILD_BETTER_PICKAXE) + ; + + private final Achievement parent; + + private Achievement() { + parent = null; + } + + private Achievement(Achievement parent) { + this.parent = parent; + } + + /** + * Returns whether or not this achievement has a parent achievement. + * + * @return whether the achievement has a parent achievement + */ + public boolean hasParent() { + return parent != null; + } + + /** + * Returns the parent achievement of this achievement, or null if none. + * + * @return the parent achievement or null + */ + public Achievement getParent() { + return parent; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Art.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Art.java new file mode 100644 index 0000000..ba66f16 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Art.java @@ -0,0 +1,111 @@ +package org.bukkit; + +import java.util.HashMap; + +import org.apache.commons.lang.Validate; + +import com.google.common.collect.Maps; + +/** + * Represents the art on a painting + */ +public enum Art { + KEBAB(0, 1, 1), + AZTEC(1, 1, 1), + ALBAN(2, 1, 1), + AZTEC2(3, 1, 1), + BOMB(4, 1, 1), + PLANT(5, 1, 1), + WASTELAND(6, 1, 1), + POOL(7, 2, 1), + COURBET(8, 2, 1), + SEA(9, 2, 1), + SUNSET(10, 2, 1), + CREEBET(11, 2, 1), + WANDERER(12, 1, 2), + GRAHAM(13, 1, 2), + MATCH(14, 2, 2), + BUST(15, 2, 2), + STAGE(16, 2, 2), + VOID(17, 2, 2), + SKULL_AND_ROSES(18, 2, 2), + WITHER(19, 2, 2), + FIGHTERS(20, 4, 2), + POINTER(21, 4, 4), + PIGSCENE(22, 4, 4), + BURNINGSKULL(23, 4, 4), + SKELETON(24, 4, 3), + DONKEYKONG(25, 4, 3); + + private int id, width, height; + private static final HashMap BY_NAME = Maps.newHashMap(); + private static final HashMap BY_ID = Maps.newHashMap(); + + private Art(int id, int width, int height) { + this.id = id; + this.width = width; + this.height = height; + } + + /** + * Gets the width of the painting, in blocks + * + * @return The width of the painting, in blocks + */ + public int getBlockWidth() { + return width; + } + + /** + * Gets the height of the painting, in blocks + * + * @return The height of the painting, in blocks + */ + public int getBlockHeight() { + return height; + } + + /** + * Get the ID of this painting. + * + * @return The ID of this painting + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + + /** + * Get a painting by its numeric ID + * + * @param id The ID + * @return The painting + * @deprecated Magic value + */ + @Deprecated + public static Art getById(int id) { + return BY_ID.get(id); + } + + /** + * Get a painting by its unique name + *

+ * This ignores underscores and capitalization + * + * @param name The name + * @return The painting + */ + public static Art getByName(String name) { + Validate.notNull(name, "Name cannot be null"); + + return BY_NAME.get(name.toLowerCase().replaceAll("_", "")); + } + + static { + for (Art art : values()) { + BY_ID.put(art.id, art); + BY_NAME.put(art.toString().toLowerCase().replaceAll("_", ""), art); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BanEntry.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BanEntry.java new file mode 100644 index 0000000..b2437c6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BanEntry.java @@ -0,0 +1,128 @@ +package org.bukkit; + +import java.util.Date; + +/** + * A single entry from a ban list. This may represent either a player ban or + * an IP ban. + *

+ * Ban entries include the following properties: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Property information
PropertyDescription
Target Name / IP AddressThe target name or IP address
Creation DateThe creation date of the ban
SourceThe source of the ban, such as a player, console, plugin, etc
Expiration DateThe expiration date of the ban
ReasonThe reason for the ban
+ *

+ * Unsaved information is not automatically written to the implementation's + * ban list, instead, the {@link #save()} method must be called to write the + * changes to the ban list. If this ban entry has expired (such as from an + * unban) and is no longer found in the list, the {@link #save()} call will + * re-add it to the list, therefore banning the victim specified. + *

+ * Likewise, changes to the associated {@link BanList} or other entries may or + * may not be reflected in this entry. + */ +public interface BanEntry { + + /** + * Gets the target involved. This may be in the form of an IP or a player + * name. + * + * @return the target name or IP address + */ + public String getTarget(); + + /** + * Gets the date this ban entry was created. + * + * @return the creation date + */ + public Date getCreated(); + + /** + * Sets the date this ban entry was created. + * + * @param created the new created date, cannot be null + * @see #save() saving changes + */ + public void setCreated(Date created); + + /** + * Gets the source of this ban. + *

+ * Note: A source is considered any String, although this is generally a + * player name. + * + * @return the source of the ban + */ + public String getSource(); + + /** + * Sets the source of this ban. + *

+ * Note: A source is considered any String, although this is generally a + * player name. + * + * @param source the new source where null values become empty strings + * @see #save() saving changes + */ + public void setSource(String source); + + /** + * Gets the date this ban expires on, or null for no defined end date. + * + * @return the expiration date + */ + public Date getExpiration(); + + /** + * Sets the date this ban expires on. Null values are considered + * "infinite" bans. + * + * @param expiration the new expiration date, or null to indicate an + * eternity + * @see #save() saving changes + */ + public void setExpiration(Date expiration); + + /** + * Gets the reason for this ban. + * + * @return the ban reason, or null if not set + */ + public String getReason(); + + /** + * Sets the reason for this ban. Reasons must not be null. + * + * @param reason the new reason, null values assume the implementation + * default + * @see #save() saving changes + */ + public void setReason(String reason); + + /** + * Saves the ban entry, overwriting any previous data in the ban list. + *

+ * Saving the ban entry of an unbanned player will cause the player to be + * banned once again. + */ + public void save(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BanList.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BanList.java new file mode 100644 index 0000000..c21b858 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BanList.java @@ -0,0 +1,72 @@ +package org.bukkit; + +import java.util.Date; +import java.util.Set; + +/** + * A ban list, containing bans of some {@link Type}. + */ +public interface BanList { + + /** + * Represents a ban-type that a {@link BanList} may track. + */ + public enum Type { + /** + * Banned player names + */ + NAME, + /** + * Banned player IP addresses + */ + IP, + ; + } + + /** + * Gets a {@link BanEntry} by target. + * + * @param target entry parameter to search for + * @return the corresponding entry, or null if none found + */ + public BanEntry getBanEntry(String target); + + /** + * Adds a ban to the this list. If a previous ban exists, this will + * update the previous entry. + * + * @param target the target of the ban + * @param reason reason for the ban, null indicates implementation default + * @param expires date for the ban's expiration (unban), or null to imply + * forever + * @param source source of the ban, null indicates implementation default + * @return the entry for the newly created ban, or the entry for the + * (updated) previous ban + */ + public BanEntry addBan(String target, String reason, Date expires, String source); + + /** + * Gets a set containing every {@link BanEntry} in this list. + * + * @return an immutable set containing every entry tracked by this list + */ + public Set getBanEntries(); + + /** + * Gets if a {@link BanEntry} exists for the target, indicating an active + * ban status. + * + * @param target the target to find + * @return true if a {@link BanEntry} exists for the name, indicating an + * active ban status, false otherwise + */ + public boolean isBanned(String target); + + /** + * Removes the specified target from this list, therefore indicating a + * "not banned" status. + * + * @param target the target to remove from this list + */ + public void pardon(String target); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BlockChangeDelegate.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BlockChangeDelegate.java new file mode 100644 index 0000000..e6b9f0e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/BlockChangeDelegate.java @@ -0,0 +1,104 @@ +package org.bukkit; + +/** + * A delegate for handling block changes. This serves as a direct interface + * between generation algorithms in the server implementation and utilizing + * code. + */ +public interface BlockChangeDelegate { + + /** + * Set a block type at the specified coordinates without doing all world + * updates and notifications. + *

+ * It is safe to have this call World.setTypeId, but it may be slower than + * World.setRawTypeId. + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param typeId New block ID + * @return true if the block was set successfully + * @deprecated Magic value + */ + @Deprecated + public boolean setRawTypeId(int x, int y, int z, int typeId); + + /** + * Set a block type and data at the specified coordinates without doing + * all world updates and notifications. + *

+ * It is safe to have this call World.setTypeId, but it may be slower than + * World.setRawTypeId. + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param typeId New block ID + * @param data Block data + * @return true if the block was set successfully + * @deprecated Magic value + */ + @Deprecated + public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data); + + /** + * Set a block type at the specified coordinates. + *

+ * This method cannot call World.setRawTypeId, a full update is needed. + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param typeId New block ID + * @return true if the block was set successfully + * @deprecated Magic value + */ + @Deprecated + public boolean setTypeId(int x, int y, int z, int typeId); + + /** + * Set a block type and data at the specified coordinates. + *

+ * This method cannot call World.setRawTypeId, a full update is needed. + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param typeId New block ID + * @param data Block data + * @return true if the block was set successfully + * @deprecated Magic value + */ + @Deprecated + public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data); + + /** + * Get the block type at the location. + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @return The block ID + * @deprecated Magic value + */ + @Deprecated + public int getTypeId(int x, int y, int z); + + /** + * Gets the height of the world. + * + * @return Height of the world + */ + public int getHeight(); + + /** + * Checks if the specified block is empty (air) or not. + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @return True if the block is considered empty. + */ + public boolean isEmpty(int x, int y, int z); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Bukkit.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Bukkit.java new file mode 100644 index 0000000..8fbc828 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Bukkit.java @@ -0,0 +1,1169 @@ +package org.bukkit; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Logger; + +import org.bukkit.Warning.WarningState; +import org.bukkit.command.CommandException; +import org.bukkit.command.CommandMap; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.help.HelpMap; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; +import org.bukkit.map.MapView; +import org.bukkit.permissions.Permissible; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.ServicesManager; +import org.bukkit.plugin.messaging.Messenger; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scoreboard.ScoreboardManager; +import org.bukkit.util.CachedServerIcon; + +import com.avaje.ebean.config.ServerConfig; +import com.google.common.collect.ImmutableList; +import org.bukkit.generator.ChunkGenerator; + +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.meta.ItemMeta; + +/** + * Represents the Bukkit core, for version and Server singleton handling + */ +public final class Bukkit { + private static Server server; + + /** + * Static class cannot be initialized. + */ + private Bukkit() {} + + /** + * Gets the current {@link Server} singleton + * + * @return Server instance being ran + */ + public static Server getServer() { + return server; + } + + /** + * Attempts to set the {@link Server} singleton. + *

+ * This cannot be done if the Server is already set. + * + * @param server Server instance + */ + public static void setServer(Server server) { + if (Bukkit.server != null) { + throw new UnsupportedOperationException("Cannot redefine singleton Server"); + } + + Bukkit.server = server; + server.getLogger().info("This server is running " + getName() + " version " + getVersion() + " (Implementing API version " + getBukkitVersion() + ")"); + } + + /** + * Gets the name of this server implementation. + * + * @return name of this server implementation + */ + public static String getName() { + return server.getName(); + } + + /** + * Gets the version string of this server implementation. + * + * @return version of this server implementation + */ + public static String getVersion() { + return server.getVersion(); + } + + /** + * Gets the Bukkit version that this server is running. + * + * @return version of Bukkit + */ + public static String getBukkitVersion() { + return server.getBukkitVersion(); + } + + /** + * Gets an array copy of all currently logged in players. + *

+ * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @deprecated superseded by {@link #getOnlinePlayers()} + * @return an array of Players that are currently online + */ + @Deprecated + public static Player[] _INVALID_getOnlinePlayers() { + return server._INVALID_getOnlinePlayers(); + } + + /** + * Gets a view of all currently logged in players. This {@linkplain + * Collections#unmodifiableCollection(Collection) view} is a reused + * object, making some operations like {@link Collection#size()} + * zero-allocation. + *

+ * The collection is a view backed by the internal representation, such + * that, changes to the internal state of the server will be reflected + * immediately. However, the reuse of the returned collection (identity) + * is not strictly guaranteed for future or all implementations. Casting + * the collection, or relying on interface implementations (like {@link + * Serializable} or {@link List}), is deprecated. + *

+ * Iteration behavior is undefined outside of self-contained main-thread + * uses. Normal and immediate iterator use without consequences that + * affect the collection are fully supported. The effects following + * (non-exhaustive) {@link Entity#teleport(Location) teleportation}, + * {@link Player#setHealth(double) death}, and {@link Player#kickPlayer( + * String) kicking} are undefined. Any use of this collection from + * asynchronous threads is unsafe. + *

+ * For safe consequential iteration or mimicking the old array behavior, + * using {@link Collection#toArray(Object[])} is recommended. For making + * snapshots, {@link ImmutableList#copyOf(Collection)} is recommended. + * + * @return a view of currently online players. + */ + public static Collection getOnlinePlayers() { + return server.getOnlinePlayers(); + } + + /** + * Get the maximum amount of players which can login to this server. + * + * @return the amount of players this server allows + */ + public static int getMaxPlayers() { + return server.getMaxPlayers(); + } + + /** + * Get the game port that the server runs on. + * + * @return the port number of this server + */ + public static int getPort() { + return server.getPort(); + } + + /** + * Get the view distance from this server. + * + * @return the view distance from this server. + */ + public static int getViewDistance() { + return server.getViewDistance(); + } + + /** + * Get the IP that this server is bound to, or empty string if not + * specified. + * + * @return the IP string that this server is bound to, otherwise empty + * string + */ + public static String getIp() { + return server.getIp(); + } + + /** + * Get the name of this server. + * + * @return the name of this server + */ + public static String getServerName() { + return server.getServerName(); + } + + /** + * Get an ID of this server. The ID is a simple generally alphanumeric ID + * that can be used for uniquely identifying this server. + * + * @return the ID of this server + */ + public static String getServerId() { + return server.getServerId(); + } + + /** + * Get world type (level-type setting) for default world. + * + * @return the value of level-type (e.g. DEFAULT, FLAT, DEFAULT_1_1) + */ + public static String getWorldType() { + return server.getWorldType(); + } + + /** + * Get generate-structures setting. + * + * @return true if structure generation is enabled, false otherwise + */ + public static boolean getGenerateStructures() { + return server.getGenerateStructures(); + } + + /** + * Gets whether this server allows the End or not. + * + * @return whether this server allows the End or not + */ + public static boolean getAllowEnd() { + return server.getAllowEnd(); + } + + /** + * Gets whether this server allows the Nether or not. + * + * @return whether this server allows the Nether or not + */ + public static boolean getAllowNether() { + return server.getAllowNether(); + } + + /** + * Gets whether this server has a whitelist or not. + * + * @return whether this server has a whitelist or not + */ + public static boolean hasWhitelist() { + return server.hasWhitelist(); + } + + /** + * Sets if the server is whitelisted. + * + * @param value true for whitelist on, false for off + */ + public static void setWhitelist(boolean value) { + server.setWhitelist(value); + } + + /** + * Gets a list of whitelisted players. + * + * @return a set containing all whitelisted players + */ + public static Set getWhitelistedPlayers() { + return server.getWhitelistedPlayers(); + } + + /** + * Reloads the whitelist from disk. + */ + public static void reloadWhitelist() { + server.reloadWhitelist(); + } + + /** + * Broadcast a message to all players. + *

+ * This is the same as calling {@link #broadcast(java.lang.String, + * java.lang.String)} to {@link Server#BROADCAST_CHANNEL_USERS} + * + * @param message the message + * @return the number of players + */ + public static int broadcastMessage(String message) { + return server.broadcastMessage(message); + } + + // Paper start + /** + * Sends the component to the player + * + * @param component the components to send + */ + public static void broadcast(net.md_5.bungee.api.chat.BaseComponent component) { + server.broadcast(component); + } + + /** + * Sends an array of components as a single message to the player + * + * @param components the components to send + */ + public static void broadcast(net.md_5.bungee.api.chat.BaseComponent... components) { + server.broadcast(components); + } + // Paper end + + /** + * Gets the name of the update folder. The update folder is used to safely + * update plugins at the right moment on a plugin load. + *

+ * The update folder name is relative to the plugins folder. + * + * @return the name of the update folder + */ + public static String getUpdateFolder() { + return server.getUpdateFolder(); + } + + /** + * Gets the update folder. The update folder is used to safely update + * plugins at the right moment on a plugin load. + * + * @return the update folder + */ + public static File getUpdateFolderFile() { + return server.getUpdateFolderFile(); + } + + /** + * Gets the value of the connection throttle setting. + * + * @return the value of the connection throttle setting + */ + public static long getConnectionThrottle() { + return server.getConnectionThrottle(); + } + + /** + * Gets default ticks per animal spawns value. + *

+ * Example Usage: + *

    + *
  • A value of 1 will mean the server will attempt to spawn monsters + * every tick. + *
  • A value of 400 will mean the server will attempt to spawn monsters + * every 400th tick. + *
  • A value below 0 will be reset back to Minecraft's default. + *
+ *

+ * Note: If set to 0, animal spawning will be disabled. We + * recommend using spawn-animals to control this instead. + *

+ * Minecraft default: 400. + * + * @return the default ticks per animal spawns value + */ + public static int getTicksPerAnimalSpawns() { + return server.getTicksPerAnimalSpawns(); + } + + /** + * Gets the default ticks per monster spawns value. + *

+ * Example Usage: + *

    + *
  • A value of 1 will mean the server will attempt to spawn monsters + * every tick. + *
  • A value of 400 will mean the server will attempt to spawn monsters + * every 400th tick. + *
  • A value below 0 will be reset back to Minecraft's default. + *
+ *

+ * Note: If set to 0, monsters spawning will be disabled. We + * recommend using spawn-monsters to control this instead. + *

+ * Minecraft default: 1. + * + * @return the default ticks per monsters spawn value + */ + public static int getTicksPerMonsterSpawns() { + return server.getTicksPerMonsterSpawns(); + } + + /** + * Gets a player object by the given username. + *

+ * This method may not return objects for offline players. + * + * @param name the name to look up + * @return a player if one was found, null otherwise + */ + public static Player getPlayer(String name) { + return server.getPlayer(name); + } + + /** + * Gets the player with the exact given name, case insensitive. + * + * @param name Exact name of the player to retrieve + * @return a player object if one was found, null otherwise + */ + public static Player getPlayerExact(String name) { + return server.getPlayerExact(name); + } + + /** + * Attempts to match any players with the given name, and returns a list + * of all possibly matches. + *

+ * This list is not sorted in any particular order. If an exact match is + * found, the returned list will only contain a single result. + * + * @param name the (partial) name to match + * @return list of all possible players + */ + public static List matchPlayer(String name) { + return server.matchPlayer(name); + } + + /** + * Gets the player with the given UUID. + * + * @param id UUID of the player to retrieve + * @return a player object if one was found, null otherwise + */ + public static Player getPlayer(UUID id) { + return server.getPlayer(id); + } + + /** + * Gets the plugin manager for interfacing with plugins. + * + * @return a plugin manager for this Server instance + */ + public static PluginManager getPluginManager() { + return server.getPluginManager(); + } + + /** + * Gets the scheduler for managing scheduled events. + * + * @return a scheduling service for this server + */ + public static BukkitScheduler getScheduler() { + return server.getScheduler(); + } + + /** + * Gets a services manager. + * + * @return s services manager + */ + public static ServicesManager getServicesManager() { + return server.getServicesManager(); + } + + /** + * Gets a list of all worlds on this server. + * + * @return a list of worlds + */ + public static List getWorlds() { + return server.getWorlds(); + } + + /** + * Creates or loads a world with the given name using the specified + * options. + *

+ * If the world is already loaded, it will just return the equivalent of + * getWorld(creator.name()). + * + * @param creator the options to use when creating the world + * @return newly created or loaded world + */ + public static World createWorld(WorldCreator creator) { + return server.createWorld(creator); + } + + /** + * Unloads a world with the given name. + * + * @param name Name of the world to unload + * @param save whether to save the chunks before unloading + * @return true if successful, false otherwise + */ + public static boolean unloadWorld(String name, boolean save) { + return server.unloadWorld(name, save); + } + + /** + * Unloads the given world. + * + * @param world the world to unload + * @param save whether to save the chunks before unloading + * @return true if successful, false otherwise + */ + public static boolean unloadWorld(World world, boolean save) { + return server.unloadWorld(world, save); + } + + /** + * Gets the world with the given name. + * + * @param name the name of the world to retrieve + * @return a world with the given name, or null if none exists + */ + public static World getWorld(String name) { + return server.getWorld(name); + } + + /** + * Gets the world from the given Unique ID. + * + * @param uid a unique-id of the world to retrieve + * @return a world with the given Unique ID, or null if none exists + */ + public static World getWorld(UUID uid) { + return server.getWorld(uid); + } + + /** + * Gets the map from the given item ID. + * + * @param id the id of the map to get + * @return a map view if it exists, or null otherwise + * @deprecated Magic value + */ + @Deprecated + public static MapView getMap(short id) { + return server.getMap(id); + } + + /** + * Create a new map with an automatically assigned ID. + * + * @param world the world the map will belong to + * @return a newly created map view + */ + public static MapView createMap(World world) { + 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. + * + * @return Logger associated with this server + */ + public static Logger getLogger() { + return server.getLogger(); + } + + /** + * Gets a {@link PluginCommand} with the given name or alias. + * + * @param name the name of the command to retrieve + * @return a plugin command if found, null otherwise + */ + public static PluginCommand getPluginCommand(String name) { + return server.getPluginCommand(name); + } + + /** + * Writes loaded players to disk. + */ + public static void savePlayers() { + server.savePlayers(); + } + + /** + * Dispatches a command on this server, and executes it if found. + * + * @param sender the apparent sender of the command + * @param commandLine the command + arguments. Example: test abc + * 123 + * @return returns false if no target is found + * @throws CommandException thrown when the executor for the given command + * fails with an unhandled exception + */ + public static boolean dispatchCommand(CommandSender sender, String commandLine) throws CommandException { + return server.dispatchCommand(sender, commandLine); + } + + /** + * Populates a given {@link ServerConfig} with values attributes to this + * server. + * + * @param config the server config to populate + */ + public static void configureDbConfig(ServerConfig config) { + server.configureDbConfig(config); + } + + /** + * Adds a recipe to the crafting manager. + * + * @param recipe the recipe to add + * @return true if the recipe was added, false if it wasn't for some + * reason + */ + public static boolean addRecipe(Recipe recipe) { + return server.addRecipe(recipe); + } + + /** + * Get a list of all recipes for a given item. The stack size is ignored + * in comparisons. If the durability is -1, it will match any data value. + * + * @param result the item to match against recipe results + * @return a list of recipes with the given result + */ + public static List getRecipesFor(ItemStack result) { + return server.getRecipesFor(result); + } + + /** + * Get an iterator through the list of crafting recipes. + * + * @return an iterator + */ + public static Iterator recipeIterator() { + return server.recipeIterator(); + } + + /** + * Clears the list of crafting recipes. + */ + public static void clearRecipes() { + server.clearRecipes(); + } + + /** + * Resets the list of crafting recipes to the default. + */ + public static void resetRecipes() { + server.resetRecipes(); + } + + /** + * Gets a list of command aliases defined in the server properties. + * + * @return a map of aliases to command names + */ + public static Map getCommandAliases() { + return server.getCommandAliases(); + } + + /** + * Gets the radius, in blocks, around each worlds spawn point to protect. + * + * @return spawn radius, or 0 if none + */ + public static int getSpawnRadius() { + return server.getSpawnRadius(); + } + + /** + * Sets the radius, in blocks, around each worlds spawn point to protect. + * + * @param value new spawn radius, or 0 if none + */ + public static void setSpawnRadius(int value) { + server.setSpawnRadius(value); + } + + /** + * Gets whether the Server is in online mode or not. + * + * @return true if the server authenticates clients, false otherwise + */ + public static boolean getOnlineMode() { + return server.getOnlineMode(); + } + + /** + * Gets whether this server allows flying or not. + * + * @return true if the server allows flight, false otherwise + */ + public static boolean getAllowFlight() { + return server.getAllowFlight(); + } + + /** + * Gets whether the server is in hardcore mode or not. + * + * @return true if the server mode is hardcore, false otherwise + */ + public static boolean isHardcore() { + return server.isHardcore(); + } + + /** + * Gets whether to use vanilla (false) or exact behaviour (true). + * + *

    + *
  • Vanilla behaviour: check for collisions and move the player if + * needed. + *
  • Exact behaviour: spawn players exactly where they should be. + *
+ * + * @return true if exact location locations are used for spawning, false + * for vanilla collision detection or otherwise + * + * @deprecated non standard and unused feature. + */ + @Deprecated + public static boolean useExactLoginLocation() { + return server.useExactLoginLocation(); + } + + /** + * Shutdowns the server, stopping everything. + */ + public static void shutdown() { + server.shutdown(); + } + + /** + * Broadcasts the specified message to every user with the given + * permission name. + * + * @param message message to broadcast + * @param permission the required permission {@link Permissible + * permissibles} must have to receive the broadcast + * @return number of message recipients + */ + public static int broadcast(String message, String permission) { + return server.broadcast(message, permission); + } + + /** + * Gets the player by the given name, regardless if they are offline or + * online. + *

+ * This method may involve a blocking web request to get the UUID for the + * given name. + *

+ * This will return an object even if the player does not exist. To this + * method, all players will exist. + * + * @deprecated Persistent storage of users should be by UUID as names are no longer + * unique past a single session. + * @param name the name the player to retrieve + * @return an offline player + * @see #getOfflinePlayer(java.util.UUID) + */ + @Deprecated + public static OfflinePlayer getOfflinePlayer(String name) { + return server.getOfflinePlayer(name); + } + + /** + * Gets the player by the given UUID, regardless if they are offline or + * online. + *

+ * This will return an object even if the player does not exist. To this + * method, all players will exist. + * + * @param id the UUID of the player to retrieve + * @return an offline player + */ + public static OfflinePlayer getOfflinePlayer(UUID id) { + return server.getOfflinePlayer(id); + } + + /** + * Gets a set containing all current IPs that are banned. + * + * @return a set containing banned IP addresses + */ + public static Set getIPBans() { + return server.getIPBans(); + } + + /** + * Bans the specified address from the server. + * + * @param address the IP address to ban + */ + public static void banIP(String address) { + server.banIP(address); + } + + /** + * Unbans the specified address from the server. + * + * @param address the IP address to unban + */ + public static void unbanIP(String address) { + server.unbanIP(address); + } + + /** + * Gets a set containing all banned players. + * + * @return a set containing banned players + */ + public static Set getBannedPlayers() { + return server.getBannedPlayers(); + } + + /** + * Gets a ban list for the supplied type. + *

+ * Bans by name are no longer supported and this method will return + * null when trying to request them. The replacement is bans by UUID. + * + * @param type the type of list to fetch, cannot be null + * @return a ban list of the specified type + */ + public static BanList getBanList(BanList.Type type){ + return server.getBanList(type); + } + + /** + * Gets a set containing all player operators. + * + * @return a set containing player operators + */ + public static Set getOperators() { + return server.getOperators(); + } + + /** + * Gets the default {@link GameMode} for new players. + * + * @return the default game mode + */ + public static GameMode getDefaultGameMode() { + return server.getDefaultGameMode(); + } + + /** + * Sets the default {@link GameMode} for new players. + * + * @param mode the new game mode + */ + public static void setDefaultGameMode(GameMode mode) { + server.setDefaultGameMode(mode); + } + + /** + * Gets a {@link ConsoleCommandSender} that may be used as an input source + * for this server. + * + * @return a console command sender + */ + public static ConsoleCommandSender getConsoleSender() { + return server.getConsoleSender(); + } + + /** + * Gets the folder that contains all of the various {@link World}s. + * + * @return folder that contains all worlds + */ + public static File getWorldContainer() { + return server.getWorldContainer(); + } + + /** + * Gets every player that has ever played on this server. + * + * @return an array containing all previous players + */ + public static OfflinePlayer[] getOfflinePlayers() { + return server.getOfflinePlayers(); + } + + /** + * Gets the {@link Messenger} responsible for this server. + * + * @return messenger responsible for this server + */ + public static Messenger getMessenger() { + return server.getMessenger(); + } + + /** + * Gets the {@link HelpMap} providing help topics for this server. + * + * @return a help map for this server + */ + public static HelpMap getHelpMap() { + return server.getHelpMap(); + } + + /** + * Creates an empty inventory of the specified type. If the type is {@link + * InventoryType#CHEST}, the new inventory has a size of 27; otherwise the + * new inventory has the normal size for its type. + * + * @param owner the holder of the inventory, or null to indicate no holder + * @param type the type of inventory to create + * @return a new inventory + */ + public static Inventory createInventory(InventoryHolder owner, InventoryType type) { + return server.createInventory(owner, type); + } + + /** + * Creates an empty inventory with the specified type and title. If the type + * is {@link InventoryType#CHEST}, the new inventory has a size of 27; + * otherwise the new inventory has the normal size for its type.
+ * It should be noted that some inventory types do not support titles and + * may not render with said titles on the Minecraft client. + * + * @param owner The holder of the inventory; can be null if there's no holder. + * @param type The type of inventory to create. + * @param title The title of the inventory, to be displayed when it is viewed. + * @return The new inventory. + */ + public static Inventory createInventory(InventoryHolder owner, InventoryType type, String title) { + return server.createInventory(owner, type, title); + } + + /** + * Creates an empty inventory of type {@link InventoryType#CHEST} with the + * specified size. + * + * @param owner the holder of the inventory, or null to indicate no holder + * @param size a multiple of 9 as the size of inventory to create + * @return a new inventory + * @throws IllegalArgumentException if the size is not a multiple of 9 + */ + public static Inventory createInventory(InventoryHolder owner, int size) throws IllegalArgumentException { + return server.createInventory(owner, size); + } + + /** + * Creates an empty inventory of type {@link InventoryType#CHEST} with the + * specified size and title. + * + * @param owner the holder of the inventory, or null to indicate no holder + * @param size a multiple of 9 as the size of inventory to create + * @param title the title of the inventory, displayed when inventory is + * viewed + * @return a new inventory + * @throws IllegalArgumentException if the size is not a multiple of 9 + */ + public static Inventory createInventory(InventoryHolder owner, int size, String title) throws IllegalArgumentException { + return server.createInventory(owner, size, title); + } + + /** + * Gets user-specified limit for number of monsters that can spawn in a + * chunk. + * + * @return the monster spawn limit + */ + public static int getMonsterSpawnLimit() { + return server.getMonsterSpawnLimit(); + } + + /** + * Gets user-specified limit for number of animals that can spawn in a + * chunk. + * + * @return the animal spawn limit + */ + public static int getAnimalSpawnLimit() { + return server.getAnimalSpawnLimit(); + } + + /** + * Gets user-specified limit for number of water animals that can spawn in + * a chunk. + * + * @return the water animal spawn limit + */ + public static int getWaterAnimalSpawnLimit() { + return server.getWaterAnimalSpawnLimit(); + } + + /** + * Gets user-specified limit for number of ambient mobs that can spawn in + * a chunk. + * + * @return the ambient spawn limit + */ + public static int getAmbientSpawnLimit() { + return server.getAmbientSpawnLimit(); + } + + /** + * Checks the current thread against the expected primary thread for the + * server. + *

+ * Note: this method should not be used to indicate the current + * synchronized state of the runtime. A current thread matching the main + * thread indicates that it is synchronized, but a mismatch does not + * preclude the same assumption. + * + * @return true if the current thread matches the expected primary thread, + * false otherwise + */ + public static boolean isPrimaryThread() { + return server.isPrimaryThread(); + } + + /** + * Gets the message that is displayed on the server list. + * + * @return the servers MOTD + */ + public static String getMotd() { + return server.getMotd(); + } + + /** + * Gets the default message that is displayed when the server is stopped. + * + * @return the shutdown message + */ + public static String getShutdownMessage() { + return server.getShutdownMessage(); + } + + /** + * Gets the current warning state for the server. + * + * @return the configured warning state + */ + public static WarningState getWarningState() { + return server.getWarningState(); + } + + /** + * Gets the instance of the item factory (for {@link ItemMeta}). + * + * @return the item factory + * @see ItemFactory + */ + public static ItemFactory getItemFactory() { + return server.getItemFactory(); + } + + /** + * Gets the instance of the scoreboard manager. + *

+ * This will only exist after the first world has loaded. + * + * @return the scoreboard manager or null if no worlds are loaded. + */ + public static ScoreboardManager getScoreboardManager() { + return server.getScoreboardManager(); + } + + /** + * Gets an instance of the server's default server-icon. + * + * @return the default server-icon; null values may be used by the + * implementation to indicate no defined icon, but this behavior is + * not guaranteed + */ + public static CachedServerIcon getServerIcon() { + return server.getServerIcon(); + } + + /** + * Loads an image from a file, and returns a cached image for the specific + * server-icon. + *

+ * Size and type are implementation defined. An incompatible file is + * guaranteed to throw an implementation-defined {@link Exception}. + * + * @param file the file to load the from + * @throws IllegalArgumentException if image is null + * @throws Exception if the image does not meet current server server-icon + * specifications + * @return a cached server-icon that can be used for a {@link + * ServerListPingEvent#setServerIcon(CachedServerIcon)} + */ + public static CachedServerIcon loadServerIcon(File file) throws IllegalArgumentException, Exception { + return server.loadServerIcon(file); + } + + /** + * Creates a cached server-icon for the specific image. + *

+ * Size and type are implementation defined. An incompatible file is + * guaranteed to throw an implementation-defined {@link Exception}. + * + * @param image the image to use + * @throws IllegalArgumentException if image is null + * @throws Exception if the image does not meet current server + * server-icon specifications + * @return a cached server-icon that can be used for a {@link + * ServerListPingEvent#setServerIcon(CachedServerIcon)} + */ + public static CachedServerIcon loadServerIcon(BufferedImage image) throws IllegalArgumentException, Exception { + return server.loadServerIcon(image); + } + + /** + * Set the idle kick timeout. Any players idle for the specified amount of + * time will be automatically kicked. + *

+ * A value of 0 will disable the idle kick timeout. + * + * @param threshold the idle timeout in minutes + */ + public static void setIdleTimeout(int threshold) { + server.setIdleTimeout(threshold); + } + + /** + * Gets the idle kick timeout. + * + * @return the idle timeout in minutes + */ + public static int getIdleTimeout() { + return server.getIdleTimeout(); + } + + /** + * Create a ChunkData for use in a generator. + * + * See {@link ChunkGenerator#generateChunkData(org.bukkit.World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)} + * + * @param world the world to create the ChunkData for + * @return a new ChunkData for the world + * + */ + public static ChunkGenerator.ChunkData createChunkData(World world) { + return server.createChunkData(world); + } + + /** + * @see UnsafeValues + * @return the unsafe values instance + */ + @Deprecated + public static UnsafeValues getUnsafe() { + return server.getUnsafe(); + } + + // Paper start + /** + * Gets the active {@link CommandMap}. + * + * @return the active command map + */ + public static CommandMap getCommandMap() { + return server.getCommandMap(); + } + // Paper end + + public static Server.Spigot spigot() + { + return server.spigot(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/ChatColor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/ChatColor.java new file mode 100644 index 0000000..adbae51 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/ChatColor.java @@ -0,0 +1,371 @@ +package org.bukkit; + +import java.util.Map; +import java.util.regex.Pattern; + +import org.apache.commons.lang.Validate; + +import com.google.common.collect.Maps; + +/** + * All supported color values for chat + */ +public enum ChatColor{ + /** + * Represents black + */ + BLACK('0', 0x00) { + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.BLACK; + } + }, + /** + * Represents dark blue + */ + DARK_BLUE('1', 0x1){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.DARK_BLUE; + } + }, + /** + * Represents dark green + */ + DARK_GREEN('2', 0x2){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.DARK_GREEN; + } + }, + /** + * Represents dark blue (aqua) + */ + DARK_AQUA('3', 0x3){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.DARK_AQUA; + } + }, + /** + * Represents dark red + */ + DARK_RED('4', 0x4){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.DARK_RED; + } + }, + /** + * Represents dark purple + */ + DARK_PURPLE('5', 0x5){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.DARK_PURPLE; + } + }, + /** + * Represents gold + */ + GOLD('6', 0x6){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.GOLD; + } + }, + /** + * Represents gray + */ + GRAY('7', 0x7){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.GRAY; + } + }, + /** + * Represents dark gray + */ + DARK_GRAY('8', 0x8){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.DARK_GRAY; + } + }, + /** + * Represents blue + */ + BLUE('9', 0x9){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.BLUE; + } + }, + /** + * Represents green + */ + GREEN('a', 0xA){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.GREEN; + } + }, + /** + * Represents aqua + */ + AQUA('b', 0xB){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.AQUA; + } + }, + /** + * Represents red + */ + RED('c', 0xC){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.RED; + } + }, + /** + * Represents light purple + */ + LIGHT_PURPLE('d', 0xD){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.LIGHT_PURPLE; + } + }, + /** + * Represents yellow + */ + YELLOW('e', 0xE){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.YELLOW; + } + }, + /** + * Represents white + */ + WHITE('f', 0xF){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.WHITE; + } + }, + /** + * Represents magical characters that change around randomly + */ + MAGIC('k', 0x10, true){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.MAGIC; + } + }, + /** + * Makes the text bold. + */ + BOLD('l', 0x11, true){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.BOLD; + } + }, + /** + * Makes a line appear through the text. + */ + STRIKETHROUGH('m', 0x12, true){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.STRIKETHROUGH; + } + }, + /** + * Makes the text appear underlined. + */ + UNDERLINE('n', 0x13, true){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.UNDERLINE; + } + }, + /** + * Makes the text italic. + */ + ITALIC('o', 0x14, true){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.ITALIC; + } + }, + /** + * Resets all previous chat colors or formats. + */ + RESET('r', 0x15){ + @Override + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.RESET; + } + }; + + /** + * The special character which prefixes all chat colour codes. Use this if + * you need to dynamically convert colour codes from your custom format. + */ + public static final char COLOR_CHAR = '\u00A7'; + private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "[0-9A-FK-OR]"); + + private final int intCode; + private final char code; + private final boolean isFormat; + private final String toString; + private final static Map BY_ID = Maps.newHashMap(); + private final static Map BY_CHAR = Maps.newHashMap(); + + private ChatColor(char code, int intCode) { + this(code, intCode, false); + } + + private ChatColor(char code, int intCode, boolean isFormat) { + this.code = code; + this.intCode = intCode; + this.isFormat = isFormat; + this.toString = new String(new char[] {COLOR_CHAR, code}); + } + + public net.md_5.bungee.api.ChatColor asBungee() { + return net.md_5.bungee.api.ChatColor.RESET; + }; + + /** + * Gets the char value associated with this color + * + * @return A char value of this color code + */ + public char getChar() { + return code; + } + + @Override + public String toString() { + return toString; + } + + /** + * Checks if this code is a format code as opposed to a color code. + * + * @return whether this ChatColor is a format code + */ + public boolean isFormat() { + return isFormat; + } + + /** + * Checks if this code is a color code as opposed to a format code. + * + * @return whether this ChatColor is a color code + */ + public boolean isColor() { + return !isFormat && this != RESET; + } + + /** + * Gets the color represented by the specified color code + * + * @param code Code to check + * @return Associative {@link org.bukkit.ChatColor} with the given code, + * or null if it doesn't exist + */ + public static ChatColor getByChar(char code) { + return BY_CHAR.get(code); + } + + /** + * Gets the color represented by the specified color code + * + * @param code Code to check + * @return Associative {@link org.bukkit.ChatColor} with the given code, + * or null if it doesn't exist + */ + public static ChatColor getByChar(String code) { + Validate.notNull(code, "Code cannot be null"); + Validate.isTrue(code.length() > 0, "Code must have at least one char"); + + return BY_CHAR.get(code.charAt(0)); + } + + /** + * Strips the given message of all color codes + * + * @param input String to strip of color + * @return A copy of the input string, without any coloring + */ + public static String stripColor(final String input) { + if (input == null) { + return null; + } + + return STRIP_COLOR_PATTERN.matcher(input).replaceAll(""); + } + + /** + * Translates a string using an alternate color code character into a + * string that uses the internal ChatColor.COLOR_CODE color code + * character. The alternate color code character will only be replaced if + * it is immediately followed by 0-9, A-F, a-f, K-O, k-o, R or r. + * + * @param altColorChar The alternate color code character to replace. Ex: {@literal &} + * @param textToTranslate Text containing the alternate color code character. + * @return Text containing the ChatColor.COLOR_CODE color code character. + */ + public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) { + char[] b = textToTranslate.toCharArray(); + for (int i = 0; i < b.length - 1; i++) { + if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i+1]) > -1) { + b[i] = ChatColor.COLOR_CHAR; + b[i+1] = Character.toLowerCase(b[i+1]); + } + } + return new String(b); + } + + /** + * Gets the ChatColors used at the end of the given input string. + * + * @param input Input string to retrieve the colors from. + * @return Any remaining ChatColors to pass onto the next line. + */ + public static String getLastColors(String input) { + String result = ""; + int length = input.length(); + + // Search backwards from the end as it is faster + for (int index = length - 1; index > -1; index--) { + char section = input.charAt(index); + if (section == COLOR_CHAR && index < length - 1) { + char c = input.charAt(index + 1); + ChatColor color = getByChar(c); + + if (color != null) { + result = color.toString() + result; + + // Once we find a color or reset we can stop searching + if (color.isColor() || color.equals(RESET)) { + break; + } + } + } + } + + return result; + } + + static { + for (ChatColor color : values()) { + BY_ID.put(color.intCode, color); + BY_CHAR.put(color.code, color); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Chunk.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Chunk.java new file mode 100644 index 0000000..0510151 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Chunk.java @@ -0,0 +1,124 @@ +package org.bukkit; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; + +/** + * Represents a chunk of blocks + */ +public interface Chunk { + + /** + * Gets the X-coordinate of this chunk + * + * @return X-coordinate + */ + int getX(); + + /** + * Gets the Z-coordinate of this chunk + * + * @return Z-coordinate + */ + int getZ(); + + /** + * Gets the world containing this chunk + * + * @return Parent World + */ + World getWorld(); + + /** + * Gets a block from this chunk + * + * @param x 0-15 + * @param y 0-127 + * @param z 0-15 + * @return the Block + */ + Block getBlock(int x, int y, int z); + + /** + * Capture thread-safe read-only snapshot of chunk data + * + * @return ChunkSnapshot + */ + ChunkSnapshot getChunkSnapshot(); + + /** + * Capture thread-safe read-only snapshot of chunk data + * + * @param includeMaxblocky - if true, snapshot includes per-coordinate + * maximum Y values + * @param includeBiome - if true, snapshot includes per-coordinate biome + * type + * @param includeBiomeTempRain - if true, snapshot includes per-coordinate + * raw biome temperature and rainfall + * @return ChunkSnapshot + */ + ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain); + + /** + * Get a list of all entities in the chunk. + * + * @return The entities. + */ + Entity[] getEntities(); + + /** + * Get a list of all tile entities in the chunk. + * + * @return The tile entities. + */ + BlockState[] getTileEntities(); + + /** + * Checks if the chunk is loaded. + * + * @return True if it is loaded. + */ + boolean isLoaded(); + + /** + * Loads the chunk. + * + * @param generate Whether or not to generate a chunk if it doesn't + * already exist + * @return true if the chunk has loaded successfully, otherwise false + */ + boolean load(boolean generate); + + /** + * Loads the chunk. + * + * @return true if the chunk has loaded successfully, otherwise false + */ + boolean load(); + + /** + * Unloads and optionally saves the Chunk + * + * @param save Controls whether the chunk is saved + * @param safe Controls whether to unload the chunk when players are + * nearby + * @return true if the chunk has unloaded successfully, otherwise false + */ + boolean unload(boolean save, boolean safe); + + /** + * Unloads and optionally saves the Chunk + * + * @param save Controls whether the chunk is saved + * @return true if the chunk has unloaded successfully, otherwise false + */ + boolean unload(boolean save); + + /** + * Unloads and optionally saves the Chunk + * + * @return true if the chunk has unloaded successfully, otherwise false + */ + boolean unload(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/ChunkSnapshot.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/ChunkSnapshot.java new file mode 100644 index 0000000..83fccc8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/ChunkSnapshot.java @@ -0,0 +1,129 @@ +package org.bukkit; + +import org.bukkit.block.Biome; + +/** + * Represents a static, thread-safe snapshot of chunk of blocks. + *

+ * Purpose is to allow clean, efficient copy of a chunk data to be made, and + * then handed off for processing in another thread (e.g. map rendering) + */ +public interface ChunkSnapshot { + + /** + * Gets the X-coordinate of this chunk + * + * @return X-coordinate + */ + int getX(); + + /** + * Gets the Z-coordinate of this chunk + * + * @return Z-coordinate + */ + int getZ(); + + /** + * Gets name of the world containing this chunk + * + * @return Parent World Name + */ + String getWorldName(); + + /** + * Get block type for block at corresponding coordinate in the chunk + * + * @param x 0-15 + * @param y 0-127 + * @param z 0-15 + * @return 0-255 + * @deprecated Magic value + */ + @Deprecated + int getBlockTypeId(int x, int y, int z); + + /** + * Get block data for block at corresponding coordinate in the chunk + * + * @param x 0-15 + * @param y 0-127 + * @param z 0-15 + * @return 0-15 + * @deprecated Magic value + */ + @Deprecated + int getBlockData(int x, int y, int z); + + /** + * Get sky light level for block at corresponding coordinate in the chunk + * + * @param x 0-15 + * @param y 0-127 + * @param z 0-15 + * @return 0-15 + */ + int getBlockSkyLight(int x, int y, int z); + + /** + * Get light level emitted by block at corresponding coordinate in the + * chunk + * + * @param x 0-15 + * @param y 0-127 + * @param z 0-15 + * @return 0-15 + */ + int getBlockEmittedLight(int x, int y, int z); + + /** + * Gets the highest non-air coordinate at the given coordinates + * + * @param x X-coordinate of the blocks + * @param z Z-coordinate of the blocks + * @return Y-coordinate of the highest non-air block + */ + int getHighestBlockYAt(int x, int z); + + /** + * Get biome at given coordinates + * + * @param x X-coordinate + * @param z Z-coordinate + * @return Biome at given coordinate + */ + Biome getBiome(int x, int z); + + /** + * Get raw biome temperature (0.0-1.0) at given coordinate + * + * @param x X-coordinate + * @param z Z-coordinate + * @return temperature at given coordinate + */ + double getRawBiomeTemperature(int x, int z); + + /** + * Get raw biome rainfall (0.0-1.0) at given coordinate + * + * @param x X-coordinate + * @param z Z-coordinate + * @return rainfall at given coordinate + */ + double getRawBiomeRainfall(int x, int z); + + /** + * Get world full time when chunk snapshot was captured + * + * @return time in ticks + */ + long getCaptureFullTime(); + + /** + * Test if section is empty + * + * @param sy - section Y coordinate (block Y / 16) + * @return true if empty, false if not + */ + boolean isSectionEmpty(int sy); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/CoalType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/CoalType.java new file mode 100644 index 0000000..4fcccd2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/CoalType.java @@ -0,0 +1,50 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +/** + * Represents the two types of coal + */ +public enum CoalType { + COAL(0x0), + CHARCOAL(0x1); + + private final byte data; + private final static Map BY_DATA = Maps.newHashMap(); + + private CoalType(final int data) { + this.data = (byte) data; + } + + /** + * Gets the associated data value representing this type of coal + * + * @return A byte containing the data value of this coal type + * @deprecated Magic value + */ + @Deprecated + public byte getData() { + return data; + } + + /** + * Gets the type of coal with the given data value + * + * @param data Data value to fetch + * @return The {@link CoalType} representing the given value, or null if + * it doesn't exist + * @deprecated Magic value + */ + @Deprecated + public static CoalType getByData(final byte data) { + return BY_DATA.get(data); + } + + static { + for (CoalType type : values()) { + BY_DATA.put(type.data, type); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Color.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Color.java new file mode 100644 index 0000000..83927dd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Color.java @@ -0,0 +1,344 @@ +package org.bukkit; + +import java.util.Map; + +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; + +import com.google.common.collect.ImmutableMap; + +/** + * A container for a color palette. This class is immutable; the set methods + * return a new color. The color names listed as fields are HTML4 standards, + * but subject to change. + */ +@SerializableAs("Color") +public final class Color implements ConfigurationSerializable { + private static final int BIT_MASK = 0xff; + + /** + * White, or (0xFF,0xFF,0xFF) in (R,G,B) + */ + public static final Color WHITE = fromRGB(0xFFFFFF); + + /** + * Silver, or (0xC0,0xC0,0xC0) in (R,G,B) + */ + public static final Color SILVER = fromRGB(0xC0C0C0); + + /** + * Gray, or (0x80,0x80,0x80) in (R,G,B) + */ + public static final Color GRAY = fromRGB(0x808080); + + /** + * Black, or (0x00,0x00,0x00) in (R,G,B) + */ + public static final Color BLACK = fromRGB(0x000000); + + /** + * Red, or (0xFF,0x00,0x00) in (R,G,B) + */ + public static final Color RED = fromRGB(0xFF0000); + + /** + * Maroon, or (0x80,0x00,0x00) in (R,G,B) + */ + public static final Color MAROON = fromRGB(0x800000); + + /** + * Yellow, or (0xFF,0xFF,0x00) in (R,G,B) + */ + public static final Color YELLOW = fromRGB(0xFFFF00); + + /** + * Olive, or (0x80,0x80,0x00) in (R,G,B) + */ + public static final Color OLIVE = fromRGB(0x808000); + + /** + * Lime, or (0x00,0xFF,0x00) in (R,G,B) + */ + public static final Color LIME = fromRGB(0x00FF00); + + /** + * Green, or (0x00,0x80,0x00) in (R,G,B) + */ + public static final Color GREEN = fromRGB(0x008000); + + /** + * Aqua, or (0x00,0xFF,0xFF) in (R,G,B) + */ + public static final Color AQUA = fromRGB(0x00FFFF); + + /** + * Teal, or (0x00,0x80,0x80) in (R,G,B) + */ + public static final Color TEAL = fromRGB(0x008080); + + /** + * Blue, or (0x00,0x00,0xFF) in (R,G,B) + */ + public static final Color BLUE = fromRGB(0x0000FF); + + /** + * Navy, or (0x00,0x00,0x80) in (R,G,B) + */ + public static final Color NAVY = fromRGB(0x000080); + + /** + * Fuchsia, or (0xFF,0x00,0xFF) in (R,G,B) + */ + public static final Color FUCHSIA = fromRGB(0xFF00FF); + + /** + * Purple, or (0x80,0x00,0x80) in (R,G,B) + */ + public static final Color PURPLE = fromRGB(0x800080); + + /** + * Orange, or (0xFF,0xA5,0x00) in (R,G,B) + */ + public static final Color ORANGE = fromRGB(0xFFA500); + + private final byte red; + private final byte green; + private final byte blue; + + /** + * Creates a new Color object from a red, green, and blue + * + * @param red integer from 0-255 + * @param green integer from 0-255 + * @param blue integer from 0-255 + * @return a new Color object for the red, green, blue + * @throws IllegalArgumentException if any value is strictly {@literal >255 or <0} + */ + public static Color fromRGB(int red, int green, int blue) throws IllegalArgumentException { + return new Color(red, green, blue); + } + + /** + * Creates a new Color object from a blue, green, and red + * + * @param blue integer from 0-255 + * @param green integer from 0-255 + * @param red integer from 0-255 + * @return a new Color object for the red, green, blue + * @throws IllegalArgumentException if any value is strictly {@literal >255 or <0} + */ + public static Color fromBGR(int blue, int green, int red) throws IllegalArgumentException { + return new Color(red, green, blue); + } + + /** + * Creates a new color object from an integer that contains the red, + * green, and blue bytes in the lowest order 24 bits. + * + * @param rgb the integer storing the red, green, and blue values + * @return a new color object for specified values + * @throws IllegalArgumentException if any data is in the highest order 8 + * bits + */ + public static Color fromRGB(int rgb) throws IllegalArgumentException { + Validate.isTrue((rgb >> 24) == 0, "Extrenuous data in: ", rgb); + return fromRGB(rgb >> 16 & BIT_MASK, rgb >> 8 & BIT_MASK, rgb >> 0 & BIT_MASK); + } + + /** + * Creates a new color object from an integer that contains the blue, + * green, and red bytes in the lowest order 24 bits. + * + * @param bgr the integer storing the blue, green, and red values + * @return a new color object for specified values + * @throws IllegalArgumentException if any data is in the highest order 8 + * bits + */ + public static Color fromBGR(int bgr) throws IllegalArgumentException { + Validate.isTrue((bgr >> 24) == 0, "Extrenuous data in: ", bgr); + return fromBGR(bgr >> 16 & BIT_MASK, bgr >> 8 & BIT_MASK, bgr >> 0 & BIT_MASK); + } + + private Color(int red, int green, int blue) { + Validate.isTrue(red >= 0 && red <= BIT_MASK, "Red is not between 0-255: ", red); + Validate.isTrue(green >= 0 && green <= BIT_MASK, "Green is not between 0-255: ", green); + Validate.isTrue(blue >= 0 && blue <= BIT_MASK, "Blue is not between 0-255: ", blue); + + this.red = (byte) red; + this.green = (byte) green; + this.blue = (byte) blue; + } + + /** + * Gets the red component + * + * @return red component, from 0 to 255 + */ + public int getRed() { + return BIT_MASK & red; + } + + /** + * Creates a new Color object with specified component + * + * @param red the red component, from 0 to 255 + * @return a new color object with the red component + */ + public Color setRed(int red) { + return fromRGB(red, getGreen(), getBlue()); + } + + /** + * Gets the green component + * + * @return green component, from 0 to 255 + */ + public int getGreen() { + return BIT_MASK & green; + } + + /** + * Creates a new Color object with specified component + * + * @param green the red component, from 0 to 255 + * @return a new color object with the red component + */ + public Color setGreen(int green) { + return fromRGB(getRed(), green, getBlue()); + } + + /** + * Gets the blue component + * + * @return blue component, from 0 to 255 + */ + public int getBlue() { + return BIT_MASK & blue; + } + + /** + * Creates a new Color object with specified component + * + * @param blue the red component, from 0 to 255 + * @return a new color object with the red component + */ + public Color setBlue(int blue) { + return fromRGB(getRed(), getGreen(), blue); + } + + /** + * + * @return An integer representation of this color, as 0xRRGGBB + */ + public int asRGB() { + return getRed() << 16 | getGreen() << 8 | getBlue() << 0; + } + + /** + * + * @return An integer representation of this color, as 0xBBGGRR + */ + public int asBGR() { + return getBlue() << 16 | getGreen() << 8 | getRed() << 0; + } + + /** + * Creates a new color with its RGB components changed as if it was dyed + * with the colors passed in, replicating vanilla workbench dyeing + * + * @param colors The DyeColors to dye with + * @return A new color with the changed rgb components + */ + // TODO: Javadoc what this method does, not what it mimics. API != Implementation + public Color mixDyes(DyeColor... colors) { + Validate.noNullElements(colors, "Colors cannot be null"); + + Color[] toPass = new Color[colors.length]; + for (int i = 0; i < colors.length; i++) { + toPass[i] = colors[i].getColor(); + } + + return mixColors(toPass); + } + + /** + * Creates a new color with its RGB components changed as if it was dyed + * with the colors passed in, replicating vanilla workbench dyeing + * + * @param colors The colors to dye with + * @return A new color with the changed rgb components + */ + // TODO: Javadoc what this method does, not what it mimics. API != Implementation + public Color mixColors(Color... colors) { + Validate.noNullElements(colors, "Colors cannot be null"); + + int totalRed = this.getRed(); + int totalGreen = this.getGreen(); + int totalBlue = this.getBlue(); + int totalMax = Math.max(Math.max(totalRed, totalGreen), totalBlue); + for (Color color : colors) { + totalRed += color.getRed(); + totalGreen += color.getGreen(); + totalBlue += color.getBlue(); + totalMax += Math.max(Math.max(color.getRed(), color.getGreen()), color.getBlue()); + } + + float averageRed = totalRed / (colors.length + 1); + float averageGreen = totalGreen / (colors.length + 1); + float averageBlue = totalBlue / (colors.length + 1); + float averageMax = totalMax / (colors.length + 1); + + float maximumOfAverages = Math.max(Math.max(averageRed, averageGreen), averageBlue); + float gainFactor = averageMax / maximumOfAverages; + + return Color.fromRGB((int) (averageRed * gainFactor), (int) (averageGreen * gainFactor), (int) (averageBlue * gainFactor)); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Color)) { + return false; + } + final Color that = (Color) o; + return this.blue == that.blue && this.green == that.green && this.red == that.red; + } + + @Override + public int hashCode() { + return asRGB() ^ Color.class.hashCode(); + } + + public Map serialize() { + return ImmutableMap.of( + "RED", getRed(), + "BLUE", getBlue(), + "GREEN", getGreen() + ); + } + + @SuppressWarnings("javadoc") + public static Color deserialize(Map map) { + return fromRGB( + asInt("RED", map), + asInt("GREEN", map), + asInt("BLUE", map) + ); + } + + private static int asInt(String string, Map map) { + Object value = map.get(string); + if (value == null) { + throw new IllegalArgumentException(string + " not in map " + map); + } + if (!(value instanceof Number)) { + throw new IllegalArgumentException(string + '(' + value + ") is not a number"); + } + return ((Number) value).intValue(); + } + + @Override + public String toString() { + return "Color:[rgb0x" + Integer.toHexString(getRed()).toUpperCase() + Integer.toHexString(getGreen()).toUpperCase() + Integer.toHexString(getBlue()).toUpperCase() + "]"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/CropState.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/CropState.java new file mode 100644 index 0000000..ef0faf9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/CropState.java @@ -0,0 +1,81 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +/** + * Represents the different growth states of crops + */ +public enum CropState { + + /** + * State when first seeded + */ + SEEDED(0x0), + /** + * First growth stage + */ + GERMINATED(0x1), + /** + * Second growth stage + */ + VERY_SMALL(0x2), + /** + * Third growth stage + */ + SMALL(0x3), + /** + * Fourth growth stage + */ + MEDIUM(0x4), + /** + * Fifth growth stage + */ + TALL(0x5), + /** + * Almost ripe stage + */ + VERY_TALL(0x6), + /** + * Ripe stage + */ + RIPE(0x7); + + private final byte data; + private final static Map BY_DATA = Maps.newHashMap(); + + private CropState(final int data) { + this.data = (byte) data; + } + + /** + * Gets the associated data value representing this growth state + * + * @return A byte containing the data value of this growth state + * @deprecated Magic value + */ + @Deprecated + public byte getData() { + return data; + } + + /** + * Gets the CropState with the given data value + * + * @param data Data value to fetch + * @return The {@link CropState} representing the given value, or null if + * it doesn't exist + * @deprecated Magic value + */ + @Deprecated + public static CropState getByData(final byte data) { + return BY_DATA.get(data); + } + + static { + for (CropState cropState : values()) { + BY_DATA.put(cropState.getData(), cropState); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Difficulty.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Difficulty.java new file mode 100644 index 0000000..a8a5a78 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Difficulty.java @@ -0,0 +1,72 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +/** + * Represents the various difficulty levels that are available. + */ +public enum Difficulty { + /** + * Players regain health over time, hostile mobs don't spawn, the hunger + * bar does not deplete. + */ + PEACEFUL(0), + + /** + * Hostile mobs spawn, enemies deal less damage than on normal difficulty, + * the hunger bar does deplete and starving deals up to 5 hearts of + * damage. (Default value) + */ + EASY(1), + + /** + * Hostile mobs spawn, enemies deal normal amounts of damage, the hunger + * bar does deplete and starving deals up to 9.5 hearts of damage. + */ + NORMAL(2), + + /** + * Hostile mobs spawn, enemies deal greater damage than on normal + * difficulty, the hunger bar does deplete and starving can kill players. + */ + HARD(3); + + private final int value; + private final static Map BY_ID = Maps.newHashMap(); + + private Difficulty(final int value) { + this.value = value; + } + + /** + * Gets the difficulty value associated with this Difficulty. + * + * @return An integer value of this difficulty + * @deprecated Magic value + */ + @Deprecated + public int getValue() { + return value; + } + + /** + * Gets the Difficulty represented by the specified value + * + * @param value Value to check + * @return Associative {@link Difficulty} with the given value, or null if + * it doesn't exist + * @deprecated Magic value + */ + @Deprecated + public static Difficulty getByValue(final int value) { + return BY_ID.get(value); + } + + static { + for (Difficulty diff : values()) { + BY_ID.put(diff.value, diff); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/DyeColor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/DyeColor.java new file mode 100644 index 0000000..214806e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/DyeColor.java @@ -0,0 +1,239 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.ImmutableMap; + +/** + * All supported color values for dyes and cloth + */ +public enum DyeColor { + + /** + * Represents white dye. + */ + WHITE(0x0, 0xF, Color.WHITE, Color.fromRGB(0xF0F0F0)), + /** + * Represents orange dye. + */ + ORANGE(0x1, 0xE, Color.fromRGB(0xD87F33), Color.fromRGB(0xEB8844)), + /** + * Represents magenta dye. + */ + MAGENTA(0x2, 0xD, Color.fromRGB(0xB24CD8), Color.fromRGB(0xC354CD)), + /** + * Represents light blue dye. + */ + LIGHT_BLUE(0x3, 0xC, Color.fromRGB(0x6699D8), Color.fromRGB(0x6689D3)), + /** + * Represents yellow dye. + */ + YELLOW(0x4, 0xB, Color.fromRGB(0xE5E533), Color.fromRGB(0xDECF2A)), + /** + * Represents lime dye. + */ + LIME(0x5, 0xA, Color.fromRGB(0x7FCC19), Color.fromRGB(0x41CD34)), + /** + * Represents pink dye. + */ + PINK(0x6, 0x9, Color.fromRGB(0xF27FA5), Color.fromRGB(0xD88198)), + /** + * Represents gray dye. + */ + GRAY(0x7, 0x8, Color.fromRGB(0x4C4C4C), Color.fromRGB(0x434343)), + /** + * Represents silver dye. + */ + SILVER(0x8, 0x7, Color.fromRGB(0x999999), Color.fromRGB(0xABABAB)), + /** + * Represents cyan dye. + */ + CYAN(0x9, 0x6, Color.fromRGB(0x4C7F99), Color.fromRGB(0x287697)), + /** + * Represents purple dye. + */ + PURPLE(0xA, 0x5, Color.fromRGB(0x7F3FB2), Color.fromRGB(0x7B2FBE)), + /** + * Represents blue dye. + */ + BLUE(0xB, 0x4, Color.fromRGB(0x334CB2), Color.fromRGB(0x253192)), + /** + * Represents brown dye. + */ + BROWN(0xC, 0x3, Color.fromRGB(0x664C33), Color.fromRGB(0x51301A)), + /** + * Represents green dye. + */ + GREEN(0xD, 0x2, Color.fromRGB(0x667F33), Color.fromRGB(0x3B511A)), + /** + * Represents red dye. + */ + RED(0xE, 0x1, Color.fromRGB(0x993333), Color.fromRGB(0xB3312C)), + /** + * Represents black dye. + */ + BLACK(0xF, 0x0, Color.fromRGB(0x191919), Color.fromRGB(0x1E1B1B)); + + private final byte woolData; + private final byte dyeData; + private final Color color; + private final Color firework; + private final static DyeColor[] BY_WOOL_DATA; + private final static DyeColor[] BY_DYE_DATA; + private final static Map BY_COLOR; + private final static Map BY_FIREWORK; + + private DyeColor(final int woolData, final int dyeData, Color color, Color firework) { + this.woolData = (byte) woolData; + this.dyeData = (byte) dyeData; + this.color = color; + this.firework = firework; + } + + /** + * Gets the associated (wool) data value representing this color. + * + * @return A byte containing the (wool) data value of this color + * @deprecated The name is misleading. It would imply {@link + * Material#INK_SACK} but uses {@link Material#WOOL} + * @see #getWoolData() + * @see #getDyeData() + */ + @Deprecated + public byte getData() { + return getWoolData(); + } + + /** + * Gets the associated wool data value representing this color. + * + * @return A byte containing the wool data value of this color + * @see #getDyeData() + * @deprecated Magic value + */ + @Deprecated + public byte getWoolData() { + return woolData; + } + + /** + * Gets the associated dye data value representing this color. + * + * @return A byte containing the dye data value of this color + * @see #getWoolData() + * @deprecated Magic value + */ + @Deprecated + public byte getDyeData() { + return dyeData; + } + + /** + * Gets the color that this dye represents. + * + * @return The {@link Color} that this dye represents + */ + public Color getColor() { + return color; + } + + /** + * Gets the firework color that this dye represents. + * + * @return The {@link Color} that this dye represents + */ + public Color getFireworkColor() { + return firework; + } + + /** + * Gets the DyeColor with the given (wool) data value. + * + * @param data (wool) data value to fetch + * @return The {@link DyeColor} representing the given value, or null if + * it doesn't exist + * @deprecated The name is misleading. It would imply {@link + * Material#INK_SACK} but uses {@link Material#WOOL} + * @see #getByDyeData(byte) + * @see #getByWoolData(byte) + */ + @Deprecated + public static DyeColor getByData(final byte data) { + return getByWoolData(data); + } + + /** + * Gets the DyeColor with the given wool data value. + * + * @param data Wool data value to fetch + * @return The {@link DyeColor} representing the given value, or null if + * it doesn't exist + * @see #getByDyeData(byte) + * @deprecated Magic value + */ + @Deprecated + public static DyeColor getByWoolData(final byte data) { + int i = 0xff & data; + if (i >= BY_WOOL_DATA.length) { + return null; + } + return BY_WOOL_DATA[i]; + } + + /** + * Gets the DyeColor with the given dye data value. + * + * @param data Dye data value to fetch + * @return The {@link DyeColor} representing the given value, or null if + * it doesn't exist + * @see #getByWoolData(byte) + * @deprecated Magic value + */ + @Deprecated + public static DyeColor getByDyeData(final byte data) { + int i = 0xff & data; + if (i >= BY_DYE_DATA.length) { + return null; + } + return BY_DYE_DATA[i]; + } + + /** + * Gets the DyeColor with the given color value. + * + * @param color Color value to get the dye by + * @return The {@link DyeColor} representing the given value, or null if + * it doesn't exist + */ + public static DyeColor getByColor(final Color color) { + return BY_COLOR.get(color); + } + + /** + * Gets the DyeColor with the given firework color value. + * + * @param color Color value to get dye by + * @return The {@link DyeColor} representing the given value, or null if + * it doesn't exist + */ + public static DyeColor getByFireworkColor(final Color color) { + return BY_FIREWORK.get(color); + } + + static { + BY_WOOL_DATA = values(); + BY_DYE_DATA = values(); + ImmutableMap.Builder byColor = ImmutableMap.builder(); + ImmutableMap.Builder byFirework = ImmutableMap.builder(); + + for (DyeColor color : values()) { + BY_WOOL_DATA[color.woolData & 0xff] = color; + BY_DYE_DATA[color.dyeData & 0xff] = color; + byColor.put(color.getColor(), color); + byFirework.put(color.getFireworkColor(), color); + } + + BY_COLOR = byColor.build(); + BY_FIREWORK = byFirework.build(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Effect.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Effect.java new file mode 100644 index 0000000..37f29e2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Effect.java @@ -0,0 +1,337 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +import org.bukkit.block.BlockFace; +import org.bukkit.material.MaterialData; +import org.bukkit.potion.Potion; + +/** + * A list of effects that the server is able to send to players. + */ +public enum Effect { + /** + * An alternate click sound. + */ + CLICK2(1000, Type.SOUND), + /** + * A click sound. + */ + CLICK1(1001, Type.SOUND), + /** + * Sound of a bow firing. + */ + BOW_FIRE(1002, Type.SOUND), + /** + * Sound of a door opening/closing. + */ + DOOR_TOGGLE(1003, Type.SOUND), + /** + * Sound of fire being extinguished. + */ + EXTINGUISH(1004, Type.SOUND), + /** + * A song from a record. Needs the record item ID as additional info + */ + RECORD_PLAY(1005, Type.SOUND, Material.class), + /** + * Sound of ghast shrieking. + */ + GHAST_SHRIEK(1007, Type.SOUND), + /** + * Sound of ghast firing. + */ + GHAST_SHOOT(1008, Type.SOUND), + /** + * Sound of blaze firing. + */ + BLAZE_SHOOT(1009, Type.SOUND), + /** + * Sound of zombies chewing on wooden doors. + */ + ZOMBIE_CHEW_WOODEN_DOOR(1010, Type.SOUND), + /** + * Sound of zombies chewing on iron doors. + */ + ZOMBIE_CHEW_IRON_DOOR(1011, Type.SOUND), + /** + * Sound of zombies destroying a door. + */ + ZOMBIE_DESTROY_DOOR(1012, Type.SOUND), + /** + * A visual smoke effect. Needs direction as additional info. + */ + SMOKE(2000, Type.VISUAL, BlockFace.class), + /** + * Sound of a block breaking. Needs block ID as additional info. + */ + STEP_SOUND(2001, Type.SOUND, Material.class), + /** + * Visual effect of a splash potion breaking. Needs potion data value as + * additional info. + */ + POTION_BREAK(2002, Type.VISUAL, Potion.class), + /** + * An ender eye signal; a visual effect. + */ + ENDER_SIGNAL(2003, Type.VISUAL), + /** + * The flames seen on a mobspawner; a visual effect. + */ + MOBSPAWNER_FLAMES(2004, Type.VISUAL), + /** + * The spark that comes off a fireworks + */ + FIREWORKS_SPARK("fireworksSpark", Type.PARTICLE), + /** + * Critical hit particles + */ + CRIT("crit", Type.PARTICLE), + /** + * Blue critical hit particles + */ + MAGIC_CRIT("magicCrit", Type.PARTICLE), + /** + * Multicolored potion effect particles + */ + POTION_SWIRL("mobSpell", Type.PARTICLE), + /** + * Multicolored potion effect particles that are slightly transparent + */ + POTION_SWIRL_TRANSPARENT("mobSpellAmbient", Type.PARTICLE), + /** + * A puff of white potion swirls + */ + SPELL("spell", Type.PARTICLE), + /** + * A puff of white stars + */ + INSTANT_SPELL("instantSpell", Type.PARTICLE), + /** + * A puff of purple particles + */ + WITCH_MAGIC("witchMagic", Type.PARTICLE), + /** + * The note that appears above note blocks + */ + NOTE("note", Type.PARTICLE), + /** + * The particles shown at nether portals + */ + PORTAL("portal", Type.PARTICLE), + /** + * The symbols that fly towards the enchantment table + */ + FLYING_GLYPH("enchantmenttable", Type.PARTICLE), + /** + * Fire particles + */ + FLAME("flame", Type.PARTICLE), + /** + * The particles that pop out of lava + */ + LAVA_POP("lava", Type.PARTICLE), + /** + * A small gray square + */ + FOOTSTEP("footstep", Type.PARTICLE), + /** + * Water particles + */ + SPLASH("splash", Type.PARTICLE), + /** + * Smoke particles + */ + PARTICLE_SMOKE("smoke", Type.PARTICLE), + /** + * The biggest explosion particle effect + */ + EXPLOSION_HUGE("hugeexplosion", Type.PARTICLE), + /** + * A larger version of the explode particle + */ + EXPLOSION_LARGE("largeexplode", Type.PARTICLE), + /** + * Explosion particles + */ + EXPLOSION("explode", Type.PARTICLE), + /** + * Small gray particles + */ + VOID_FOG("depthsuspend", Type.PARTICLE), + /** + * Small gray particles + */ + SMALL_SMOKE("townaura", Type.PARTICLE), + /** + * A puff of white smoke + */ + CLOUD("cloud", Type.PARTICLE), + /** + * Multicolored dust particles + */ + COLOURED_DUST("reddust", Type.PARTICLE), + /** + * Snowball breaking + */ + SNOWBALL_BREAK("snowballpoof", Type.PARTICLE), + /** + * The water drip particle that appears on blocks under water + */ + WATERDRIP("dripWater", Type.PARTICLE), + /** + * The lava drip particle that appears on blocks under lava + */ + LAVADRIP("dripLava", Type.PARTICLE), + /** + * White particles + */ + SNOW_SHOVEL("snowshovel", Type.PARTICLE), + /** + * The particle shown when a slime jumps + */ + SLIME("slime", Type.PARTICLE), + /** + * The particle that appears when breading animals + */ + HEART("heart", Type.PARTICLE), + /** + * The particle that appears when hitting a villager + */ + VILLAGER_THUNDERCLOUD("angryVillager", Type.PARTICLE), + /** + * The particle that appears when trading with a villager + */ + HAPPY_VILLAGER("happyVillager", Type.PARTICLE), + /** + * The smoke particles that appears on blazes, minecarts + * with furnaces and fire + */ + LARGE_SMOKE("largesmoke", Type.PARTICLE), + /** + * The particles generated when a tool breaks. + * This particle requires a Material so that the client can select the correct texture. + */ + ITEM_BREAK("iconcrack", Type.PARTICLE, Material.class), + /** + * The particles generated while breaking a block. + * This particle requires a Material and data value so that the client can select the correct texture. + */ + TILE_BREAK("blockcrack", Type.PARTICLE, MaterialData.class), + /** + * The particles generated while sprinting a block + * This particle requires a Material and data value so that the client can select the correct texture. + */ + TILE_DUST("blockdust", Type.PARTICLE, MaterialData.class); + + private final int id; + private final Type type; + private final Class data; + private static final Map BY_ID = Maps.newHashMap(); + private static final Map BY_NAME = Maps.newHashMap(); + private final String particleName; + + private Effect(int id, Type type) { + this(id,type,null); + } + + private Effect(int id, Type type, Class data) { + this.id = id; + this.type = type; + this.data = data; + particleName = null; + } + + private Effect(String particleName, Type type, Class data) { + this.particleName = particleName; + this.type = type; + id = 0; + this.data = data; + } + + private Effect(String particleName, Type type) { + this.particleName = particleName; + this.type = type; + id = 0; + this.data = null; + } + + /** + * Gets the ID for this effect. + * + * @return if this Effect isn't of type PARTICLE it returns ID of this effect + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return this.id; + } + + /** + * Returns the effect's name. This returns null if the effect is not a particle + * + * @return The effect's name + */ + public String getName() { + return particleName; + } + + /** + * @return The type of the effect. + */ + public Type getType() { + return this.type; + } + + /** + * @return if this Effect isn't of type PARTICLE it returns the class which represents data for this effect, or null if none + */ + public Class getData() { + return this.data; + } + + /** + * Gets the Effect associated with the given ID. + * + * @param id ID of the Effect to return + * @return Effect with the given ID + * @deprecated Magic value + */ + @Deprecated + public static Effect getById(int id) { + return BY_ID.get(id); + } + + static { + for (Effect effect : values()) { + if (effect.type != Type.PARTICLE) { + BY_ID.put(effect.id, effect); + } + } + } + + /** + * Gets the Effect associated with the given name. + * + * @param name name of the Effect to return + * @return Effect with the given name + */ + public static Effect getByName(String name) { + return BY_NAME.get(name); + } + + static { + for (Effect effect : values()) { + if (effect.type == Type.PARTICLE) { + BY_NAME.put(effect.particleName, effect); + } + } + } + + /** + * Represents the type of an effect. + */ + public enum Type {SOUND, VISUAL, PARTICLE} +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/EntityEffect.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/EntityEffect.java new file mode 100644 index 0000000..c816edf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/EntityEffect.java @@ -0,0 +1,136 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +/** + * A list of all Effects that can happen to entities. + */ +public enum EntityEffect { + + /** + * When mobs get hurt. + */ + HURT(2), + + /** + * When a mob dies. + *

+ * This will cause client-glitches! + */ + DEATH(3), + + /** + * The smoke when taming a wolf fails. + *

+ * Without client-mods this will be ignored if the entity is not a wolf. + */ + WOLF_SMOKE(6), + + /** + * The hearts when taming a wolf succeeds. + *

+ * Without client-mods this will be ignored if the entity is not a wolf. + */ + WOLF_HEARTS(7), + + /** + * When a wolf shakes (after being wet). + *

+ * Without client-mods this will be ignored if the entity is not a wolf. + */ + WOLF_SHAKE(8), + + /** + * When a sheep eats a LONG_GRASS block. + */ + SHEEP_EAT(10), + + /** + * When an Iron Golem gives a rose. + *

+ * This will not play an effect if the entity is not an iron golem. + */ + IRON_GOLEM_ROSE(11), + + /** + * Hearts from a villager. + *

+ * This will not play an effect if the entity is not a villager. + */ + VILLAGER_HEART(12), + + /** + * When a villager is angry. + *

+ * This will not play an effect if the entity is not a villager. + */ + VILLAGER_ANGRY(13), + + /** + * Happy particles from a villager. + *

+ * This will not play an effect if the entity is not a villager. + */ + VILLAGER_HAPPY(14), + + /** + * Magic particles from a witch. + *

+ * This will not play an effect if the entity is not a witch. + */ + WITCH_MAGIC(15), + + /** + * When a zombie transforms into a villager by shaking violently. + *

+ * This will not play an effect if the entity is not a zombie. + */ + ZOMBIE_TRANSFORM(16), + + /** + * When a firework explodes. + *

+ * This will not play an effect if the entity is not a firework. + */ + FIREWORK_EXPLODE(17); + + private final byte data; + private final static Map BY_DATA = Maps.newHashMap(); + + EntityEffect(final int data) { + this.data = (byte) data; + } + + /** + * Gets the data value of this EntityEffect + * + * @return The data value + * @deprecated Magic value + */ + @Deprecated + public byte getData() { + return data; + } + + /** + * Gets the EntityEffect with the given data value + * + * @param data Data value to fetch + * @return The {@link EntityEffect} representing the given value, or null + * if it doesn't exist + * @deprecated Magic value + */ + @Deprecated + public static EntityEffect getByData(final byte data) { + return BY_DATA.get(data); + } + + + static { + for (EntityEffect entityEffect : values()) { + BY_DATA.put(entityEffect.data, entityEffect); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/FireworkEffect.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/FireworkEffect.java new file mode 100644 index 0000000..4b0687f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/FireworkEffect.java @@ -0,0 +1,424 @@ +package org.bukkit; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +/** + * Represents a single firework effect. + */ +@SerializableAs("Firework") +public final class FireworkEffect implements ConfigurationSerializable { + + /** + * The type or shape of the effect. + */ + public enum Type { + /** + * A small ball effect. + */ + BALL, + /** + * A large ball effect. + */ + BALL_LARGE, + /** + * A star-shaped effect. + */ + STAR, + /** + * A burst effect. + */ + BURST, + /** + * A creeper-face effect. + */ + CREEPER, + ; + } + + /** + * Construct a firework effect. + * + * @return A utility object for building a firework effect + */ + public static Builder builder() { + return new Builder(); + } + + /** + * This is a builder for FireworkEffects. + * + * @see FireworkEffect#builder() + */ + public static final class Builder { + boolean flicker = false; + boolean trail = false; + final ImmutableList.Builder colors = ImmutableList.builder(); + ImmutableList.Builder fadeColors = null; + Type type = Type.BALL; + + Builder() {} + + /** + * Specify the type of the firework effect. + * + * @param type The effect type + * @return This object, for chaining + * @throws IllegalArgumentException If type is null + */ + public Builder with(Type type) throws IllegalArgumentException { + Validate.notNull(type, "Cannot have null type"); + this.type = type; + return this; + } + + /** + * Add a flicker to the firework effect. + * + * @return This object, for chaining + */ + public Builder withFlicker() { + flicker = true; + return this; + } + + /** + * Set whether the firework effect should flicker. + * + * @param flicker true if it should flicker, false if not + * @return This object, for chaining + */ + public Builder flicker(boolean flicker) { + this.flicker = flicker; + return this; + } + + /** + * Add a trail to the firework effect. + * + * @return This object, for chaining + */ + public Builder withTrail() { + trail = true; + return this; + } + + /** + * Set whether the firework effect should have a trail. + * + * @param trail true if it should have a trail, false for no trail + * @return This object, for chaining + */ + public Builder trail(boolean trail) { + this.trail = trail; + return this; + } + + /** + * Add a primary color to the firework effect. + * + * @param color The color to add + * @return This object, for chaining + * @throws IllegalArgumentException If color is null + */ + public Builder withColor(Color color) throws IllegalArgumentException { + Validate.notNull(color, "Cannot have null color"); + + colors.add(color); + + return this; + } + + /** + * Add several primary colors to the firework effect. + * + * @param colors The colors to add + * @return This object, for chaining + * @throws IllegalArgumentException If colors is null + * @throws IllegalArgumentException If any color is null (may be + * thrown after changes have occurred) + */ + public Builder withColor(Color...colors) throws IllegalArgumentException { + Validate.notNull(colors, "Cannot have null colors"); + if (colors.length == 0) { + return this; + } + + ImmutableList.Builder list = this.colors; + for (Color color : colors) { + Validate.notNull(color, "Color cannot be null"); + list.add(color); + } + + return this; + } + + /** + * Add several primary colors to the firework effect. + * + * @param colors An iterable object whose iterator yields the desired + * colors + * @return This object, for chaining + * @throws IllegalArgumentException If colors is null + * @throws IllegalArgumentException If any color is null (may be + * thrown after changes have occurred) + */ + public Builder withColor(Iterable colors) throws IllegalArgumentException { + Validate.notNull(colors, "Cannot have null colors"); + + ImmutableList.Builder list = this.colors; + for (Object color : colors) { + if (!(color instanceof Color)) { + throw new IllegalArgumentException(color + " is not a Color in " + colors); + } + list.add((Color) color); + } + + return this; + } + + /** + * Add a fade color to the firework effect. + * + * @param color The color to add + * @return This object, for chaining + * @throws IllegalArgumentException If colors is null + * @throws IllegalArgumentException If any color is null (may be + * thrown after changes have occurred) + */ + public Builder withFade(Color color) throws IllegalArgumentException { + Validate.notNull(color, "Cannot have null color"); + + if (fadeColors == null) { + fadeColors = ImmutableList.builder(); + } + + fadeColors.add(color); + + return this; + } + + /** + * Add several fade colors to the firework effect. + * + * @param colors The colors to add + * @return This object, for chaining + * @throws IllegalArgumentException If colors is null + * @throws IllegalArgumentException If any color is null (may be + * thrown after changes have occurred) + */ + public Builder withFade(Color...colors) throws IllegalArgumentException { + Validate.notNull(colors, "Cannot have null colors"); + if (colors.length == 0) { + return this; + } + + ImmutableList.Builder list = this.fadeColors; + if (list == null) { + list = this.fadeColors = ImmutableList.builder(); + } + + for (Color color : colors) { + Validate.notNull(color, "Color cannot be null"); + list.add(color); + } + + return this; + } + + /** + * Add several fade colors to the firework effect. + * + * @param colors An iterable object whose iterator yields the desired + * colors + * @return This object, for chaining + * @throws IllegalArgumentException If colors is null + * @throws IllegalArgumentException If any color is null (may be + * thrown after changes have occurred) + */ + public Builder withFade(Iterable colors) throws IllegalArgumentException { + Validate.notNull(colors, "Cannot have null colors"); + + ImmutableList.Builder list = this.fadeColors; + if (list == null) { + list = this.fadeColors = ImmutableList.builder(); + } + + for (Object color : colors) { + if (!(color instanceof Color)) { + throw new IllegalArgumentException(color + " is not a Color in " + colors); + } + list.add((Color) color); + } + + return this; + } + + /** + * Create a {@link FireworkEffect} from the current contents of this + * builder. + *

+ * To successfully build, you must have specified at least one color. + * + * @return The representative firework effect + */ + public FireworkEffect build() { + return new FireworkEffect( + flicker, + trail, + colors.build(), + fadeColors == null ? ImmutableList.of() : fadeColors.build(), + type + ); + } + } + + private static final String FLICKER = "flicker"; + private static final String TRAIL = "trail"; + private static final String COLORS = "colors"; + private static final String FADE_COLORS = "fade-colors"; + private static final String TYPE = "type"; + + private final boolean flicker; + private final boolean trail; + private final ImmutableList colors; + private final ImmutableList fadeColors; + private final Type type; + private String string = null; + + FireworkEffect(boolean flicker, boolean trail, ImmutableList colors, ImmutableList fadeColors, Type type) { + if (colors.isEmpty()) { + throw new IllegalStateException("Cannot make FireworkEffect without any color"); + } + this.flicker = flicker; + this.trail = trail; + this.colors = colors; + this.fadeColors = fadeColors; + this.type = type; + } + + /** + * Get whether the firework effect flickers. + * + * @return true if it flickers, false if not + */ + public boolean hasFlicker() { + return flicker; + } + + /** + * Get whether the firework effect has a trail. + * + * @return true if it has a trail, false if not + */ + public boolean hasTrail() { + return trail; + } + + /** + * Get the primary colors of the firework effect. + * + * @return An immutable list of the primary colors + */ + public List getColors() { + return colors; + } + + /** + * Get the fade colors of the firework effect. + * + * @return An immutable list of the fade colors + */ + public List getFadeColors() { + return fadeColors; + } + + /** + * Get the type of the firework effect. + * + * @return The effect type + */ + public Type getType() { + return type; + } + + /** + * @see ConfigurationSerializable + * @param map the map to deserialize + * @return the resulting serializable + */ + public static ConfigurationSerializable deserialize(Map map) { + Type type = Type.valueOf((String) map.get(TYPE)); + if (type == null) { + throw new IllegalArgumentException(map.get(TYPE) + " is not a valid Type"); + } + + return builder() + .flicker((Boolean) map.get(FLICKER)) + .trail((Boolean) map.get(TRAIL)) + .withColor((Iterable) map.get(COLORS)) + .withFade((Iterable) map.get(FADE_COLORS)) + .with(type) + .build(); + } + + @Override + public Map serialize() { + return ImmutableMap.of( + FLICKER, flicker, + TRAIL, trail, + COLORS, colors, + FADE_COLORS, fadeColors, + TYPE, type.name() + ); + } + + @Override + public String toString() { + final String string = this.string; + if (string == null) { + return this.string = "FireworkEffect:" + serialize(); + } + return string; + } + + @Override + public int hashCode() { + /** + * TRUE and FALSE as per boolean.hashCode() + */ + final int PRIME = 31, TRUE = 1231, FALSE = 1237; + int hash = 1; + hash = hash * PRIME + (flicker ? TRUE : FALSE); + hash = hash * PRIME + (trail ? TRUE : FALSE); + hash = hash * PRIME + type.hashCode(); + hash = hash * PRIME + colors.hashCode(); + hash = hash * PRIME + fadeColors.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof FireworkEffect)) { + return false; + } + + FireworkEffect that = (FireworkEffect) obj; + return this.flicker == that.flicker + && this.trail == that.trail + && this.type == that.type + && this.colors.equals(that.colors) + && this.fadeColors.equals(that.fadeColors); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/GameMode.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/GameMode.java new file mode 100644 index 0000000..803944e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/GameMode.java @@ -0,0 +1,73 @@ +package org.bukkit; + +import java.util.Map; + +import org.bukkit.entity.HumanEntity; + +import com.google.common.collect.Maps; + +/** + * Represents the various type of game modes that {@link HumanEntity}s may + * have + */ +public enum GameMode { + /** + * Creative mode may fly, build instantly, become invulnerable and create + * free items. + */ + CREATIVE(1), + + /** + * Survival mode is the "normal" gameplay type, with no special features. + */ + SURVIVAL(0), + + /** + * Adventure mode cannot break blocks without the correct tools. + */ + ADVENTURE(2), + + /** + * Spectator mode cannot interact with the world in anyway and is + * invisible to normal players. This grants the player the + * ability to no-clip through the world. + */ + SPECTATOR(3); + + private final int value; + private final static Map BY_ID = Maps.newHashMap(); + + private GameMode(final int value) { + this.value = value; + } + + /** + * Gets the mode value associated with this GameMode + * + * @return An integer value of this gamemode + * @deprecated Magic value + */ + @Deprecated + public int getValue() { + return value; + } + + /** + * Gets the GameMode represented by the specified value + * + * @param value Value to check + * @return Associative {@link GameMode} with the given value, or null if + * it doesn't exist + * @deprecated Magic value + */ + @Deprecated + public static GameMode getByValue(final int value) { + return BY_ID.get(value); + } + + static { + for (GameMode mode : values()) { + BY_ID.put(mode.getValue(), mode); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/GrassSpecies.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/GrassSpecies.java new file mode 100644 index 0000000..1111515 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/GrassSpecies.java @@ -0,0 +1,61 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +/** + * Represents the different types of grass. + */ +public enum GrassSpecies { + + /** + * Represents the dead looking grass. + */ + DEAD(0x0), + /** + * Represents the normal grass species. + */ + NORMAL(0x1), + /** + * Represents the fern-looking grass species. + */ + FERN_LIKE(0x2); + + private final byte data; + private final static Map BY_DATA = Maps.newHashMap(); + + private GrassSpecies(final int data) { + this.data = (byte) data; + } + + /** + * Gets the associated data value representing this species + * + * @return A byte containing the data value of this grass species + * @deprecated Magic value + */ + @Deprecated + public byte getData() { + return data; + } + + /** + * Gets the GrassSpecies with the given data value + * + * @param data Data value to fetch + * @return The {@link GrassSpecies} representing the given value, or null + * if it doesn't exist + * @deprecated Magic value + */ + @Deprecated + public static GrassSpecies getByData(final byte data) { + return BY_DATA.get(data); + } + + static { + for (GrassSpecies grassSpecies : values()) { + BY_DATA.put(grassSpecies.getData(), grassSpecies); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Instrument.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Instrument.java new file mode 100644 index 0000000..891a2b1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Instrument.java @@ -0,0 +1,67 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +public enum Instrument { + + /** + * Piano is the standard instrument for a note block. + */ + PIANO(0x0), + /** + * Bass drum is normally played when a note block is on top of a + * stone-like block + */ + BASS_DRUM(0x1), + /** + * Snare drum is normally played when a note block is on top of a sandy + * block. + */ + SNARE_DRUM(0x2), + /** + * Sticks are normally played when a note block is on top of a glass + * block. + */ + STICKS(0x3), + /** + * Bass guitar is normally played when a note block is on top of a wooden + * block. + */ + BASS_GUITAR(0x4); + + private final byte type; + private final static Map BY_DATA = Maps.newHashMap(); + + private Instrument(final int type) { + this.type = (byte) type; + } + + /** + * @return The type ID of this instrument. + * @deprecated Magic value + */ + @Deprecated + public byte getType() { + return this.type; + } + + /** + * Get an instrument by its type ID. + * + * @param type The type ID + * @return The instrument + * @deprecated Magic value + */ + @Deprecated + public static Instrument getByType(final byte type) { + return BY_DATA.get(type); + } + + static { + for (Instrument instrument : Instrument.values()) { + BY_DATA.put(instrument.getType(), instrument); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Location.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Location.java new file mode 100644 index 0000000..e7af316 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Location.java @@ -0,0 +1,600 @@ +package org.bukkit; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.block.Block; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.util.NumberConversions; +import static org.bukkit.util.NumberConversions.checkFinite; +import org.bukkit.util.Vector; + +/** + * Represents a 3-dimensional position in a world + */ +public class Location implements Cloneable, ConfigurationSerializable { + private World world; + private double x; + private double y; + private double z; + private float pitch; + private float yaw; + + /** + * Constructs a new Location with the given coordinates + * + * @param world The world in which this location resides + * @param x The x-coordinate of this new location + * @param y The y-coordinate of this new location + * @param z The z-coordinate of this new location + */ + public Location(final World world, final double x, final double y, final double z) { + this(world, x, y, z, 0, 0); + } + + /** + * Constructs a new Location with the given coordinates and direction + * + * @param world The world in which this location resides + * @param x The x-coordinate of this new location + * @param y The y-coordinate of this new location + * @param z The z-coordinate of this new location + * @param yaw The absolute rotation on the x-plane, in degrees + * @param pitch The absolute rotation on the y-plane, in degrees + */ + public Location(final World world, final double x, final double y, final double z, final float yaw, final float pitch) { + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.pitch = pitch; + this.yaw = yaw; + } + + /** + * Sets the world that this location resides in + * + * @param world New world that this location resides in + */ + public void setWorld(World world) { + this.world = world; + } + + /** + * Gets the world that this location resides in + * + * @return World that contains this location + */ + public World getWorld() { + return world; + } + + /** + * Gets the chunk at the represented location + * + * @return Chunk at the represented location + */ + public Chunk getChunk() { + return world.getChunkAt(this); + } + + /** + * Gets the block at the represented location + * + * @return Block at the represented location + */ + public Block getBlock() { + return world.getBlockAt(this); + } + + /** + * Sets the x-coordinate of this location + * + * @param x X-coordinate + */ + public void setX(double x) { + this.x = x; + } + + /** + * Gets the x-coordinate of this location + * + * @return x-coordinate + */ + public double getX() { + return x; + } + + /** + * Gets the floored value of the X component, indicating the block that + * this location is contained with. + * + * @return block X + */ + public int getBlockX() { + return locToBlock(x); + } + + /** + * Sets the y-coordinate of this location + * + * @param y y-coordinate + */ + public void setY(double y) { + this.y = y; + } + + /** + * Gets the y-coordinate of this location + * + * @return y-coordinate + */ + public double getY() { + return y; + } + + /** + * Gets the floored value of the Y component, indicating the block that + * this location is contained with. + * + * @return block y + */ + public int getBlockY() { + return locToBlock(y); + } + + /** + * Sets the z-coordinate of this location + * + * @param z z-coordinate + */ + public void setZ(double z) { + this.z = z; + } + + /** + * Gets the z-coordinate of this location + * + * @return z-coordinate + */ + public double getZ() { + return z; + } + + /** + * Gets the floored value of the Z component, indicating the block that + * this location is contained with. + * + * @return block z + */ + public int getBlockZ() { + return locToBlock(z); + } + + /** + * Sets the yaw of this location, measured in degrees. + *

    + *
  • A yaw of 0 or 360 represents the positive z direction. + *
  • A yaw of 180 represents the negative z direction. + *
  • A yaw of 90 represents the negative x direction. + *
  • A yaw of 270 represents the positive x direction. + *
+ * Increasing yaw values are the equivalent of turning to your + * right-facing, increasing the scale of the next respective axis, and + * decreasing the scale of the previous axis. + * + * @param yaw new rotation's yaw + */ + public void setYaw(float yaw) { + this.yaw = yaw; + } + + /** + * Gets the yaw of this location, measured in degrees. + *
    + *
  • A yaw of 0 or 360 represents the positive z direction. + *
  • A yaw of 180 represents the negative z direction. + *
  • A yaw of 90 represents the negative x direction. + *
  • A yaw of 270 represents the positive x direction. + *
+ * Increasing yaw values are the equivalent of turning to your + * right-facing, increasing the scale of the next respective axis, and + * decreasing the scale of the previous axis. + * + * @return the rotation's yaw + */ + public float getYaw() { + return yaw; + } + + /** + * Sets the pitch of this location, measured in degrees. + *
    + *
  • A pitch of 0 represents level forward facing. + *
  • A pitch of 90 represents downward facing, or negative y + * direction. + *
  • A pitch of -90 represents upward facing, or positive y direction. + *
+ * Increasing pitch values the equivalent of looking down. + * + * @param pitch new incline's pitch + */ + public void setPitch(float pitch) { + this.pitch = pitch; + } + + /** + * Gets the pitch of this location, measured in degrees. + *
    + *
  • A pitch of 0 represents level forward facing. + *
  • A pitch of 90 represents downward facing, or negative y + * direction. + *
  • A pitch of -90 represents upward facing, or positive y direction. + *
+ * Increasing pitch values the equivalent of looking down. + * + * @return the incline's pitch + */ + public float getPitch() { + return pitch; + } + + /** + * Gets a unit-vector pointing in the direction that this Location is + * facing. + * + * @return a vector pointing the direction of this location's {@link + * #getPitch() pitch} and {@link #getYaw() yaw} + */ + public Vector getDirection() { + Vector vector = new Vector(); + + double rotX = this.getYaw(); + double rotY = this.getPitch(); + + vector.setY(-Math.sin(Math.toRadians(rotY))); + + double xz = Math.cos(Math.toRadians(rotY)); + + vector.setX(-xz * Math.sin(Math.toRadians(rotX))); + vector.setZ(xz * Math.cos(Math.toRadians(rotX))); + + return vector; + } + + /** + * Sets the {@link #getYaw() yaw} and {@link #getPitch() pitch} to point + * in the direction of the vector. + * + * @param vector the direction vector + * @return the same location + */ + public Location setDirection(Vector vector) { + /* + * Sin = Opp / Hyp + * Cos = Adj / Hyp + * Tan = Opp / Adj + * + * x = -Opp + * z = Adj + */ + final double _2PI = 2 * Math.PI; + final double x = vector.getX(); + final double z = vector.getZ(); + + if (x == 0 && z == 0) { + pitch = vector.getY() > 0 ? -90 : 90; + return this; + } + + double theta = Math.atan2(-x, z); + yaw = (float) Math.toDegrees((theta + _2PI) % _2PI); + + double x2 = NumberConversions.square(x); + double z2 = NumberConversions.square(z); + double xz = Math.sqrt(x2 + z2); + pitch = (float) Math.toDegrees(Math.atan(-vector.getY() / xz)); + + return this; + } + + /** + * Adds the location by another. + * + * @see Vector + * @param vec The other location + * @return the same location + * @throws IllegalArgumentException for differing worlds + */ + public Location add(Location vec) { + if (vec == null || vec.getWorld() != getWorld()) { + throw new IllegalArgumentException("Cannot add Locations of differing worlds"); + } + + x += vec.x; + y += vec.y; + z += vec.z; + return this; + } + + /** + * Adds the location by a vector. + * + * @see Vector + * @param vec Vector to use + * @return the same location + */ + public Location add(Vector vec) { + this.x += vec.getX(); + this.y += vec.getY(); + this.z += vec.getZ(); + return this; + } + + /** + * Adds the location by another. Not world-aware. + * + * @see Vector + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @return the same location + */ + public Location add(double x, double y, double z) { + this.x += x; + this.y += y; + this.z += z; + return this; + } + + /** + * Subtracts the location by another. + * + * @see Vector + * @param vec The other location + * @return the same location + * @throws IllegalArgumentException for differing worlds + */ + public Location subtract(Location vec) { + if (vec == null || vec.getWorld() != getWorld()) { + throw new IllegalArgumentException("Cannot add Locations of differing worlds"); + } + + x -= vec.x; + y -= vec.y; + z -= vec.z; + return this; + } + + /** + * Subtracts the location by a vector. + * + * @see Vector + * @param vec The vector to use + * @return the same location + */ + public Location subtract(Vector vec) { + this.x -= vec.getX(); + this.y -= vec.getY(); + this.z -= vec.getZ(); + return this; + } + + /** + * Subtracts the location by another. Not world-aware and + * orientation independent. + * + * @see Vector + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @return the same location + */ + public Location subtract(double x, double y, double z) { + this.x -= x; + this.y -= y; + this.z -= z; + return this; + } + + /** + * Gets the magnitude of the location, defined as sqrt(x^2+y^2+z^2). The + * value of this method is not cached and uses a costly square-root + * function, so do not repeatedly call this method to get the location's + * magnitude. NaN will be returned if the inner result of the sqrt() + * function overflows, which will be caused if the length is too long. Not + * world-aware and orientation independent. + * + * @see Vector + * @return the magnitude + */ + public double length() { + return Math.sqrt(NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z)); + } + + /** + * Gets the magnitude of the location squared. Not world-aware and + * orientation independent. + * + * @see Vector + * @return the magnitude + */ + public double lengthSquared() { + return NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z); + } + + /** + * Get the distance between this location and another. The value of this + * method is not cached and uses a costly square-root function, so do not + * repeatedly call this method to get the location's magnitude. NaN will + * be returned if the inner result of the sqrt() function overflows, which + * will be caused if the distance is too long. + * + * @see Vector + * @param o The other location + * @return the distance + * @throws IllegalArgumentException for differing worlds + */ + public double distance(Location o) { + return Math.sqrt(distanceSquared(o)); + } + + /** + * Get the squared distance between this location and another. + * + * @see Vector + * @param o The other location + * @return the distance + * @throws IllegalArgumentException for differing worlds + */ + public double distanceSquared(Location o) { + if (o == null) { + throw new IllegalArgumentException("Cannot measure distance to a null location"); + } else if (o.getWorld() == null || getWorld() == null) { + throw new IllegalArgumentException("Cannot measure distance to a null world"); + } else if (o.getWorld() != getWorld()) { + throw new IllegalArgumentException("Cannot measure distance between " + getWorld().getName() + " and " + o.getWorld().getName()); + } + + return NumberConversions.square(x - o.x) + NumberConversions.square(y - o.y) + NumberConversions.square(z - o.z); + } + + /** + * Performs scalar multiplication, multiplying all components with a + * scalar. Not world-aware. + * + * @param m The factor + * @see Vector + * @return the same location + */ + public Location multiply(double m) { + x *= m; + y *= m; + z *= m; + return this; + } + + /** + * Zero this location's components. Not world-aware. + * + * @see Vector + * @return the same location + */ + public Location zero() { + x = 0; + y = 0; + z = 0; + return this; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Location other = (Location) obj; + + if (this.world != other.world && (this.world == null || !this.world.equals(other.world))) { + return false; + } + if (Double.doubleToLongBits(this.x) != Double.doubleToLongBits(other.x)) { + return false; + } + if (Double.doubleToLongBits(this.y) != Double.doubleToLongBits(other.y)) { + return false; + } + if (Double.doubleToLongBits(this.z) != Double.doubleToLongBits(other.z)) { + return false; + } + if (Float.floatToIntBits(this.pitch) != Float.floatToIntBits(other.pitch)) { + return false; + } + if (Float.floatToIntBits(this.yaw) != Float.floatToIntBits(other.yaw)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 3; + + hash = 19 * hash + (this.world != null ? this.world.hashCode() : 0); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32)); + hash = 19 * hash + Float.floatToIntBits(this.pitch); + hash = 19 * hash + Float.floatToIntBits(this.yaw); + return hash; + } + + @Override + public String toString() { + return "Location{" + "world=" + world + ",x=" + x + ",y=" + y + ",z=" + z + ",pitch=" + pitch + ",yaw=" + yaw + '}'; + } + + /** + * Constructs a new {@link Vector} based on this Location + * + * @return New Vector containing the coordinates represented by this + * Location + */ + public Vector toVector() { + return new Vector(x, y, z); + } + + @Override + public Location clone() { + try { + return (Location) super.clone(); + } catch (CloneNotSupportedException e) { + throw new Error(e); + } + } + + /** + * Safely converts a double (location coordinate) to an int (block + * coordinate) + * + * @param loc Precise coordinate + * @return Block coordinate + */ + public static int locToBlock(double loc) { + return NumberConversions.floor(loc); + } + + @Utility + public Map serialize() { + Map data = new HashMap(); + data.put("world", this.world.getName()); + + data.put("x", this.x); + data.put("y", this.y); + data.put("z", this.z); + + data.put("yaw", this.yaw); + data.put("pitch", this.pitch); + + return data; + } + + /** + * Required method for deserialization + * + * @param args map to deserialize + * @return deserialized location + * @throws IllegalArgumentException if the world don't exists + * @see ConfigurationSerializable + */ + public static Location deserialize(Map args) { + World world = Bukkit.getWorld((String) args.get("world")); + if (world == null) { + throw new IllegalArgumentException("unknown world"); + } + + return new Location(world, NumberConversions.toDouble(args.get("x")), NumberConversions.toDouble(args.get("y")), NumberConversions.toDouble(args.get("z")), NumberConversions.toFloat(args.get("yaw")), NumberConversions.toFloat(args.get("pitch"))); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Material.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Material.java new file mode 100644 index 0000000..0fb2605 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Material.java @@ -0,0 +1,1143 @@ +package org.bukkit; + +import java.lang.reflect.Constructor; +import java.util.Map; + +import org.apache.commons.lang.Validate; +import org.bukkit.map.MapView; +import org.bukkit.material.Bed; +import org.bukkit.material.Button; +import org.bukkit.material.Cake; +import org.bukkit.material.Cauldron; +import org.bukkit.material.Chest; +import org.bukkit.material.Coal; +import org.bukkit.material.CocoaPlant; +import org.bukkit.material.Command; +import org.bukkit.material.Crops; +import org.bukkit.material.DetectorRail; +import org.bukkit.material.Diode; +import org.bukkit.material.Dispenser; +import org.bukkit.material.Door; +import org.bukkit.material.Dye; +import org.bukkit.material.EnderChest; +import org.bukkit.material.FlowerPot; +import org.bukkit.material.Furnace; +import org.bukkit.material.Gate; +import org.bukkit.material.Ladder; +import org.bukkit.material.Lever; +import org.bukkit.material.LongGrass; +import org.bukkit.material.MaterialData; +import org.bukkit.material.MonsterEggs; +import org.bukkit.material.Mushroom; +import org.bukkit.material.NetherWarts; +import org.bukkit.material.PistonBaseMaterial; +import org.bukkit.material.PistonExtensionMaterial; +import org.bukkit.material.PoweredRail; +import org.bukkit.material.PressurePlate; +import org.bukkit.material.Pumpkin; +import org.bukkit.material.Rails; +import org.bukkit.material.RedstoneTorch; +import org.bukkit.material.RedstoneWire; +import org.bukkit.material.Sandstone; +import org.bukkit.material.Sign; +import org.bukkit.material.Skull; +import org.bukkit.material.SmoothBrick; +import org.bukkit.material.SpawnEgg; +import org.bukkit.material.Stairs; +import org.bukkit.material.Step; +import org.bukkit.material.Torch; +import org.bukkit.material.TrapDoor; +import org.bukkit.material.Tree; +import org.bukkit.material.Tripwire; +import org.bukkit.material.TripwireHook; +import org.bukkit.material.Vine; +import org.bukkit.material.WoodenStep; +import org.bukkit.material.Wool; +import org.bukkit.potion.Potion; +import org.bukkit.util.Java15Compat; + +import com.google.common.collect.Maps; +import org.bukkit.material.Banner; + +/** + * An enum of all material IDs accepted by the official server and client + */ +public enum Material { + AIR(0, 0), + STONE(1), + GRASS(2), + DIRT(3), + COBBLESTONE(4), + WOOD(5, Tree.class), + SAPLING(6, Tree.class), + BEDROCK(7), + WATER(8, MaterialData.class), + STATIONARY_WATER(9, MaterialData.class), + LAVA(10, MaterialData.class), + STATIONARY_LAVA(11, MaterialData.class), + SAND(12), + GRAVEL(13), + GOLD_ORE(14), + IRON_ORE(15), + COAL_ORE(16), + LOG(17, Tree.class), + LEAVES(18, Tree.class), + SPONGE(19), + GLASS(20), + LAPIS_ORE(21), + LAPIS_BLOCK(22), + DISPENSER(23, Dispenser.class), + SANDSTONE(24, Sandstone.class), + NOTE_BLOCK(25), + BED_BLOCK(26, Bed.class), + POWERED_RAIL(27, PoweredRail.class), + DETECTOR_RAIL(28, DetectorRail.class), + PISTON_STICKY_BASE(29, PistonBaseMaterial.class), + WEB(30), + LONG_GRASS(31, LongGrass.class), + DEAD_BUSH(32), + PISTON_BASE(33, PistonBaseMaterial.class), + PISTON_EXTENSION(34, PistonExtensionMaterial.class), + WOOL(35, Wool.class), + PISTON_MOVING_PIECE(36), + YELLOW_FLOWER(37), + RED_ROSE(38), + BROWN_MUSHROOM(39), + RED_MUSHROOM(40), + GOLD_BLOCK(41), + IRON_BLOCK(42), + DOUBLE_STEP(43, Step.class), + STEP(44, Step.class), + BRICK(45), + TNT(46), + BOOKSHELF(47), + MOSSY_COBBLESTONE(48), + OBSIDIAN(49), + TORCH(50, Torch.class), + FIRE(51), + MOB_SPAWNER(52), + WOOD_STAIRS(53, Stairs.class), + CHEST(54, Chest.class), + REDSTONE_WIRE(55, RedstoneWire.class), + DIAMOND_ORE(56), + DIAMOND_BLOCK(57), + WORKBENCH(58), + CROPS(59, Crops.class), + SOIL(60, MaterialData.class), + FURNACE(61, Furnace.class), + BURNING_FURNACE(62, Furnace.class), + SIGN_POST(63, 64, Sign.class), + WOODEN_DOOR(64, Door.class), + LADDER(65, Ladder.class), + RAILS(66, Rails.class), + COBBLESTONE_STAIRS(67, Stairs.class), + WALL_SIGN(68, 64, Sign.class), + LEVER(69, Lever.class), + STONE_PLATE(70, PressurePlate.class), + IRON_DOOR_BLOCK(71, Door.class), + WOOD_PLATE(72, PressurePlate.class), + REDSTONE_ORE(73), + GLOWING_REDSTONE_ORE(74), + REDSTONE_TORCH_OFF(75, RedstoneTorch.class), + REDSTONE_TORCH_ON(76, RedstoneTorch.class), + STONE_BUTTON(77, Button.class), + SNOW(78), + ICE(79), + SNOW_BLOCK(80), + CACTUS(81, MaterialData.class), + CLAY(82), + SUGAR_CANE_BLOCK(83, MaterialData.class), + JUKEBOX(84), + FENCE(85), + PUMPKIN(86, Pumpkin.class), + NETHERRACK(87), + SOUL_SAND(88), + GLOWSTONE(89), + PORTAL(90), + JACK_O_LANTERN(91, Pumpkin.class), + CAKE_BLOCK(92, 64, Cake.class), + DIODE_BLOCK_OFF(93, Diode.class), + DIODE_BLOCK_ON(94, Diode.class), + STAINED_GLASS(95), + TRAP_DOOR(96, TrapDoor.class), + MONSTER_EGGS(97, MonsterEggs.class), + SMOOTH_BRICK(98, SmoothBrick.class), + HUGE_MUSHROOM_1(99, Mushroom.class), + HUGE_MUSHROOM_2(100, Mushroom.class), + IRON_FENCE(101), + THIN_GLASS(102), + MELON_BLOCK(103), + PUMPKIN_STEM(104, MaterialData.class), + MELON_STEM(105, MaterialData.class), + VINE(106, Vine.class), + FENCE_GATE(107, Gate.class), + BRICK_STAIRS(108, Stairs.class), + SMOOTH_STAIRS(109, Stairs.class), + MYCEL(110), + WATER_LILY(111), + NETHER_BRICK(112), + NETHER_FENCE(113), + NETHER_BRICK_STAIRS(114, Stairs.class), + NETHER_WARTS(115, NetherWarts.class), + ENCHANTMENT_TABLE(116), + BREWING_STAND(117, MaterialData.class), + CAULDRON(118, Cauldron.class), + ENDER_PORTAL(119), + ENDER_PORTAL_FRAME(120), + ENDER_STONE(121), + DRAGON_EGG(122), + REDSTONE_LAMP_OFF(123), + REDSTONE_LAMP_ON(124), + WOOD_DOUBLE_STEP(125, WoodenStep.class), + WOOD_STEP(126, WoodenStep.class), + COCOA(127, CocoaPlant.class), + SANDSTONE_STAIRS(128, Stairs.class), + EMERALD_ORE(129), + ENDER_CHEST(130, EnderChest.class), + TRIPWIRE_HOOK(131, TripwireHook.class), + TRIPWIRE(132, Tripwire.class), + EMERALD_BLOCK(133), + SPRUCE_WOOD_STAIRS(134, Stairs.class), + BIRCH_WOOD_STAIRS(135, Stairs.class), + JUNGLE_WOOD_STAIRS(136, Stairs.class), + COMMAND(137, Command.class), + BEACON(138), + COBBLE_WALL(139), + FLOWER_POT(140, FlowerPot.class), + CARROT(141), + POTATO(142), + WOOD_BUTTON(143, Button.class), + SKULL(144, Skull.class), + ANVIL(145), + TRAPPED_CHEST(146, Chest.class), + GOLD_PLATE(147), + IRON_PLATE(148), + REDSTONE_COMPARATOR_OFF(149), + REDSTONE_COMPARATOR_ON(150), + DAYLIGHT_DETECTOR(151), + REDSTONE_BLOCK(152), + QUARTZ_ORE(153), + HOPPER(154), + QUARTZ_BLOCK(155), + QUARTZ_STAIRS(156, Stairs.class), + ACTIVATOR_RAIL(157, PoweredRail.class), + DROPPER(158, Dispenser.class), + STAINED_CLAY(159), + STAINED_GLASS_PANE(160), + LEAVES_2(161), + LOG_2(162), + ACACIA_STAIRS(163, Stairs.class), + DARK_OAK_STAIRS(164, Stairs.class), + SLIME_BLOCK(165), + BARRIER(166), + IRON_TRAPDOOR(167, TrapDoor.class), + PRISMARINE(168), + SEA_LANTERN(169), + HAY_BLOCK(170), + CARPET(171), + HARD_CLAY(172), + COAL_BLOCK(173), + PACKED_ICE(174), + DOUBLE_PLANT(175), + STANDING_BANNER(176, Banner.class), + WALL_BANNER(177, Banner.class), + DAYLIGHT_DETECTOR_INVERTED(178), + RED_SANDSTONE(179), + RED_SANDSTONE_STAIRS(180, Stairs.class), + DOUBLE_STONE_SLAB2(181), + STONE_SLAB2(182), + SPRUCE_FENCE_GATE(183, Gate.class), + BIRCH_FENCE_GATE(184, Gate.class), + JUNGLE_FENCE_GATE(185, Gate.class), + DARK_OAK_FENCE_GATE(186, Gate.class), + ACACIA_FENCE_GATE(187, Gate.class), + SPRUCE_FENCE(188), + BIRCH_FENCE(189), + JUNGLE_FENCE(190), + DARK_OAK_FENCE(191), + ACACIA_FENCE(192), + SPRUCE_DOOR(193, Door.class), + BIRCH_DOOR(194, Door.class), + JUNGLE_DOOR(195, Door.class), + ACACIA_DOOR(196, Door.class), + DARK_OAK_DOOR(197, Door.class), + // ----- Item Separator ----- + IRON_SPADE(256, 1, 250), + IRON_PICKAXE(257, 1, 250), + IRON_AXE(258, 1, 250), + FLINT_AND_STEEL(259, 1, 64), + APPLE(260), + BOW(261, 1, 384), + ARROW(262), + COAL(263, Coal.class), + DIAMOND(264), + IRON_INGOT(265), + GOLD_INGOT(266), + IRON_SWORD(267, 1, 250), + WOOD_SWORD(268, 1, 59), + WOOD_SPADE(269, 1, 59), + WOOD_PICKAXE(270, 1, 59), + WOOD_AXE(271, 1, 59), + STONE_SWORD(272, 1, 131), + STONE_SPADE(273, 1, 131), + STONE_PICKAXE(274, 1, 131), + STONE_AXE(275, 1, 131), + DIAMOND_SWORD(276, 1, 1561), + DIAMOND_SPADE(277, 1, 1561), + DIAMOND_PICKAXE(278, 1, 1561), + DIAMOND_AXE(279, 1, 1561), + STICK(280), + BOWL(281), + MUSHROOM_SOUP(282, 1), + GOLD_SWORD(283, 1, 32), + GOLD_SPADE(284, 1, 32), + GOLD_PICKAXE(285, 1, 32), + GOLD_AXE(286, 1, 32), + STRING(287), + FEATHER(288), + SULPHUR(289), + WOOD_HOE(290, 1, 59), + STONE_HOE(291, 1, 131), + IRON_HOE(292, 1, 250), + DIAMOND_HOE(293, 1, 1561), + GOLD_HOE(294, 1, 32), + SEEDS(295), + WHEAT(296), + BREAD(297), + LEATHER_HELMET(298, 1, 55), + LEATHER_CHESTPLATE(299, 1, 80), + LEATHER_LEGGINGS(300, 1, 75), + LEATHER_BOOTS(301, 1, 65), + CHAINMAIL_HELMET(302, 1, 165), + CHAINMAIL_CHESTPLATE(303, 1, 240), + CHAINMAIL_LEGGINGS(304, 1, 225), + CHAINMAIL_BOOTS(305, 1, 195), + IRON_HELMET(306, 1, 165), + IRON_CHESTPLATE(307, 1, 240), + IRON_LEGGINGS(308, 1, 225), + IRON_BOOTS(309, 1, 195), + DIAMOND_HELMET(310, 1, 363), + DIAMOND_CHESTPLATE(311, 1, 528), + DIAMOND_LEGGINGS(312, 1, 495), + DIAMOND_BOOTS(313, 1, 429), + GOLD_HELMET(314, 1, 77), + GOLD_CHESTPLATE(315, 1, 112), + GOLD_LEGGINGS(316, 1, 105), + GOLD_BOOTS(317, 1, 91), + FLINT(318), + PORK(319), + GRILLED_PORK(320), + PAINTING(321), + GOLDEN_APPLE(322), + SIGN(323, 16), + WOOD_DOOR(324, 64), + BUCKET(325, 16), + WATER_BUCKET(326, 1), + LAVA_BUCKET(327, 1), + MINECART(328, 1), + SADDLE(329, 1), + IRON_DOOR(330, 64), + REDSTONE(331), + SNOW_BALL(332, 16), + BOAT(333, 1), + LEATHER(334), + MILK_BUCKET(335, 1), + CLAY_BRICK(336), + CLAY_BALL(337), + SUGAR_CANE(338), + PAPER(339), + BOOK(340), + SLIME_BALL(341), + STORAGE_MINECART(342, 1), + POWERED_MINECART(343, 1), + EGG(344, 16), + COMPASS(345), + FISHING_ROD(346, 1, 64), + WATCH(347), + GLOWSTONE_DUST(348), + RAW_FISH(349), + COOKED_FISH(350), + INK_SACK(351, Dye.class), + BONE(352), + SUGAR(353), + CAKE(354, 1), + BED(355, 1), + DIODE(356), + COOKIE(357), + /** + * @see MapView + */ + MAP(358, MaterialData.class), + SHEARS(359, 1, 238), + MELON(360), + PUMPKIN_SEEDS(361), + MELON_SEEDS(362), + RAW_BEEF(363), + COOKED_BEEF(364), + RAW_CHICKEN(365), + COOKED_CHICKEN(366), + ROTTEN_FLESH(367), + ENDER_PEARL(368, 16), + BLAZE_ROD(369), + GHAST_TEAR(370), + GOLD_NUGGET(371), + NETHER_STALK(372), + /** + * @see Potion + */ + POTION(373, 1, MaterialData.class), + GLASS_BOTTLE(374), + SPIDER_EYE(375), + FERMENTED_SPIDER_EYE(376), + BLAZE_POWDER(377), + MAGMA_CREAM(378), + BREWING_STAND_ITEM(379), + CAULDRON_ITEM(380), + EYE_OF_ENDER(381), + SPECKLED_MELON(382), + MONSTER_EGG(383, 64, SpawnEgg.class), + EXP_BOTTLE(384, 64), + FIREBALL(385, 64), + BOOK_AND_QUILL(386, 1), + WRITTEN_BOOK(387, 16), + EMERALD(388, 64), + ITEM_FRAME(389), + FLOWER_POT_ITEM(390), + CARROT_ITEM(391), + POTATO_ITEM(392), + BAKED_POTATO(393), + POISONOUS_POTATO(394), + EMPTY_MAP(395), + GOLDEN_CARROT(396), + SKULL_ITEM(397), + CARROT_STICK(398, 1, 25), + NETHER_STAR(399), + PUMPKIN_PIE(400), + FIREWORK(401), + FIREWORK_CHARGE(402), + ENCHANTED_BOOK(403, 1), + REDSTONE_COMPARATOR(404), + NETHER_BRICK_ITEM(405), + QUARTZ(406), + EXPLOSIVE_MINECART(407, 1), + HOPPER_MINECART(408, 1), + PRISMARINE_SHARD(409), + PRISMARINE_CRYSTALS(410), + RABBIT(411), + COOKED_RABBIT(412), + RABBIT_STEW(413, 1), + RABBIT_FOOT(414), + RABBIT_HIDE(415), + ARMOR_STAND(416, 16), + IRON_BARDING(417, 1), + GOLD_BARDING(418, 1), + DIAMOND_BARDING(419, 1), + LEASH(420), + NAME_TAG(421), + COMMAND_MINECART(422, 1), + MUTTON(423), + COOKED_MUTTON(424), + BANNER(425, 16), + SPRUCE_DOOR_ITEM(427), + BIRCH_DOOR_ITEM(428), + JUNGLE_DOOR_ITEM(429), + ACACIA_DOOR_ITEM(430), + DARK_OAK_DOOR_ITEM(431), + GOLD_RECORD(2256, 1), + GREEN_RECORD(2257, 1), + RECORD_3(2258, 1), + RECORD_4(2259, 1), + RECORD_5(2260, 1), + RECORD_6(2261, 1), + RECORD_7(2262, 1), + RECORD_8(2263, 1), + RECORD_9(2264, 1), + RECORD_10(2265, 1), + RECORD_11(2266, 1), + RECORD_12(2267, 1), + ; + + private final int id; + private final Constructor ctor; + private static Material[] byId = new Material[383]; + private final static Map BY_NAME = Maps.newHashMap(); + private final int maxStack; + private final short durability; + + private Material(final int id) { + this(id, 64); + } + + private Material(final int id, final int stack) { + this(id, stack, MaterialData.class); + } + + private Material(final int id, final int stack, final int durability) { + this(id, stack, durability, MaterialData.class); + } + + private Material(final int id, final Class data) { + this(id, 64, data); + } + + private Material(final int id, final int stack, final Class data) { + this(id, stack, 0, data); + } + + private Material(final int id, final int stack, final int durability, final Class data) { + this.id = id; + this.durability = (short) durability; + this.maxStack = stack; + // try to cache the constructor for this material + try { + this.ctor = data.getConstructor(int.class, byte.class); + } catch (NoSuchMethodException ex) { + throw new AssertionError(ex); + } catch (SecurityException ex) { + throw new AssertionError(ex); + } + } + + /** + * Gets the item ID or block ID of this Material + * + * @return ID of this material + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + + /** + * Gets the maximum amount of this material that can be held in a stack + * + * @return Maximum stack size for this material + */ + public int getMaxStackSize() { + return maxStack; + } + + /** + * Gets the maximum durability of this material + * + * @return Maximum durability for this material + */ + public short getMaxDurability() { + return durability; + } + + /** + * Gets the MaterialData class associated with this Material + * + * @return MaterialData associated with this Material + */ + public Class getData() { + return ctor.getDeclaringClass(); + } + + /** + * Constructs a new MaterialData relevant for this Material, with the + * given initial data + * + * @param raw Initial data to construct the MaterialData with + * @return New MaterialData with the given data + * @deprecated Magic value + */ + @Deprecated + public MaterialData getNewData(final byte raw) { + try { + return ctor.newInstance(id, raw); + } catch (InstantiationException ex) { + final Throwable t = ex.getCause(); + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } + if (t instanceof Error) { + throw (Error) t; + } + throw new AssertionError(t); + } catch (Throwable t) { + throw new AssertionError(t); + } + } + + /** + * Checks if this Material is a placable block + * + * @return true if this material is a block + */ + public boolean isBlock() { + return id < 256; + } + + /** + * Checks if this Material is edible. + * + * @return true if this Material is edible. + */ + public boolean isEdible() { + switch (this) { + case BREAD: + case CARROT_ITEM: + case BAKED_POTATO: + case POTATO_ITEM: + case POISONOUS_POTATO: + case GOLDEN_CARROT: + case PUMPKIN_PIE: + case COOKIE: + case MELON: + case MUSHROOM_SOUP: + case RAW_CHICKEN: + case COOKED_CHICKEN: + case RAW_BEEF: + case COOKED_BEEF: + case RAW_FISH: + case COOKED_FISH: + case PORK: + case GRILLED_PORK: + case APPLE: + case GOLDEN_APPLE: + case ROTTEN_FLESH: + case SPIDER_EYE: + case RABBIT: + case COOKED_RABBIT: + case RABBIT_STEW: + case MUTTON: + case COOKED_MUTTON: + return true; + default: + return false; + } + } + + /** + * Attempts to get the Material with the given ID + * + * @param id ID of the material to get + * @return Material if found, or null + * @deprecated Magic value + */ + @Deprecated + public static Material getMaterial(final int id) { + if (byId.length > id && id >= 0) { + return byId[id]; + } else { + return null; + } + } + + /** + * Attempts to get the Material with the given name. + *

+ * This is a normal lookup, names must be the precise name they are given + * in the enum. + * + * @param name Name of the material to get + * @return Material if found, or null + */ + public static Material getMaterial(final String name) { + return BY_NAME.get(name); + } + + /** + * Attempts to match the Material with the given name. + *

+ * This is a match lookup; names will be converted to uppercase, then + * stripped of special characters in an attempt to format it like the + * enum. + *

+ * Using this for match by ID is deprecated. + * + * @param name Name of the material to get + * @return Material if found, or null + */ + public static Material matchMaterial(final String name) { + Validate.notNull(name, "Name cannot be null"); + + Material result = null; + + try { + result = getMaterial(Integer.parseInt(name)); + } catch (NumberFormatException ex) {} + + if (result == null) { + String filtered = name.toUpperCase(); + + filtered = filtered.replaceAll("\\s+", "_").replaceAll("\\W", ""); + result = BY_NAME.get(filtered); + } + + return result; + } + + static { + for (Material material : values()) { + if (byId.length > material.id) { + byId[material.id] = material; + } else { + byId = Java15Compat.Arrays_copyOfRange(byId, 0, material.id + 2); + byId[material.id] = material; + } + BY_NAME.put(material.name(), material); + } + } + + /** + * @return True if this material represents a playable music disk. + */ + public boolean isRecord() { + return id >= GOLD_RECORD.id && id <= RECORD_12.id; + } + + /** + * Check if the material is a block and solid (cannot be passed through by + * a player) + * + * @return True if this material is a block and solid + */ + public boolean isSolid() { + if (!isBlock() || id == 0) { + return false; + } + switch (this) { + case STONE: + case GRASS: + case DIRT: + case COBBLESTONE: + case WOOD: + case BEDROCK: + case SAND: + case GRAVEL: + case GOLD_ORE: + case IRON_ORE: + case COAL_ORE: + case LOG: + case LEAVES: + case SPONGE: + case GLASS: + case LAPIS_ORE: + case LAPIS_BLOCK: + case DISPENSER: + case SANDSTONE: + case NOTE_BLOCK: + case BED_BLOCK: + case PISTON_STICKY_BASE: + case PISTON_BASE: + case PISTON_EXTENSION: + case WOOL: + case PISTON_MOVING_PIECE: + case GOLD_BLOCK: + case IRON_BLOCK: + case DOUBLE_STEP: + case STEP: + case BRICK: + case TNT: + case BOOKSHELF: + case MOSSY_COBBLESTONE: + case OBSIDIAN: + case MOB_SPAWNER: + case WOOD_STAIRS: + case CHEST: + case DIAMOND_ORE: + case DIAMOND_BLOCK: + case WORKBENCH: + case SOIL: + case FURNACE: + case BURNING_FURNACE: + case SIGN_POST: + case WOODEN_DOOR: + case COBBLESTONE_STAIRS: + case WALL_SIGN: + case STONE_PLATE: + case IRON_DOOR_BLOCK: + case WOOD_PLATE: + case REDSTONE_ORE: + case GLOWING_REDSTONE_ORE: + case ICE: + case SNOW_BLOCK: + case CACTUS: + case CLAY: + case JUKEBOX: + case FENCE: + case PUMPKIN: + case NETHERRACK: + case SOUL_SAND: + case GLOWSTONE: + case JACK_O_LANTERN: + case CAKE_BLOCK: + case STAINED_GLASS: + case TRAP_DOOR: + case MONSTER_EGGS: + case SMOOTH_BRICK: + case HUGE_MUSHROOM_1: + case HUGE_MUSHROOM_2: + case IRON_FENCE: + case THIN_GLASS: + case MELON_BLOCK: + case FENCE_GATE: + case BRICK_STAIRS: + case SMOOTH_STAIRS: + case MYCEL: + case NETHER_BRICK: + case NETHER_FENCE: + case NETHER_BRICK_STAIRS: + case ENCHANTMENT_TABLE: + case BREWING_STAND: + case CAULDRON: + case ENDER_PORTAL_FRAME: + case ENDER_STONE: + case DRAGON_EGG: + case REDSTONE_LAMP_OFF: + case REDSTONE_LAMP_ON: + case WOOD_DOUBLE_STEP: + case WOOD_STEP: + case SANDSTONE_STAIRS: + case EMERALD_ORE: + case ENDER_CHEST: + case EMERALD_BLOCK: + case SPRUCE_WOOD_STAIRS: + case BIRCH_WOOD_STAIRS: + case JUNGLE_WOOD_STAIRS: + case COMMAND: + case BEACON: + case COBBLE_WALL: + case ANVIL: + case TRAPPED_CHEST: + case GOLD_PLATE: + case IRON_PLATE: + case DAYLIGHT_DETECTOR: + case REDSTONE_BLOCK: + case QUARTZ_ORE: + case HOPPER: + case QUARTZ_BLOCK: + case QUARTZ_STAIRS: + case DROPPER: + case STAINED_CLAY: + case HAY_BLOCK: + case HARD_CLAY: + case COAL_BLOCK: + case STAINED_GLASS_PANE: + case LEAVES_2: + case LOG_2: + case ACACIA_STAIRS: + case DARK_OAK_STAIRS: + case PACKED_ICE: + case RED_SANDSTONE: + case SLIME_BLOCK: + case BARRIER: + case IRON_TRAPDOOR: + case PRISMARINE: + case SEA_LANTERN: + case DOUBLE_STONE_SLAB2: + case RED_SANDSTONE_STAIRS: + case STONE_SLAB2: + case SPRUCE_FENCE_GATE: + case BIRCH_FENCE_GATE: + case JUNGLE_FENCE_GATE: + case DARK_OAK_FENCE_GATE: + case ACACIA_FENCE_GATE: + case SPRUCE_FENCE: + case BIRCH_FENCE: + case JUNGLE_FENCE: + case DARK_OAK_FENCE: + case ACACIA_FENCE: + case STANDING_BANNER: + case WALL_BANNER: + case DAYLIGHT_DETECTOR_INVERTED: + case SPRUCE_DOOR: + case BIRCH_DOOR: + case JUNGLE_DOOR: + case ACACIA_DOOR: + case DARK_OAK_DOOR: + return true; + default: + return false; + } + } + + /** + * Check if the material is a block and does not block any light + * + * @return True if this material is a block and does not block any light + */ + public boolean isTransparent() { + if (!isBlock()) { + return false; + } + switch (this) { + case AIR: + case SAPLING: + case POWERED_RAIL: + case DETECTOR_RAIL: + case LONG_GRASS: + case DEAD_BUSH: + case YELLOW_FLOWER: + case RED_ROSE: + case BROWN_MUSHROOM: + case RED_MUSHROOM: + case TORCH: + case FIRE: + case REDSTONE_WIRE: + case CROPS: + case LADDER: + case RAILS: + case LEVER: + case REDSTONE_TORCH_OFF: + case REDSTONE_TORCH_ON: + case STONE_BUTTON: + case SNOW: + case SUGAR_CANE_BLOCK: + case PORTAL: + case DIODE_BLOCK_OFF: + case DIODE_BLOCK_ON: + case PUMPKIN_STEM: + case MELON_STEM: + case VINE: + case WATER_LILY: + case NETHER_WARTS: + case ENDER_PORTAL: + case COCOA: + case TRIPWIRE_HOOK: + case TRIPWIRE: + case FLOWER_POT: + case CARROT: + case POTATO: + case WOOD_BUTTON: + case SKULL: + case REDSTONE_COMPARATOR_OFF: + case REDSTONE_COMPARATOR_ON: + case ACTIVATOR_RAIL: + case CARPET: + case DOUBLE_PLANT: + return true; + default: + return false; + } + } + + /** + * Check if the material is a block and can catch fire + * + * @return True if this material is a block and can catch fire + */ + public boolean isFlammable() { + if (!isBlock()) { + return false; + } + switch (this) { + case WOOD: + case LOG: + case LEAVES: + case NOTE_BLOCK: + case BED_BLOCK: + case LONG_GRASS: + case DEAD_BUSH: + case WOOL: + case TNT: + case BOOKSHELF: + case WOOD_STAIRS: + case CHEST: + case WORKBENCH: + case SIGN_POST: + case WOODEN_DOOR: + case WALL_SIGN: + case WOOD_PLATE: + case JUKEBOX: + case FENCE: + case TRAP_DOOR: + case HUGE_MUSHROOM_1: + case HUGE_MUSHROOM_2: + case VINE: + case FENCE_GATE: + case WOOD_DOUBLE_STEP: + case WOOD_STEP: + case SPRUCE_WOOD_STAIRS: + case BIRCH_WOOD_STAIRS: + case JUNGLE_WOOD_STAIRS: + case TRAPPED_CHEST: + case DAYLIGHT_DETECTOR: + case CARPET: + case LEAVES_2: + case LOG_2: + case ACACIA_STAIRS: + case DARK_OAK_STAIRS: + case DOUBLE_PLANT: + case SPRUCE_FENCE_GATE: + case BIRCH_FENCE_GATE: + case JUNGLE_FENCE_GATE: + case DARK_OAK_FENCE_GATE: + case ACACIA_FENCE_GATE: + case SPRUCE_FENCE: + case BIRCH_FENCE: + case JUNGLE_FENCE: + case DARK_OAK_FENCE: + case ACACIA_FENCE: + case STANDING_BANNER: + case WALL_BANNER: + case DAYLIGHT_DETECTOR_INVERTED: + case SPRUCE_DOOR: + case BIRCH_DOOR: + case JUNGLE_DOOR: + case ACACIA_DOOR: + case DARK_OAK_DOOR: + return true; + default: + return false; + } + } + + /** + * Check if the material is a block and can burn away + * + * @return True if this material is a block and can burn away + */ + public boolean isBurnable() { + if (!isBlock()) { + return false; + } + switch (this) { + case WOOD: + case LOG: + case LEAVES: + case LONG_GRASS: + case WOOL: + case YELLOW_FLOWER: + case RED_ROSE: + case TNT: + case BOOKSHELF: + case WOOD_STAIRS: + case FENCE: + case VINE: + case WOOD_DOUBLE_STEP: + case WOOD_STEP: + case SPRUCE_WOOD_STAIRS: + case BIRCH_WOOD_STAIRS: + case JUNGLE_WOOD_STAIRS: + case HAY_BLOCK: + case COAL_BLOCK: + case LEAVES_2: + case LOG_2: + case CARPET: + case DOUBLE_PLANT: + case DEAD_BUSH: + case FENCE_GATE: + case SPRUCE_FENCE_GATE: + case BIRCH_FENCE_GATE: + case JUNGLE_FENCE_GATE: + case DARK_OAK_FENCE_GATE: + case ACACIA_FENCE_GATE: + case SPRUCE_FENCE: + case BIRCH_FENCE: + case JUNGLE_FENCE: + case DARK_OAK_FENCE: + case ACACIA_FENCE: + return true; + default: + return false; + } + } + + /** + * Check if the material is a block and completely blocks vision + * + * @return True if this material is a block and completely blocks vision + */ + public boolean isOccluding() { + if (!isBlock()) { + return false; + } + switch (this) { + case STONE: + case GRASS: + case DIRT: + case COBBLESTONE: + case WOOD: + case BEDROCK: + case SAND: + case GRAVEL: + case GOLD_ORE: + case IRON_ORE: + case COAL_ORE: + case LOG: + case SPONGE: + case LAPIS_ORE: + case LAPIS_BLOCK: + case DISPENSER: + case SANDSTONE: + case NOTE_BLOCK: + case WOOL: + case GOLD_BLOCK: + case IRON_BLOCK: + case DOUBLE_STEP: + case BRICK: + case BOOKSHELF: + case MOSSY_COBBLESTONE: + case OBSIDIAN: + case MOB_SPAWNER: + case DIAMOND_ORE: + case DIAMOND_BLOCK: + case WORKBENCH: + case FURNACE: + case BURNING_FURNACE: + case REDSTONE_ORE: + case GLOWING_REDSTONE_ORE: + case SNOW_BLOCK: + case CLAY: + case JUKEBOX: + case PUMPKIN: + case NETHERRACK: + case SOUL_SAND: + case JACK_O_LANTERN: + case MONSTER_EGGS: + case SMOOTH_BRICK: + case HUGE_MUSHROOM_1: + case HUGE_MUSHROOM_2: + case MELON_BLOCK: + case MYCEL: + case NETHER_BRICK: + case ENDER_PORTAL_FRAME: + case ENDER_STONE: + case REDSTONE_LAMP_OFF: + case REDSTONE_LAMP_ON: + case WOOD_DOUBLE_STEP: + case EMERALD_ORE: + case EMERALD_BLOCK: + case COMMAND: + case QUARTZ_ORE: + case QUARTZ_BLOCK: + case DROPPER: + case STAINED_CLAY: + case HAY_BLOCK: + case HARD_CLAY: + case COAL_BLOCK: + case LOG_2: + case PACKED_ICE: + case SLIME_BLOCK: + case BARRIER: + case PRISMARINE: + case RED_SANDSTONE: + case DOUBLE_STONE_SLAB2: + return true; + default: + return false; + } + } + + /** + * @return True if this material is affected by gravity. + */ + public boolean hasGravity() { + if (!isBlock()) { + return false; + } + switch (this) { + case SAND: + case GRAVEL: + case ANVIL: + return true; + default: + return false; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/NetherWartsState.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/NetherWartsState.java new file mode 100644 index 0000000..f43209c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/NetherWartsState.java @@ -0,0 +1,21 @@ +package org.bukkit; + +public enum NetherWartsState { + + /** + * State when first seeded + */ + SEEDED, + /** + * First growth stage + */ + STAGE_ONE, + /** + * Second growth stage + */ + STAGE_TWO, + /** + * Ready to harvest + */ + RIPE; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Note.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Note.java new file mode 100644 index 0000000..417936f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Note.java @@ -0,0 +1,276 @@ +package org.bukkit; + +import java.util.Map; + +import org.apache.commons.lang.Validate; + +import com.google.common.collect.Maps; + +/** + * A note class to store a specific note. + */ +public class Note { + + /** + * An enum holding tones. + */ + public enum Tone { + G(0x1, true), + A(0x3, true), + B(0x5, false), + C(0x6, true), + D(0x8, true), + E(0xA, false), + F(0xB, true); + + private final boolean sharpable; + private final byte id; + + private static final Map BY_DATA = Maps.newHashMap(); + /** The number of tones including sharped tones. */ + public static final byte TONES_COUNT = 12; + + private Tone(int id, boolean sharpable) { + this.id = (byte) (id % TONES_COUNT); + this.sharpable = sharpable; + } + + /** + * Returns the not sharped id of this tone. + * + * @return the not sharped id of this tone. + * @deprecated Magic value + */ + @Deprecated + public byte getId() { + return getId(false); + } + + /** + * Returns the id of this tone. These method allows to return the + * sharped id of the tone. If the tone couldn't be sharped it always + * return the not sharped id of this tone. + * + * @param sharped Set to true to return the sharped id. + * @return the id of this tone. + * @deprecated Magic value + */ + @Deprecated + public byte getId(boolean sharped) { + byte id = (byte) (sharped && sharpable ? this.id + 1 : this.id); + + return (byte) (id % TONES_COUNT); + } + + /** + * Returns if this tone could be sharped. + * + * @return if this tone could be sharped. + */ + public boolean isSharpable() { + return sharpable; + } + + /** + * Returns if this tone id is the sharped id of the tone. + * + * @param id the id of the tone. + * @return if the tone id is the sharped id of the tone. + * @throws IllegalArgumentException if neither the tone nor the + * semitone have the id. + * @deprecated Magic value + */ + @Deprecated + public boolean isSharped(byte id) { + if (id == getId(false)) { + return false; + } else if (id == getId(true)) { + return true; + } else { + // The id isn't matching to the tone! + throw new IllegalArgumentException("The id isn't matching to the tone."); + } + } + + /** + * Returns the tone to id. Also returning the semitones. + * + * @param id the id of the tone. + * @return the tone to id. + * @deprecated Magic value + */ + @Deprecated + public static Tone getById(byte id) { + return BY_DATA.get(id); + } + + static { + for (Tone tone : values()) { + int id = tone.id % TONES_COUNT; + BY_DATA.put((byte) id, tone); + + if (tone.isSharpable()) { + id = (id + 1) % TONES_COUNT; + BY_DATA.put((byte) id, tone); + } + } + } + } + + private final byte note; + + /** + * Creates a new note. + * + * @param note Internal note id. {@link #getId()} always return this + * value. The value has to be in the interval [0; 24]. + */ + public Note(int note) { + Validate.isTrue(note >= 0 && note <= 24, "The note value has to be between 0 and 24."); + + this.note = (byte) note; + } + + /** + * Creates a new note. + * + * @param octave The octave where the note is in. Has to be 0 - 2. + * @param tone The tone within the octave. If the octave is 2 the note has + * to be F#. + * @param sharped Set if the tone is sharped (e.g. for F#). + */ + public Note(int octave, Tone tone, boolean sharped) { + if (sharped && !tone.isSharpable()) { + tone = Tone.values()[tone.ordinal() + 1]; + sharped = false; + } + if (octave < 0 || octave > 2 || (octave == 2 && !(tone == Tone.F && sharped))) { + throw new IllegalArgumentException("Tone and octave have to be between F#0 and F#2"); + } + + this.note = (byte) (octave * Tone.TONES_COUNT + tone.getId(sharped)); + } + + /** + * Creates a new note for a flat tone, such as A-flat. + * + * @param octave The octave where the note is in. Has to be 0 - 1. + * @param tone The tone within the octave. + * @return The new note. + */ + public static Note flat(int octave, Tone tone) { + Validate.isTrue(octave != 2, "Octave cannot be 2 for flats"); + tone = tone == Tone.G ? Tone.F : Tone.values()[tone.ordinal() - 1]; + return new Note(octave, tone, tone.isSharpable()); + } + + /** + * Creates a new note for a sharp tone, such as A-sharp. + * + * @param octave The octave where the note is in. Has to be 0 - 2. + * @param tone The tone within the octave. If the octave is 2 the note has + * to be F#. + * @return The new note. + */ + public static Note sharp(int octave, Tone tone) { + return new Note(octave, tone, true); + } + + /** + * Creates a new note for a natural tone, such as A-natural. + * + * @param octave The octave where the note is in. Has to be 0 - 1. + * @param tone The tone within the octave. + * @return The new note. + */ + public static Note natural(int octave, Tone tone) { + Validate.isTrue(octave != 2, "Octave cannot be 2 for naturals"); + return new Note(octave, tone, false); + } + + /** + * @return The note a semitone above this one. + */ + public Note sharped() { + Validate.isTrue(note < 24, "This note cannot be sharped because it is the highest known note!"); + return new Note(note + 1); + } + + /** + * @return The note a semitone below this one. + */ + public Note flattened() { + Validate.isTrue(note > 0, "This note cannot be flattened because it is the lowest known note!"); + return new Note(note - 1); + } + + /** + * Returns the internal id of this note. + * + * @return the internal id of this note. + * @deprecated Magic value + */ + @Deprecated + public byte getId() { + return note; + } + + /** + * Returns the octave of this note. + * + * @return the octave of this note. + */ + public int getOctave() { + return note / Tone.TONES_COUNT; + } + + private byte getToneByte() { + return (byte) (note % Tone.TONES_COUNT); + } + + /** + * Returns the tone of this note. + * + * @return the tone of this note. + */ + public Tone getTone() { + return Tone.getById(getToneByte()); + } + + /** + * Returns if this note is sharped. + * + * @return if this note is sharped. + */ + public boolean isSharped() { + byte note = getToneByte(); + return Tone.getById(note).isSharped(note); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + note; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Note other = (Note) obj; + if (note != other.note) + return false; + return true; + } + + @Override + public String toString() { + return "Note{" + getTone().toString() + (isSharped() ? "#" : "") + "}"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/OfflinePlayer.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/OfflinePlayer.java new file mode 100644 index 0000000..e98706a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/OfflinePlayer.java @@ -0,0 +1,118 @@ +package org.bukkit; + +import java.util.Date; +import java.util.UUID; + +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.entity.AnimalTamer; +import org.bukkit.entity.Player; +import org.bukkit.permissions.ServerOperator; + +public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable { + + /** + * Checks if this player is currently online + * + * @return true if they are online + */ + public boolean isOnline(); + + /** + * Returns the name of this player + *

+ * Names are no longer unique past a single game session. For persistent storage + * it is recommended that you use {@link #getUniqueId()} instead. + * + * @return Player name or null if we have not seen a name for this player yet + */ + public String getName(); + + /** + * Returns the UUID of this player + * + * @return Player UUID + */ + public UUID getUniqueId(); + + /** + * Checks if this player is banned or not + * + * @return true if banned, otherwise false + */ + public boolean isBanned(); + + /** + * Bans or unbans this player + * + * @param banned true if banned + * @deprecated Use {@link org.bukkit.BanList#addBan(String, String, Date, + * String)} or {@link org.bukkit.BanList#pardon(String)} to enhance + * functionality + */ + @Deprecated + public void setBanned(boolean banned); + + /** + * Checks if this player is whitelisted or not + * + * @return true if whitelisted + */ + public boolean isWhitelisted(); + + /** + * Sets if this player is whitelisted or not + * + * @param value true if whitelisted + */ + public void setWhitelisted(boolean value); + + /** + * Gets a {@link Player} object that this represents, if there is one + *

+ * If the player is online, this will return that player. Otherwise, + * it will return null. + * + * @return Online player + */ + public Player getPlayer(); + + /** + * Gets the first date and time that this player was witnessed on this + * server. + *

+ * If the player has never played before, this will return 0. Otherwise, + * it will be the amount of milliseconds since midnight, January 1, 1970 + * UTC. + * + * @return Date of first log-in for this player, or 0 + */ + public long getFirstPlayed(); + + /** + * Gets the last date and time that this player was witnessed on this + * server. + *

+ * If the player has never played before, this will return 0. Otherwise, + * it will be the amount of milliseconds since midnight, January 1, 1970 + * UTC. + * + * @return Date of last log-in for this player, or 0 + */ + public long getLastPlayed(); + + /** + * Checks if this player has played on this server before. + * + * @return True if the player has played before, otherwise false + */ + public boolean hasPlayedBefore(); + + /** + * Gets the Location where the player will spawn at their bed, null if + * they have not slept in one or their current bed spawn is invalid. + * + * @return Bed Spawn Location if bed exists, otherwise null. + */ + public Location getBedSpawnLocation(); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/PortalType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/PortalType.java new file mode 100644 index 0000000..427cfbb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/PortalType.java @@ -0,0 +1,22 @@ +package org.bukkit; + +/** + * Represents various types of portals that can be made in a world. + */ +public enum PortalType { + + /** + * This is a Nether portal, made of obsidian. + */ + NETHER, + + /** + * This is an Ender portal. + */ + ENDER, + + /** + * This is a custom Plugin portal. + */ + CUSTOM; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Rotation.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Rotation.java new file mode 100644 index 0000000..5d059ea --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Rotation.java @@ -0,0 +1,63 @@ +package org.bukkit; + +/** + * An enum to specify a rotation based orientation, like that on a clock. + *

+ * It represents how something is viewed, as opposed to cardinal directions. + */ +public enum Rotation { + + /** + * No rotation + */ + NONE, + /** + * Rotated clockwise by 45 degrees + */ + CLOCKWISE_45, + /** + * Rotated clockwise by 90 degrees + */ + CLOCKWISE, + /** + * Rotated clockwise by 135 degrees + */ + CLOCKWISE_135, + /** + * Flipped upside-down, a 180 degree rotation + */ + FLIPPED, + /** + * Flipped upside-down + 45 degree rotation + */ + FLIPPED_45, + /** + * Rotated counter-clockwise by 90 degrees + */ + COUNTER_CLOCKWISE, + /** + * Rotated counter-clockwise by 45 degrees + */ + COUNTER_CLOCKWISE_45 + ; + + private static final Rotation [] rotations = values(); + + /** + * Rotate clockwise by 90 degrees. + * + * @return the relative rotation + */ + public Rotation rotateClockwise() { + return rotations[(this.ordinal() + 1) & 0x7]; + } + + /** + * Rotate counter-clockwise by 90 degrees. + * + * @return the relative rotation + */ + public Rotation rotateCounterClockwise() { + return rotations[(this.ordinal() - 1) & 0x7]; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/SandstoneType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/SandstoneType.java new file mode 100644 index 0000000..a9ac16e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/SandstoneType.java @@ -0,0 +1,51 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +/** + * Represents the three different types of Sandstone + */ +public enum SandstoneType { + CRACKED(0x0), + GLYPHED(0x1), + SMOOTH(0x2); + + private final byte data; + private final static Map BY_DATA = Maps.newHashMap(); + + private SandstoneType(final int data) { + this.data = (byte) data; + } + + /** + * Gets the associated data value representing this type of sandstone + * + * @return A byte containing the data value of this sandstone type + * @deprecated Magic value + */ + @Deprecated + public byte getData() { + return data; + } + + /** + * Gets the type of sandstone with the given data value + * + * @param data Data value to fetch + * @return The {@link SandstoneType} representing the given value, or null + * if it doesn't exist + * @deprecated Magic value + */ + @Deprecated + public static SandstoneType getByData(final byte data) { + return BY_DATA.get(data); + } + + static { + for (SandstoneType type : values()) { + BY_DATA.put(type.data, type); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Server.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Server.java new file mode 100644 index 0000000..1b62463 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Server.java @@ -0,0 +1,1010 @@ +package org.bukkit; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.logging.Logger; + +import org.bukkit.Warning.WarningState; +import org.bukkit.command.CommandException; +import org.bukkit.command.CommandMap; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.help.HelpMap; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; +import org.bukkit.map.MapView; +import org.bukkit.permissions.Permissible; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.ServicesManager; +import org.bukkit.plugin.messaging.Messenger; +import org.bukkit.plugin.messaging.PluginMessageRecipient; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scoreboard.ScoreboardManager; +import org.bukkit.util.CachedServerIcon; + +import com.avaje.ebean.config.ServerConfig; +import com.google.common.collect.ImmutableList; +import org.bukkit.generator.ChunkGenerator; + +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.meta.ItemMeta; + +/** + * Represents a server implementation. + */ +public interface Server extends PluginMessageRecipient { + + /** + * Used for all administrative messages, such as an operator using a + * command. + *

+ * For use in {@link #broadcast(java.lang.String, java.lang.String)}. + */ + public static final String BROADCAST_CHANNEL_ADMINISTRATIVE = "bukkit.broadcast.admin"; + + /** + * Used for all announcement messages, such as informing users that a + * player has joined. + *

+ * For use in {@link #broadcast(java.lang.String, java.lang.String)}. + */ + public static final String BROADCAST_CHANNEL_USERS = "bukkit.broadcast.user"; + + /** + * Gets the name of this server implementation. + * + * @return name of this server implementation + */ + public String getName(); + + /** + * Gets the version string of this server implementation. + * + * @return version of this server implementation + */ + public String getVersion(); + + /** + * Gets the Bukkit version that this server is running. + * + * @return version of Bukkit + */ + public String getBukkitVersion(); + + /** + * Gets an array copy of all currently logged in players. + *

+ * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @deprecated superseded by {@link #getOnlinePlayers()} + * @return an array of Players that are currently online + */ + @Deprecated + public Player[] _INVALID_getOnlinePlayers(); + + /** + * Gets a view of all currently logged in players. This {@linkplain + * Collections#unmodifiableCollection(Collection) view} is a reused + * object, making some operations like {@link Collection#size()} + * zero-allocation. + *

+ * The collection is a view backed by the internal representation, such + * that, changes to the internal state of the server will be reflected + * immediately. However, the reuse of the returned collection (identity) + * is not strictly guaranteed for future or all implementations. Casting + * the collection, or relying on interface implementations (like {@link + * Serializable} or {@link List}), is deprecated. + *

+ * Iteration behavior is undefined outside of self-contained main-thread + * uses. Normal and immediate iterator use without consequences that + * affect the collection are fully supported. The effects following + * (non-exhaustive) {@link Entity#teleport(Location) teleportation}, + * {@link Player#setHealth(double) death}, and {@link Player#kickPlayer( + * String) kicking} are undefined. Any use of this collection from + * asynchronous threads is unsafe. + *

+ * For safe consequential iteration or mimicking the old array behavior, + * using {@link Collection#toArray(Object[])} is recommended. For making + * snapshots, {@link ImmutableList#copyOf(Collection)} is recommended. + * + * @return a view of currently online players. + */ + public Collection getOnlinePlayers(); + + /** + * Get the maximum amount of players which can login to this server. + * + * @return the amount of players this server allows + */ + public int getMaxPlayers(); + + /** + * Get the game port that the server runs on. + * + * @return the port number of this server + */ + public int getPort(); + + /** + * Get the view distance from this server. + * + * @return the view distance from this server. + */ + public int getViewDistance(); + + /** + * Get the IP that this server is bound to, or empty string if not + * specified. + * + * @return the IP string that this server is bound to, otherwise empty + * string + */ + public String getIp(); + + /** + * Get the name of this server. + * + * @return the name of this server + */ + public String getServerName(); + + /** + * Get an ID of this server. The ID is a simple generally alphanumeric ID + * that can be used for uniquely identifying this server. + * + * @return the ID of this server + */ + public String getServerId(); + + /** + * Get world type (level-type setting) for default world. + * + * @return the value of level-type (e.g. DEFAULT, FLAT, DEFAULT_1_1) + */ + public String getWorldType(); + + /** + * Get generate-structures setting. + * + * @return true if structure generation is enabled, false otherwise + */ + public boolean getGenerateStructures(); + + /** + * Gets whether this server allows the End or not. + * + * @return whether this server allows the End or not + */ + public boolean getAllowEnd(); + + /** + * Gets whether this server allows the Nether or not. + * + * @return whether this server allows the Nether or not + */ + public boolean getAllowNether(); + + /** + * Gets whether this server has a whitelist or not. + * + * @return whether this server has a whitelist or not + */ + public boolean hasWhitelist(); + + /** + * Sets if the server is whitelisted. + * + * @param value true for whitelist on, false for off + */ + public void setWhitelist(boolean value); + + /** + * Gets a list of whitelisted players. + * + * @return a set containing all whitelisted players + */ + public Set getWhitelistedPlayers(); + + /** + * Reloads the whitelist from disk. + */ + public void reloadWhitelist(); + + /** + * Broadcast a message to all players. + *

+ * This is the same as calling {@link #broadcast(java.lang.String, + * java.lang.String)} to {@link #BROADCAST_CHANNEL_USERS} + * + * @param message the message + * @return the number of players + */ + public int broadcastMessage(String message); + + // Paper start + /** + * Sends the component to the player + * + * @param component the components to send + */ + public void broadcast(net.md_5.bungee.api.chat.BaseComponent component); + + /** + * Sends an array of components as a single message to the player + * + * @param components the components to send + */ + public void broadcast(net.md_5.bungee.api.chat.BaseComponent... components); + // Paper end + + /** + * Gets the name of the update folder. The update folder is used to safely + * update plugins at the right moment on a plugin load. + *

+ * The update folder name is relative to the plugins folder. + * + * @return the name of the update folder + */ + public String getUpdateFolder(); + + /** + * Gets the update folder. The update folder is used to safely update + * plugins at the right moment on a plugin load. + * + * @return the update folder + */ + public File getUpdateFolderFile(); + + /** + * Gets the value of the connection throttle setting. + * + * @return the value of the connection throttle setting + */ + public long getConnectionThrottle(); + + /** + * Gets default ticks per animal spawns value. + *

+ * Example Usage: + *

    + *
  • A value of 1 will mean the server will attempt to spawn monsters + * every tick. + *
  • A value of 400 will mean the server will attempt to spawn monsters + * every 400th tick. + *
  • A value below 0 will be reset back to Minecraft's default. + *
+ *

+ * Note: If set to 0, animal spawning will be disabled. We + * recommend using spawn-animals to control this instead. + *

+ * Minecraft default: 400. + * + * @return the default ticks per animal spawns value + */ + public int getTicksPerAnimalSpawns(); + + /** + * Gets the default ticks per monster spawns value. + *

+ * Example Usage: + *

    + *
  • A value of 1 will mean the server will attempt to spawn monsters + * every tick. + *
  • A value of 400 will mean the server will attempt to spawn monsters + * every 400th tick. + *
  • A value below 0 will be reset back to Minecraft's default. + *
+ *

+ * Note: If set to 0, monsters spawning will be disabled. We + * recommend using spawn-monsters to control this instead. + *

+ * Minecraft default: 1. + * + * @return the default ticks per monsters spawn value + */ + public int getTicksPerMonsterSpawns(); + + /** + * Gets a player object by the given username. + *

+ * This method may not return objects for offline players. + * + * @param name the name to look up + * @return a player if one was found, null otherwise + */ + public Player getPlayer(String name); + + /** + * Gets the player with the exact given name, case insensitive. + * + * @param name Exact name of the player to retrieve + * @return a player object if one was found, null otherwise + */ + public Player getPlayerExact(String name); + + /** + * Attempts to match any players with the given name, and returns a list + * of all possibly matches. + *

+ * This list is not sorted in any particular order. If an exact match is + * found, the returned list will only contain a single result. + * + * @param name the (partial) name to match + * @return list of all possible players + */ + public List matchPlayer(String name); + + /** + * Gets the player with the given UUID. + * + * @param id UUID of the player to retrieve + * @return a player object if one was found, null otherwise + */ + public Player getPlayer(UUID id); + + /** + * Gets the plugin manager for interfacing with plugins. + * + * @return a plugin manager for this Server instance + */ + public PluginManager getPluginManager(); + + /** + * Gets the scheduler for managing scheduled events. + * + * @return a scheduling service for this server + */ + public BukkitScheduler getScheduler(); + + /** + * Gets a services manager. + * + * @return s services manager + */ + public ServicesManager getServicesManager(); + + /** + * Gets a list of all worlds on this server. + * + * @return a list of worlds + */ + public List getWorlds(); + + /** + * Creates or loads a world with the given name using the specified + * options. + *

+ * If the world is already loaded, it will just return the equivalent of + * getWorld(creator.name()). + * + * @param creator the options to use when creating the world + * @return newly created or loaded world + */ + public World createWorld(WorldCreator creator); + + /** + * Unloads a world with the given name. + * + * @param name Name of the world to unload + * @param save whether to save the chunks before unloading + * @return true if successful, false otherwise + */ + public boolean unloadWorld(String name, boolean save); + + /** + * Unloads the given world. + * + * @param world the world to unload + * @param save whether to save the chunks before unloading + * @return true if successful, false otherwise + */ + public boolean unloadWorld(World world, boolean save); + + /** + * Gets the world with the given name. + * + * @param name the name of the world to retrieve + * @return a world with the given name, or null if none exists + */ + public World getWorld(String name); + + /** + * Gets the world from the given Unique ID. + * + * @param uid a unique-id of the world to retrieve + * @return a world with the given Unique ID, or null if none exists + */ + public World getWorld(UUID uid); + + /** + * Gets the map from the given item ID. + * + * @param id the id of the map to get + * @return a map view if it exists, or null otherwise + * @deprecated Magic value + */ + @Deprecated + public MapView getMap(short id); + + /** + * Create a new map with an automatically assigned ID. + * + * @param world the world the map will belong to + * @return a newly created map view + */ + public MapView createMap(World world); + + /** + * Reloads the server, refreshing settings and plugin information. + */ + public void reload(); + + /** + * Returns the primary logger associated with this server instance. + * + * @return Logger associated with this server + */ + public Logger getLogger(); + + /** + * Gets a {@link PluginCommand} with the given name or alias. + * + * @param name the name of the command to retrieve + * @return a plugin command if found, null otherwise + */ + public PluginCommand getPluginCommand(String name); + + /** + * Writes loaded players to disk. + */ + public void savePlayers(); + + /** + * Dispatches a command on this server, and executes it if found. + * + * @param sender the apparent sender of the command + * @param commandLine the command + arguments. Example: test abc + * 123 + * @return returns false if no target is found + * @throws CommandException thrown when the executor for the given command + * fails with an unhandled exception + */ + public boolean dispatchCommand(CommandSender sender, String commandLine) throws CommandException; + + /** + * Populates a given {@link ServerConfig} with values attributes to this + * server. + * + * @param config the server config to populate + */ + public void configureDbConfig(ServerConfig config); + + /** + * Adds a recipe to the crafting manager. + * + * @param recipe the recipe to add + * @return true if the recipe was added, false if it wasn't for some + * reason + */ + public boolean addRecipe(Recipe recipe); + + /** + * Get a list of all recipes for a given item. The stack size is ignored + * in comparisons. If the durability is -1, it will match any data value. + * + * @param result the item to match against recipe results + * @return a list of recipes with the given result + */ + public List getRecipesFor(ItemStack result); + + /** + * Get an iterator through the list of crafting recipes. + * + * @return an iterator + */ + public Iterator recipeIterator(); + + /** + * Clears the list of crafting recipes. + */ + public void clearRecipes(); + + /** + * Resets the list of crafting recipes to the default. + */ + public void resetRecipes(); + + /** + * Gets a list of command aliases defined in the server properties. + * + * @return a map of aliases to command names + */ + public Map getCommandAliases(); + + /** + * Gets the radius, in blocks, around each worlds spawn point to protect. + * + * @return spawn radius, or 0 if none + */ + public int getSpawnRadius(); + + /** + * Sets the radius, in blocks, around each worlds spawn point to protect. + * + * @param value new spawn radius, or 0 if none + */ + public void setSpawnRadius(int value); + + /** + * Gets whether the Server is in online mode or not. + * + * @return true if the server authenticates clients, false otherwise + */ + public boolean getOnlineMode(); + + /** + * Gets whether this server allows flying or not. + * + * @return true if the server allows flight, false otherwise + */ + public boolean getAllowFlight(); + + /** + * Gets whether the server is in hardcore mode or not. + * + * @return true if the server mode is hardcore, false otherwise + */ + public boolean isHardcore(); + + /** + * Gets whether to use vanilla (false) or exact behaviour (true). + * + *

    + *
  • Vanilla behaviour: check for collisions and move the player if + * needed. + *
  • Exact behaviour: spawn players exactly where they should be. + *
+ * + * @return true if exact location locations are used for spawning, false + * for vanilla collision detection or otherwise + * + * @deprecated non standard and unused feature. + */ + @Deprecated + public boolean useExactLoginLocation(); + + /** + * Shutdowns the server, stopping everything. + */ + public void shutdown(); + + /** + * Broadcasts the specified message to every user with the given + * permission name. + * + * @param message message to broadcast + * @param permission the required permission {@link Permissible + * permissibles} must have to receive the broadcast + * @return number of message recipients + */ + public int broadcast(String message, String permission); + + /** + * Gets the player by the given name, regardless if they are offline or + * online. + *

+ * This method may involve a blocking web request to get the UUID for the + * given name. + *

+ * This will return an object even if the player does not exist. To this + * method, all players will exist. + * + * @deprecated Persistent storage of users should be by UUID as names are no longer + * unique past a single session. + * @param name the name the player to retrieve + * @return an offline player + * @see #getOfflinePlayer(java.util.UUID) + */ + @Deprecated + public OfflinePlayer getOfflinePlayer(String name); + + /** + * Gets the player by the given UUID, regardless if they are offline or + * online. + *

+ * This will return an object even if the player does not exist. To this + * method, all players will exist. + * + * @param id the UUID of the player to retrieve + * @return an offline player + */ + public OfflinePlayer getOfflinePlayer(UUID id); + + /** + * Gets a set containing all current IPs that are banned. + * + * @return a set containing banned IP addresses + */ + public Set getIPBans(); + + /** + * Bans the specified address from the server. + * + * @param address the IP address to ban + */ + public void banIP(String address); + + /** + * Unbans the specified address from the server. + * + * @param address the IP address to unban + */ + public void unbanIP(String address); + + /** + * Gets a set containing all banned players. + * + * @return a set containing banned players + */ + public Set getBannedPlayers(); + + /** + * Gets a ban list for the supplied type. + *

+ * Bans by name are no longer supported and this method will return + * null when trying to request them. The replacement is bans by UUID. + * + * @param type the type of list to fetch, cannot be null + * @return a ban list of the specified type + */ + public BanList getBanList(BanList.Type type); + + /** + * Gets a set containing all player operators. + * + * @return a set containing player operators + */ + public Set getOperators(); + + /** + * Gets the default {@link GameMode} for new players. + * + * @return the default game mode + */ + public GameMode getDefaultGameMode(); + + /** + * Sets the default {@link GameMode} for new players. + * + * @param mode the new game mode + */ + public void setDefaultGameMode(GameMode mode); + + /** + * Gets a {@link ConsoleCommandSender} that may be used as an input source + * for this server. + * + * @return a console command sender + */ + public ConsoleCommandSender getConsoleSender(); + + /** + * Gets the folder that contains all of the various {@link World}s. + * + * @return folder that contains all worlds + */ + public File getWorldContainer(); + + /** + * Gets every player that has ever played on this server. + * + * @return an array containing all previous players + */ + public OfflinePlayer[] getOfflinePlayers(); + + /** + * Gets the {@link Messenger} responsible for this server. + * + * @return messenger responsible for this server + */ + public Messenger getMessenger(); + + /** + * Gets the {@link HelpMap} providing help topics for this server. + * + * @return a help map for this server + */ + public HelpMap getHelpMap(); + + /** + * Creates an empty inventory of the specified type. If the type is {@link + * InventoryType#CHEST}, the new inventory has a size of 27; otherwise the + * new inventory has the normal size for its type. + * + * @param owner the holder of the inventory, or null to indicate no holder + * @param type the type of inventory to create + * @return a new inventory + */ + Inventory createInventory(InventoryHolder owner, InventoryType type); + + /** + * Creates an empty inventory with the specified type and title. If the type + * is {@link InventoryType#CHEST}, the new inventory has a size of 27; + * otherwise the new inventory has the normal size for its type.
+ * It should be noted that some inventory types do not support titles and + * may not render with said titles on the Minecraft client. + * + * @param owner The holder of the inventory; can be null if there's no holder. + * @param type The type of inventory to create. + * @param title The title of the inventory, to be displayed when it is viewed. + * @return The new inventory. + */ + Inventory createInventory(InventoryHolder owner, InventoryType type, String title); + + /** + * Creates an empty inventory of type {@link InventoryType#CHEST} with the + * specified size. + * + * @param owner the holder of the inventory, or null to indicate no holder + * @param size a multiple of 9 as the size of inventory to create + * @return a new inventory + * @throws IllegalArgumentException if the size is not a multiple of 9 + */ + Inventory createInventory(InventoryHolder owner, int size) throws IllegalArgumentException; + + /** + * Creates an empty inventory of type {@link InventoryType#CHEST} with the + * specified size and title. + * + * @param owner the holder of the inventory, or null to indicate no holder + * @param size a multiple of 9 as the size of inventory to create + * @param title the title of the inventory, displayed when inventory is + * viewed + * @return a new inventory + * @throws IllegalArgumentException if the size is not a multiple of 9 + */ + Inventory createInventory(InventoryHolder owner, int size, String title) throws IllegalArgumentException; + + /** + * Gets user-specified limit for number of monsters that can spawn in a + * chunk. + * + * @return the monster spawn limit + */ + int getMonsterSpawnLimit(); + + /** + * Gets user-specified limit for number of animals that can spawn in a + * chunk. + * + * @return the animal spawn limit + */ + int getAnimalSpawnLimit(); + + /** + * Gets user-specified limit for number of water animals that can spawn in + * a chunk. + * + * @return the water animal spawn limit + */ + int getWaterAnimalSpawnLimit(); + + /** + * Gets user-specified limit for number of ambient mobs that can spawn in + * a chunk. + * + * @return the ambient spawn limit + */ + int getAmbientSpawnLimit(); + + /** + * Checks the current thread against the expected primary thread for the + * server. + *

+ * Note: this method should not be used to indicate the current + * synchronized state of the runtime. A current thread matching the main + * thread indicates that it is synchronized, but a mismatch does not + * preclude the same assumption. + * + * @return true if the current thread matches the expected primary thread, + * false otherwise + */ + boolean isPrimaryThread(); + + /** + * Gets the message that is displayed on the server list. + * + * @return the servers MOTD + */ + String getMotd(); + + /** + * Gets the default message that is displayed when the server is stopped. + * + * @return the shutdown message + */ + String getShutdownMessage(); + + /** + * Gets the current warning state for the server. + * + * @return the configured warning state + */ + public WarningState getWarningState(); + + /** + * Gets the instance of the item factory (for {@link ItemMeta}). + * + * @return the item factory + * @see ItemFactory + */ + ItemFactory getItemFactory(); + + /** + * Gets the instance of the scoreboard manager. + *

+ * This will only exist after the first world has loaded. + * + * @return the scoreboard manager or null if no worlds are loaded. + */ + ScoreboardManager getScoreboardManager(); + + /** + * Gets an instance of the server's default server-icon. + * + * @return the default server-icon; null values may be used by the + * implementation to indicate no defined icon, but this behavior is + * not guaranteed + */ + CachedServerIcon getServerIcon(); + + /** + * Loads an image from a file, and returns a cached image for the specific + * server-icon. + *

+ * Size and type are implementation defined. An incompatible file is + * guaranteed to throw an implementation-defined {@link Exception}. + * + * @param file the file to load the from + * @throws IllegalArgumentException if image is null + * @throws Exception if the image does not meet current server server-icon + * specifications + * @return a cached server-icon that can be used for a {@link + * ServerListPingEvent#setServerIcon(CachedServerIcon)} + */ + CachedServerIcon loadServerIcon(File file) throws IllegalArgumentException, Exception; + + /** + * Creates a cached server-icon for the specific image. + *

+ * Size and type are implementation defined. An incompatible file is + * guaranteed to throw an implementation-defined {@link Exception}. + * + * @param image the image to use + * @throws IllegalArgumentException if image is null + * @throws Exception if the image does not meet current server + * server-icon specifications + * @return a cached server-icon that can be used for a {@link + * ServerListPingEvent#setServerIcon(CachedServerIcon)} + */ + CachedServerIcon loadServerIcon(BufferedImage image) throws IllegalArgumentException, Exception; + + /** + * Set the idle kick timeout. Any players idle for the specified amount of + * time will be automatically kicked. + *

+ * A value of 0 will disable the idle kick timeout. + * + * @param threshold the idle timeout in minutes + */ + public void setIdleTimeout(int threshold); + + /** + * Gets the idle kick timeout. + * + * @return the idle timeout in minutes + */ + public int getIdleTimeout(); + + /** + * Create a ChunkData for use in a generator. + * + * See {@link ChunkGenerator#generateChunkData(org.bukkit.World, java.util.Random, int, int, org.bukkit.generator.ChunkGenerator.BiomeGrid)} + * + * @param world the world to create the ChunkData for + * @return a new ChunkData for the world + * + */ + public ChunkGenerator.ChunkData createChunkData(World world); + + /** + * @see UnsafeValues + * @return the unsafe values instance + */ + @Deprecated + UnsafeValues getUnsafe(); + + // Paper start + /** + * Gets the active {@link CommandMap}. + * + * @return the active command map + */ + CommandMap getCommandMap(); + // Paper end + + public class Spigot + { + @Deprecated + public org.bukkit.configuration.file.YamlConfiguration getConfig() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + public org.bukkit.configuration.file.YamlConfiguration getBukkitConfig() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + public org.bukkit.configuration.file.YamlConfiguration getSpigotConfig() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + public org.bukkit.configuration.file.YamlConfiguration getPaperSpigotConfig() + { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Sends the component to the player + * + * @param component the components to send + */ + public void broadcast(net.md_5.bungee.api.chat.BaseComponent component) { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Sends an array of components as a single message to the player + * + * @param components the components to send + */ + public void broadcast(net.md_5.bungee.api.chat.BaseComponent... components) { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Restart the server. If the server administrator has not configured restarting, the server will stop. + */ + public void restart() { + throw new UnsupportedOperationException("Not supported yet."); + } + + // PaperSpigot start - Add getTPS method + public double[] getTPS() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + // PaperSpigot end + } + + Spigot spigot(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/SkullType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/SkullType.java new file mode 100644 index 0000000..abd07c2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/SkullType.java @@ -0,0 +1,12 @@ +package org.bukkit; + +/** + * Represents the different types of skulls. + */ +public enum SkullType { + SKELETON, + WITHER, + ZOMBIE, + PLAYER, + CREEPER; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Sound.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Sound.java new file mode 100644 index 0000000..0913530 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Sound.java @@ -0,0 +1,211 @@ +package org.bukkit; + +/** + * An Enum of Sounds the server is able to send to players. + *

+ * WARNING: At any time, sounds may be added/removed from this Enum or even + * MineCraft itself! There is no guarantee the sounds will play. There is no + * guarantee values will not be removed from this Enum. As such, you should + * not depend on the ordinal values of this class. + */ +public enum Sound { + AMBIENCE_CAVE, + AMBIENCE_RAIN, + AMBIENCE_THUNDER, + ANVIL_BREAK, + ANVIL_LAND, + ANVIL_USE, + ARROW_HIT, + BURP, + CHEST_CLOSE, + CHEST_OPEN, + CLICK, + DOOR_CLOSE, + DOOR_OPEN, + DRINK, + EAT, + EXPLODE, + FALL_BIG, + FALL_SMALL, + FIRE, + FIRE_IGNITE, + FIZZ, + FUSE, + GLASS, + HURT_FLESH, + ITEM_BREAK, + ITEM_PICKUP, + LAVA, + LAVA_POP, + LEVEL_UP, + MINECART_BASE, + MINECART_INSIDE, + NOTE_BASS, + NOTE_PIANO, + NOTE_BASS_DRUM, + NOTE_STICKS, + NOTE_BASS_GUITAR, + NOTE_SNARE_DRUM, + NOTE_PLING, + ORB_PICKUP, + PISTON_EXTEND, + PISTON_RETRACT, + PORTAL, + PORTAL_TRAVEL, + PORTAL_TRIGGER, + SHOOT_ARROW, + SPLASH, + SPLASH2, + STEP_GRASS, + STEP_GRAVEL, + STEP_LADDER, + STEP_SAND, + STEP_SNOW, + STEP_STONE, + STEP_WOOD, + STEP_WOOL, + SWIM, + WATER, + WOOD_CLICK, + // Mob sounds + BAT_DEATH, + BAT_HURT, + BAT_IDLE, + BAT_LOOP, + BAT_TAKEOFF, + BLAZE_BREATH, + BLAZE_DEATH, + BLAZE_HIT, + CAT_HISS, + CAT_HIT, + CAT_MEOW, + CAT_PURR, + CAT_PURREOW, + CHICKEN_IDLE, + CHICKEN_HURT, + CHICKEN_EGG_POP, + CHICKEN_WALK, + COW_IDLE, + COW_HURT, + COW_WALK, + CREEPER_HISS, + CREEPER_DEATH, + ENDERDRAGON_DEATH, + ENDERDRAGON_GROWL, + ENDERDRAGON_HIT, + ENDERDRAGON_WINGS, + ENDERMAN_DEATH, + ENDERMAN_HIT, + ENDERMAN_IDLE, + ENDERMAN_TELEPORT, + ENDERMAN_SCREAM, + ENDERMAN_STARE, + GHAST_SCREAM, + GHAST_SCREAM2, + GHAST_CHARGE, + GHAST_DEATH, + GHAST_FIREBALL, + GHAST_MOAN, + IRONGOLEM_DEATH, + IRONGOLEM_HIT, + IRONGOLEM_THROW, + IRONGOLEM_WALK, + MAGMACUBE_WALK, + MAGMACUBE_WALK2, + MAGMACUBE_JUMP, + PIG_IDLE, + PIG_DEATH, + PIG_WALK, + SHEEP_IDLE, + SHEEP_SHEAR, + SHEEP_WALK, + SILVERFISH_HIT, + SILVERFISH_KILL, + SILVERFISH_IDLE, + SILVERFISH_WALK, + SKELETON_IDLE, + SKELETON_DEATH, + SKELETON_HURT, + SKELETON_WALK, + SLIME_ATTACK, + SLIME_WALK, + SLIME_WALK2, + SPIDER_IDLE, + SPIDER_DEATH, + SPIDER_WALK, + WITHER_DEATH, + WITHER_HURT, + WITHER_IDLE, + WITHER_SHOOT, + WITHER_SPAWN, + WOLF_BARK, + WOLF_DEATH, + WOLF_GROWL, + WOLF_HOWL, + WOLF_HURT, + WOLF_PANT, + WOLF_SHAKE, + WOLF_WALK, + WOLF_WHINE, + ZOMBIE_METAL, + ZOMBIE_WOOD, + ZOMBIE_WOODBREAK, + ZOMBIE_IDLE, + ZOMBIE_DEATH, + ZOMBIE_HURT, + ZOMBIE_INFECT, + ZOMBIE_UNFECT, + ZOMBIE_REMEDY, + ZOMBIE_WALK, + ZOMBIE_PIG_IDLE, + ZOMBIE_PIG_ANGRY, + ZOMBIE_PIG_DEATH, + ZOMBIE_PIG_HURT, + // Dig Sounds + DIG_WOOL, + DIG_GRASS, + DIG_GRAVEL, + DIG_SAND, + DIG_SNOW, + DIG_STONE, + DIG_WOOD, + // Fireworks + FIREWORK_BLAST, + FIREWORK_BLAST2, + FIREWORK_LARGE_BLAST, + FIREWORK_LARGE_BLAST2, + FIREWORK_TWINKLE, + FIREWORK_TWINKLE2, + FIREWORK_LAUNCH, + SUCCESSFUL_HIT, + // Horses + HORSE_ANGRY, + HORSE_ARMOR, + HORSE_BREATHE, + HORSE_DEATH, + HORSE_GALLOP, + HORSE_HIT, + HORSE_IDLE, + HORSE_JUMP, + HORSE_LAND, + HORSE_SADDLE, + HORSE_SOFT, + HORSE_WOOD, + DONKEY_ANGRY, + DONKEY_DEATH, + DONKEY_HIT, + DONKEY_IDLE, + HORSE_SKELETON_DEATH, + HORSE_SKELETON_HIT, + HORSE_SKELETON_IDLE, + HORSE_ZOMBIE_DEATH, + HORSE_ZOMBIE_HIT, + HORSE_ZOMBIE_IDLE, + // Villager + VILLAGER_DEATH, + VILLAGER_HAGGLE, + VILLAGER_HIT, + VILLAGER_IDLE, + VILLAGER_NO, + VILLAGER_YES, +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Statistic.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Statistic.java new file mode 100644 index 0000000..3764f1f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Statistic.java @@ -0,0 +1,133 @@ +package org.bukkit; + +/** + * Represents a countable statistic, which is tracked by the server. + */ +public enum Statistic { + DAMAGE_DEALT, + DAMAGE_TAKEN, + DEATHS, + MOB_KILLS, + PLAYER_KILLS, + FISH_CAUGHT, + ANIMALS_BRED, + TREASURE_FISHED, + JUNK_FISHED, + LEAVE_GAME, + JUMP, + DROP, + PLAY_ONE_TICK, + WALK_ONE_CM, + SWIM_ONE_CM, + FALL_ONE_CM, + CLIMB_ONE_CM, + FLY_ONE_CM, + DIVE_ONE_CM, + MINECART_ONE_CM, + BOAT_ONE_CM, + PIG_ONE_CM, + HORSE_ONE_CM, + SPRINT_ONE_CM, + CROUCH_ONE_CM, + MINE_BLOCK(Type.BLOCK), + USE_ITEM(Type.ITEM), + BREAK_ITEM(Type.ITEM), + CRAFT_ITEM(Type.ITEM), + KILL_ENTITY(Type.ENTITY), + ENTITY_KILLED_BY(Type.ENTITY), + TIME_SINCE_DEATH, + TALKED_TO_VILLAGER, + TRADED_WITH_VILLAGER, + CAKE_SLICES_EATEN, + CAULDRON_FILLED, + CAULDRON_USED, + ARMOR_CLEANED, + BANNER_CLEANED, + BREWINGSTAND_INTERACTION, + BEACON_INTERACTION, + DROPPER_INSPECTED, + HOPPER_INSPECTED, + DISPENSER_INSPECTED, + NOTEBLOCK_PLAYED, + NOTEBLOCK_TUNED, + FLOWER_POTTED, + TRAPPED_CHEST_TRIGGERED, + ENDERCHEST_OPENED, + ITEM_ENCHANTED, + RECORD_PLAYED, + FURNACE_INTERACTION, + CRAFTING_TABLE_INTERACTION, + CHEST_OPENED; + + private final Type type; + + private Statistic() { + this(Type.UNTYPED); + } + + private Statistic(Type type) { + this.type = type; + } + + /** + * Gets the type of this statistic. + * + * @return the type of this statistic + */ + public Type getType() { + return type; + } + + /** + * Checks if this is a substatistic. + *

+ * A substatistic exists en masse for each block, item, or entitytype, depending on + * {@link #getType()}. + *

+ * This is a redundant method and equivalent to checking + * getType() != Type.UNTYPED + * + * @return true if this is a substatistic + */ + public boolean isSubstatistic() { + return type != Type.UNTYPED; + } + + /** + * Checks if this is a substatistic dealing with blocks. + *

+ * This is a redundant method and equivalent to checking + * getType() == Type.BLOCK + * + * @return true if this deals with blocks + */ + public boolean isBlock() { + return type == Type.BLOCK; + } + + /** + * The type of statistic. + * + */ + public enum Type { + /** + * Statistics of this type do not require a qualifier. + */ + UNTYPED, + + /** + * Statistics of this type require an Item Material qualifier. + */ + ITEM, + + /** + * Statistics of this type require a Block Material qualifier. + */ + BLOCK, + + /** + * Statistics of this type require an EntityType qualifier. + */ + ENTITY; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TravelAgent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TravelAgent.java new file mode 100644 index 0000000..2dfeffa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TravelAgent.java @@ -0,0 +1,94 @@ +package org.bukkit; + +/** + * The Travel Agent handles the creation and the research of Nether and End + * portals when Entities try to use one. + *

+ * It is used in {@link org.bukkit.event.entity.EntityPortalEvent} and in + * {@link org.bukkit.event.player.PlayerPortalEvent} to help developers + * reproduce and/or modify Vanilla behaviour. + */ +public interface TravelAgent { + + /** + * Set the Block radius to search in for available portals. + * + * @param radius the radius in which to search for a portal from the + * location + * @return this travel agent + */ + public TravelAgent setSearchRadius(int radius); + + /** + * Gets the search radius value for finding an available portal. + * + * @return the currently set search radius + */ + public int getSearchRadius(); + + /** + * Sets the maximum radius from the given location to create a portal. + * + * @param radius the radius in which to create a portal from the location + * @return this travel agent + */ + public TravelAgent setCreationRadius(int radius); + + /** + * Gets the maximum radius from the given location to create a portal. + * + * @return the currently set creation radius + */ + public int getCreationRadius(); + + /** + * Returns whether the TravelAgent will attempt to create a destination + * portal or not. + * + * @return whether the TravelAgent should create a destination portal or + * not + */ + public boolean getCanCreatePortal(); + + /** + * Sets whether the TravelAgent should attempt to create a destination + * portal or not. + * + * @param create Sets whether the TravelAgent should create a destination + * portal or not + */ + public void setCanCreatePortal(boolean create); + + /** + * Attempt to find a portal near the given location, if a portal is not + * found it will attempt to create one. + * + * @param location the location where the search for a portal should begin + * @return the location of a portal which has been found or returns the + * location passed to the method if unsuccessful + * @see #createPortal(Location) + */ + public Location findOrCreate(Location location); + + /** + * Attempt to find a portal near the given location. + * + * @param location the desired location of the portal + * @return the location of the nearest portal to the location + */ + public Location findPortal(Location location); + + /** + * Attempt to create a portal near the given location. + *

+ * In the case of a Nether portal teleportation, this will attempt to + * create a Nether portal. + *

+ * In the case of an Ender portal teleportation, this will (re-)create the + * obsidian platform and clean blocks above it. + * + * @param location the desired location of the portal + * @return true if a portal was successfully created + */ + public boolean createPortal(Location location); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TreeSpecies.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TreeSpecies.java new file mode 100644 index 0000000..f29062a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TreeSpecies.java @@ -0,0 +1,74 @@ +package org.bukkit; + +import java.util.Map; + +import com.google.common.collect.Maps; + +/** + * Represents the different species of trees regardless of size. + */ +public enum TreeSpecies { + + /** + * Represents the common tree species. + */ + GENERIC(0x0), + /** + * Represents the darker barked/leaved tree species. + */ + REDWOOD(0x1), + /** + * Represents birches. + */ + BIRCH(0x2), + /** + * Represents jungle trees. + */ + JUNGLE(0x3), + /** + * Represents acacia trees. + */ + ACACIA(0x4), + /** + * Represents dark oak trees. + */ + DARK_OAK(0x5), + ; + + private final byte data; + private final static Map BY_DATA = Maps.newHashMap(); + + private TreeSpecies(final int data) { + this.data = (byte) data; + } + + /** + * Gets the associated data value representing this species + * + * @return A byte containing the data value of this tree species + * @deprecated Magic value + */ + @Deprecated + public byte getData() { + return data; + } + + /** + * Gets the TreeSpecies with the given data value + * + * @param data Data value to fetch + * @return The {@link TreeSpecies} representing the given value, or null + * if it doesn't exist + * @deprecated Magic value + */ + @Deprecated + public static TreeSpecies getByData(final byte data) { + return BY_DATA.get(data); + } + + static { + for (TreeSpecies species : values()) { + BY_DATA.put(species.data, species); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TreeType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TreeType.java new file mode 100644 index 0000000..5a5c4d9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/TreeType.java @@ -0,0 +1,72 @@ +package org.bukkit; + +/** + * Tree and organic structure types. + */ +public enum TreeType { + + /** + * Regular tree, no branches + */ + TREE, + /** + * Regular tree, extra tall with branches + */ + BIG_TREE, + /** + * Redwood tree, shaped like a pine tree + */ + REDWOOD, + /** + * Tall redwood tree with just a few leaves at the top + */ + TALL_REDWOOD, + /** + * Birch tree + */ + BIRCH, + /** + * Standard jungle tree; 4 blocks wide and tall + */ + JUNGLE, + /** + * Smaller jungle tree; 1 block wide + */ + SMALL_JUNGLE, + /** + * Jungle tree with cocoa plants; 1 block wide + */ + COCOA_TREE, + /** + * Small bush that grows in the jungle + */ + JUNGLE_BUSH, + /** + * Big red mushroom; short and fat + */ + RED_MUSHROOM, + /** + * Big brown mushroom; tall and umbrella-like + */ + BROWN_MUSHROOM, + /** + * Swamp tree (regular with vines on the side) + */ + SWAMP, + /** + * Acacia tree. + */ + ACACIA, + /** + * Dark Oak tree. + */ + DARK_OAK, + /** + * Mega redwood tree; 4 blocks wide and tall + */ + MEGA_REDWOOD, + /** + * Tall birch tree + */ + TALL_BIRCH, +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/UnsafeValues.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/UnsafeValues.java new file mode 100644 index 0000000..568c83e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/UnsafeValues.java @@ -0,0 +1,33 @@ +package org.bukkit; + +import java.util.List; + +import org.bukkit.inventory.ItemStack; + +/** + * This interface provides value conversions that may be specific to a + * runtime, or have arbitrary meaning (read: magic values). + *

+ * Their existence and behavior is not guaranteed across future versions. They + * may be poorly named, throw exceptions, have misleading parameters, or any + * other bad programming practice. + *

+ * This interface is unsupported and only for internal use. + * + * @deprecated Unsupported {@literal &} internal use only + */ +@Deprecated +public interface UnsafeValues { + + Material getMaterialFromInternalName(String name); + + List tabCompleteInternalMaterialName(String token, List completions); + + ItemStack modifyItemStack(ItemStack stack, String arguments); + + Statistic getStatisticFromInternalName(String name); + + Achievement getAchievementFromInternalName(String name); + + List tabCompleteInternalStatisticOrAchievementName(String token, List completions); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Utility.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Utility.java new file mode 100644 index 0000000..da66853 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Utility.java @@ -0,0 +1,18 @@ +package org.bukkit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation indicates a method (and sometimes constructor) will chain + * its internal operations. + *

+ * This is solely meant for identifying methods that don't need to be + * overridden / handled manually. + */ +@Target({ElementType.CONSTRUCTOR, ElementType.METHOD}) +@Retention(RetentionPolicy.SOURCE) +public @interface Utility { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Warning.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Warning.java new file mode 100644 index 0000000..6a2a3b0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/Warning.java @@ -0,0 +1,109 @@ +package org.bukkit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Map; + +import com.google.common.collect.ImmutableMap; + +/** + * This designates the warning state for a specific item. + *

+ * When the server settings dictate 'default' warnings, warnings are printed + * if the {@link #value()} is true. + */ +@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Warning { + + /** + * This represents the states that server verbose for warnings may be. + */ + public enum WarningState { + + /** + * Indicates all warnings should be printed for deprecated items. + */ + ON, + /** + * Indicates no warnings should be printed for deprecated items. + */ + OFF, + /** + * Indicates each warning would default to the configured {@link + * Warning} annotation, or always if annotation not found. + */ + DEFAULT; + + private static final Map values = ImmutableMap.builder() + .put("off", OFF) + .put("false", OFF) + .put("f", OFF) + .put("no", OFF) + .put("n", OFF) + .put("on", ON) + .put("true", ON) + .put("t", ON) + .put("yes", ON) + .put("y", ON) + .put("", DEFAULT) + .put("d", DEFAULT) + .put("default", DEFAULT) + .build(); + + /** + * This method checks the provided warning should be printed for this + * state + * + * @param warning The warning annotation added to a deprecated item + * @return

    + *
  • ON is always True + *
  • OFF is always false + *
  • DEFAULT is false if and only if annotation is not null and + * specifies false for {@link Warning#value()}, true otherwise. + *
+ */ + public boolean printFor(Warning warning) { + if (this == DEFAULT) { + return warning == null || warning.value(); + } + return this == ON; + } + + /** + * This method returns the corresponding warning state for the given + * string value. + * + * @param value The string value to check + * @return {@link #DEFAULT} if not found, or the respective + * WarningState + */ + public static WarningState value(final String value) { + if (value == null) { + return DEFAULT; + } + WarningState state = values.get(value.toLowerCase()); + if (state == null) { + return DEFAULT; + } + return state; + } + } + + /** + * This sets if the deprecation warnings when registering events gets + * printed when the setting is in the default state. + * + * @return false normally, or true to encourage warning printout + */ + boolean value() default false; + + /** + * This can provide detailed information on why the event is deprecated. + * + * @return The reason an event is deprecated + */ + String reason() default ""; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WeatherType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WeatherType.java new file mode 100644 index 0000000..36b993f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WeatherType.java @@ -0,0 +1,17 @@ +package org.bukkit; + +/** + * An enum of all current weather types + */ +public enum WeatherType { + + /** + * Raining or snowing depending on biome. + */ + DOWNFALL, + /** + * Clear weather, clouds but no rain. + */ + CLEAR, + ; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/World.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/World.java new file mode 100644 index 0000000..caa92fb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/World.java @@ -0,0 +1,1355 @@ +package org.bukkit; + +import java.io.File; + +import com.avaje.ebean.validation.NotNull; +import org.bukkit.generator.ChunkGenerator; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.block.Biome; +import org.bukkit.block.Block; +import org.bukkit.entity.*; +import org.bukkit.generator.BlockPopulator; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.Metadatable; +import org.bukkit.plugin.messaging.PluginMessageRecipient; +import org.bukkit.util.Vector; + +/** + * Represents a world, which may contain entities, chunks and blocks + */ +public interface World extends PluginMessageRecipient, Metadatable { + + /** + * Gets the {@link Block} at the given coordinates + * + * @param x X-coordinate of the block + * @param y Y-coordinate of the block + * @param z Z-coordinate of the block + * @return Block at the given coordinates + * @see #getBlockTypeIdAt(int, int, int) Returns the current type ID of + * the block + */ + public Block getBlockAt(int x, int y, int z); + + /** + * Gets the {@link Block} at the given {@link Location} + * + * @param location Location of the block + * @return Block at the given location + * @see #getBlockTypeIdAt(org.bukkit.Location) Returns the current type ID + * of the block + */ + public Block getBlockAt(Location location); + + /** + * Gets the block type ID at the given coordinates + * + * @param x X-coordinate of the block + * @param y Y-coordinate of the block + * @param z Z-coordinate of the block + * @return Type ID of the block at the given coordinates + * @see #getBlockAt(int, int, int) Returns a live Block object at the + * given location + * @deprecated Magic value + */ + @Deprecated + public int getBlockTypeIdAt(int x, int y, int z); + + /** + * Gets the block type ID at the given {@link Location} + * + * @param location Location of the block + * @return Type ID of the block at the given location + * @see #getBlockAt(org.bukkit.Location) Returns a live Block object at + * the given location + * @deprecated Magic value + */ + @Deprecated + public int getBlockTypeIdAt(Location location); + + /** + * Gets the highest non-air coordinate at the given coordinates + * + * @param x X-coordinate of the blocks + * @param z Z-coordinate of the blocks + * @return Y-coordinate of the highest non-air block + */ + public int getHighestBlockYAt(int x, int z); + + /** + * Gets the highest non-air coordinate at the given {@link Location} + * + * @param location Location of the blocks + * @return Y-coordinate of the highest non-air block + */ + public int getHighestBlockYAt(Location location); + + /** + * Gets the highest non-empty block at the given coordinates + * + * @param x X-coordinate of the block + * @param z Z-coordinate of the block + * @return Highest non-empty block + */ + public Block getHighestBlockAt(int x, int z); + + /** + * Gets the highest non-empty block at the given coordinates + * + * @param location Coordinates to get the highest block + * @return Highest non-empty block + */ + public Block getHighestBlockAt(Location location); + + /** + * Gets the {@link Chunk} at the given coordinates + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @return Chunk at the given coordinates + */ + public Chunk getChunkAt(int x, int z); + + /** + * Gets the {@link Chunk} at the given {@link Location} + * + * @param location Location of the chunk + * @return Chunk at the given location + */ + public Chunk getChunkAt(Location location); + + /** + * Gets the {@link Chunk} that contains the given {@link Block} + * + * @param block Block to get the containing chunk from + * @return The chunk that contains the given block + */ + public Chunk getChunkAt(Block block); + + // PaperSpigot start - Async chunk load API + public static interface ChunkLoadCallback { + public void onLoad(Chunk chunk); + } + public void getChunkAtAsync(int x, int z, ChunkLoadCallback cb); + public void getChunkAtAsync(Location location, ChunkLoadCallback cb); + public void getChunkAtAsync(Block block, ChunkLoadCallback cb); + public java.util.concurrent.CompletableFuture getChunkAtAsync(final int x, final int z, final boolean gen); + // PaperSpigot end + + /** + * Checks if a {@link Chunk} has been generated at the specified chunk key, + * which is the X and Z packed into a long. + * + * @param chunkKey The Chunk Key to look up the chunk by + * @return true if the chunk has been generated, otherwise false + */ + public default boolean isChunkGenerated(long chunkKey) throws IOException { + return isChunkGenerated((int) chunkKey, (int) (chunkKey >> 32)); + } + + /** + * Checks if a {@link Chunk} has been generated at the given coordinates. + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @return true if the chunk has been generated, otherwise false + */ + public boolean isChunkGenerated(int x, int z) throws IOException; + + /** + * Checks if the specified {@link Chunk} is loaded + * + * @param chunk The chunk to check + * @return true if the chunk is loaded, otherwise false + */ + public boolean isChunkLoaded(Chunk chunk); + + /** + * Gets an array of all loaded {@link Chunk}s + * + * @return Chunk[] containing all loaded chunks + */ + public Chunk[] getLoadedChunks(); + + /** + * Loads the specified {@link Chunk} + * + * @param chunk The chunk to load + */ + public void loadChunk(Chunk chunk); + + /** + * Checks if the {@link Chunk} at the specified coordinates is loaded + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @return true if the chunk is loaded, otherwise false + */ + public boolean isChunkLoaded(int x, int z); + + /** + * Checks if the {@link Chunk} at the specified coordinates is loaded and + * in use by one or more players + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @return true if the chunk is loaded and in use by one or more players, + * otherwise false + */ + public boolean isChunkInUse(int x, int z); + + /** + * Loads the {@link Chunk} at the specified coordinates + *

+ * If the chunk does not exist, it will be generated. + *

+ * This method is analogous to {@link #loadChunk(int, int, boolean)} where + * generate is true. + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + */ + public void loadChunk(int x, int z); + + /** + * Loads the {@link Chunk} at the specified coordinates + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @param generate Whether or not to generate a chunk if it doesn't + * already exist + * @return true if the chunk has loaded successfully, otherwise false + */ + public boolean loadChunk(int x, int z, boolean generate); + + /** + * Safely unloads and saves the {@link Chunk} at the specified coordinates + *

+ * This method is analogous to {@link #unloadChunk(int, int, boolean, + * boolean)} where safe and saveis true + * + * @param chunk the chunk to unload + * @return true if the chunk has unloaded successfully, otherwise false + */ + public boolean unloadChunk(Chunk chunk); + + /** + * Safely unloads and saves the {@link Chunk} at the specified coordinates + *

+ * This method is analogous to {@link #unloadChunk(int, int, boolean, + * boolean)} where safe and saveis true + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @return true if the chunk has unloaded successfully, otherwise false + */ + public boolean unloadChunk(int x, int z); + + /** + * Safely unloads and optionally saves the {@link Chunk} at the specified + * coordinates + *

+ * This method is analogous to {@link #unloadChunk(int, int, boolean, + * boolean)} where save is true + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @param save Whether or not to save the chunk + * @return true if the chunk has unloaded successfully, otherwise false + */ + public boolean unloadChunk(int x, int z, boolean save); + + /** + * Unloads and optionally saves the {@link Chunk} at the specified + * coordinates + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @param save Controls whether the chunk is saved + * @param safe Controls whether to unload the chunk when players are + * nearby + * @return true if the chunk has unloaded successfully, otherwise false + */ + public boolean unloadChunk(int x, int z, boolean save, boolean safe); + + /** + * Safely queues the {@link Chunk} at the specified coordinates for + * unloading + *

+ * This method is analogous to {@link #unloadChunkRequest(int, int, + * boolean)} where safe is true + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @return true is the queue attempt was successful, otherwise false + */ + public boolean unloadChunkRequest(int x, int z); + + /** + * Queues the {@link Chunk} at the specified coordinates for unloading + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @param safe Controls whether to queue the chunk when players are nearby + * @return Whether the chunk was actually queued + */ + public boolean unloadChunkRequest(int x, int z, boolean safe); + + /** + * Regenerates the {@link Chunk} at the specified coordinates + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @return Whether the chunk was actually regenerated + */ + public boolean regenerateChunk(int x, int z); + + /** + * Resends the {@link Chunk} to all clients + * + * @param x X-coordinate of the chunk + * @param z Z-coordinate of the chunk + * @return Whether the chunk was actually refreshed + * + * @deprecated This method is not guaranteed to work suitably across all client implementations. + */ + @Deprecated + public boolean refreshChunk(int x, int z); + + /** + * Drops an item at the specified {@link Location} + * + * @param location Location to drop the item + * @param item ItemStack to drop + * @return ItemDrop entity created as a result of this method + */ + public Item dropItem(Location location, ItemStack item); + + /** + * Drops an item at the specified {@link Location} with a random offset + * + * @param location Location to drop the item + * @param item ItemStack to drop + * @return ItemDrop entity created as a result of this method + */ + public Item dropItemNaturally(Location location, ItemStack item); + + /** + * Creates an {@link Arrow} entity at the given {@link Location} + * + * @param location Location to spawn the arrow + * @param direction Direction to shoot the arrow in + * @param speed Speed of the arrow. A recommend speed is 0.6 + * @param spread Spread of the arrow. A recommend spread is 12 + * @return Arrow entity spawned as a result of this method + */ + public Arrow spawnArrow(Location location, Vector direction, float speed, float spread); + + /** + * Creates a tree at the given {@link Location} + * + * @param location Location to spawn the tree + * @param type Type of the tree to create + * @return true if the tree was created successfully, otherwise false + */ + public boolean generateTree(Location location, TreeType type); + + /** + * Creates a tree at the given {@link Location} + * + * @param loc Location to spawn the tree + * @param type Type of the tree to create + * @param delegate A class to call for each block changed as a result of + * this method + * @return true if the tree was created successfully, otherwise false + */ + public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate); + + /** + * Creates a entity at the given {@link Location} + * + * @param loc The location to spawn the entity + * @param type The entity to spawn + * @return Resulting Entity of this method, or null if it was unsuccessful + */ + public Entity spawnEntity(Location loc, EntityType type); + + /** + * Creates a creature at the given {@link Location} + * + * @param loc The location to spawn the creature + * @param type The creature to spawn + * @return Resulting LivingEntity of this method, or null if it was + * unsuccessful + * @deprecated Has issues spawning non LivingEntities. Use {@link + * #spawnEntity(Location, EntityType) spawnEntity} instead. + */ + @Deprecated + public LivingEntity spawnCreature(Location loc, EntityType type); + + /** + * Creates a creature at the given {@link Location} + * + * @param loc The location to spawn the creature + * @param type The creature to spawn + * @return Resulting LivingEntity of this method, or null if it was + * unsuccessful + */ + @Deprecated + public LivingEntity spawnCreature(Location loc, CreatureType type); + + /** + * Strikes lightning at the given {@link Location} + * + * @param loc The location to strike lightning + * @return The lightning entity. + */ + public LightningStrike strikeLightning(Location loc); + + /** + * Strikes lightning at the given {@link Location} without doing damage + * + * @param loc The location to strike lightning + * @return The lightning entity. + */ + public LightningStrike strikeLightningEffect(Location loc); + + /** + * Get a list of all entities in this World + * + * @return A List of all Entities currently residing in this world + */ + public List getEntities(); + + /** + * Get a list of all living entities in this World + * + * @return A List of all LivingEntities currently residing in this world + */ + public List getLivingEntities(); + + /** + * Get a collection of all entities in this World matching the given + * class/interface + * + * @param an entity subclass + * @param classes The classes representing the types of entity to match + * @return A List of all Entities currently residing in this world that + * match the given class/interface + */ + @Deprecated + public Collection getEntitiesByClass(Class... classes); + + /** + * Get a collection of all entities in this World matching the given + * class/interface + * + * @param an entity subclass + * @param cls The class representing the type of entity to match + * @return A List of all Entities currently residing in this world that + * match the given class/interface + */ + public Collection getEntitiesByClass(Class cls); + + /** + * Get a collection of all entities in this World matching any of the + * given classes/interfaces + * + * @param classes The classes representing the types of entity to match + * @return A List of all Entities currently residing in this world that + * match one or more of the given classes/interfaces + */ + public Collection getEntitiesByClasses(Class... classes); + + /** + * Get a list of all players in this World + * + * @return A list of all Players currently residing in this world + */ + public List getPlayers(); + + /** + * Returns a list of entities within a bounding box centered around a Location. + * + * Some implementations may impose artificial restrictions on the size of the search bounding box. + * + * @param location The center of the bounding box + * @param x 1/2 the size of the box along x axis + * @param y 1/2 the size of the box along y axis + * @param z 1/2 the size of the box along z axis + * @return the collection of entities near location. This will always be a non-null collection. + */ + public Collection getNearbyEntities(Location location, double x, double y, double z); + + /** + * Gets the unique name of this world + * + * @return Name of this world + */ + public String getName(); + + /** + * Gets the Unique ID of this world + * + * @return Unique ID of this world. + */ + public UUID getUID(); + + /** + * Gets the default spawn {@link Location} of this world + * + * @return The spawn location of this world + */ + public Location getSpawnLocation(); + + /** + * Sets the spawn location of the world + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @return True if it was successfully set. + */ + public boolean setSpawnLocation(int x, int y, int z); + + /** + * Gets the relative in-game time of this world. + *

+ * The relative time is analogous to hours * 1000 + * + * @return The current relative time + * @see #getFullTime() Returns an absolute time of this world + */ + public long getTime(); + + /** + * Sets the relative in-game time on the server. + *

+ * The relative time is analogous to hours * 1000 + *

+ * Note that setting the relative time below the current relative time + * will actually move the clock forward a day. If you require to rewind + * time, please see {@link #setFullTime(long)} + * + * @param time The new relative time to set the in-game time to (in + * hours*1000) + * @see #setFullTime(long) Sets the absolute time of this world + */ + public void setTime(long time); + + /** + * Gets the full in-game time on this world + * + * @return The current absolute time + * @see #getTime() Returns a relative time of this world + */ + public long getFullTime(); + + /** + * Sets the in-game time on the server + *

+ * Note that this sets the full time of the world, which may cause adverse + * effects such as breaking redstone clocks and any scheduled events + * + * @param time The new absolute time to set this world to + * @see #setTime(long) Sets the relative time of this world + */ + public void setFullTime(long time); + + /** + * Returns whether the world has an ongoing storm. + * + * @return Whether there is an ongoing storm + */ + public boolean hasStorm(); + + /** + * Set whether there is a storm. A duration will be set for the new + * current conditions. + * + * @param hasStorm Whether there is rain and snow + */ + public void setStorm(boolean hasStorm); + + /** + * Get the remaining time in ticks of the current conditions. + * + * @return Time in ticks + */ + public int getWeatherDuration(); + + /** + * Set the remaining time in ticks of the current conditions. + * + * @param duration Time in ticks + */ + public void setWeatherDuration(int duration); + + /** + * Returns whether there is thunder. + * + * @return Whether there is thunder + */ + public boolean isThundering(); + + /** + * Set whether it is thundering. + * + * @param thundering Whether it is thundering + */ + public void setThundering(boolean thundering); + + /** + * Get the thundering duration. + * + * @return Duration in ticks + */ + public int getThunderDuration(); + + /** + * Set the thundering duration. + * + * @param duration Duration in ticks + */ + public void setThunderDuration(int duration); + + /** + * Creates explosion at given coordinates with given power + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param power The power of explosion, where 4F is TNT + * @return false if explosion was canceled, otherwise true + */ + public boolean createExplosion(double x, double y, double z, float power); + + /** + * Creates explosion at given coordinates with given power and optionally + * setting blocks on fire. + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param power The power of explosion, where 4F is TNT + * @param setFire Whether or not to set blocks on fire + * @return false if explosion was canceled, otherwise true + */ + public boolean createExplosion(double x, double y, double z, float power, boolean setFire); + + /** + * Creates explosion at given coordinates with given power and optionally + * setting blocks on fire or breaking blocks. + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param power The power of explosion, where 4F is TNT + * @param setFire Whether or not to set blocks on fire + * @param breakBlocks Whether or not to have blocks be destroyed + * @return false if explosion was canceled, otherwise true + */ + public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks); + + /** + * Creates explosion at given coordinates with given power + * + * @param loc Location to blow up + * @param power The power of explosion, where 4F is TNT + * @return false if explosion was canceled, otherwise true + */ + public boolean createExplosion(Location loc, float power); + + /** + * Creates explosion at given coordinates with given power and optionally + * setting blocks on fire. + * + * @param loc Location to blow up + * @param power The power of explosion, where 4F is TNT + * @param setFire Whether or not to set blocks on fire + * @return false if explosion was canceled, otherwise true + */ + public boolean createExplosion(Location loc, float power, boolean setFire); + + /** + * Gets the {@link Environment} type of this world + * + * @return This worlds Environment type + */ + public Environment getEnvironment(); + + /** + * Gets the Seed for this world. + * + * @return This worlds Seed + */ + public long getSeed(); + + /** + * Gets the current PVP setting for this world. + * + * @return True if PVP is enabled + */ + public boolean getPVP(); + + /** + * Sets the PVP setting for this world. + * + * @param pvp True/False whether PVP should be Enabled. + */ + public void setPVP(boolean pvp); + + /** + * Gets the chunk generator for this world + * + * @return ChunkGenerator associated with this world + */ + public ChunkGenerator getGenerator(); + + /** + * Saves world to disk + */ + public void save(); + + /** + * Gets a list of all applied {@link BlockPopulator}s for this World + * + * @return List containing any or none BlockPopulators + */ + public List getPopulators(); + + /** + * Spawn an entity of a specific class at the given {@link Location} + * + * @param location the {@link Location} to spawn the entity at + * @param clazz the class of the {@link Entity} to spawn + * @param the class of the {@link Entity} to spawn + * @return an instance of the spawned {@link Entity} + * @throws IllegalArgumentException if either parameter is null or the + * {@link Entity} requested cannot be spawned + */ + public T spawn(Location location, Class clazz) throws IllegalArgumentException; + + /** + * Spawn a {@link FallingBlock} entity at the given {@link Location} of + * the specified {@link Material}. The material dictates what is falling. + * When the FallingBlock hits the ground, it will place that block. + *

+ * The Material must be a block type, check with {@link Material#isBlock() + * material.isBlock()}. The Material may not be air. + * + * @param location The {@link Location} to spawn the FallingBlock + * @param material The block {@link Material} type + * @param data The block data + * @return The spawned {@link FallingBlock} instance + * @throws IllegalArgumentException if {@link Location} or {@link + * Material} are null or {@link Material} is not a block + * @deprecated Magic value + */ + @Deprecated + public FallingBlock spawnFallingBlock(Location location, Material material, byte data) throws IllegalArgumentException; + + /** + * Spawn a {@link FallingBlock} entity at the given {@link Location} of + * the specified blockId (converted to {@link Material}) + * + * @param location The {@link Location} to spawn the FallingBlock + * @param blockId The id of the intended material + * @param blockData The block data + * @return The spawned FallingBlock instance + * @throws IllegalArgumentException if location is null, or blockId is + * invalid + * @see #spawnFallingBlock(org.bukkit.Location, org.bukkit.Material, byte) + * @deprecated Magic value + */ + @Deprecated + public FallingBlock spawnFallingBlock(Location location, int blockId, byte blockData) throws IllegalArgumentException; + + /** + * Plays an effect to all players within a default radius around a given + * location. + * + * @param location the {@link Location} around which players must be to + * hear the sound + * @param effect the {@link Effect} + * @param data a data bit needed for some effects + */ + public void playEffect(Location location, Effect effect, int data); + + /** + * Plays an effect to all players within a given radius around a location. + * + * @param location the {@link Location} around which players must be to + * hear the effect + * @param effect the {@link Effect} + * @param data a data bit needed for some effects + * @param radius the radius around the location + */ + public void playEffect(Location location, Effect effect, int data, int radius); + + /** + * Plays an effect to all players within a default radius around a given + * location. + * + * @param data dependant on the type of effect + * @param location the {@link Location} around which players must be to + * hear the sound + * @param effect the {@link Effect} + * @param data a data bit needed for some effects + */ + public void playEffect(Location location, Effect effect, T data); + + /** + * Plays an effect to all players within a given radius around a location. + * + * @param data dependant on the type of effect + * @param location the {@link Location} around which players must be to + * hear the effect + * @param effect the {@link Effect} + * @param data a data bit needed for some effects + * @param radius the radius around the location + */ + public void playEffect(Location location, Effect effect, T data, int radius); + + /** + * Get empty chunk snapshot (equivalent to all air blocks), optionally + * including valid biome data. Used for representing an ungenerated chunk, + * or for fetching only biome data without loading a chunk. + * + * @param x - chunk x coordinate + * @param z - chunk z coordinate + * @param includeBiome - if true, snapshot includes per-coordinate biome + * type + * @param includeBiomeTempRain - if true, snapshot includes per-coordinate + * raw biome temperature and rainfall + * @return The empty snapshot. + */ + public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTempRain); + + /** + * Sets the spawn flags for this. + * + * @param allowMonsters - if true, monsters are allowed to spawn in this + * world. + * @param allowAnimals - if true, animals are allowed to spawn in this + * world. + */ + public void setSpawnFlags(boolean allowMonsters, boolean allowAnimals); + + /** + * Gets whether animals can spawn in this world. + * + * @return whether animals can spawn in this world. + */ + public boolean getAllowAnimals(); + + /** + * Gets whether monsters can spawn in this world. + * + * @return whether monsters can spawn in this world. + */ + public boolean getAllowMonsters(); + + /** + * Gets the biome for the given block coordinates. + * + * @param x X coordinate of the block + * @param z Z coordinate of the block + * @return Biome of the requested block + */ + Biome getBiome(int x, int z); + + /** + * Sets the biome for the given block coordinates + * + * @param x X coordinate of the block + * @param z Z coordinate of the block + * @param bio new Biome type for this block + */ + void setBiome(int x, int z, Biome bio); + + /** + * Gets the temperature for the given block coordinates. + *

+ * It is safe to run this method when the block does not exist, it will + * not create the block. + * + * @param x X coordinate of the block + * @param z Z coordinate of the block + * @return Temperature of the requested block + */ + public double getTemperature(int x, int z); + + /** + * Gets the humidity for the given block coordinates. + *

+ * It is safe to run this method when the block does not exist, it will + * not create the block. + * + * @param x X coordinate of the block + * @param z Z coordinate of the block + * @return Humidity of the requested block + */ + public double getHumidity(int x, int z); + + /** + * Gets the maximum height of this world. + *

+ * If the max height is 100, there are only blocks from y=0 to y=99. + * + * @return Maximum height of the world + */ + public int getMaxHeight(); + + /** + * Gets the sea level for this world. + *

+ * This is often half of {@link #getMaxHeight()} + * + * @return Sea level + */ + public int getSeaLevel(); + + /** + * Gets whether the world's spawn area should be kept loaded into memory + * or not. + * + * @return true if the world's spawn area will be kept loaded into memory. + */ + public boolean getKeepSpawnInMemory(); + + /** + * Sets whether the world's spawn area should be kept loaded into memory + * or not. + * + * @param keepLoaded if true then the world's spawn area will be kept + * loaded into memory. + */ + public void setKeepSpawnInMemory(boolean keepLoaded); + + /** + * Gets whether or not the world will automatically save + * + * @return true if the world will automatically save, otherwise false + */ + public boolean isAutoSave(); + + /** + * Sets whether or not the world will automatically save + * + * @param value true if the world should automatically save, otherwise + * false + */ + public void setAutoSave(boolean value); + + /** + * Sets the Difficulty of the world. + * + * @param difficulty the new difficulty you want to set the world to + */ + public void setDifficulty(Difficulty difficulty); + + /** + * Gets the Difficulty of the world. + * + * @return The difficulty of the world. + */ + public Difficulty getDifficulty(); + + /** + * Gets the folder of this world on disk. + * + * @return The folder of this world. + */ + public File getWorldFolder(); + + /** + * Gets the type of this world. + * + * @return Type of this world. + */ + public WorldType getWorldType(); + + /** + * Gets whether or not structures are being generated. + * + * @return True if structures are being generated. + */ + public boolean canGenerateStructures(); + + /** + * Gets the world's ticks per animal spawns value + *

+ * This value determines how many ticks there are between attempts to + * spawn animals. + *

+ * Example Usage: + *

    + *
  • A value of 1 will mean the server will attempt to spawn animals in + * this world every tick. + *
  • A value of 400 will mean the server will attempt to spawn animals + * in this world every 400th tick. + *
  • A value below 0 will be reset back to Minecraft's default. + *
+ *

+ * Note: + * If set to 0, animal spawning will be disabled for this world. We + * recommend using {@link #setSpawnFlags(boolean, boolean)} to control + * this instead. + *

+ * Minecraft default: 400. + * + * @return The world's ticks per animal spawns value + */ + public long getTicksPerAnimalSpawns(); + + /** + * Sets the world's ticks per animal spawns value + *

+ * This value determines how many ticks there are between attempts to + * spawn animals. + *

+ * Example Usage: + *

    + *
  • A value of 1 will mean the server will attempt to spawn animals in + * this world every tick. + *
  • A value of 400 will mean the server will attempt to spawn animals + * in this world every 400th tick. + *
  • A value below 0 will be reset back to Minecraft's default. + *
+ *

+ * Note: + * If set to 0, animal spawning will be disabled for this world. We + * recommend using {@link #setSpawnFlags(boolean, boolean)} to control + * this instead. + *

+ * Minecraft default: 400. + * + * @param ticksPerAnimalSpawns the ticks per animal spawns value you want + * to set the world to + */ + public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns); + + /** + * Gets the world's ticks per monster spawns value + *

+ * This value determines how many ticks there are between attempts to + * spawn monsters. + *

+ * Example Usage: + *

    + *
  • A value of 1 will mean the server will attempt to spawn monsters in + * this world every tick. + *
  • A value of 400 will mean the server will attempt to spawn monsters + * in this world every 400th tick. + *
  • A value below 0 will be reset back to Minecraft's default. + *
+ *

+ * Note: + * If set to 0, monsters spawning will be disabled for this world. We + * recommend using {@link #setSpawnFlags(boolean, boolean)} to control + * this instead. + *

+ * Minecraft default: 1. + * + * @return The world's ticks per monster spawns value + */ + public long getTicksPerMonsterSpawns(); + + /** + * Sets the world's ticks per monster spawns value + *

+ * This value determines how many ticks there are between attempts to + * spawn monsters. + *

+ * Example Usage: + *

    + *
  • A value of 1 will mean the server will attempt to spawn monsters in + * this world on every tick. + *
  • A value of 400 will mean the server will attempt to spawn monsters + * in this world every 400th tick. + *
  • A value below 0 will be reset back to Minecraft's default. + *
+ *

+ * Note: + * If set to 0, monsters spawning will be disabled for this world. We + * recommend using {@link #setSpawnFlags(boolean, boolean)} to control + * this instead. + *

+ * Minecraft default: 1. + * + * @param ticksPerMonsterSpawns the ticks per monster spawns value you + * want to set the world to + */ + public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns); + + /** + * Gets limit for number of monsters that can spawn in a chunk in this + * world + * + * @return The monster spawn limit + */ + int getMonsterSpawnLimit(); + + /** + * Sets the limit for number of monsters that can spawn in a chunk in this + * world + *

+ * Note: If set to a negative number the world will use the + * server-wide spawn limit instead. + * + * @param limit the new mob limit + */ + void setMonsterSpawnLimit(int limit); + + /** + * Gets the limit for number of animals that can spawn in a chunk in this + * world + * + * @return The animal spawn limit + */ + int getAnimalSpawnLimit(); + + /** + * Sets the limit for number of animals that can spawn in a chunk in this + * world + *

+ * Note: If set to a negative number the world will use the + * server-wide spawn limit instead. + * + * @param limit the new mob limit + */ + void setAnimalSpawnLimit(int limit); + + /** + * Gets the limit for number of water animals that can spawn in a chunk in + * this world + * + * @return The water animal spawn limit + */ + int getWaterAnimalSpawnLimit(); + + /** + * Sets the limit for number of water animals that can spawn in a chunk in + * this world + *

+ * Note: If set to a negative number the world will use the + * server-wide spawn limit instead. + * + * @param limit the new mob limit + */ + void setWaterAnimalSpawnLimit(int limit); + + /** + * Gets the limit for number of ambient mobs that can spawn in a chunk in + * this world + * + * @return The ambient spawn limit + */ + int getAmbientSpawnLimit(); + + /** + * Sets the limit for number of ambient mobs that can spawn in a chunk in + * this world + *

+ * Note: If set to a negative number the world will use the + * server-wide spawn limit instead. + * + * @param limit the new mob limit + */ + void setAmbientSpawnLimit(int limit); + + /** + * Play a Sound at the provided Location in the World + *

+ * This function will fail silently if Location or Sound are null. + * + * @param location The location to play the sound + * @param sound The sound to play + * @param volume The volume of the sound + * @param pitch The pitch of the sound + */ + void playSound(Location location, Sound sound, float volume, float pitch); + + /** + * Get existing rules + * + * @return An array of rules + */ + public String[] getGameRules(); + + /** + * Gets the current state of the specified rule + *

+ * Will return null if rule passed is null + * + * @param rule Rule to look up value of + * @return String value of rule + */ + public String getGameRuleValue(String rule); + + /** + * Set the specified gamerule to specified value. + *

+ * The rule may attempt to validate the value passed, will return true if + * value was set. + *

+ * If rule is null, the function will return false. + * + * @param rule Rule to set + * @param value Value to set rule to + * @return True if rule was set + */ + public boolean setGameRuleValue(String rule, String value); + + /** + * Checks if string is a valid game rule + * + * @param rule Rule to check + * @return True if rule exists + */ + public boolean isGameRule(String rule); + + // Spigot start + public class Spigot + { + + /** + * Plays an effect to all players within a default radius around a given + * location. + * + * @param location the {@link Location} around which players must be to + * see the effect + * @param effect the {@link Effect} + * @throws IllegalArgumentException if the location or effect is null. + * It also throws when the effect requires a material or a material data + */ + public void playEffect(Location location, Effect effect) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Plays an effect to all players within a default radius around a given + * location. The effect will use the provided material (and material + * data if required). The particle's position on the client will be the + * given location, adjusted on each axis by a normal distribution with + * mean 0 and standard deviation given in the offset parameters, each + * particle has independently calculated offsets. The effect will have + * the given speed and particle count if the effect is a particle. Some + * effect will create multiple particles. + * + * @param location the {@link Location} around which players must be to + * see the effect + * @param effect effect the {@link Effect} + * @param id the item/block/data id for the effect + * @param data the data value of the block/item for the effect + * @param offsetX the amount to be randomly offset by in the X axis + * @param offsetY the amount to be randomly offset by in the Y axis + * @param offsetZ the amount to be randomly offset by in the Z axis + * @param speed the speed of the particles + * @param particleCount the number of particles + * @param radius the radius around the location + */ + public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Strikes lightning at the given {@link Location} and possibly without sound + * + * @param loc The location to strike lightning + * @param isSilent Whether this strike makes no sound + * @return The lightning entity. + */ + public LightningStrike strikeLightning(Location loc, boolean isSilent) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Strikes lightning at the given {@link Location} without doing damage and possibly without sound + * + * @param loc The location to strike lightning + * @param isSilent Whether this strike makes no sound + * @return The lightning entity. + */ + public LightningStrike strikeLightningEffect(Location loc, boolean isSilent) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); + // Spigot end + + /** + * Gets the world border for this world. + * + * @return The world border for this world. + */ + public WorldBorder getWorldBorder(); + + /** + * Represents various map environment types that a world may be + */ + public enum Environment { + + /** + * Represents the "normal"/"surface world" map + */ + NORMAL(0), + /** + * Represents a nether based map ("hell") + */ + NETHER(-1), + /** + * Represents the "end" map + */ + THE_END(1); + + private final int id; + private static final Map lookup = new HashMap(); + + private Environment(int id) { + this.id = id; + } + + /** + * Gets the dimension ID of this environment + * + * @return dimension ID + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + + /** + * Get an environment by ID + * + * @param id The ID of the environment + * @return The environment + * @deprecated Magic value + */ + @Deprecated + public static Environment getEnvironment(int id) { + return lookup.get(id); + } + + static { + for (Environment env : values()) { + lookup.put(env.getId(), env); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldBorder.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldBorder.java new file mode 100644 index 0000000..55c8983 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldBorder.java @@ -0,0 +1,109 @@ +package org.bukkit; + +public interface WorldBorder { + + /** + * Resets the border to default values. + */ + public void reset(); + + /** + * Gets the current side length of the border. + * + * @return The current side length of the border. + */ + public double getSize(); + + /** + * Sets the border to a square region with the specified side length in blocks. + * + * @param newSize The new size of the border. + */ + public void setSize(double newSize); + + /** + * Sets the border to a square region with the specified side length in blocks. + * + * @param newSize The new side length of the border. + * @param seconds The time in seconds in which the border grows or shrinks from the previous size to that being set. + */ + public void setSize(double newSize, long seconds); + + /** + * Gets the current border center. + * + * @return The current border center. + */ + public Location getCenter(); + + /** + * Sets the new border center. + * + * @param x The new center x-coordinate. + * @param z The new center z-coordinate. + */ + public void setCenter(double x, double z); + + /** + * Sets the new border center. + * + * @param location The new location of the border center. (Only x/z used) + */ + public void setCenter(Location location); + + /** + * Gets the current border damage buffer. + * + * @return The current border damage buffer. + */ + public double getDamageBuffer(); + + /** + * Sets the amount of blocks a player may safely be outside the border before taking damage. + * + * @param blocks The amount of blocks. (The default is 5 blocks.) + */ + public void setDamageBuffer(double blocks); + + /** + * Gets the current border damage amount. + * + * @return The current border damage amount. + */ + public double getDamageAmount(); + + /** + * Sets the amount of damage a player takes when outside the border plus the border buffer. + * + * @param damage The amount of damage. (The default is 0.2 damage per second per block.) + */ + public void setDamageAmount(double damage); + + /** + * Gets the current border warning time in seconds. + * + * @return The current border warning time in seconds. + */ + public int getWarningTime(); + + /** + * Sets the warning time that causes the screen to be tinted red when a contracting border will reach the player within the specified time. + * + * @param seconds The amount of time in seconds. (The default is 15 seconds.) + */ + public void setWarningTime(int seconds); + + /** + * Gets the current border warning distance. + * + * @return The current border warning distance. + */ + public int getWarningDistance(); + + /** + * Sets the warning distance that causes the screen to be tinted red when the player is within the specified number of blocks from the border. + * + * @param distance The distance in blocks. (The default is 5 blocks.) + */ + public void setWarningDistance(int distance); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldCreator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldCreator.java new file mode 100644 index 0000000..53980fd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldCreator.java @@ -0,0 +1,317 @@ +package org.bukkit; + +import java.util.Random; +import org.bukkit.command.CommandSender; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.plugin.Plugin; + +/** + * Represents various types of options that may be used to create a world. + */ +public class WorldCreator { + private final String name; + private long seed; + private World.Environment environment = World.Environment.NORMAL; + private ChunkGenerator generator = null; + private WorldType type = WorldType.NORMAL; + private boolean generateStructures = true; + private String generatorSettings = ""; + + /** + * Creates an empty WorldCreationOptions for the given world name + * + * @param name Name of the world that will be created + */ + public WorldCreator(String name) { + if (name == null) { + throw new IllegalArgumentException("World name cannot be null"); + } + + this.name = name; + this.seed = (new Random()).nextLong(); + } + + /** + * Copies the options from the specified world + * + * @param world World to copy options from + * @return This object, for chaining + */ + public WorldCreator copy(World world) { + if (world == null) { + throw new IllegalArgumentException("World cannot be null"); + } + + seed = world.getSeed(); + environment = world.getEnvironment(); + generator = world.getGenerator(); + + return this; + } + + /** + * Copies the options from the specified {@link WorldCreator} + * + * @param creator World creator to copy options from + * @return This object, for chaining + */ + public WorldCreator copy(WorldCreator creator) { + if (creator == null) { + throw new IllegalArgumentException("Creator cannot be null"); + } + + seed = creator.seed(); + environment = creator.environment(); + generator = creator.generator(); + + return this; + } + + /** + * Gets the name of the world that is to be loaded or created. + * + * @return World name + */ + public String name() { + return name; + } + + /** + * Gets the seed that will be used to create this world + * + * @return World seed + */ + public long seed() { + return seed; + } + + /** + * Sets the seed that will be used to create this world + * + * @param seed World seed + * @return This object, for chaining + */ + public WorldCreator seed(long seed) { + this.seed = seed; + + return this; + } + + /** + * Gets the environment that will be used to create or load the world + * + * @return World environment + */ + public World.Environment environment() { + return environment; + } + + /** + * Sets the environment that will be used to create or load the world + * + * @param env World environment + * @return This object, for chaining + */ + public WorldCreator environment(World.Environment env) { + this.environment = env; + + return this; + } + + /** + * Gets the type of the world that will be created or loaded + * + * @return World type + */ + public WorldType type() { + return type; + } + + /** + * Sets the type of the world that will be created or loaded + * + * @param type World type + * @return This object, for chaining + */ + public WorldCreator type(WorldType type) { + this.type = type; + + return this; + } + + /** + * Gets the generator that will be used to create or load the world. + *

+ * This may be null, in which case the "natural" generator for this + * environment will be used. + * + * @return Chunk generator + */ + public ChunkGenerator generator() { + return generator; + } + + /** + * Sets the generator that will be used to create or load the world. + *

+ * This may be null, in which case the "natural" generator for this + * environment will be used. + * + * @param generator Chunk generator + * @return This object, for chaining + */ + public WorldCreator generator(ChunkGenerator generator) { + this.generator = generator; + + return this; + } + + /** + * Sets the generator that will be used to create or load the world. + *

+ * This may be null, in which case the "natural" generator for this + * environment will be used. + *

+ * If the generator cannot be found for the given name, the natural + * environment generator will be used instead and a warning will be + * printed to the console. + * + * @param generator Name of the generator to use, in "plugin:id" notation + * @return This object, for chaining + */ + public WorldCreator generator(String generator) { + this.generator = getGeneratorForName(name, generator, Bukkit.getConsoleSender()); + + return this; + } + + /** + * Sets the generator that will be used to create or load the world. + *

+ * This may be null, in which case the "natural" generator for this + * environment will be used. + *

+ * If the generator cannot be found for the given name, the natural + * environment generator will be used instead and a warning will be + * printed to the specified output + * + * @param generator Name of the generator to use, in "plugin:id" notation + * @param output {@link CommandSender} that will receive any error + * messages + * @return This object, for chaining + */ + public WorldCreator generator(String generator, CommandSender output) { + this.generator = getGeneratorForName(name, generator, output); + + return this; + } + + /** + * Sets the generator settings of the world that will be created or loaded + * + * @param generatorSettings The settings that should be used by the generator + * @return This object, for chaining + */ + public WorldCreator generatorSettings(String generatorSettings) { + this.generatorSettings = generatorSettings; + + return this; + } + + /** + * Gets the generator settings of the world that will be created or loaded + * + * @return The settings that should be used by the generator + */ + public String generatorSettings() { + return generatorSettings; + } + + /** + * Sets whether or not worlds created or loaded with this creator will + * have structures. + * + * @param generate Whether to generate structures + * @return This object, for chaining + */ + public WorldCreator generateStructures(boolean generate) { + this.generateStructures = generate; + + return this; + } + + /** + * Gets whether or not structures will be generated in the world. + * + * @return True if structures will be generated + */ + public boolean generateStructures() { + return generateStructures; + } + + /** + * Creates a world with the specified options. + *

+ * If the world already exists, it will be loaded from disk and some + * options may be ignored. + * + * @return Newly created or loaded world + */ + public World createWorld() { + return Bukkit.createWorld(this); + } + + /** + * Creates a new {@link WorldCreator} for the given world name + * + * @param name Name of the world to load or create + * @return Resulting WorldCreator + */ + public static WorldCreator name(String name) { + return new WorldCreator(name); + } + + /** + * Attempts to get the {@link ChunkGenerator} with the given name. + *

+ * If the generator is not found, null will be returned and a message will + * be printed to the specified {@link CommandSender} explaining why. + *

+ * The name must be in the "plugin:id" notation, or optionally just + * "plugin", where "plugin" is the safe-name of a plugin and "id" is an + * optional unique identifier for the generator you wish to request from + * the plugin. + * + * @param world Name of the world this will be used for + * @param name Name of the generator to retrieve + * @param output Where to output if errors are present + * @return Resulting generator, or null + */ + public static ChunkGenerator getGeneratorForName(String world, String name, CommandSender output) { + ChunkGenerator result = null; + + if (world == null) { + throw new IllegalArgumentException("World name must be specified"); + } + + if (output == null) { + output = Bukkit.getConsoleSender(); + } + + if (name != null) { + String[] split = name.split(":", 2); + String id = (split.length > 1) ? split[1] : null; + Plugin plugin = Bukkit.getPluginManager().getPlugin(split[0]); + + if (plugin == null) { + output.sendMessage("Could not set generator for world '" + world + "': Plugin '" + split[0] + "' does not exist"); + } else if (!plugin.isEnabled()) { + output.sendMessage("Could not set generator for world '" + world + "': Plugin '" + plugin.getDescription().getFullName() + "' is not enabled"); + } else { + result = plugin.getDefaultWorldGenerator(world, id); + } + } + + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldType.java new file mode 100644 index 0000000..e817803 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/WorldType.java @@ -0,0 +1,48 @@ +package org.bukkit; + +import com.google.common.collect.Maps; +import java.util.Map; + +/** + * Represents various types of worlds that may exist + */ +public enum WorldType { + NORMAL("DEFAULT"), + FLAT("FLAT"), + VERSION_1_1("DEFAULT_1_1"), + LARGE_BIOMES("LARGEBIOMES"), + AMPLIFIED("AMPLIFIED"), + CUSTOMIZED("CUSTOMIZED"); + + private final static Map BY_NAME = Maps.newHashMap(); + private final String name; + + private WorldType(String name) { + this.name = name; + } + + /** + * Gets the name of this WorldType + * + * @return Name of this type + */ + public String getName() { + return name; + } + + /** + * Gets a Worldtype by its name + * + * @param name Name of the WorldType to get + * @return Requested WorldType, or null if not found + */ + public static WorldType getByName(String name) { + return BY_NAME.get(name.toUpperCase()); + } + + static { + for (WorldType type : values()) { + BY_NAME.put(type.name, type); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Banner.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Banner.java new file mode 100644 index 0000000..723b883 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Banner.java @@ -0,0 +1,77 @@ +package org.bukkit.block; + +import org.bukkit.DyeColor; +import org.bukkit.block.banner.Pattern; + +import java.util.List; + +public interface Banner extends BlockState { + + /** + * Returns the base color for this banner + * + * @return the base color + */ + DyeColor getBaseColor(); + + /** + * Sets the base color for this banner + * + * @param color the base color + */ + void setBaseColor(DyeColor color); + + /** + * Returns a list of patterns on this banner + * + * @return the patterns + */ + List getPatterns(); + + /** + * Sets the patterns used on this banner + * + * @param patterns the new list of patterns + */ + void setPatterns(List patterns); + + /** + * Adds a new pattern on top of the existing + * patterns + * + * @param pattern the new pattern to add + */ + void addPattern(Pattern pattern); + + /** + * Returns the pattern at the specified index + * + * @param i the index + * @return the pattern + */ + Pattern getPattern(int i); + + /** + * Removes the pattern at the specified index + * + * @param i the index + * @return the removed pattern + */ + Pattern removePattern(int i); + + /** + * Sets the pattern at the specified index + * + * @param i the index + * @param pattern the new pattern + */ + void setPattern(int i, Pattern pattern); + + /** + * Returns the number of patterns on this + * banner + * + * @return the number of patterns + */ + int numberOfPatterns(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Beacon.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Beacon.java new file mode 100644 index 0000000..2de0583 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Beacon.java @@ -0,0 +1,9 @@ +package org.bukkit.block; + +import org.bukkit.inventory.InventoryHolder; + +/** + * Represents a beacon. + */ +public interface Beacon extends BlockState, InventoryHolder { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Biome.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Biome.java new file mode 100644 index 0000000..8b902f4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Biome.java @@ -0,0 +1,68 @@ +package org.bukkit.block; + +/** + * Holds all accepted Biomes in the default server + */ +public enum Biome { + SWAMPLAND, + FOREST, + TAIGA, + DESERT, + PLAINS, + HELL, + SKY, + OCEAN, + RIVER, + EXTREME_HILLS, + FROZEN_OCEAN, + FROZEN_RIVER, + ICE_PLAINS, + ICE_MOUNTAINS, + MUSHROOM_ISLAND, + MUSHROOM_SHORE, + BEACH, + DESERT_HILLS, + FOREST_HILLS, + TAIGA_HILLS, + SMALL_MOUNTAINS, + JUNGLE, + JUNGLE_HILLS, + JUNGLE_EDGE, + DEEP_OCEAN, + STONE_BEACH, + COLD_BEACH, + BIRCH_FOREST, + BIRCH_FOREST_HILLS, + ROOFED_FOREST, + COLD_TAIGA, + COLD_TAIGA_HILLS, + MEGA_TAIGA, + MEGA_TAIGA_HILLS, + EXTREME_HILLS_PLUS, + SAVANNA, + SAVANNA_PLATEAU, + MESA, + MESA_PLATEAU_FOREST, + MESA_PLATEAU, + SUNFLOWER_PLAINS, + DESERT_MOUNTAINS, + FLOWER_FOREST, + TAIGA_MOUNTAINS, + SWAMPLAND_MOUNTAINS, + ICE_PLAINS_SPIKES, + JUNGLE_MOUNTAINS, + JUNGLE_EDGE_MOUNTAINS, + COLD_TAIGA_MOUNTAINS, + SAVANNA_MOUNTAINS, + SAVANNA_PLATEAU_MOUNTAINS, + MESA_BRYCE, + MESA_PLATEAU_FOREST_MOUNTAINS, + MESA_PLATEAU_MOUNTAINS, + BIRCH_FOREST_MOUNTAINS, + BIRCH_FOREST_HILLS_MOUNTAINS, + ROOFED_FOREST_MOUNTAINS, + MEGA_SPRUCE_TAIGA, + EXTREME_HILLS_MOUNTAINS, + EXTREME_HILLS_PLUS_MOUNTAINS, + MEGA_SPRUCE_TAIGA_HILLS, +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Block.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Block.java new file mode 100644 index 0000000..235c15b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Block.java @@ -0,0 +1,393 @@ +package org.bukkit.block; + +import java.util.Collection; + +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.Metadatable; + +/** + * Represents a block. This is a live object, and only one Block may exist for + * any given location in a world. The state of the block may change + * concurrently to your own handling of it; use block.getState() to get a + * snapshot state of a block which will not be modified. + */ +public interface Block extends Metadatable { + + /** + * Gets the metadata for this block + * + * @return block specific metadata + * @deprecated Magic value + */ + @Deprecated + byte getData(); + + /** + * Gets the block at the given offsets + * + * @param modX X-coordinate offset + * @param modY Y-coordinate offset + * @param modZ Z-coordinate offset + * @return Block at the given offsets + */ + Block getRelative(int modX, int modY, int modZ); + + /** + * Gets the block at the given face + *

+ * This method is equal to getRelative(face, 1) + * + * @param face Face of this block to return + * @return Block at the given face + * @see #getRelative(BlockFace, int) + */ + Block getRelative(BlockFace face); + + /** + * Gets the block at the given distance of the given face + *

+ * For example, the following method places water at 100,102,100; two + * blocks above 100,100,100. + * + *

+     * Block block = world.getBlockAt(100, 100, 100);
+     * Block shower = block.getRelative(BlockFace.UP, 2);
+     * shower.setType(Material.WATER);
+     * 
+ * + * @param face Face of this block to return + * @param distance Distance to get the block at + * @return Block at the given face + */ + Block getRelative(BlockFace face, int distance); + + /** + * Gets the type of this block + * + * @return block type + */ + Material getType(); + + /** + * Gets the type-id of this block + * + * @return block type-id + * @deprecated Magic value + */ + @Deprecated + int getTypeId(); + + /** + * Gets the light level between 0-15 + * + * @return light level + */ + byte getLightLevel(); + + /** + * Get the amount of light at this block from the sky. + *

+ * Any light given from other sources (such as blocks like torches) will + * be ignored. + * + * @return Sky light level + */ + byte getLightFromSky(); + + /** + * Get the amount of light at this block from nearby blocks. + *

+ * Any light given from other sources (such as the sun) will be ignored. + * + * @return Block light level + */ + byte getLightFromBlocks(); + + /** + * Gets the world which contains this Block + * + * @return World containing this block + */ + World getWorld(); + + /** + * Gets the x-coordinate of this block + * + * @return x-coordinate + */ + int getX(); + + /** + * Gets the y-coordinate of this block + * + * @return y-coordinate + */ + int getY(); + + /** + * Gets the z-coordinate of this block + * + * @return z-coordinate + */ + int getZ(); + + /** + * Gets the Location of the block + * + * @return Location of block + */ + Location getLocation(); + + /** + * Stores the location of the block in the provided Location object. + *

+ * If the provided Location is null this method does nothing and returns + * null. + * + * @param loc the location to copy into + * @return The Location object provided or null + */ + Location getLocation(Location loc); + + /** + * Gets the chunk which contains this block + * + * @return Containing Chunk + */ + Chunk getChunk(); + + /** + * Sets the metadata for this block + * + * @param data New block specific metadata + * @deprecated Magic value + */ + @Deprecated + void setData(byte data); + + /** + * Sets the metadata for this block + * + * @param data New block specific metadata + * @param applyPhysics False to cancel physics from the changed block. + * @deprecated Magic value + */ + @Deprecated + void setData(byte data, boolean applyPhysics); + + /** + * Sets the type of this block + * + * @param type Material to change this block to + */ + void setType(Material type); + + /** + * Sets the type of this block + * + * @param type Material to change this block to + * @param applyPhysics False to cancel physics on the changed block. + */ + void setType(Material type, boolean applyPhysics); + + /** + * Sets the type-id of this block + * + * @param type Type-Id to change this block to + * @return whether the block was changed + * @deprecated Magic value + */ + @Deprecated + boolean setTypeId(int type); + + /** + * Sets the type-id of this block + * + * @param type Type-Id to change this block to + * @param applyPhysics False to cancel physics on the changed block. + * @return whether the block was changed + * @deprecated Magic value + */ + @Deprecated + boolean setTypeId(int type, boolean applyPhysics); + + /** + * Sets the type-id of this block + * + * @param type Type-Id to change this block to + * @param data The data value to change this block to + * @param applyPhysics False to cancel physics on the changed block + * @return whether the block was changed + * @deprecated Magic value + */ + @Deprecated + boolean setTypeIdAndData(int type, byte data, boolean applyPhysics); + + /** + * Gets the face relation of this block compared to the given block. + *

+ * For example: + *

{@code
+     * Block current = world.getBlockAt(100, 100, 100);
+     * Block target = world.getBlockAt(100, 101, 100);
+     *
+     * current.getFace(target) == BlockFace.Up;
+     * }
+ *
+ * If the given block is not connected to this block, null may be returned + * + * @param block Block to compare against this block + * @return BlockFace of this block which has the requested block, or null + */ + BlockFace getFace(Block block); + + /** + * Captures the current state of this block. You may then cast that state + * into any accepted type, such as Furnace or Sign. + *

+ * The returned object will never be updated, and you are not guaranteed + * that (for example) a sign is still a sign after you capture its state. + * + * @return BlockState with the current state of this block. + */ + BlockState getState(); + + /** + * Returns the biome that this block resides in + * + * @return Biome type containing this block + */ + Biome getBiome(); + + /** + * Sets the biome that this block resides in + * + * @param bio new Biome type for this block + */ + void setBiome(Biome bio); + + /** + * Returns true if the block is being powered by Redstone. + * + * @return True if the block is powered. + */ + boolean isBlockPowered(); + + /** + * Returns true if the block is being indirectly powered by Redstone. + * + * @return True if the block is indirectly powered. + */ + boolean isBlockIndirectlyPowered(); + + /** + * Returns true if the block face is being powered by Redstone. + * + * @param face The block face + * @return True if the block face is powered. + */ + boolean isBlockFacePowered(BlockFace face); + + /** + * Returns true if the block face is being indirectly powered by Redstone. + * + * @param face The block face + * @return True if the block face is indirectly powered. + */ + boolean isBlockFaceIndirectlyPowered(BlockFace face); + + /** + * Returns the redstone power being provided to this block face + * + * @param face the face of the block to query or BlockFace.SELF for the + * block itself + * @return The power level. + */ + int getBlockPower(BlockFace face); + + /** + * Returns the redstone power being provided to this block + * + * @return The power level. + */ + int getBlockPower(); + + /** + * Checks if this block is empty. + *

+ * A block is considered empty when {@link #getType()} returns {@link + * Material#AIR}. + * + * @return true if this block is empty + */ + boolean isEmpty(); + + /** + * Checks if this block is liquid. + *

+ * A block is considered liquid when {@link #getType()} returns {@link + * Material#WATER}, {@link Material#STATIONARY_WATER}, {@link + * Material#LAVA} or {@link Material#STATIONARY_LAVA}. + * + * @return true if this block is liquid + */ + boolean isLiquid(); + + /** + * Gets the temperature of the biome of this block + * + * @return Temperature of this block + */ + double getTemperature(); + + /** + * Gets the humidity of the biome of this block + * + * @return Humidity of this block + */ + double getHumidity(); + + /** + * Returns the reaction of the block when moved by a piston + * + * @return reaction + */ + PistonMoveReaction getPistonMoveReaction(); + + /** + * Breaks the block and spawns items as if a player had digged it + * + * @return true if the block was destroyed + */ + boolean breakNaturally(); + + /** + * Breaks the block and spawns items as if a player had digged it with a + * specific tool + * + * @param tool The tool or item in hand used for digging + * @return true if the block was destroyed + */ + boolean breakNaturally(ItemStack tool); + + /** + * Returns a list of items which would drop by destroying this block + * + * @return a list of dropped items for this type of block + */ + Collection getDrops(); + + /** + * Returns a list of items which would drop by destroying this block with + * a specific tool + * + * @param tool The tool or item in hand used for digging + * @return a list of dropped items for this type of block + */ + Collection getDrops(ItemStack tool); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BlockFace.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BlockFace.java new file mode 100644 index 0000000..58fb195 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BlockFace.java @@ -0,0 +1,132 @@ +package org.bukkit.block; + +/** + * Represents the face of a block + */ +public enum BlockFace { + NORTH(0, 0, -1), + EAST(1, 0, 0), + SOUTH(0, 0, 1), + WEST(-1, 0, 0), + UP(0, 1, 0), + DOWN(0, -1, 0), + NORTH_EAST(NORTH, EAST), + NORTH_WEST(NORTH, WEST), + SOUTH_EAST(SOUTH, EAST), + SOUTH_WEST(SOUTH, WEST), + WEST_NORTH_WEST(WEST, NORTH_WEST), + NORTH_NORTH_WEST(NORTH, NORTH_WEST), + NORTH_NORTH_EAST(NORTH, NORTH_EAST), + EAST_NORTH_EAST(EAST, NORTH_EAST), + EAST_SOUTH_EAST(EAST, SOUTH_EAST), + SOUTH_SOUTH_EAST(SOUTH, SOUTH_EAST), + SOUTH_SOUTH_WEST(SOUTH, SOUTH_WEST), + WEST_SOUTH_WEST(WEST, SOUTH_WEST), + SELF(0, 0, 0); + + private final int modX; + private final int modY; + private final int modZ; + + private BlockFace(final int modX, final int modY, final int modZ) { + this.modX = modX; + this.modY = modY; + this.modZ = modZ; + } + + private BlockFace(final BlockFace face1, final BlockFace face2) { + this.modX = face1.getModX() + face2.getModX(); + this.modY = face1.getModY() + face2.getModY(); + this.modZ = face1.getModZ() + face2.getModZ(); + } + + /** + * Get the amount of X-coordinates to modify to get the represented block + * + * @return Amount of X-coordinates to modify + */ + public int getModX() { + return modX; + } + + /** + * Get the amount of Y-coordinates to modify to get the represented block + * + * @return Amount of Y-coordinates to modify + */ + public int getModY() { + return modY; + } + + /** + * Get the amount of Z-coordinates to modify to get the represented block + * + * @return Amount of Z-coordinates to modify + */ + public int getModZ() { + return modZ; + } + + public BlockFace getOppositeFace() { + switch (this) { + case NORTH: + return BlockFace.SOUTH; + + case SOUTH: + return BlockFace.NORTH; + + case EAST: + return BlockFace.WEST; + + case WEST: + return BlockFace.EAST; + + case UP: + return BlockFace.DOWN; + + case DOWN: + return BlockFace.UP; + + case NORTH_EAST: + return BlockFace.SOUTH_WEST; + + case NORTH_WEST: + return BlockFace.SOUTH_EAST; + + case SOUTH_EAST: + return BlockFace.NORTH_WEST; + + case SOUTH_WEST: + return BlockFace.NORTH_EAST; + + case WEST_NORTH_WEST: + return BlockFace.EAST_SOUTH_EAST; + + case NORTH_NORTH_WEST: + return BlockFace.SOUTH_SOUTH_EAST; + + case NORTH_NORTH_EAST: + return BlockFace.SOUTH_SOUTH_WEST; + + case EAST_NORTH_EAST: + return BlockFace.WEST_SOUTH_WEST; + + case EAST_SOUTH_EAST: + return BlockFace.WEST_NORTH_WEST; + + case SOUTH_SOUTH_EAST: + return BlockFace.NORTH_NORTH_WEST; + + case SOUTH_SOUTH_WEST: + return BlockFace.NORTH_NORTH_EAST; + + case WEST_SOUTH_WEST: + return BlockFace.EAST_NORTH_EAST; + + case SELF: + return BlockFace.SELF; + } + + return BlockFace.SELF; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BlockState.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BlockState.java new file mode 100644 index 0000000..866a73d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BlockState.java @@ -0,0 +1,206 @@ +package org.bukkit.block; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.material.MaterialData; +import org.bukkit.metadata.Metadatable; + +/** + * Represents a captured state of a block, which will not change + * automatically. + *

+ * Unlike Block, which only one object can exist per coordinate, BlockState + * can exist multiple times for any given Block. Note that another plugin may + * change the state of the block and you will not know, or they may change the + * block to another type entirely, causing your BlockState to become invalid. + */ +public interface BlockState extends Metadatable { + + /** + * Gets the block represented by this BlockState + * + * @return Block that this BlockState represents + */ + Block getBlock(); + + /** + * Gets the metadata for this block + * + * @return block specific metadata + */ + MaterialData getData(); + + /** + * Gets the type of this block + * + * @return block type + */ + Material getType(); + + /** + * Gets the type-id of this block + * + * @return block type-id + * @deprecated Magic value + */ + @Deprecated + int getTypeId(); + + /** + * Gets the light level between 0-15 + * + * @return light level + */ + byte getLightLevel(); + + /** + * Gets the world which contains this Block + * + * @return World containing this block + */ + World getWorld(); + + /** + * Gets the x-coordinate of this block + * + * @return x-coordinate + */ + int getX(); + + /** + * Gets the y-coordinate of this block + * + * @return y-coordinate + */ + int getY(); + + /** + * Gets the z-coordinate of this block + * + * @return z-coordinate + */ + int getZ(); + + /** + * Gets the location of this block + * + * @return location + */ + Location getLocation(); + + /** + * Stores the location of this block in the provided Location object. + *

+ * If the provided Location is null this method does nothing and returns + * null. + * + * @param loc the location to copy into + * @return The Location object provided or null + */ + Location getLocation(Location loc); + + /** + * Gets the chunk which contains this block + * + * @return Containing Chunk + */ + Chunk getChunk(); + + /** + * Sets the metadata for this block + * + * @param data New block specific metadata + */ + void setData(MaterialData data); + + /** + * Sets the type of this block + * + * @param type Material to change this block to + */ + void setType(Material type); + + /** + * Sets the type-id of this block + * + * @param type Type-Id to change this block to + * @return Whether it worked? + * @deprecated Magic value + */ + @Deprecated + boolean setTypeId(int type); + + /** + * Attempts to update the block represented by this state, setting it to + * the new values as defined by this state. + *

+ * This has the same effect as calling update(false). That is to say, + * this will not modify the state of a block if it is no longer the same + * type as it was when this state was taken. It will return false in this + * eventuality. + * + * @return true if the update was successful, otherwise false + * @see #update(boolean) + */ + boolean update(); + + /** + * Attempts to update the block represented by this state, setting it to + * the new values as defined by this state. + *

+ * This has the same effect as calling update(force, true). That is to + * say, this will trigger a physics update to surrounding blocks. + * + * @param force true to forcefully set the state + * @return true if the update was successful, otherwise false + */ + boolean update(boolean force); + + /** + * Attempts to update the block represented by this state, setting it to + * the new values as defined by this state. + *

+ * Unless force is true, this will not modify the state of a block if it + * is no longer the same type as it was when this state was taken. It will + * return false in this eventuality. + *

+ * If force is true, it will set the type of the block to match the new + * state, set the state data and then return true. + *

+ * If applyPhysics is true, it will trigger a physics update on + * surrounding blocks which could cause them to update or disappear. + * + * @param force true to forcefully set the state + * @param applyPhysics false to cancel updating physics on surrounding + * blocks + * @return true if the update was successful, otherwise false + */ + boolean update(boolean force, boolean applyPhysics); + + /** + * @return The data as a raw byte. + * @deprecated Magic value + */ + @Deprecated + public byte getRawData(); + + /** + * @param data The new data value for the block. + * @deprecated Magic value + */ + @Deprecated + public void setRawData(byte data); + + /** + * Returns whether this state is placed in the world. + * + * Some methods will not work if the blockState isn't + * placed in the world. + * + * @return whether the state is placed in the world + * or 'virtual' (e.g. on an itemstack) + */ + boolean isPlaced(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BrewingStand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BrewingStand.java new file mode 100644 index 0000000..c66a51c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/BrewingStand.java @@ -0,0 +1,25 @@ +package org.bukkit.block; + +import org.bukkit.inventory.BrewerInventory; + +/** + * Represents a brewing stand. + */ +public interface BrewingStand extends BlockState, ContainerBlock { + + /** + * How much time is left in the brewing cycle + * + * @return Brew Time + */ + int getBrewingTime(); + + /** + * Set the time left before brewing completes. + * + * @param brewTime Brewing time + */ + void setBrewingTime(int brewTime); + + public BrewerInventory getInventory(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Chest.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Chest.java new file mode 100644 index 0000000..125d5e7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Chest.java @@ -0,0 +1,17 @@ +package org.bukkit.block; + +import org.bukkit.inventory.Inventory; + +/** + * Represents a chest. + */ +public interface Chest extends BlockState, ContainerBlock { + + /** + * Returns the chest's inventory. If this is a double chest, it returns + * just the portion of the inventory linked to this half of the chest. + * + * @return The inventory. + */ + Inventory getBlockInventory(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/CommandBlock.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/CommandBlock.java new file mode 100644 index 0000000..85d5345 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/CommandBlock.java @@ -0,0 +1,40 @@ +package org.bukkit.block; + +public interface CommandBlock extends BlockState { + + /** + * Gets the command that this CommandBlock will run when powered. + * This will never return null. If the CommandBlock does not have a + * command, an empty String will be returned instead. + * + * @return Command that this CommandBlock will run when powered. + */ + public String getCommand(); + + /** + * Sets the command that this CommandBlock will run when powered. + * Setting the command to null is the same as setting it to an empty + * String. + * + * @param command Command that this CommandBlock will run when powered. + */ + public void setCommand(String command); + + /** + * Gets the name of this CommandBlock. The name is used with commands + * that this CommandBlock executes. This name will never be null, and + * by default is "@". + * + * @return Name of this CommandBlock. + */ + public String getName(); + + /** + * Sets the name of this CommandBlock. The name is used with commands + * that this CommandBlock executes. Setting the name to null is the + * same as setting it to "@". + * + * @param name New name for this CommandBlock. + */ + public void setName(String name); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/ContainerBlock.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/ContainerBlock.java new file mode 100644 index 0000000..c69ac9e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/ContainerBlock.java @@ -0,0 +1,11 @@ +package org.bukkit.block; + +import org.bukkit.inventory.InventoryHolder; + +/** + * Indicates a block type that has inventory. + * + * @deprecated in favour of {@link InventoryHolder} + */ +@Deprecated +public interface ContainerBlock extends InventoryHolder {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/CreatureSpawner.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/CreatureSpawner.java new file mode 100644 index 0000000..e54d997 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/CreatureSpawner.java @@ -0,0 +1,88 @@ +package org.bukkit.block; + +import org.bukkit.entity.CreatureType; +import org.bukkit.entity.EntityType; + +/** + * Represents a creature spawner. + */ +public interface CreatureSpawner extends BlockState { + + /** + * Get the spawner's creature type. + * + * @return The creature type. + * @deprecated In favour of {@link #getSpawnedType()}. + */ + @Deprecated + public CreatureType getCreatureType(); + + /** + * Get the spawner's creature type. + * + * @return The creature type. + */ + public EntityType getSpawnedType(); + + /** + * Set the spawner's creature type. + * + * @param creatureType The creature type. + */ + public void setSpawnedType(EntityType creatureType); + + /** + * Set the spawner creature type. + * + * @param creatureType The creature type. + * @deprecated In favour of {@link #setSpawnedType(EntityType)}. + */ + @Deprecated + public void setCreatureType(CreatureType creatureType); + + /** + * Get the spawner's creature type. + * + * @return The creature type's name. + * @deprecated Use {@link #getCreatureTypeName()}. + */ + @Deprecated + public String getCreatureTypeId(); + + /** + * Set the spawner mob type. + * + * @param creatureType The creature type's name. + */ + public void setCreatureTypeByName(String creatureType); + + /** + * Get the spawner's creature type. + * + * @return The creature type's name. + */ + public String getCreatureTypeName(); + + /** + * Set the spawner mob type. + * + * @param creatureType The creature type's name. + * @deprecated Use {@link #setCreatureTypeByName(String)}. + */ + @Deprecated + public void setCreatureTypeId(String creatureType); + + /** + * Get the spawner's delay. + * + * @return The delay. + */ + public int getDelay(); + + /** + * Set the spawner's delay. + * + * @param delay The delay. + */ + public void setDelay(int delay); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Dispenser.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Dispenser.java new file mode 100644 index 0000000..bba753e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Dispenser.java @@ -0,0 +1,27 @@ +package org.bukkit.block; + +import org.bukkit.projectiles.BlockProjectileSource; + +/** + * Represents a dispenser. + */ +public interface Dispenser extends BlockState, ContainerBlock { + + /** + * Gets the BlockProjectileSource object for this dispenser. + *

+ * If the block is no longer a dispenser, this will return null. + * + * @return a BlockProjectileSource if valid, otherwise null + */ + public BlockProjectileSource getBlockProjectileSource(); + + /** + * Attempts to dispense the contents of this block. + *

+ * If the block is no longer a dispenser, this will return false. + * + * @return true if successful, otherwise false + */ + public boolean dispense(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/DoubleChest.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/DoubleChest.java new file mode 100644 index 0000000..148099c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/DoubleChest.java @@ -0,0 +1,50 @@ +package org.bukkit.block; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.inventory.DoubleChestInventory; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +/** + * Represents a double chest. + */ +public class DoubleChest implements InventoryHolder { + private DoubleChestInventory inventory; + + public DoubleChest(DoubleChestInventory chest) { + inventory = chest; + } + + public Inventory getInventory() { + return inventory; + } + + public InventoryHolder getLeftSide() { + return inventory.getLeftSide().getHolder(); + } + + public InventoryHolder getRightSide() { + return inventory.getRightSide().getHolder(); + } + + public Location getLocation() { + return new Location(getWorld(), getX(), getY(), getZ()); + } + + public World getWorld() { + return ((Chest)getLeftSide()).getWorld(); + } + + public double getX() { + return 0.5 * (((Chest)getLeftSide()).getX() + ((Chest)getRightSide()).getX()); + } + + public double getY() { + return 0.5 * (((Chest)getLeftSide()).getY() + ((Chest)getRightSide()).getY()); + } + + public double getZ() { + return 0.5 * (((Chest)getLeftSide()).getZ() + ((Chest)getRightSide()).getZ()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Dropper.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Dropper.java new file mode 100644 index 0000000..21fbedc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Dropper.java @@ -0,0 +1,25 @@ +package org.bukkit.block; + +import org.bukkit.inventory.InventoryHolder; + +/** + * Represents a dropper. + */ +public interface Dropper extends BlockState, InventoryHolder { + /** + * Tries to drop a randomly selected item from the Dropper's inventory, + * following the normal behavior of a Dropper. + *

+ * Normal behavior of a Dropper is as follows: + *

+ * If the block that the Dropper is facing is an InventoryHolder or + * ContainerBlock the randomly selected ItemStack is placed within that + * Inventory in the first slot that's available, starting with 0 and + * counting up. If the inventory is full, nothing happens. + *

+ * If the block that the Dropper is facing is not an InventoryHolder or + * ContainerBlock, the randomly selected ItemStack is dropped on + * the ground in the form of an {@link org.bukkit.entity.Item Item}. + */ + public void drop(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Furnace.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Furnace.java new file mode 100644 index 0000000..94af85e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Furnace.java @@ -0,0 +1,39 @@ +package org.bukkit.block; + +import org.bukkit.inventory.FurnaceInventory; + +/** + * Represents a furnace. + */ +public interface Furnace extends BlockState, ContainerBlock { + + /** + * Get burn time. + * + * @return Burn time + */ + public short getBurnTime(); + + /** + * Set burn time. + * + * @param burnTime Burn time + */ + public void setBurnTime(short burnTime); + + /** + * Get cook time. + * + * @return Cook time + */ + public short getCookTime(); + + /** + * Set cook time. + * + * @param cookTime Cook time + */ + public void setCookTime(short cookTime); + + public FurnaceInventory getInventory(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Hopper.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Hopper.java new file mode 100644 index 0000000..e097157 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Hopper.java @@ -0,0 +1,10 @@ +package org.bukkit.block; + +import org.bukkit.inventory.InventoryHolder; + +/** + * Represents a hopper. + */ +public interface Hopper extends BlockState, InventoryHolder { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Jukebox.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Jukebox.java new file mode 100644 index 0000000..7b45b83 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Jukebox.java @@ -0,0 +1,36 @@ +package org.bukkit.block; + +import org.bukkit.Material; + +/** + * Represents a Jukebox + */ +public interface Jukebox extends BlockState { + /** + * Get the record currently playing + * + * @return The record Material, or AIR if none is playing + */ + public Material getPlaying(); + + /** + * Set the record currently playing + * + * @param record The record Material, or null/AIR to stop playing + */ + public void setPlaying(Material record); + + /** + * Check if the jukebox is currently playing a record + * + * @return True if there is a record playing + */ + public boolean isPlaying(); + + /** + * Stop the jukebox playing and eject the current record + * + * @return True if a record was ejected; false if there was none playing + */ + public boolean eject(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/NoteBlock.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/NoteBlock.java new file mode 100644 index 0000000..8380068 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/NoteBlock.java @@ -0,0 +1,72 @@ +package org.bukkit.block; + +import org.bukkit.Instrument; +import org.bukkit.Note; + +/** + * Represents a note. + */ +public interface NoteBlock extends BlockState { + + /** + * Gets the note. + * + * @return The note. + */ + public Note getNote(); + + /** + * Gets the note. + * + * @return The note ID. + * @deprecated Magic value + */ + @Deprecated + public byte getRawNote(); + + /** + * Set the note. + * + * @param note The note. + */ + public void setNote(Note note); + + /** + * Set the note. + * + * @param note The note ID. + * @deprecated Magic value + */ + @Deprecated + public void setRawNote(byte note); + + /** + * Attempts to play the note at block + *

+ * If the block is no longer a note block, this will return false + * + * @return true if successful, otherwise false + */ + public boolean play(); + + /** + * Plays an arbitrary note with an arbitrary instrument + * + * @param instrument Instrument ID + * @param note Note ID + * @return true if successful, otherwise false + * @deprecated Magic value + */ + @Deprecated + public boolean play(byte instrument, byte note); + + /** + * Plays an arbitrary note with an arbitrary instrument + * + * @param instrument The instrument + * @param note The note + * @return true if successful, otherwise false + * @see Instrument Note + */ + public boolean play(Instrument instrument, Note note); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/PistonMoveReaction.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/PistonMoveReaction.java new file mode 100644 index 0000000..e5279f7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/PistonMoveReaction.java @@ -0,0 +1,51 @@ +package org.bukkit.block; + +import java.util.HashMap; +import java.util.Map; + +public enum PistonMoveReaction { + + /** + * Indicates that the block can be pushed or pulled. + */ + MOVE(0), + /** + * Indicates the block is fragile and will break if pushed on. + */ + BREAK(1), + /** + * Indicates that the block will resist being pushed or pulled. + */ + BLOCK(2); + + private int id; + private static Map byId = new HashMap(); + static { + for (PistonMoveReaction reaction : PistonMoveReaction.values()) { + byId.put(reaction.id, reaction); + } + } + + private PistonMoveReaction(int id) { + this.id = id; + } + + /** + * @return The ID of the move reaction + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return this.id; + } + + /** + * @param id An ID + * @return The move reaction with that ID + * @deprecated Magic value + */ + @Deprecated + public static PistonMoveReaction getById(int id) { + return byId.get(id); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Sign.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Sign.java new file mode 100644 index 0000000..5d7a633 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Sign.java @@ -0,0 +1,37 @@ +package org.bukkit.block; + +/** + * Represents either a SignPost or a WallSign + */ +public interface Sign extends BlockState { + + /** + * Gets all the lines of text currently on this sign. + * + * @return Array of Strings containing each line of text + */ + public String[] getLines(); + + /** + * Gets the line of text at the specified index. + *

+ * For example, getLine(0) will return the first line of text. + * + * @param index Line number to get the text from, starting at 0 + * @throws IndexOutOfBoundsException Thrown when the line does not exist + * @return Text on the given line + */ + public String getLine(int index) throws IndexOutOfBoundsException; + + /** + * Sets the line of text at the specified index. + *

+ * For example, setLine(0, "Line One") will set the first line of text to + * "Line One". + * + * @param index Line number to set the text at, starting from 0 + * @param line New text to set at the specified index + * @throws IndexOutOfBoundsException If the index is out of the range 0..3 + */ + public void setLine(int index, String line) throws IndexOutOfBoundsException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Skull.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Skull.java new file mode 100644 index 0000000..4f4896f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/Skull.java @@ -0,0 +1,62 @@ +package org.bukkit.block; + +import org.bukkit.SkullType; + +/** + * Represents a Skull + */ +public interface Skull extends BlockState { + + /** + * Checks to see if the skull has an owner + * + * @return true if the skull has an owner + */ + public boolean hasOwner(); + + /** + * Gets the owner of the skull, if one exists + * + * @return the owner of the skull or null if the skull does not have an owner + */ + public String getOwner(); + + /** + * Sets the owner of the skull + *

+ * Involves a potentially blocking web request to acquire the profile data for + * the provided name. + * + * @param name the new owner of the skull + * @return true if the owner was successfully set + */ + public boolean setOwner(String name); + + /** + * Gets the rotation of the skull in the world + * + * @return the rotation of the skull + */ + public BlockFace getRotation(); + + /** + * Sets the rotation of the skull in the world + * + * @param rotation the rotation of the skull + */ + public void setRotation(BlockFace rotation); + + /** + * Gets the type of skull + * + * @return the type of skull + */ + public SkullType getSkullType(); + + /** + * Sets the type of skull + * + * @param skullType the type of skull + */ + public void setSkullType(SkullType skullType); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/banner/Pattern.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/banner/Pattern.java new file mode 100644 index 0000000..95b0f3c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/banner/Pattern.java @@ -0,0 +1,94 @@ +package org.bukkit.block.banner; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import java.util.NoSuchElementException; +import org.bukkit.DyeColor; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; + +@SerializableAs("Pattern") +public class Pattern implements ConfigurationSerializable { + + private static final String COLOR = "color"; + private static final String PATTERN = "pattern"; + + private final DyeColor color; + private final PatternType pattern; + + /** + * Creates a new pattern from the specified color and + * pattern type + * + * @param color the pattern color + * @param pattern the pattern type + */ + public Pattern(DyeColor color, PatternType pattern) { + this.color = color; + this.pattern = pattern; + } + + /** + * Constructor for deserialization. + * + * @param map the map to deserialize from + */ + public Pattern(Map map) { + color = DyeColor.valueOf(getString(map, COLOR)); + pattern = PatternType.getByIdentifier(getString(map, PATTERN)); + } + + private static String getString(Map map, Object key) { + Object str = map.get(key); + if (str instanceof String) { + return (String) str; + } + throw new NoSuchElementException(map + " does not contain " + key); + } + + @Override + public Map serialize() { + return ImmutableMap.of( + COLOR, color.toString(), + PATTERN, pattern.getIdentifier() + ); + } + + /** + * Returns the color of the pattern + * + * @return the color of the pattern + */ + public DyeColor getColor() { + return color; + } + + /** + * Returns the type of pattern + * + * @return the pattern type + */ + public PatternType getPattern() { + return pattern; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 97 * hash + (this.color != null ? this.color.hashCode() : 0); + hash = 97 * hash + (this.pattern != null ? this.pattern.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Pattern other = (Pattern) obj; + return this.color == other.color && this.pattern == other.pattern; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/banner/PatternType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/banner/PatternType.java new file mode 100644 index 0000000..25543b0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/block/banner/PatternType.java @@ -0,0 +1,80 @@ +package org.bukkit.block.banner; + +import java.util.HashMap; +import java.util.Map; + +public enum PatternType { + BASE("b"), + SQUARE_BOTTOM_LEFT("bl"), + SQUARE_BOTTOM_RIGHT("br"), + SQUARE_TOP_LEFT("tl"), + SQUARE_TOP_RIGHT("tr"), + STRIPE_BOTTOM("bs"), + STRIPE_TOP("ts"), + STRIPE_LEFT("ls"), + STRIPE_RIGHT("rs"), + STRIPE_CENTER("cs"), + STRIPE_MIDDLE("ms"), + STRIPE_DOWNRIGHT("drs"), + STRIPE_DOWNLEFT("dls"), + STRIPE_SMALL("ss"), + CROSS("cr"), + STRAIGHT_CROSS("sc"), + TRIANGLE_BOTTOM("bt"), + TRIANGLE_TOP("tt"), + TRIANGLES_BOTTOM("bts"), + TRIANGLES_TOP("tts"), + DIAGONAL_LEFT("ld"), + DIAGONAL_RIGHT("rd"), + DIAGONAL_LEFT_MIRROR("lud"), + DIAGONAL_RIGHT_MIRROR("rud"), + CIRCLE_MIDDLE("mc"), + RHOMBUS_MIDDLE("mr"), + HALF_VERTICAL("vh"), + HALF_HORIZONTAL("hh"), + HALF_VERTICAL_MIRROR("vhr"), + HALF_HORIZONTAL_MIRROR("hhb"), + BORDER("bo"), + CURLY_BORDER("cbo"), + CREEPER("cre"), + GRADIENT("gra"), + GRADIENT_UP("gru"), + BRICKS("bri"), + SKULL("sku"), + FLOWER("flo"), + MOJANG("moj"); + + private final String identifier; + private static final Map byString = new HashMap(); + + static { + for (PatternType p : values()) { + byString.put(p.identifier, p); + } + } + + private PatternType(String key) { + this.identifier = key; + } + + /** + * Returns the identifier used to represent + * this pattern type + * + * @return the pattern's identifier + */ + public String getIdentifier() { + return identifier; + } + + /** + * Returns the pattern type which matches the passed + * identifier or null if no matches are found + * + * @param identifier the identifier + * @return the matched pattern type or null + */ + public static PatternType getByIdentifier(String identifier) { + return byString.get(identifier); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/BlockCommandSender.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/BlockCommandSender.java new file mode 100644 index 0000000..ce229d2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/BlockCommandSender.java @@ -0,0 +1,13 @@ +package org.bukkit.command; + +import org.bukkit.block.Block; + +public interface BlockCommandSender extends CommandSender { + + /** + * Returns the block this command sender belongs to + * + * @return Block for the command sender + */ + public Block getBlock(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/Command.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/Command.java new file mode 100644 index 0000000..c126a1e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/Command.java @@ -0,0 +1,450 @@ +package org.bukkit.command; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.entity.Player; +import org.bukkit.entity.minecart.CommandMinecart; +import org.bukkit.permissions.Permissible; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +/** + * Represents a Command, which executes various tasks upon user input + */ +public abstract class Command { + private String name; + private String nextLabel; + private String label; + private List aliases; + private List activeAliases; + private CommandMap commandMap = null; + protected String description = ""; + protected String usageMessage; + private String permission; + private String permissionMessage; + public co.aikar.timings.Timing timings; // Spigot + public String getTimingName() {return getName();} // Spigot + + protected Command(String name) { + this(name, "", "/" + name, new ArrayList()); + } + + protected Command(String name, String description, String usageMessage, List aliases) { + this.name = name; + this.nextLabel = name; + this.label = name; + this.description = description; + this.usageMessage = usageMessage; + this.aliases = aliases; + this.activeAliases = new ArrayList(aliases); + } + + /** + * Executes the command, returning its success + * + * @param sender Source object which is executing this command + * @param commandLabel The alias of the command used + * @param args All arguments passed to the command, split via ' ' + * @return true if the command was successful, otherwise false + */ + public abstract boolean execute(CommandSender sender, String commandLabel, String[] args); + + /** + * Executed on tab completion for this command, returning a list of + * options the player can tab through. + * + * @deprecated This method is not supported and returns null + * @param sender Source object which is executing this command + * @param args All arguments passed to the command, split via ' ' + * @return a list of tab-completions for the specified arguments. This + * will never be null. List may be immutable. + */ + @Deprecated + public List tabComplete(CommandSender sender, String[] args) { + return null; + } + + /** + * Executed on tab completion for this command, returning a list of + * options the player can tab through. + * + * @param sender Source object which is executing this command + * @param alias the alias being used + * @param args All arguments passed to the command, split via ' ' + * @return a list of tab-completions for the specified arguments. This + * will never be null. List may be immutable. + * @throws IllegalArgumentException if sender, alias, or args is null + */ + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 0) { + return ImmutableList.of(); + } + + String lastWord = args[args.length - 1]; + + Player senderPlayer = sender instanceof Player ? (Player) sender : null; + + ArrayList matchedPlayers = new ArrayList(); + for (Player player : sender.getServer().getOnlinePlayers()) { + String name = player.getName(); + if ((senderPlayer == null || senderPlayer.canSee(player)) && StringUtil.startsWithIgnoreCase(name, lastWord)) { + matchedPlayers.add(name); + } + } + + Collections.sort(matchedPlayers, String.CASE_INSENSITIVE_ORDER); + return matchedPlayers; + } + + // PaperSpigot start - location tab-completes + /** + * Executed on tab completion for this command, returning a list of options the player can tab through. This method + * returns the {@link Location} of the block the player is looking at at the time of the tab complete. + *

+ * Commands that want to use the Location information in their tab-complete implementations need to override this + * method. The Location provided by this method is the block that the player is currently looking at when the player + * attempts the tab complete. For this to be valid, the block must be highlighted by the player (i.e. the player is + * close enough to interact with the block). + * + * @param sender Source object which is executing this command + * @param alias the alias being used + * @param args All arguments passed to the command, split via ' ' + * @param location the location of the block the player is looking at + * @return a list of tab-completions for the specified arguments. This + * will never be null. List may be immutable. + * @throws IllegalArgumentException if sender, alias, or args is null + */ + public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException { + // Simply default to the standard tab-complete, subclasses can override this if needed + return tabComplete(sender, alias, args); + } + // PaperSpigot end + + /** + * Returns the name of this command + * + * @return Name of this command + */ + public String getName() { + return name; + } + + /** + * Sets the name of this command. + *

+ * May only be used before registering the command. + * Will return true if the new name is set, and false + * if the command has already been registered. + * + * @param name New command name + * @return returns true if the name change happened instantly or false if + * the command was already registered + */ + public boolean setName(String name) { + if (!isRegistered()) { + this.name = name; + return true; + } + return false; + } + + /** + * Gets the permission required by users to be able to perform this + * command + * + * @return Permission name, or null if none + */ + public String getPermission() { + return permission; + } + + /** + * Sets the permission required by users to be able to perform this + * command + * + * @param permission Permission name or null + */ + public void setPermission(String permission) { + this.permission = permission; + } + + /** + * Tests the given {@link CommandSender} to see if they can perform this + * command. + *

+ * If they do not have permission, they will be informed that they cannot + * do this. + * + * @param target User to test + * @return true if they can use it, otherwise false + */ + public boolean testPermission(CommandSender target) { + if (testPermissionSilent(target)) { + return true; + } + + if (permissionMessage == null) { + target.sendMessage(ChatColor.RED + "I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error."); + } else if (permissionMessage.length() != 0) { + for (String line : permissionMessage.replace("", permission).split("\n")) { + target.sendMessage(line); + } + } + + return false; + } + + /** + * Tests the given {@link CommandSender} to see if they can perform this + * command. + *

+ * No error is sent to the sender. + * + * @param target User to test + * @return true if they can use it, otherwise false + */ + public boolean testPermissionSilent(CommandSender target) { + if ((permission == null) || (permission.length() == 0)) { + return true; + } + + for (String p : permission.split(";")) { + if (target.hasPermission(p)) { + return true; + } + } + + return false; + } + + /** + * Returns the label for this command + * + * @return Label of this command + */ + public String getLabel() { + return label; + } + + /** + * Sets the label of this command. + *

+ * May only be used before registering the command. + * Will return true if the new name is set, and false + * if the command has already been registered. + * + * @param name The command's name + * @return returns true if the name change happened instantly or false if + * the command was already registered + */ + public boolean setLabel(String name) { + this.nextLabel = name; + if (!isRegistered()) { + this.label = name; + return true; + } + return false; + } + + /** + * Registers this command to a CommandMap. + * Once called it only allows changes the registered CommandMap + * + * @param commandMap the CommandMap to register this command to + * @return true if the registration was successful (the current registered + * CommandMap was the passed CommandMap or null) false otherwise + */ + public boolean register(CommandMap commandMap) { + if (allowChangesFrom(commandMap)) { + this.commandMap = commandMap; + return true; + } + + return false; + } + + /** + * Unregisters this command from the passed CommandMap applying any + * outstanding changes + * + * @param commandMap the CommandMap to unregister + * @return true if the unregistration was successfull (the current + * registered CommandMap was the passed CommandMap or null) false + * otherwise + */ + public boolean unregister(CommandMap commandMap) { + if (allowChangesFrom(commandMap)) { + this.commandMap = null; + this.activeAliases = new ArrayList(this.aliases); + this.label = this.nextLabel; + return true; + } + + return false; + } + + private boolean allowChangesFrom(CommandMap commandMap) { + return (null == this.commandMap || this.commandMap == commandMap); + } + + /** + * Returns the current registered state of this command + * + * @return true if this command is currently registered false otherwise + */ + public boolean isRegistered() { + return (null != this.commandMap); + } + + /** + * Returns a list of active aliases of this command + * + * @return List of aliases + */ + public List getAliases() { + return activeAliases; + } + + /** + * Returns a message to be displayed on a failed permission check for this + * command + * + * @return Permission check failed message + */ + public String getPermissionMessage() { + return permissionMessage; + } + + /** + * Gets a brief description of this command + * + * @return Description of this command + */ + public String getDescription() { + return description; + } + + /** + * Gets an example usage of this command + * + * @return One or more example usages + */ + public String getUsage() { + return usageMessage; + } + + /** + * Sets the list of aliases to request on registration for this command. + * This is not effective outside of defining aliases in the {@link + * PluginDescriptionFile#getCommands()} (under the + * `aliases' node) is equivalent to this method. + * + * @param aliases aliases to register to this command + * @return this command object, for chaining + */ + public Command setAliases(List aliases) { + this.aliases = aliases; + if (!isRegistered()) { + this.activeAliases = new ArrayList(aliases); + } + return this; + } + + /** + * Sets a brief description of this command. Defining a description in the + * {@link PluginDescriptionFile#getCommands()} (under the + * `description' node) is equivalent to this method. + * + * @param description new command description + * @return this command object, for chaining + */ + public Command setDescription(String description) { + this.description = description; + return this; + } + + /** + * Sets the message sent when a permission check fails + * + * @param permissionMessage new permission message, null to indicate + * default message, or an empty string to indicate no message + * @return this command object, for chaining + */ + public Command setPermissionMessage(String permissionMessage) { + this.permissionMessage = permissionMessage; + return this; + } + + /** + * Sets the example usage of this command + * + * @param usage new example usage + * @return this command object, for chaining + */ + public Command setUsage(String usage) { + this.usageMessage = usage; + return this; + } + + public static void broadcastCommandMessage(CommandSender source, String message) { + broadcastCommandMessage(source, message, true); + } + + public static void broadcastCommandMessage(CommandSender source, String message, boolean sendToSource) { + String result = source.getName() + ": " + message; + + if (source instanceof BlockCommandSender) { + BlockCommandSender blockCommandSender = (BlockCommandSender) source; + + if (blockCommandSender.getBlock().getWorld().getGameRuleValue("commandBlockOutput").equalsIgnoreCase("false")) { + Bukkit.getConsoleSender().sendMessage(result); + return; + } + } else if (source instanceof CommandMinecart) { + CommandMinecart commandMinecart = (CommandMinecart) source; + + if (commandMinecart.getWorld().getGameRuleValue("commandBlockOutput").equalsIgnoreCase("false")) { + Bukkit.getConsoleSender().sendMessage(result); + return; + } + } + + Set users = Bukkit.getPluginManager().getPermissionSubscriptions(Server.BROADCAST_CHANNEL_ADMINISTRATIVE); + String colored = ChatColor.GRAY + "" + ChatColor.ITALIC + "[" + result + ChatColor.GRAY + ChatColor.ITALIC + "]"; + + if (sendToSource && !(source instanceof ConsoleCommandSender)) { + source.sendMessage(message); + } + + for (Permissible user : users) { + if (user instanceof CommandSender) { + CommandSender target = (CommandSender) user; + + if (target instanceof ConsoleCommandSender) { + target.sendMessage(result); + } else if (target != source) { + target.sendMessage(colored); + } + } + } + } + + @Override + public String toString() { + return getClass().getName() + '(' + name + ')'; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandException.java new file mode 100644 index 0000000..b63015f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandException.java @@ -0,0 +1,28 @@ +package org.bukkit.command; + +/** + * Thrown when an unhandled exception occurs during the execution of a Command + */ +@SuppressWarnings("serial") +public class CommandException extends RuntimeException { + + /** + * Creates a new instance of CommandException without detail + * message. + */ + public CommandException() {} + + /** + * Constructs an instance of CommandException with the + * specified detail message. + * + * @param msg the detail message. + */ + public CommandException(String msg) { + super(msg); + } + + public CommandException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandExecutor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandExecutor.java new file mode 100644 index 0000000..c75586f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandExecutor.java @@ -0,0 +1,18 @@ +package org.bukkit.command; + +/** + * Represents a class which contains a single method for executing commands + */ +public interface CommandExecutor { + + /** + * Executes the given command, returning its success + * + * @param sender Source of the command + * @param command Command which was executed + * @param label Alias of the command which was used + * @param args Passed command arguments + * @return true if a valid command, otherwise false + */ + public boolean onCommand(CommandSender sender, Command command, String label, String[] args); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandMap.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandMap.java new file mode 100644 index 0000000..e7e20d8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandMap.java @@ -0,0 +1,109 @@ +package org.bukkit.command; + +import java.util.List; + +public interface CommandMap { + + /** + * Registers all the commands belonging to a certain plugin. + *

+ * Caller can use:- + *

    + *
  • command.getName() to determine the label registered for this + * command + *
  • command.getAliases() to determine the aliases which where + * registered + *
+ * + * @param fallbackPrefix a prefix which is prepended to each command with + * a ':' one or more times to make the command unique + * @param commands a list of commands to register + */ + public void registerAll(String fallbackPrefix, List commands); + + /** + * Registers a command. Returns true on success; false if name is already + * taken and fallback had to be used. + *

+ * Caller can use:- + *

    + *
  • command.getName() to determine the label registered for this + * command + *
  • command.getAliases() to determine the aliases which where + * registered + *
+ * + * @param label the label of the command, without the '/'-prefix. + * @param fallbackPrefix a prefix which is prepended to the command with a + * ':' one or more times to make the command unique + * @param command the command to register + * @return true if command was registered with the passed in label, false + * otherwise, which indicates the fallbackPrefix was used one or more + * times + */ + public boolean register(String label, String fallbackPrefix, Command command); + + /** + * Registers a command. Returns true on success; false if name is already + * taken and fallback had to be used. + *

+ * Caller can use:- + *

    + *
  • command.getName() to determine the label registered for this + * command + *
  • command.getAliases() to determine the aliases which where + * registered + *
+ * + * @param fallbackPrefix a prefix which is prepended to the command with a + * ':' one or more times to make the command unique + * @param command the command to register, from which label is determined + * from the command name + * @return true if command was registered with the passed in label, false + * otherwise, which indicates the fallbackPrefix was used one or more + * times + */ + public boolean register(String fallbackPrefix, Command command); + + /** + * Looks for the requested command and executes it if found. + * + * @param sender The command's sender + * @param cmdLine command + arguments. Example: "/test abc 123" + * @return returns false if no target is found, true otherwise. + * @throws CommandException Thrown when the executor for the given command + * fails with an unhandled exception + */ + public boolean dispatch(CommandSender sender, String cmdLine) throws CommandException; + + /** + * Clears all registered commands. + */ + public void clearCommands(); + + /** + * Gets the command registered to the specified name + * + * @param name Name of the command to retrieve + * @return Command with the specified name or null if a command with that + * label doesn't exist + */ + public Command getCommand(String name); + + + /** + * Looks for the requested command and executes an appropriate + * tab-completer if found. This method will also tab-complete partial + * commands. + * + * @param sender The command's sender. + * @param cmdLine The entire command string to tab-complete, excluding + * initial slash. + * @return a list of possible tab-completions. This list may be immutable. + * Will be null if no matching command of which sender has permission. + * @throws CommandException Thrown when the tab-completer for the given + * command fails with an unhandled exception + * @throws IllegalArgumentException if either sender or cmdLine are null + */ + public List tabComplete(CommandSender sender, String cmdLine) throws IllegalArgumentException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandSender.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandSender.java new file mode 100644 index 0000000..4ad0028 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/CommandSender.java @@ -0,0 +1,61 @@ +package org.bukkit.command; + +import org.bukkit.Server; +import org.bukkit.permissions.Permissible; + +public interface CommandSender extends Permissible { + + /** + * Sends this sender a message + * + * @param message Message to be displayed + */ + public void sendMessage(String message); + + /** + * Sends this sender multiple messages + * + * @param messages An array of messages to be displayed + */ + public void sendMessage(String[] messages); + + /** + * Returns the server instance that this command is running on + * + * @return Server instance + */ + public Server getServer(); + + /** + * Gets the name of this command sender + * + * @return Name of the sender + */ + public String getName(); + + // Paper start + /** + * Sends the component to the sender + * + *

If this sender does not support sending full components then + * the component will be sent as legacy text.

+ * + * @param component the component to send + */ + default void sendMessage(net.md_5.bungee.api.chat.BaseComponent component) { + this.sendMessage(component.toLegacyText()); + } + + /** + * Sends an array of components as a single message to the sender + * + *

If this sender does not support sending full components then + * the components will be sent as legacy text.

+ * + * @param components the components to send + */ + default void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components) { + this.sendMessage(new net.md_5.bungee.api.chat.TextComponent(components).toLegacyText()); + } + // Paper end +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/ConsoleCommandSender.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/ConsoleCommandSender.java new file mode 100644 index 0000000..f309c2e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/ConsoleCommandSender.java @@ -0,0 +1,6 @@ +package org.bukkit.command; + +import org.bukkit.conversations.Conversable; + +public interface ConsoleCommandSender extends CommandSender, Conversable { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/FormattedCommandAlias.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/FormattedCommandAlias.java new file mode 100644 index 0000000..f89ad07 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/FormattedCommandAlias.java @@ -0,0 +1,128 @@ +package org.bukkit.command; + +import java.util.ArrayList; +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.server.RemoteServerCommandEvent; +import org.bukkit.event.server.ServerCommandEvent; + +public class FormattedCommandAlias extends Command { + private final String[] formatStrings; + + public FormattedCommandAlias(String alias, String[] formatStrings) { + super(alias); + timings = co.aikar.timings.TimingsManager.getCommandTiming("minecraft", this); // Spigot + this.formatStrings = formatStrings; + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + boolean result = false; + ArrayList commands = new ArrayList(); + for (String formatString : formatStrings) { + try { + commands.add(buildCommand(formatString, args)); + } catch (Throwable throwable) { + if (throwable instanceof IllegalArgumentException) { + sender.sendMessage(throwable.getMessage()); + } else { + sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); + } + return false; + } + } + + for (String command : commands) { + result |= Bukkit.dispatchCommand(sender, command); + } + + return result; + } + + private String buildCommand(String formatString, String[] args) { + int index = formatString.indexOf("$"); + while (index != -1) { + int start = index; + + if (index > 0 && formatString.charAt(start - 1) == '\\') { + formatString = formatString.substring(0, start - 1) + formatString.substring(start); + index = formatString.indexOf("$", index); + continue; + } + + boolean required = false; + if (formatString.charAt(index + 1) == '$') { + required = true; + // Move index past the second $ + index++; + } + + // Move index past the $ + index++; + int argStart = index; + while (index < formatString.length() && inRange(((int) formatString.charAt(index)) - 48, 0, 9)) { + // Move index past current digit + index++; + } + + // No numbers found + if (argStart == index) { + throw new IllegalArgumentException("Invalid replacement token"); + } + + int position = Integer.valueOf(formatString.substring(argStart, index)); + + // Arguments are not 0 indexed + if (position == 0) { + throw new IllegalArgumentException("Invalid replacement token"); + } + + // Convert position to 0 index + position--; + + boolean rest = false; + if (index < formatString.length() && formatString.charAt(index) == '-') { + rest = true; + // Move index past the - + index++; + } + + int end = index; + + if (required && position >= args.length) { + throw new IllegalArgumentException("Missing required argument " + (position + 1)); + } + + StringBuilder replacement = new StringBuilder(); + if (rest && position < args.length) { + for (int i = position; i < args.length; i++) { + if (i != position) { + replacement.append(' '); + } + replacement.append(args[i]); + } + } else if (position < args.length) { + replacement.append(args[position]); + } + + formatString = formatString.substring(0, start) + replacement.toString() + formatString.substring(end); + // Move index past the replaced data so we don't process it again + index = start + replacement.length(); + + // Move to the next replacement token + index = formatString.indexOf("$", index); + } + + return formatString; + } + + @Override // Spigot + public String getTimingName() {return "Command Forwarder - " + super.getTimingName();} // Spigot + + private static boolean inRange(int i, int j, int k) { + return i >= j && i <= k; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/MultipleCommandAlias.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/MultipleCommandAlias.java new file mode 100644 index 0000000..a0a4129 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/MultipleCommandAlias.java @@ -0,0 +1,33 @@ +package org.bukkit.command; + +/** + * Represents a command that delegates to one or more other commands + */ +public class MultipleCommandAlias extends Command { + private Command[] commands; + + public MultipleCommandAlias(String name, Command[] commands) { + super(name); + this.commands = commands; + } + + /** + * Gets the commands associated with the multi-command alias. + * + * @return commands associated with alias + */ + public Command[] getCommands() { + return commands; + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + boolean result = false; + + for (Command command : commands) { + result |= command.execute(sender, commandLabel, args); + } + + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginCommand.java new file mode 100644 index 0000000..597d7c2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginCommand.java @@ -0,0 +1,171 @@ +package org.bukkit.command; + +import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.plugin.Plugin; + +import java.util.List; + +/** + * Represents a {@link Command} belonging to a plugin + */ +public final class PluginCommand extends Command implements PluginIdentifiableCommand { + private final Plugin owningPlugin; + private CommandExecutor executor; + private TabCompleter completer; + + protected PluginCommand(String name, Plugin owner) { + super(name); + this.executor = owner; + this.owningPlugin = owner; + this.usageMessage = ""; + } + + /** + * Executes the command, returning its success + * + * @param sender Source object which is executing this command + * @param commandLabel The alias of the command used + * @param args All arguments passed to the command, split via ' ' + * @return true if the command was successful, otherwise false + */ + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + boolean success = false; + + if (!owningPlugin.isEnabled()) { + return false; + } + + if (!testPermission(sender)) { + return true; + } + + try { + success = executor.onCommand(sender, this, commandLabel, args); + } catch (Throwable ex) { + throw new CommandException("Unhandled exception executing command '" + commandLabel + "' in plugin " + owningPlugin.getDescription().getFullName(), ex); + } + + if (!success && usageMessage.length() > 0) { + for (String line : usageMessage.replace("", commandLabel).split("\n")) { + sender.sendMessage(line); + } + } + + return success; + } + + /** + * Sets the {@link CommandExecutor} to run when parsing this command + * + * @param executor New executor to run + */ + public void setExecutor(CommandExecutor executor) { + this.executor = executor == null ? owningPlugin : executor; + } + + /** + * Gets the {@link CommandExecutor} associated with this command + * + * @return CommandExecutor object linked to this command + */ + public CommandExecutor getExecutor() { + return executor; + } + + /** + * Sets the {@link TabCompleter} to run when tab-completing this command. + *

+ * If no TabCompleter is specified, and the command's executor implements + * TabCompleter, then the executor will be used for tab completion. + * + * @param completer New tab completer + */ + public void setTabCompleter(TabCompleter completer) { + this.completer = completer; + } + + /** + * Gets the {@link TabCompleter} associated with this command. + * + * @return TabCompleter object linked to this command + */ + public TabCompleter getTabCompleter() { + return completer; + } + + /** + * Gets the owner of this PluginCommand + * + * @return Plugin that owns this command + */ + public Plugin getPlugin() { + return owningPlugin; + } + + /** + * {@inheritDoc} + *

+ * Delegates to the tab completer if present. + *

+ * If it is not present or returns null, will delegate to the current + * command executor if it implements {@link TabCompleter}. If a non-null + * list has not been found, will default to standard player name + * completion in {@link + * Command#tabComplete(CommandSender, String, String[])}. + *

+ * This method does not consider permissions. + * + * @throws CommandException if the completer or executor throw an + * exception during the process of tab-completing. + * @throws IllegalArgumentException if sender, alias, or args is null + */ + @Override + public java.util.List tabComplete(CommandSender sender, String alias, String[] args) throws CommandException, IllegalArgumentException { + return tabComplete(sender, alias, args, null); // PaperSpigot - The code from this method has been (slightly modified) moved to the Location method. + } + + // PaperSpigot start - location tab-completes + /** + * This code was copied from tabComplete(CommandSender sender, String alias, String[] args) + */ + @Override + public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws CommandException, IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + List completions = null; + try { + if (completer != null) { + completions = completer.onTabComplete(sender, this, alias, args, location); // PaperSpigot - add location argument + } + if (completions == null && executor instanceof TabCompleter) { + completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args, location); // PaperSpigot - add location argument + } + } catch (Throwable ex) { + StringBuilder message = new StringBuilder(); + message.append("Unhandled exception during tab completion for command '/").append(alias).append(' '); + for (String arg : args) { + message.append(arg).append(' '); + } + message.deleteCharAt(message.length() - 1).append("' in plugin ").append(owningPlugin.getDescription().getFullName()); + throw new CommandException(message.toString(), ex); + } + + if (completions == null) { + return super.tabComplete(sender, alias, args); + } + return completions; + } + // PaperSpigot end + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(super.toString()); + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + stringBuilder.append(", ").append(owningPlugin.getDescription().getFullName()).append(')'); + return stringBuilder.toString(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginCommandYamlParser.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginCommandYamlParser.java new file mode 100644 index 0000000..5854583 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginCommandYamlParser.java @@ -0,0 +1,76 @@ +package org.bukkit.command; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +public class PluginCommandYamlParser { + + public static List parse(Plugin plugin) { + List pluginCmds = new ArrayList(); + + Map> map = plugin.getDescription().getCommands(); + + if (map == null) { + return pluginCmds; + } + + for (Entry> entry : map.entrySet()) { + if (entry.getKey().contains(":")) { + Bukkit.getServer().getLogger().severe("Could not load command " + entry.getKey() + " for plugin " + plugin.getName() + ": Illegal Characters"); + continue; + } + Command newCmd = new PluginCommand(entry.getKey(), plugin); + Object description = entry.getValue().get("description"); + Object usage = entry.getValue().get("usage"); + Object aliases = entry.getValue().get("aliases"); + Object permission = entry.getValue().get("permission"); + Object permissionMessage = entry.getValue().get("permission-message"); + + if (description != null) { + newCmd.setDescription(description.toString()); + } + + if (usage != null) { + newCmd.setUsage(usage.toString()); + } + + if (aliases != null) { + List aliasList = new ArrayList(); + + if (aliases instanceof List) { + for (Object o : (List) aliases) { + if (o.toString().contains(":")) { + Bukkit.getServer().getLogger().severe("Could not load alias " + o.toString() + " for plugin " + plugin.getName() + ": Illegal Characters"); + continue; + } + aliasList.add(o.toString()); + } + } else { + if (aliases.toString().contains(":")) { + Bukkit.getServer().getLogger().severe("Could not load alias " + aliases.toString() + " for plugin " + plugin.getName() + ": Illegal Characters"); + } else { + aliasList.add(aliases.toString()); + } + } + + newCmd.setAliases(aliasList); + } + + if (permission != null) { + newCmd.setPermission(permission.toString()); + } + + if (permissionMessage != null) { + newCmd.setPermissionMessage(permissionMessage.toString()); + } + + pluginCmds.add(newCmd); + } + return pluginCmds; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginIdentifiableCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginIdentifiableCommand.java new file mode 100644 index 0000000..c5e0d2c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/PluginIdentifiableCommand.java @@ -0,0 +1,19 @@ +package org.bukkit.command; + +import org.bukkit.plugin.Plugin; + +/** + * This interface is used by the help system to group commands into + * sub-indexes based on the {@link Plugin} they are a part of. Custom command + * implementations will need to implement this interface to have a sub-index + * automatically generated on the plugin's behalf. + */ +public interface PluginIdentifiableCommand { + + /** + * Gets the owner of this PluginIdentifiableCommand. + * + * @return Plugin that owns this PluginIdentifiableCommand. + */ + public Plugin getPlugin(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/ProxiedCommandSender.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/ProxiedCommandSender.java new file mode 100644 index 0000000..24c4eba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/ProxiedCommandSender.java @@ -0,0 +1,20 @@ + +package org.bukkit.command; + +public interface ProxiedCommandSender extends CommandSender { + + /** + * Returns the CommandSender which triggered this proxied command + * + * @return the caller which triggered the command + */ + CommandSender getCaller(); + + /** + * Returns the CommandSender which is being used to call the command + * + * @return the caller which the command is being run as + */ + CommandSender getCallee(); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/RemoteConsoleCommandSender.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/RemoteConsoleCommandSender.java new file mode 100644 index 0000000..dc3bc1d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/RemoteConsoleCommandSender.java @@ -0,0 +1,4 @@ +package org.bukkit.command; + +public interface RemoteConsoleCommandSender extends CommandSender { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/SimpleCommandMap.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/SimpleCommandMap.java new file mode 100644 index 0000000..4866e9f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/SimpleCommandMap.java @@ -0,0 +1,271 @@ +package org.bukkit.command; + +import lombok.Getter; +import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.command.defaults.*; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import java.util.*; +import java.util.regex.Pattern; + +import static org.bukkit.util.Java15Compat.Arrays_copyOfRange; + +public class SimpleCommandMap implements CommandMap { + private static final Pattern PATTERN_ON_SPACE = Pattern.compile(" ", Pattern.LITERAL); + @Getter protected final Map knownCommands = new HashMap(); + private final Server server; + + public SimpleCommandMap(final Server server) { + this.server = server; + setDefaultCommands(); + } + + 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 + } + + public void setFallbackCommands() { + register("bukkit", new HelpCommand()); + } + + /** + * {@inheritDoc} + */ + public void registerAll(String fallbackPrefix, List commands) { + if (commands != null) { + for (Command c : commands) { + register(fallbackPrefix, c); + } + } + } + + /** + * {@inheritDoc} + */ + public boolean register(String fallbackPrefix, Command command) { + return register(command.getName(), fallbackPrefix, command); + } + + /** + * {@inheritDoc} + */ + public boolean register(String label, String fallbackPrefix, Command command) { + command.timings = co.aikar.timings.TimingsManager.getCommandTiming(fallbackPrefix, command); // Spigot + label = label.toLowerCase().trim(); + fallbackPrefix = fallbackPrefix.toLowerCase().trim(); + boolean registered = register(label, command, false, fallbackPrefix); + + Iterator iterator = command.getAliases().iterator(); + while (iterator.hasNext()) { + if (!register(iterator.next(), command, true, fallbackPrefix)) { + iterator.remove(); + } + } + + // If we failed to register under the real name, we need to set the command label to the direct address + if (!registered) { + command.setLabel(fallbackPrefix + ":" + label); + } + + // Register to us so further updates of the commands label and aliases are postponed until its reregistered + command.register(this); + + return registered; + } + + /** + * Registers a command with the given name is possible. Also uses + * fallbackPrefix to create a unique name. + * + * @param label the name of the command, without the '/'-prefix. + * @param command the command to register + * @param isAlias whether the command is an alias + * @param fallbackPrefix a prefix which is prepended to the command for a + * unique address + * @return true if command was registered, false otherwise. + */ + private synchronized boolean register(String label, Command command, boolean isAlias, String fallbackPrefix) { + knownCommands.put(fallbackPrefix + ":" + label, command); + if ((command instanceof VanillaCommand || isAlias) && knownCommands.containsKey(label)) { + // Request is for an alias/fallback command and it conflicts with + // a existing command or previous alias ignore it + // Note: This will mean it gets removed from the commands list of active aliases + return false; + } + + boolean registered = true; + + // If the command exists but is an alias we overwrite it, otherwise we return + Command conflict = knownCommands.get(label); + if (conflict != null && conflict.getLabel().equals(label)) { + return false; + } + + if (!isAlias) { + command.setLabel(label); + } + knownCommands.put(label, command); + + return registered; + } + + /** + * {@inheritDoc} + */ + public boolean dispatch(CommandSender sender, String commandLine) throws CommandException { + String[] args = PATTERN_ON_SPACE.split(commandLine); + + if (args.length == 0) { + return false; + } + + String sentCommandLabel = args[0].toLowerCase(); + Command target = getCommand(sentCommandLabel); + + if (target == null) { + return false; + } + + try { + if(target.timings != null) target.timings.startTiming(); // Spigot + // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false) + target.execute(sender, sentCommandLabel, Arrays_copyOfRange(args, 1, args.length)); + if(target.timings != null) target.timings.stopTiming(); // Spigot + } catch (CommandException ex) { + if(target.timings != null) target.timings.stopTiming(); // Spigot + throw ex; + } catch (Throwable ex) { + if(target.timings != null) target.timings.stopTiming(); // Spigot + throw new CommandException("Unhandled exception executing '" + commandLine + "' in " + target, ex); + } + + // return true as command was handled + return true; + } + + public synchronized void clearCommands() { + for (Map.Entry entry : knownCommands.entrySet()) { + entry.getValue().unregister(this); + } + knownCommands.clear(); + setDefaultCommands(); + } + + public Command getCommand(String name) { + Command target = knownCommands.get(name.toLowerCase()); + return target; + } + + public List tabComplete(CommandSender sender, String cmdLine) { + return tabComplete(sender, cmdLine, null); // PaperSpigot - location tab-completes, code moved below + } + + // PaperSpigot start - location tab-completes + /* + this code was copied, except for the noted change, from tabComplete(CommandSender sender, String cmdLine) + */ + public List tabComplete(CommandSender sender, String cmdLine, Location location) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(cmdLine, "Command line cannot null"); + + int spaceIndex = cmdLine.indexOf(' '); + + if (spaceIndex == -1) { + ArrayList completions = new ArrayList(); + Map knownCommands = this.knownCommands; + + final String prefix = (sender instanceof Player ? "/" : ""); + + for (Map.Entry commandEntry : knownCommands.entrySet()) { + Command command = commandEntry.getValue(); + + if (!command.testPermissionSilent(sender)) { + continue; + } + + String name = commandEntry.getKey(); // Use the alias, not command name + + if (StringUtil.startsWithIgnoreCase(name, cmdLine)) { + completions.add(prefix + name); + } + } + + Collections.sort(completions, String.CASE_INSENSITIVE_ORDER); + return completions; + } + + String commandName = cmdLine.substring(0, spaceIndex); + Command target = getCommand(commandName); + + if (target == null) { + return null; + } + + if (!target.testPermissionSilent(sender)) { + return null; + } + + String argLine = cmdLine.substring(spaceIndex + 1); + String[] args = PATTERN_ON_SPACE.split(argLine, -1); + + try { + return target.tabComplete(sender, commandName, args, location); // PaperSpigot - add location argument + } catch (CommandException ex) { + throw ex; + } catch (Throwable ex) { + throw new CommandException("Unhandled exception executing tab-completer for '" + cmdLine + "' in " + target, ex); + } + } + // PaperSpigot end + + public Collection getCommands() { + return Collections.unmodifiableCollection(knownCommands.values()); + } + + public void registerServerAliases() { + Map values = server.getCommandAliases(); + + for (String alias : values.keySet()) { + if (alias.contains(":") || alias.contains(" ")) { + server.getLogger().warning("Could not register alias " + alias + " because it contains illegal characters"); + continue; + } + + String[] commandStrings = values.get(alias); + List targets = new ArrayList(); + StringBuilder bad = new StringBuilder(); + + for (String commandString : commandStrings) { + String[] commandArgs = commandString.split(" "); + Command command = getCommand(commandArgs[0]); + + if (command == null) { + if (bad.length() > 0) { + bad.append(", "); + } + bad.append(commandString); + } else { + targets.add(commandString); + } + } + + if (bad.length() > 0) { + server.getLogger().warning("Could not register alias " + alias + " because it contains commands that do not exist: " + bad); + continue; + } + + // We register these as commands so they have absolute priority. + if (targets.size() > 0) { + knownCommands.put(alias.toLowerCase(), new FormattedCommandAlias(alias.toLowerCase(), targets.toArray(new String[targets.size()]))); + } else { + knownCommands.remove(alias.toLowerCase()); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabCommandExecutor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabCommandExecutor.java new file mode 100644 index 0000000..d24d795 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabCommandExecutor.java @@ -0,0 +1,16 @@ +package org.bukkit.command; + +import java.util.List; + +/** + * Represents a class which can handle command tab completion and commands + * + * @deprecated Remains for plugins that would have implemented it even without + * functionality + * @see TabExecutor + */ +@Deprecated +public interface TabCommandExecutor extends CommandExecutor { + public List onTabComplete(); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabCompleter.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabCompleter.java new file mode 100644 index 0000000..2cb971c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabCompleter.java @@ -0,0 +1,30 @@ +package org.bukkit.command; + +import org.bukkit.Location; + +import java.util.List; + +/** + * Represents a class which can suggest tab completions for commands. + */ +public interface TabCompleter { + + /** + * Requests a list of possible completions for a command argument. + * + * @param sender Source of the command + * @param command Command which was executed + * @param alias The alias used + * @param args The arguments passed to the command, including final + * partial argument to be completed and command label + * @return A List of possible completions for the final argument, or null + * to default to the command executor + */ + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args); + + // PaperSpigot start - location tab-completes + default List onTabComplete(CommandSender sender, Command command, String alias, String[] args, Location location) { + return onTabComplete(sender, command, alias, args); + } + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabExecutor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabExecutor.java new file mode 100644 index 0000000..6b8e3fb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/TabExecutor.java @@ -0,0 +1,8 @@ +package org.bukkit.command; + +/** + * This class is provided as a convenience to implement both TabCompleter and + * CommandExecutor. + */ +public interface TabExecutor extends TabCompleter, CommandExecutor { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/AchievementCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/AchievementCommand.java new file mode 100644 index 0000000..c2e1795 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/AchievementCommand.java @@ -0,0 +1,188 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Achievement; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Statistic; +import org.bukkit.Material; +import org.bukkit.Statistic.Type; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerAchievementAwardedEvent; +import org.bukkit.event.player.PlayerStatisticIncrementEvent; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class AchievementCommand extends VanillaCommand { + public AchievementCommand() { + super("achievement"); + this.description = "Gives the specified player an achievement or changes a statistic value. Use '*' to give all achievements."; + this.usageMessage = "/achievement give [player]"; + this.setPermission("bukkit.command.achievement"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + if (args.length < 2) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + if (!args[0].equalsIgnoreCase("give")) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + String statisticString = args[1]; + Player player = null; + + if (args.length > 2) { + player = Bukkit.getPlayer(args[1]); + } else if (sender instanceof Player) { + player = (Player) sender; + } + + if (player == null) { + sender.sendMessage("You must specify which player you wish to perform this action on."); + return true; + } + + if (statisticString.equals("*")) { + for (Achievement achievement : Achievement.values()) { + if (player.hasAchievement(achievement)) { + continue; + } + PlayerAchievementAwardedEvent event = new PlayerAchievementAwardedEvent(player, achievement); + Bukkit.getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) { + player.awardAchievement(achievement); + } + } + Command.broadcastCommandMessage(sender, String.format("Successfully given all achievements to %s", player.getName())); + return true; + } + + Achievement achievement = Bukkit.getUnsafe().getAchievementFromInternalName(statisticString); + Statistic statistic = Bukkit.getUnsafe().getStatisticFromInternalName(statisticString); + + if (achievement != null) { + if (player.hasAchievement(achievement)) { + sender.sendMessage(String.format("%s already has achievement %s", player.getName(), statisticString)); + return true; + } + + PlayerAchievementAwardedEvent event = new PlayerAchievementAwardedEvent(player, achievement); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + sender.sendMessage(String.format("Unable to award %s the achievement %s", player.getName(), statisticString)); + return true; + } + player.awardAchievement(achievement); + + Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString)); + return true; + } + + if (statistic == null) { + sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString)); + return true; + } + + if (statistic.getType() == Type.UNTYPED) { + PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName())); + return true; + } + player.incrementStatistic(statistic); + Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString)); + return true; + } + + if (statistic.getType() == Type.ENTITY) { + EntityType entityType = EntityType.fromName(statisticString.substring(statisticString.lastIndexOf(".") + 1)); + + if (entityType == null) { + sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString)); + return true; + } + + PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1, entityType); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName())); + return true; + } + + try { + player.incrementStatistic(statistic, entityType); + } catch (IllegalArgumentException e) { + sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString)); + return true; + } + } else { + int id; + try { + id = getInteger(sender, statisticString.substring(statisticString.lastIndexOf(".") + 1), 0, Integer.MAX_VALUE, true); + } catch (NumberFormatException e) { + sender.sendMessage(e.getMessage()); + return true; + } + + Material material = Material.getMaterial(id); + + if (material == null) { + sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString)); + return true; + } + + PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1, material); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName())); + return true; + } + + try { + player.incrementStatistic(statistic, material); + } catch (IllegalArgumentException e) { + sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString)); + return true; + } + } + + Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString)); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return Arrays.asList("give"); + } + + if (args.length == 2) { + return Bukkit.getUnsafe().tabCompleteInternalStatisticOrAchievementName(args[1], new ArrayList()); + } + + if (args.length == 3) { + return super.tabComplete(sender, alias, args); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanCommand.java new file mode 100644 index 0000000..59b804c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanCommand.java @@ -0,0 +1,56 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.bukkit.BanList; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class BanCommand extends VanillaCommand { + public BanCommand() { + super("ban"); + this.description = "Prevents the specified player from using this server"; + this.usageMessage = "/ban [reason ...]"; + this.setPermission("bukkit.command.ban.player"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + String reason = args.length > 0 ? StringUtils.join(args, ' ', 1, args.length) : null; + Bukkit.getBanList(BanList.Type.NAME).addBan(args[0], reason, null, sender.getName()); + + Player player = Bukkit.getPlayer(args[0]); + if (player != null) { + player.kickPlayer("Banned by admin."); + } + + Command.broadcastCommandMessage(sender, "Banned player " + args[0]); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length >= 1) { + return super.tabComplete(sender, alias, args); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanIpCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanIpCommand.java new file mode 100644 index 0000000..9fcd046 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanIpCommand.java @@ -0,0 +1,78 @@ +package org.bukkit.command.defaults; + +import java.util.List; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.bukkit.BanList; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class BanIpCommand extends VanillaCommand { + public static final Pattern ipValidity = Pattern.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"); + + public BanIpCommand() { + super("ban-ip"); + this.description = "Prevents the specified IP address from using this server"; + this.usageMessage = "/ban-ip [reason ...]"; + this.setPermission("bukkit.command.ban.ip"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length < 1) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + String reason = args.length > 0 ? StringUtils.join(args, ' ', 1, args.length) : null; + + if (ipValidity.matcher(args[0]).matches()) { + processIPBan(args[0], sender, reason); + } else { + Player player = Bukkit.getPlayer(args[0]); + + if (player == null) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + processIPBan(player.getAddress().getAddress().getHostAddress(), sender, reason); + } + + return true; + } + + private void processIPBan(String ip, CommandSender sender, String reason) { + Bukkit.getBanList(BanList.Type.IP).addBan(ip, reason, null, sender.getName()); + + // Find all matching players and kick + for (Player player : Bukkit.getOnlinePlayers()) { + if (player.getAddress().getAddress().getHostAddress().equals(ip)) { + player.kickPlayer("You have been IP banned."); + } + } + + Command.broadcastCommandMessage(sender, "Banned IP Address " + ip); + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return super.tabComplete(sender, alias, args); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanListCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanListCommand.java new file mode 100644 index 0000000..f8d32df --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BanListCommand.java @@ -0,0 +1,74 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.apache.commons.lang.Validate; +import org.bukkit.BanEntry; +import org.bukkit.BanList; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class BanListCommand extends VanillaCommand { + private static final List BANLIST_TYPES = ImmutableList.of("ips", "players"); + + public BanListCommand() { + super("banlist"); + this.description = "View all players banned from this server"; + this.usageMessage = "/banlist [ips|players]"; + this.setPermission("bukkit.command.ban.list"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + BanList.Type banType = BanList.Type.NAME; + if (args.length > 0) { + if (args[0].equalsIgnoreCase("ips")) { + banType = BanList.Type.IP; + } else if (!args[0].equalsIgnoreCase("players")) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + } + + StringBuilder message = new StringBuilder(); + BanEntry[] banlist = Bukkit.getBanList(banType).getBanEntries().toArray(new BanEntry[0]); + + for (int x = 0; x < banlist.length; x++) { + if (x != 0) { + if (x == banlist.length - 1) { + message.append(" and "); + } else { + message.append(", "); + } + } + + message.append(banlist[x].getTarget()); + } + + sender.sendMessage("There are " + banlist.length + " total banned players:"); + sender.sendMessage(message.toString()); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], BANLIST_TYPES, new ArrayList(BANLIST_TYPES.size())); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BukkitCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BukkitCommand.java new file mode 100644 index 0000000..23c8580 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/BukkitCommand.java @@ -0,0 +1,15 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.bukkit.command.Command; + +public abstract class BukkitCommand extends Command { + protected BukkitCommand(String name) { + super(name); + } + + protected BukkitCommand(String name, String description, String usageMessage, List aliases) { + super(name, description, usageMessage, aliases); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ClearCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ClearCommand.java new file mode 100644 index 0000000..05317e1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ClearCommand.java @@ -0,0 +1,115 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Deprecated +public class ClearCommand extends VanillaCommand { + private static List materials; + static { + ArrayList materialList = new ArrayList(); + for (Material material : Material.values()) { + materialList.add(material.name()); + } + Collections.sort(materialList); + materials = ImmutableList.copyOf(materialList); + } + + public ClearCommand() { + super("clear"); + this.description = "Clears the player's inventory. Can specify item and data filters too."; + this.usageMessage = "/clear [item] [data]"; + this.setPermission("bukkit.command.clear"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + Player player = null; + if (args.length > 0) { + player = Bukkit.getPlayer(args[0]); + } else if (sender instanceof Player) { + player = (Player) sender; + } + + if (player != null) { + int id; + + if (args.length > 1 && !(args[1].equals("-1"))) { + Material material = Material.matchMaterial(args[1]); + if (material == null) { + sender.sendMessage(ChatColor.RED + "There's no item called " + args[1]); + return false; + } + + id = material.getId(); + } else { + id = -1; + } + + int data = args.length >= 3 ? getInteger(sender, args[2], 0) : -1; + int count = player.getInventory().clear(id, data); + + Command.broadcastCommandMessage(sender, "Cleared the inventory of " + player.getDisplayName() + ", removing " + count + " items"); + } else if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "Please provide a player!"); + } else { + sender.sendMessage(ChatColor.RED + "Can't find player " + args[0]); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return super.tabComplete(sender, alias, args); + } + if (args.length == 2) { + final String arg = args[1]; + final List materials = ClearCommand.materials; + List completion = null; + + final int size = materials.size(); + int i = Collections.binarySearch(materials, arg, String.CASE_INSENSITIVE_ORDER); + + if (i < 0) { + // Insertion (start) index + i = -1 - i; + } + + for ( ; i < size; i++) { + String material = materials.get(i); + if (StringUtil.startsWithIgnoreCase(material, arg)) { + if (completion == null) { + completion = new ArrayList(); + } + completion.add(material); + } else { + break; + } + } + + if (completion != null) { + return completion; + } + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DefaultGameModeCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DefaultGameModeCommand.java new file mode 100644 index 0000000..f217aea --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DefaultGameModeCommand.java @@ -0,0 +1,71 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class DefaultGameModeCommand extends VanillaCommand { + private static final List GAMEMODE_NAMES = ImmutableList.of("adventure", "creative", "survival"); + + public DefaultGameModeCommand() { + super("defaultgamemode"); + this.description = "Set the default gamemode"; + this.usageMessage = "/defaultgamemode "; + this.setPermission("bukkit.command.defaultgamemode"); + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + if (!testPermission(sender)) return true; + if (args.length == 0) { + sender.sendMessage("Usage: " + usageMessage); + return false; + } + + String modeArg = args[0]; + int value = -1; + + try { + value = Integer.parseInt(modeArg); + } catch (NumberFormatException ex) {} + + GameMode mode = GameMode.getByValue(value); + + if (mode == null) { + if (modeArg.equalsIgnoreCase("creative") || modeArg.equalsIgnoreCase("c")) { + mode = GameMode.CREATIVE; + } else if (modeArg.equalsIgnoreCase("adventure") || modeArg.equalsIgnoreCase("a")) { + mode = GameMode.ADVENTURE; + } else { + mode = GameMode.SURVIVAL; + } + } + + Bukkit.getServer().setDefaultGameMode(mode); + Command.broadcastCommandMessage(sender, "Default game mode set to " + mode.toString().toLowerCase()); + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], GAMEMODE_NAMES, new ArrayList(GAMEMODE_NAMES.size())); + } + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DeopCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DeopCommand.java new file mode 100644 index 0000000..86be15e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DeopCommand.java @@ -0,0 +1,63 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class DeopCommand extends VanillaCommand { + public DeopCommand() { + super("deop"); + this.description = "Takes the specified player's operator status"; + this.usageMessage = "/deop "; + this.setPermission("bukkit.command.op.take"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length != 1 || args[0].length() == 0) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + OfflinePlayer player = Bukkit.getOfflinePlayer(args[0]); + player.setOp(false); + + if (player instanceof Player) { + ((Player) player).sendMessage(ChatColor.YELLOW + "You are no longer op!"); + } + + Command.broadcastCommandMessage(sender, "De-opped " + args[0]); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + List completions = new ArrayList(); + for (OfflinePlayer player : Bukkit.getOperators()) { + String playerName = player.getName(); + if (StringUtil.startsWithIgnoreCase(playerName, args[0])) { + completions.add(playerName); + } + } + return completions; + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DifficultyCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DifficultyCommand.java new file mode 100644 index 0000000..74a8ac2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/DifficultyCommand.java @@ -0,0 +1,82 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; +import org.bukkit.Difficulty; + +import java.util.ArrayList; +import java.util.List; + +@Deprecated +public class DifficultyCommand extends VanillaCommand { + private static final List DIFFICULTY_NAMES = ImmutableList.of("peaceful", "easy", "normal", "hard"); + + public DifficultyCommand() { + super("difficulty"); + this.description = "Sets the game difficulty"; + this.usageMessage = "/difficulty "; + this.setPermission("bukkit.command.difficulty"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length != 1 || args[0].length() == 0) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + Difficulty difficulty = Difficulty.getByValue(getDifficultyForString(sender, args[0])); + + if (Bukkit.isHardcore()) { + difficulty = Difficulty.HARD; + } + + Bukkit.getWorlds().get(0).setDifficulty(difficulty); + + int levelCount = 1; + if (Bukkit.getAllowNether()) { + Bukkit.getWorlds().get(levelCount).setDifficulty(difficulty); + levelCount++; + } + + if (Bukkit.getAllowEnd()) { + Bukkit.getWorlds().get(levelCount).setDifficulty(difficulty); + } + + Command.broadcastCommandMessage(sender, "Set difficulty to " + difficulty.toString()); + return true; + } + + protected int getDifficultyForString(CommandSender sender, String name) { + if (name.equalsIgnoreCase("peaceful") || name.equalsIgnoreCase("p")) { + return 0; + } else if (name.equalsIgnoreCase("easy") || name.equalsIgnoreCase("e")) { + return 1; + } else if (name.equalsIgnoreCase("normal") || name.equalsIgnoreCase("n")) { + return 2; + } else if (name.equalsIgnoreCase("hard") || name.equalsIgnoreCase("h")) { + return 3; + } else { + return getInteger(sender, name, 0, 3); + } + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], DIFFICULTY_NAMES, new ArrayList(DIFFICULTY_NAMES.size())); + } + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/EffectCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/EffectCommand.java new file mode 100644 index 0000000..de63bbe --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/EffectCommand.java @@ -0,0 +1,120 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.ImmutableList; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.StringUtil; + +@Deprecated +public class EffectCommand extends VanillaCommand { + private static final List effects; + + public EffectCommand() { + super("effect"); + this.description = "Adds/Removes effects on players"; + this.usageMessage = "/effect [seconds] [amplifier]"; + this.setPermission("bukkit.command.effect"); + } + + static { + ImmutableList.Builder builder = ImmutableList.builder(); + + for (PotionEffectType type : PotionEffectType.values()) { + if (type != null) { + builder.add(type.getName()); + } + } + + effects = builder.build(); + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + if (!testPermission(sender)) { + return true; + } + + if (args.length < 2) { + sender.sendMessage(getUsage()); + return true; + } + + final Player player = sender.getServer().getPlayer(args[0]); + + if (player == null) { + sender.sendMessage(ChatColor.RED + String.format("Player, %s, not found", args[0])); + return true; + } + + if ("clear".equalsIgnoreCase(args[1])) { + for (PotionEffect effect : player.getActivePotionEffects()) { + player.removePotionEffect(effect.getType()); + } + sender.sendMessage(String.format("Took all effects from %s", args[0])); + return true; + } + + PotionEffectType effect = PotionEffectType.getByName(args[1]); + + if (effect == null) { + effect = PotionEffectType.getById(getInteger(sender, args[1], 0)); + } + + if (effect == null) { + sender.sendMessage(ChatColor.RED + String.format("Effect, %s, not found", args[1])); + return true; + } + + int duration = 600; + int duration_temp = 30; + int amplification = 0; + + if (args.length >= 3) { + duration_temp = getInteger(sender, args[2], 0, 1000000); + if (effect.isInstant()) { + duration = duration_temp; + } else { + duration = duration_temp * 20; + } + } else if (effect.isInstant()) { + duration = 1; + } + + if (args.length >= 4) { + amplification = getInteger(sender, args[3], 0, 255); + } + + if (duration_temp == 0) { + if (!player.hasPotionEffect(effect)) { + sender.sendMessage(String.format("Couldn't take %s from %s as they do not have the effect", effect.getName(), args[0])); + return true; + } + + player.removePotionEffect(effect); + broadcastCommandMessage(sender, String.format("Took %s from %s", effect.getName(), args[0])); + } else { + final PotionEffect applyEffect = new PotionEffect(effect, duration, amplification); + + player.addPotionEffect(applyEffect, true); + broadcastCommandMessage(sender, String.format("Given %s (ID %d) * %d to %s for %d seconds", effect.getName(), effect.getId(), amplification, args[0], duration_temp)); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String commandLabel, String[] args) { + if (args.length == 1) { + return super.tabComplete(sender, commandLabel, args); + } else if (args.length == 2) { + return StringUtil.copyPartialMatches(args[1], effects, new ArrayList(effects.size())); + } + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/EnchantCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/EnchantCommand.java new file mode 100644 index 0000000..5f0b686 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/EnchantCommand.java @@ -0,0 +1,170 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.Validate; +import org.apache.commons.lang.WordUtils; +import com.google.common.collect.ImmutableList; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.StringUtil; + +@Deprecated +public class EnchantCommand extends VanillaCommand { + private static final List ENCHANTMENT_NAMES = new ArrayList(); + + public EnchantCommand() { + super("enchant"); + this.description = "Adds enchantments to the item the player is currently holding. Specify 0 for the level to remove an enchantment. Specify force to ignore normal enchantment restrictions"; + this.usageMessage = "/enchant [level|max|0] [force]"; + this.setPermission("bukkit.command.enchant"); + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + if (!testPermission(sender)) return true; + if (args.length < 2) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + boolean force = false; + if (args.length > 2) { + force = args[args.length > 3 ? 3 : 2].equalsIgnoreCase("force"); + } + + Player player = Bukkit.getPlayerExact(args[0]); + if (player == null) { + sender.sendMessage("Can't find player " + args[0]); + } else { + ItemStack item = player.getItemInHand(); + if (item.getType() == Material.AIR) { + sender.sendMessage("The player isn't holding an item"); + } else { + String itemName = item.getType().toString().replaceAll("_", " "); + itemName = WordUtils.capitalizeFully(itemName); + + Enchantment enchantment = getEnchantment(args[1].toUpperCase()); + if (enchantment == null) { + sender.sendMessage(String.format("Enchantment does not exist: %s", args[1])); + } else { + String enchantmentName = enchantment.getName().replaceAll("_", " "); + enchantmentName = WordUtils.capitalizeFully(enchantmentName); + + if (!force && !enchantment.canEnchantItem(item)) { + sender.sendMessage(String.format("%s cannot be applied to %s", enchantmentName, itemName)); + } else { + int level = 1; + if (args.length > 2) { + Integer integer = getInteger(args[2]); + int minLevel = enchantment.getStartLevel(); + int maxLevel = force ? Short.MAX_VALUE : enchantment.getMaxLevel(); + + if (integer != null) { + if (integer == 0) { + item.removeEnchantment(enchantment); + Command.broadcastCommandMessage(sender, String.format("Removed %s on %s's %s", enchantmentName, player.getName(), itemName)); + return true; + } + + if (integer < minLevel || integer > maxLevel) { + sender.sendMessage(String.format("Level for enchantment %s must be between %d and %d", enchantmentName, minLevel, maxLevel)); + sender.sendMessage("Specify 0 for level to remove an enchantment"); + return true; + } + + level = integer; + } + + if ("max".equals(args[2])) { + level = maxLevel; + } + } + + Map enchantments = item.getEnchantments(); + boolean conflicts = false; + + if (!force && !enchantments.isEmpty()) { // TODO: Improve this to use a "hasEnchantments" call + for (Map.Entry entry : enchantments.entrySet()) { + Enchantment enchant = entry.getKey(); + + if (enchant.equals(enchantment)) continue; + if (enchant.conflictsWith(enchantment)) { + sender.sendMessage(String.format("Can't apply the enchantment %s on an item with the enchantment %s", enchantmentName, WordUtils.capitalizeFully(enchant.getName().replaceAll("_", " ")))); + conflicts = true; + break; + } + } + } + + if (!conflicts) { + item.addUnsafeEnchantment(enchantment, level); + + Command.broadcastCommandMessage(sender, String.format("Applied %s (Lvl %d) on %s's %s", enchantmentName, level, player.getName(), itemName), false); + sender.sendMessage(String.format("Enchanting succeeded, applied %s (Lvl %d) onto your %s", enchantmentName, level, itemName)); + } + } + } + } + } + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return super.tabComplete(sender, alias, args); + } + + if (args.length == 2) { + return StringUtil.copyPartialMatches(args[1], ENCHANTMENT_NAMES, new ArrayList(ENCHANTMENT_NAMES.size())); + } + + if (args.length == 3 || args.length == 4) { + if (!args[args.length - 2].equalsIgnoreCase("force")) { + return ImmutableList.of("force"); + } + } + + return ImmutableList.of(); + } + + private Enchantment getEnchantment(String lookup) { + Enchantment enchantment = Enchantment.getByName(lookup); + + if (enchantment == null) { + Integer id = getInteger(lookup); + if (id != null) { + enchantment = Enchantment.getById(id); + } + } + + return enchantment; + } + + public static void buildEnchantments() { + if (!ENCHANTMENT_NAMES.isEmpty()) { + throw new IllegalStateException("Enchantments have already been built!"); + } + + for (Enchantment enchantment : Enchantment.values()) { + ENCHANTMENT_NAMES.add(enchantment.getName()); + } + + Collections.sort(ENCHANTMENT_NAMES); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ExpCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ExpCommand.java new file mode 100644 index 0000000..aa33c0c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ExpCommand.java @@ -0,0 +1,90 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class ExpCommand extends VanillaCommand { + public ExpCommand() { + super("xp"); + this.description = "Gives the specified player a certain amount of experience. Specify L to give levels instead, with a negative amount resulting in taking levels."; + this.usageMessage = "/xp [player] OR /xp L [player]"; + this.setPermission("bukkit.command.xp"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + if (args.length > 0) { + String inputAmount = args[0]; + Player player = null; + + boolean isLevel = inputAmount.endsWith("l") || inputAmount.endsWith("L"); + if (isLevel && inputAmount.length() > 1) { + inputAmount = inputAmount.substring(0, inputAmount.length() - 1); + } + + int amount = getInteger(sender, inputAmount, Integer.MIN_VALUE, Integer.MAX_VALUE); + boolean isTaking = amount < 0; + + if (isTaking) { + amount *= -1; + } + + if (args.length > 1) { + player = Bukkit.getPlayer(args[1]); + } else if (sender instanceof Player) { + player = (Player) sender; + } + + if (player != null) { + if (isLevel) { + if (isTaking) { + player.giveExpLevels(-amount); + Command.broadcastCommandMessage(sender, "Taken " + amount + " level(s) from " + player.getName()); + } else { + player.giveExpLevels(amount); + Command.broadcastCommandMessage(sender, "Given " + amount + " level(s) to " + player.getName()); + } + } else { + if (isTaking) { + sender.sendMessage(ChatColor.RED + "Taking experience can only be done by levels, cannot give players negative experience points"); + return false; + } else { + player.giveExp(amount); + Command.broadcastCommandMessage(sender, "Given " + amount + " experience to " + player.getName()); + } + } + } else { + sender.sendMessage("Can't find player, was one provided?\n" + ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + return true; + } + + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 2) { + return super.tabComplete(sender, alias, args); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GameModeCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GameModeCommand.java new file mode 100644 index 0000000..f9675a0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GameModeCommand.java @@ -0,0 +1,101 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class GameModeCommand extends VanillaCommand { + private static final List GAMEMODE_NAMES = ImmutableList.of("adventure", "creative", "survival", "spectator"); + + public GameModeCommand() { + super("gamemode"); + this.description = "Changes the player to a specific game mode"; + this.usageMessage = "/gamemode [player]"; + this.setPermission("bukkit.command.gamemode"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + String modeArg = args[0]; + String playerArg = sender.getName(); + + if (args.length == 2) { + playerArg = args[1]; + } + + Player player = Bukkit.getPlayerExact(playerArg); + + if (player != null) { + int value = -1; + + try { + value = Integer.parseInt(modeArg); + } catch (NumberFormatException ex) {} + + GameMode mode = GameMode.getByValue(value); + + if (mode == null) { + if (modeArg.equalsIgnoreCase("creative") || modeArg.equalsIgnoreCase("c")) { + mode = GameMode.CREATIVE; + } else if (modeArg.equalsIgnoreCase("adventure") || modeArg.equalsIgnoreCase("a")) { + mode = GameMode.ADVENTURE; + } else if (modeArg.equalsIgnoreCase("spectator") || modeArg.equalsIgnoreCase("sp")) { + mode = GameMode.SPECTATOR; + } else { + mode = GameMode.SURVIVAL; + } + } + + if (mode != player.getGameMode()) { + player.setGameMode(mode); + + if (mode != player.getGameMode()) { + sender.sendMessage("Game mode change for " + player.getName() + " failed!"); + } else { + if (player == sender) { + Command.broadcastCommandMessage(sender, "Set own game mode to " + mode.toString() + " mode"); + } else { + Command.broadcastCommandMessage(sender, "Set " + player.getName() + "'s game mode to " + mode.toString() + " mode"); + } + } + } else { + sender.sendMessage(player.getName() + " already has game mode " + mode.getValue()); + } + } else { + sender.sendMessage("Can't find player " + playerArg); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], GAMEMODE_NAMES, new ArrayList(GAMEMODE_NAMES.size())); + } else if (args.length == 2) { + return super.tabComplete(sender, alias, args); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GameRuleCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GameRuleCommand.java new file mode 100644 index 0000000..13e2589 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GameRuleCommand.java @@ -0,0 +1,89 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.Validate; +import org.bukkit.ChatColor; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.HumanEntity; + +@Deprecated +public class GameRuleCommand extends VanillaCommand { + private static final List GAMERULE_STATES = ImmutableList.of("true", "false"); + + public GameRuleCommand() { + super("gamerule"); + this.description = "Sets a server's game rules"; + this.usageMessage = "/gamerule OR /gamerule "; + this.setPermission("bukkit.command.gamerule"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + if (args.length > 0) { + String rule = args[0]; + World world = getGameWorld(sender); + + if (world.isGameRule(rule)) { + if (args.length > 1) { + String value = args[1]; + + world.setGameRuleValue(rule, value); + Command.broadcastCommandMessage(sender, "Game rule " + rule + " has been set to: " + value); + } else { + String value = world.getGameRuleValue(rule); + sender.sendMessage(rule + " = " + value); + } + } else { + sender.sendMessage(ChatColor.RED + "No game rule called " + rule + " is available"); + } + + return true; + } else { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + sender.sendMessage("Rules: " + this.createString(getGameWorld(sender).getGameRules(), 0, ", ")); + + return true; + } + } + + private World getGameWorld(CommandSender sender) { + if (sender instanceof HumanEntity) { + World world = ((HumanEntity) sender).getWorld(); + if (world != null) { + return world; + } + } else if (sender instanceof BlockCommandSender) { + return ((BlockCommandSender) sender).getBlock().getWorld(); + } + + return Bukkit.getWorlds().get(0); + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], Arrays.asList(getGameWorld(sender).getGameRules()), new ArrayList()); + } + + if (args.length == 2) { + return StringUtil.copyPartialMatches(args[1], GAMERULE_STATES, new ArrayList(GAMERULE_STATES.size())); + } + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GiveCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GiveCommand.java new file mode 100644 index 0000000..c8b7f0f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/GiveCommand.java @@ -0,0 +1,130 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.StringUtil; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; + +@Deprecated +public class GiveCommand extends VanillaCommand { + private static List materials; + static { + ArrayList materialList = new ArrayList(); + for (Material material : Material.values()) { + materialList.add(material.name()); + } + Collections.sort(materialList); + materials = ImmutableList.copyOf(materialList); + } + + public GiveCommand() { + super("give"); + this.description = "Gives the specified player a certain amount of items"; + this.usageMessage = "/give [amount [data]]"; + this.setPermission("bukkit.command.give"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if ((args.length < 2)) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + Player player = Bukkit.getPlayerExact(args[0]); + + if (player != null) { + Material material = Material.matchMaterial(args[1]); + + if (material == null) { + material = Bukkit.getUnsafe().getMaterialFromInternalName(args[1]); + } + + if (material != null) { + int amount = 1; + short data = 0; + + if (args.length >= 3) { + amount = this.getInteger(sender, args[2], 1, 64); + + if (args.length >= 4) { + try { + data = Short.parseShort(args[3]); + } catch (NumberFormatException ex) {} + } + } + + ItemStack stack = new ItemStack(material, amount, data); + + if (args.length >= 5) { + try { + stack = Bukkit.getUnsafe().modifyItemStack(stack, Joiner.on(' ').join(Arrays.asList(args).subList(4, args.length))); + } catch (Throwable t) { + player.sendMessage("Not a valid tag"); + return true; + } + } + + player.getInventory().addItem(stack); + + Command.broadcastCommandMessage(sender, "Gave " + player.getName() + " some " + material.getId() + " (" + material + ")"); + } else { + sender.sendMessage("There's no item called " + args[1]); + } + } else { + sender.sendMessage("Can't find player " + args[0]); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return super.tabComplete(sender, alias, args); + } + if (args.length == 2) { + final String arg = args[1]; + final List materials = GiveCommand.materials; + List completion = new ArrayList(); + + final int size = materials.size(); + int i = Collections.binarySearch(materials, arg, String.CASE_INSENSITIVE_ORDER); + + if (i < 0) { + // Insertion (start) index + i = -1 - i; + } + + for ( ; i < size; i++) { + String material = materials.get(i); + if (StringUtil.startsWithIgnoreCase(material, arg)) { + completion.add(material); + } else { + break; + } + } + + return Bukkit.getUnsafe().tabCompleteInternalMaterialName(arg, completion); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/HelpCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/HelpCommand.java new file mode 100644 index 0000000..8093d18 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/HelpCommand.java @@ -0,0 +1,228 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.apache.commons.lang.math.NumberUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.help.HelpMap; +import org.bukkit.help.HelpTopic; +import org.bukkit.help.HelpTopicComparator; +import org.bukkit.help.IndexHelpTopic; +import org.bukkit.util.ChatPaginator; + +import com.google.common.collect.ImmutableList; + +public class HelpCommand extends VanillaCommand { + public HelpCommand() { + super("help"); + this.description = "Shows the help menu"; + this.usageMessage = "/help \n/help \n/help "; + this.setAliases(Arrays.asList(new String[] { "?" })); + this.setPermission("group.admin"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + String command; + int pageNumber; + int pageHeight; + int pageWidth; + + if (args.length == 0) { + command = ""; + pageNumber = 1; + } else if (NumberUtils.isDigits(args[args.length - 1])) { + command = StringUtils.join(ArrayUtils.subarray(args, 0, args.length - 1), " "); + try { + pageNumber = NumberUtils.createInteger(args[args.length - 1]); + } catch (NumberFormatException exception) { + pageNumber = 1; + } + if (pageNumber <= 0) { + pageNumber = 1; + } + } else { + command = StringUtils.join(args, " "); + pageNumber = 1; + } + + if (sender instanceof ConsoleCommandSender) { + pageHeight = ChatPaginator.UNBOUNDED_PAGE_HEIGHT; + pageWidth = ChatPaginator.UNBOUNDED_PAGE_WIDTH; + } else { + pageHeight = ChatPaginator.CLOSED_CHAT_PAGE_HEIGHT - 1; + pageWidth = ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH; + } + + HelpMap helpMap = Bukkit.getServer().getHelpMap(); + HelpTopic topic = helpMap.getHelpTopic(command); + + if (topic == null) { + topic = helpMap.getHelpTopic("/" + command); + } + + if (topic == null) { + topic = findPossibleMatches(command); + } + + if (topic == null || !topic.canSee(sender)) { + sender.sendMessage(ChatColor.RED + "No help for " + command); + return true; + } + + ChatPaginator.ChatPage page = ChatPaginator.paginate(topic.getFullText(sender), pageNumber, pageWidth, pageHeight); + + StringBuilder header = new StringBuilder(); + header.append(ChatColor.YELLOW); + header.append("--------- "); + header.append(ChatColor.WHITE); + header.append("Help: "); + header.append(topic.getName()); + header.append(" "); + if (page.getTotalPages() > 1) { + header.append("("); + header.append(page.getPageNumber()); + header.append("/"); + header.append(page.getTotalPages()); + header.append(") "); + } + header.append(ChatColor.YELLOW); + for (int i = header.length(); i < ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH; i++) { + header.append("-"); + } + sender.sendMessage(header.toString()); + + sender.sendMessage(page.getLines()); + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + List matchedTopics = new ArrayList(); + String searchString = args[0]; + for (HelpTopic topic : Bukkit.getServer().getHelpMap().getHelpTopics()) { + String trimmedTopic = topic.getName().startsWith("/") ? topic.getName().substring(1) : topic.getName(); + + if (trimmedTopic.startsWith(searchString)) { + matchedTopics.add(trimmedTopic); + } + } + return matchedTopics; + } + return ImmutableList.of(); + } + + protected HelpTopic findPossibleMatches(String searchString) { + int maxDistance = (searchString.length() / 5) + 3; + Set possibleMatches = new TreeSet(HelpTopicComparator.helpTopicComparatorInstance()); + + if (searchString.startsWith("/")) { + searchString = searchString.substring(1); + } + + for (HelpTopic topic : Bukkit.getServer().getHelpMap().getHelpTopics()) { + String trimmedTopic = topic.getName().startsWith("/") ? topic.getName().substring(1) : topic.getName(); + + if (trimmedTopic.length() < searchString.length()) { + continue; + } + + if (Character.toLowerCase(trimmedTopic.charAt(0)) != Character.toLowerCase(searchString.charAt(0))) { + continue; + } + + if (damerauLevenshteinDistance(searchString, trimmedTopic.substring(0, searchString.length())) < maxDistance) { + possibleMatches.add(topic); + } + } + + if (possibleMatches.size() > 0) { + return new IndexHelpTopic("Search", null, null, possibleMatches, "Search for: " + searchString); + } else { + return null; + } + } + + /** + * Computes the Dameraur-Levenshtein Distance between two strings. Adapted + * from the algorithm at Wikipedia: Damerau–Levenshtein distance + * + * @param s1 The first string being compared. + * @param s2 The second string being compared. + * @return The number of substitutions, deletions, insertions, and + * transpositions required to get from s1 to s2. + */ + protected static int damerauLevenshteinDistance(String s1, String s2) { + if (s1 == null && s2 == null) { + return 0; + } + if (s1 != null && s2 == null) { + return s1.length(); + } + if (s1 == null && s2 != null) { + return s2.length(); + } + + int s1Len = s1.length(); + int s2Len = s2.length(); + int[][] H = new int[s1Len + 2][s2Len + 2]; + + int INF = s1Len + s2Len; + H[0][0] = INF; + for (int i = 0; i <= s1Len; i++) { + H[i + 1][1] = i; + H[i + 1][0] = INF; + } + for (int j = 0; j <= s2Len; j++) { + H[1][j + 1] = j; + H[0][j + 1] = INF; + } + + Map sd = new HashMap(); + for (char Letter : (s1 + s2).toCharArray()) { + if (!sd.containsKey(Letter)) { + sd.put(Letter, 0); + } + } + + for (int i = 1; i <= s1Len; i++) { + int DB = 0; + for (int j = 1; j <= s2Len; j++) { + int i1 = sd.get(s2.charAt(j - 1)); + int j1 = DB; + + if (s1.charAt(i - 1) == s2.charAt(j - 1)) { + H[i + 1][j + 1] = H[i][j]; + DB = j; + } else { + H[i + 1][j + 1] = Math.min(H[i][j], Math.min(H[i + 1][j], H[i][j + 1])) + 1; + } + + H[i + 1][j + 1] = Math.min(H[i + 1][j + 1], H[i1][j1] + (i - i1 - 1) + 1 + (j - j1 - 1)); + } + sd.put(s1.charAt(i - 1), i); + } + + return H[s1Len + 1][s2Len + 1]; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/KickCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/KickCommand.java new file mode 100644 index 0000000..634c115 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/KickCommand.java @@ -0,0 +1,60 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class KickCommand extends VanillaCommand { + public KickCommand() { + super("kick"); + this.description = "Removes the specified player from the server"; + this.usageMessage = "/kick [reason ...]"; + this.setPermission("bukkit.command.kick"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length < 1 || args[0].length() == 0) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + Player player = Bukkit.getPlayerExact(args[0]); + + if (player != null) { + String reason = "Kicked by an operator."; + + if (args.length > 1) { + reason = createString(args, 1); + } + + player.kickPlayer(reason); + Command.broadcastCommandMessage(sender, "Kicked player " + player.getName() + ". With reason:\n" + reason); + } else { + sender.sendMessage( args[0] + " not found."); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length >= 1) { + return super.tabComplete(sender, alias, args); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/KillCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/KillCommand.java new file mode 100644 index 0000000..2143eb1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/KillCommand.java @@ -0,0 +1,51 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class KillCommand extends VanillaCommand { + public KillCommand() { + super("kill"); + this.description = "Commits suicide, only usable as a player"; + this.usageMessage = "/kill"; + this.setPermission("bukkit.command.kill"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + if (sender instanceof Player) { + Player player = (Player) sender; + + EntityDamageEvent ede = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.SUICIDE, 1000); + Bukkit.getPluginManager().callEvent(ede); + if (ede.isCancelled()) return true; + + ede.getEntity().setLastDamageCause(ede); + player.setHealth(0); + sender.sendMessage("Ouch. That look like it hurt."); + } else { + sender.sendMessage("You can only perform this command as a player"); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ListCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ListCommand.java new file mode 100644 index 0000000..ea62bee --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ListCommand.java @@ -0,0 +1,55 @@ +package org.bukkit.command.defaults; + +import java.util.Collection; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class ListCommand extends VanillaCommand { + public ListCommand() { + super("list"); + this.description = "Lists all online players"; + this.usageMessage = "/list"; + this.setPermission("bukkit.command.list"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + StringBuilder online = new StringBuilder(); + + final Collection players = Bukkit.getOnlinePlayers(); + + for (Player player : players) { + // If a player is hidden from the sender don't show them in the list + if (sender instanceof Player && !((Player) sender).canSee(player)) + continue; + + if (online.length() > 0) { + online.append(", "); + } + + online.append(player.getDisplayName()); + } + + sender.sendMessage("There are " + players.size() + "/" + Bukkit.getMaxPlayers() + " players online:\n" + online.toString()); + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/MeCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/MeCommand.java new file mode 100644 index 0000000..b0d7bf5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/MeCommand.java @@ -0,0 +1,36 @@ +package org.bukkit.command.defaults; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +@Deprecated +public class MeCommand extends VanillaCommand { + public MeCommand() { + super("me"); + this.description = "Performs the specified action in chat"; + this.usageMessage = "/me "; + this.setPermission("bukkit.command.me"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length < 1) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + StringBuilder message = new StringBuilder(); + message.append(sender.getName()); + + for (String arg : args) { + message.append(" "); + message.append(arg); + } + + Bukkit.broadcastMessage("* " + message.toString()); + + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/OpCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/OpCommand.java new file mode 100644 index 0000000..f5bb8b1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/OpCommand.java @@ -0,0 +1,76 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class OpCommand extends VanillaCommand { + public OpCommand() { + super("op"); + this.description = "Gives the specified player operator status"; + this.usageMessage = "/op "; + this.setPermission("bukkit.command.op.give"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length != 1 || args[0].length() == 0) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + OfflinePlayer player = Bukkit.getOfflinePlayer(args[0]); + player.setOp(true); + + Command.broadcastCommandMessage(sender, "Opped " + args[0]); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + if (!(sender instanceof Player)) { + return ImmutableList.of(); + } + + String lastWord = args[0]; + if (lastWord.length() == 0) { + return ImmutableList.of(); + } + + Player senderPlayer = (Player) sender; + + ArrayList matchedPlayers = new ArrayList(); + for (Player player : sender.getServer().getOnlinePlayers()) { + String name = player.getName(); + if (!senderPlayer.canSee(player) || player.isOp()) { + continue; + } + if (StringUtil.startsWithIgnoreCase(name, lastWord)) { + matchedPlayers.add(name); + } + } + + Collections.sort(matchedPlayers, String.CASE_INSENSITIVE_ORDER); + return matchedPlayers; + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PardonCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PardonCommand.java new file mode 100644 index 0000000..762189a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PardonCommand.java @@ -0,0 +1,57 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.BanList; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class PardonCommand extends VanillaCommand { + public PardonCommand() { + super("pardon"); + this.description = "Allows the specified player to use this server"; + this.usageMessage = "/pardon "; + this.setPermission("bukkit.command.unban.player"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + Bukkit.getBanList(BanList.Type.NAME).pardon(args[0]); + Command.broadcastCommandMessage(sender, "Pardoned " + args[0]); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + List completions = new ArrayList(); + for (OfflinePlayer player : Bukkit.getBannedPlayers()) { + String name = player.getName(); + if (StringUtil.startsWithIgnoreCase(name, args[0])) { + completions.add(name); + } + } + return completions; + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PardonIpCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PardonIpCommand.java new file mode 100644 index 0000000..0f63c26 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PardonIpCommand.java @@ -0,0 +1,53 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class PardonIpCommand extends VanillaCommand { + public PardonIpCommand() { + super("pardon-ip"); + this.description = "Allows the specified IP address to use this server"; + this.usageMessage = "/pardon-ip

"; + this.setPermission("bukkit.command.unban.ip"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + if (BanIpCommand.ipValidity.matcher(args[0]).matches()) { + Bukkit.unbanIP(args[0]); + Command.broadcastCommandMessage(sender, "Pardoned ip " + args[0]); + } else { + sender.sendMessage("Invalid ip"); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], Bukkit.getIPBans(), new ArrayList()); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PlaySoundCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PlaySoundCommand.java new file mode 100644 index 0000000..a7737ad --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PlaySoundCommand.java @@ -0,0 +1,88 @@ +package org.bukkit.command.defaults; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@Deprecated +public class PlaySoundCommand extends VanillaCommand { + public PlaySoundCommand() { + super("playsound"); + this.description = "Plays a sound to a given player"; + this.usageMessage = "/playsound [x] [y] [z] [volume] [pitch] [minimumVolume]"; + this.setPermission("bukkit.command.playsound"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) { + return true; + } + + if (args.length < 2) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + final String soundArg = args[0]; + final String playerArg = args[1]; + + final Player player = Bukkit.getPlayerExact(playerArg); + if (player == null) { + sender.sendMessage(ChatColor.RED + "Can't find player " + playerArg); + return false; + } + + final Location location = player.getLocation(); + + double x = Math.floor(location.getX()); + double y = Math.floor(location.getY() + 0.5D); + double z = Math.floor(location.getZ()); + double volume = 1.0D; + double pitch = 1.0D; + double minimumVolume = 0.0D; + + switch (args.length) { + default: + case 8: + minimumVolume = getDouble(sender, args[7], 0.0D, 1.0D); + case 7: + pitch = getDouble(sender, args[6], 0.0D, 2.0D); + case 6: + volume = getDouble(sender, args[5], 0.0D, Float.MAX_VALUE); + case 5: + z = getRelativeDouble(z, sender, args[4]); + case 4: + y = getRelativeDouble(y, sender, args[3]); + case 3: + x = getRelativeDouble(x, sender, args[2]); + case 2: + // Noop + } + + final double fixedVolume = volume > 1.0D ? volume * 16.0D : 16.0D; + final Location soundLocation = new Location(player.getWorld(), x, y, z); + if (location.distanceSquared(soundLocation) > fixedVolume * fixedVolume) { + if (minimumVolume <= 0.0D) { + sender.sendMessage(ChatColor.RED + playerArg + " is too far away to hear the sound"); + return false; + } + + final double deltaX = x - location.getX(); + final double deltaY = y - location.getY(); + final double deltaZ = z - location.getZ(); + final double delta = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / 2.0D; + + if (delta > 0.0D) { + location.add(deltaX / delta, deltaY / delta, deltaZ / delta); + } + + player.playSound(location, soundArg, (float) minimumVolume, (float) pitch); + } else { + player.playSound(soundLocation, soundArg, (float) volume, (float) pitch); + } + sender.sendMessage(String.format("Played '%s' to %s", soundArg, playerArg)); + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PluginsCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PluginsCommand.java new file mode 100644 index 0000000..2bc603f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/PluginsCommand.java @@ -0,0 +1,52 @@ +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.CommandSender; +import org.bukkit.plugin.Plugin; + +public class PluginsCommand extends BukkitCommand { + public PluginsCommand(String name) { + super(name); + this.description = "Gets a list of plugins running on the server"; + this.usageMessage = "/plugins"; + this.setPermission("group.admin"); + this.setAliases(Collections.singletonList("pl")); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + sender.sendMessage("Plugins " + getPluginList()); + return true; + } + + private String getPluginList() { + StringBuilder pluginList = new StringBuilder(); + Plugin[] plugins = Bukkit.getPluginManager().getPlugins(); + + for (Plugin plugin : plugins) { + if (pluginList.length() > 0) { + pluginList.append(ChatColor.WHITE); + pluginList.append(", "); + } + + pluginList.append(plugin.isEnabled() ? ChatColor.GREEN : ChatColor.RED); + pluginList.append(plugin.getDescription().getName()); + } + + return "(" + plugins.length + "): " + pluginList.toString(); + } + + // 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/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ReloadCommand.java new file mode 100644 index 0000000..c70d512 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ReloadCommand.java @@ -0,0 +1,38 @@ +package org.bukkit.command.defaults; + +import java.util.Arrays; + +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(Arrays.asList("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/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveCommand.java new file mode 100644 index 0000000..d08d3ed --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveCommand.java @@ -0,0 +1,47 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class SaveCommand extends VanillaCommand { + public SaveCommand() { + super("save-all"); + this.description = "Saves the server to disk"; + this.usageMessage = "/save-all"; + this.setPermission("bukkit.command.save.perform"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + Command.broadcastCommandMessage(sender, "Forcing save.."); + + Bukkit.savePlayers(); + + for (World world : Bukkit.getWorlds()) { + world.save(); + } + + Command.broadcastCommandMessage(sender, "Save complete."); + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveOffCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveOffCommand.java new file mode 100644 index 0000000..54e6bca --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveOffCommand.java @@ -0,0 +1,42 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class SaveOffCommand extends VanillaCommand { + public SaveOffCommand() { + super("save-off"); + this.description = "Disables server autosaving"; + this.usageMessage = "/save-off"; + this.setPermission("bukkit.command.save.disable"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + for (World world : Bukkit.getWorlds()) { + world.setAutoSave(false); + } + + Command.broadcastCommandMessage(sender, "Disabled level saving.."); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveOnCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveOnCommand.java new file mode 100644 index 0000000..760e1c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SaveOnCommand.java @@ -0,0 +1,42 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class SaveOnCommand extends VanillaCommand { + public SaveOnCommand() { + super("save-on"); + this.description = "Enables server autosaving"; + this.usageMessage = "/save-on"; + this.setPermission("bukkit.command.save.enable"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + for (World world : Bukkit.getWorlds()) { + world.setAutoSave(true); + } + + Command.broadcastCommandMessage(sender, "Enabled level saving.."); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SayCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SayCommand.java new file mode 100644 index 0000000..c6e5b8e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SayCommand.java @@ -0,0 +1,55 @@ +package org.bukkit.command.defaults; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class SayCommand extends VanillaCommand { + public SayCommand() { + super("say"); + this.description = "Broadcast something real official like"; + this.usageMessage = "/say "; + this.setAliases(Collections.singletonList("broadcast")); + this.setPermission("group.admin"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + StringBuilder message = new StringBuilder(); + + message.append("&7[&4Broadcast&7] ").append(args[0]); + for (int i = 1; i < args.length; i++) { + message.append(" ").append(args[i]); + } + + Bukkit.broadcastMessage(ChatColor.translateAlternateColorCodes('&', message.toString())); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + + if (args.length >= 1) { + return super.tabComplete(sender, alias, args); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ScoreboardCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ScoreboardCommand.java new file mode 100644 index 0000000..00197f7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ScoreboardCommand.java @@ -0,0 +1,618 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +@Deprecated +public class ScoreboardCommand extends VanillaCommand { + + private static final List MAIN_CHOICES = ImmutableList.of("objectives", "players", "teams"); + private static final List OBJECTIVES_CHOICES = ImmutableList.of("list", "add", "remove", "setdisplay"); + private static final List OBJECTIVES_CRITERIA = ImmutableList.of("health", "playerKillCount", "totalKillCount", "deathCount", "dummy"); + private static final List PLAYERS_CHOICES = ImmutableList.of("set", "add", "remove", "reset", "list"); + private static final List TEAMS_CHOICES = ImmutableList.of("add", "remove", "join", "leave", "empty", "list", "option"); + private static final List TEAMS_OPTION_CHOICES = ImmutableList.of("color", "friendlyfire", "seeFriendlyInvisibles"); + private static final Map OBJECTIVES_DISPLAYSLOT = ImmutableMap.of("belowName", DisplaySlot.BELOW_NAME, "list", DisplaySlot.PLAYER_LIST, "sidebar", DisplaySlot.SIDEBAR); + private static final Map TEAMS_OPTION_COLOR = ImmutableMap.builder() + .put("aqua", ChatColor.AQUA) + .put("black", ChatColor.BLACK) + .put("blue", ChatColor.BLUE) + .put("bold", ChatColor.BOLD) + .put("dark_aqua", ChatColor.DARK_AQUA) + .put("dark_blue", ChatColor.DARK_BLUE) + .put("dark_gray", ChatColor.DARK_GRAY) + .put("dark_green", ChatColor.DARK_GREEN) + .put("dark_purple", ChatColor.DARK_PURPLE) + .put("dark_red", ChatColor.DARK_RED) + .put("gold", ChatColor.GOLD) + .put("gray", ChatColor.GRAY) + .put("green", ChatColor.GREEN) + .put("italic", ChatColor.ITALIC) + .put("light_purple", ChatColor.LIGHT_PURPLE) + .put("obfuscated", ChatColor.MAGIC) // This is the important line + .put("red", ChatColor.RED) + .put("reset", ChatColor.RESET) + .put("strikethrough", ChatColor.STRIKETHROUGH) + .put("underline", ChatColor.UNDERLINE) + .put("white", ChatColor.WHITE) + .put("yellow", ChatColor.YELLOW) + .build(); + private static final List BOOLEAN = ImmutableList.of("true", "false"); + + public ScoreboardCommand() { + super("scoreboard"); + this.description = "Scoreboard control"; + this.usageMessage = "/scoreboard"; + this.setPermission("bukkit.command.scoreboard"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) + return true; + if (args.length < 1 || args[0].length() == 0) { + sender.sendMessage(ChatColor.RED + "Usage: /scoreboard "); + return false; + } + + final Scoreboard mainScoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); + + if (args[0].equalsIgnoreCase("objectives")) { + if (args.length == 1) { + sender.sendMessage(ChatColor.RED + "Usage: /scoreboard objectives "); + return false; + } + if (args[1].equalsIgnoreCase("list")) { + Set objectives = mainScoreboard.getObjectives(); + if (objectives.isEmpty()) { + sender.sendMessage(ChatColor.RED + "There are no objectives on the scoreboard"); + return false; + } + sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + objectives.size() + " objective(s) on scoreboard"); + for (Objective objective : objectives) { + sender.sendMessage("- " + objective.getName() + ": displays as '" + objective.getDisplayName() + "' and is type '" + objective.getCriteria() + "'"); + } + } else if (args[1].equalsIgnoreCase("add")) { + if (args.length < 4) { + sender.sendMessage(ChatColor.RED + "/scoreboard objectives add [display name ...]"); + return false; + } + String name = args[2]; + String criteria = args[3]; + + if (criteria == null) { + sender.sendMessage(ChatColor.RED + "Invalid objective criteria type. Valid types are: " + stringCollectionToString(OBJECTIVES_CRITERIA)); + } else if (name.length() > 16) { + sender.sendMessage(ChatColor.RED + "The name '" + name + "' is too long for an objective, it can be at most 16 characters long"); + } else if (mainScoreboard.getObjective(name) != null) { + sender.sendMessage(ChatColor.RED + "An objective with the name '" + name + "' already exists"); + } else { + String displayName = null; + if (args.length > 4) { + displayName = StringUtils.join(ArrayUtils.subarray(args, 4, args.length), ' '); + if (displayName.length() > 32) { + sender.sendMessage(ChatColor.RED + "The name '" + displayName + "' is too long for an objective, it can be at most 32 characters long"); + return false; + } + } + Objective objective = mainScoreboard.registerNewObjective(name, criteria); + if (displayName != null && displayName.length() > 0) { + objective.setDisplayName(displayName); + } + sender.sendMessage("Added new objective '" + name + "' successfully"); + } + } else if (args[1].equalsIgnoreCase("remove")) { + if (args.length != 3) { + sender.sendMessage(ChatColor.RED + "/scoreboard objectives remove "); + return false; + } + String name = args[2]; + Objective objective = mainScoreboard.getObjective(name); + if (objective == null) { + sender.sendMessage(ChatColor.RED + "No objective was found by the name '" + name + "'"); + } else { + objective.unregister(); + sender.sendMessage("Removed objective '" + name + "' successfully"); + } + } else if (args[1].equalsIgnoreCase("setdisplay")) { + if (args.length != 3 && args.length != 4) { + sender.sendMessage(ChatColor.RED + "/scoreboard objectives setdisplay [objective]"); + return false; + } + String slotName = args[2]; + DisplaySlot slot = OBJECTIVES_DISPLAYSLOT.get(slotName); + if (slot == null) { + sender.sendMessage(ChatColor.RED + "No such display slot '" + slotName + "'"); + } else { + if (args.length == 4) { + String objectiveName = args[3]; + Objective objective = mainScoreboard.getObjective(objectiveName); + if (objective == null) { + sender.sendMessage(ChatColor.RED + "No objective was found by the name '" + objectiveName + "'"); + return false; + } + + objective.setDisplaySlot(slot); + sender.sendMessage("Set the display objective in slot '" + slotName + "' to '" + objective.getName() + "'"); + } else { + Objective objective = mainScoreboard.getObjective(slot); + if (objective != null) { + objective.setDisplaySlot(null); + } + sender.sendMessage("Cleared objective display slot '" + slotName + "'"); + } + } + } + } else if (args[0].equalsIgnoreCase("players")) { + if (args.length == 1) { + sender.sendMessage(ChatColor.RED + "/scoreboard players "); + return false; + } + if (args[1].equalsIgnoreCase("set") || args[1].equalsIgnoreCase("add") || args[1].equalsIgnoreCase("remove")) { + if (args.length != 5) { + if (args[1].equalsIgnoreCase("set")) { + sender.sendMessage(ChatColor.RED + "/scoreboard players set "); + } else if (args[1].equalsIgnoreCase("add")) { + sender.sendMessage(ChatColor.RED + "/scoreboard players add "); + } else { + sender.sendMessage(ChatColor.RED + "/scoreboard players remove "); + } + return false; + } + String objectiveName = args[3]; + Objective objective = mainScoreboard.getObjective(objectiveName); + if (objective == null) { + sender.sendMessage(ChatColor.RED + "No objective was found by the name '" + objectiveName + "'"); + return false; + } else if (!objective.isModifiable()) { + sender.sendMessage(ChatColor.RED + "The objective '" + objectiveName + "' is read-only and cannot be set"); + return false; + } + + String valueString = args[4]; + int value; + try { + value = Integer.parseInt(valueString); + } catch (NumberFormatException e) { + sender.sendMessage(ChatColor.RED + "'" + valueString + "' is not a valid number"); + return false; + } + if (value < 1 && !args[1].equalsIgnoreCase("set")) { + sender.sendMessage(ChatColor.RED + "The number you have entered (" + value + ") is too small, it must be at least 1"); + return false; + } + + String playerName = args[2]; + if (playerName.length() > 16) { + sender.sendMessage(ChatColor.RED + "'" + playerName + "' is too long for a player name"); + return false; + } + Score score = objective.getScore(playerName); + int newScore; + if (args[1].equalsIgnoreCase("set")) { + newScore = value; + } else if (args[1].equalsIgnoreCase("add")) { + newScore = score.getScore() + value; + } else { + newScore = score.getScore() - value; + } + score.setScore(newScore); + sender.sendMessage("Set score of " + objectiveName + " for player " + playerName + " to " + newScore); + } else if (args[1].equalsIgnoreCase("reset")) { + if (args.length != 3) { + sender.sendMessage(ChatColor.RED + "/scoreboard players reset "); + return false; + } + String playerName = args[2]; + if (playerName.length() > 16) { + sender.sendMessage(ChatColor.RED + "'" + playerName + "' is too long for a player name"); + return false; + } + mainScoreboard.resetScores(playerName); + sender.sendMessage("Reset all scores of player " + playerName); + } else if (args[1].equalsIgnoreCase("list")) { + if (args.length > 3) { + sender.sendMessage(ChatColor.RED + "/scoreboard players list "); + return false; + } + if (args.length == 2) { + Set entries = mainScoreboard.getEntries(); + if (entries.isEmpty()) { + sender.sendMessage(ChatColor.RED + "There are no tracked players on the scoreboard"); + } else { + sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + entries.size() + " tracked players on the scoreboard"); + sender.sendMessage(stringCollectionToString(entries)); + } + } else { + String playerName = args[2]; + if (playerName.length() > 16) { + sender.sendMessage(ChatColor.RED + "'" + playerName + "' is too long for a player name"); + return false; + } + Set scores = mainScoreboard.getScores(playerName); + if (scores.isEmpty()) { + sender.sendMessage(ChatColor.RED + "Player " + playerName + " has no scores recorded"); + } else { + sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + scores.size() + " tracked objective(s) for " + playerName); + for (Score score : scores) { + sender.sendMessage("- " + score.getObjective().getDisplayName() + ": " + score.getScore() + " (" + score.getObjective().getName() + ")"); + } + } + } + } + } else if (args[0].equalsIgnoreCase("teams")) { + if (args.length == 1) { + sender.sendMessage(ChatColor.RED + "/scoreboard teams "); + return false; + } + if (args[1].equalsIgnoreCase("list")) { + if (args.length == 2) { + Set teams = mainScoreboard.getTeams(); + if (teams.isEmpty()) { + sender.sendMessage(ChatColor.RED + "There are no teams registered on the scoreboard"); + } else { + sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + teams.size() + " teams on the scoreboard"); + for (Team team : teams) { + sender.sendMessage("- " + team.getName() + ": '" + team.getDisplayName() + "' has " + team.getSize() + " players"); + } + } + } else if (args.length == 3) { + String teamName = args[2]; + Team team = mainScoreboard.getTeam(teamName); + if (team == null) { + sender.sendMessage(ChatColor.RED + "No team was found by the name '" + teamName + "'"); + } else { + Set players = team.getPlayers(); + if (players.isEmpty()) { + sender.sendMessage(ChatColor.RED + "Team " + team.getName() + " has no players"); + } else { + sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + players.size() + " player(s) in team " + team.getName()); + sender.sendMessage(offlinePlayerSetToString(players)); + } + } + } else { + sender.sendMessage(ChatColor.RED + "/scoreboard teams list [name]"); + return false; + } + } else if (args[1].equalsIgnoreCase("add")) { + if (args.length < 3) { + sender.sendMessage(ChatColor.RED + "/scoreboard teams add [display name ...]"); + return false; + } + String name = args[2]; + if (name.length() > 16) { + sender.sendMessage(ChatColor.RED + "The name '" + name + "' is too long for a team, it can be at most 16 characters long"); + } else if (mainScoreboard.getTeam(name) != null) { + sender.sendMessage(ChatColor.RED + "A team with the name '" + name + "' already exists"); + } else { + String displayName = null; + if (args.length > 3) { + displayName = StringUtils.join(ArrayUtils.subarray(args, 3, args.length), ' '); + if (displayName.length() > 32) { + sender.sendMessage(ChatColor.RED + "The display name '" + displayName + "' is too long for a team, it can be at most 32 characters long"); + return false; + } + } + Team team = mainScoreboard.registerNewTeam(name); + if (displayName != null && displayName.length() > 0) { + team.setDisplayName(displayName); + } + sender.sendMessage("Added new team '" + team.getName() + "' successfully"); + } + } else if (args[1].equalsIgnoreCase("remove")) { + if (args.length != 3) { + sender.sendMessage(ChatColor.RED + "/scoreboard teams remove "); + return false; + } + String name = args[2]; + Team team = mainScoreboard.getTeam(name); + if (team == null) { + sender.sendMessage(ChatColor.RED + "No team was found by the name '" + name + "'"); + } else { + team.unregister(); + sender.sendMessage("Removed team " + name); + } + } else if (args[1].equalsIgnoreCase("empty")) { + if (args.length != 3) { + sender.sendMessage(ChatColor.RED + "/scoreboard teams clear "); + return false; + } + String name = args[2]; + Team team = mainScoreboard.getTeam(name); + if (team == null) { + sender.sendMessage(ChatColor.RED + "No team was found by the name '" + name + "'"); + } else { + Set players = team.getPlayers(); + if (players.isEmpty()) { + sender.sendMessage(ChatColor.RED + "Team " + team.getName() + " is already empty, cannot remove nonexistant players"); + } else { + for (OfflinePlayer player : players) { + team.removePlayer(player); + } + sender.sendMessage("Removed all " + players.size() + " player(s) from team " + team.getName()); + } + } + } else if (args[1].equalsIgnoreCase("join")) { + if ((sender instanceof Player) ? args.length < 3 : args.length < 4) { + sender.sendMessage(ChatColor.RED + "/scoreboard teams join [player...]"); + return false; + } + String teamName = args[2]; + Team team = mainScoreboard.getTeam(teamName); + if (team == null) { + sender.sendMessage(ChatColor.RED + "No team was found by the name '" + teamName + "'"); + } else { + Set addedPlayers = new HashSet(); + if ((sender instanceof Player) && args.length == 3) { + team.addPlayer((Player) sender); + addedPlayers.add(sender.getName()); + } else { + for (int i = 3; i < args.length; i++) { + String playerName = args[i]; + OfflinePlayer offlinePlayer; + Player player = Bukkit.getPlayerExact(playerName); + if (player != null) { + offlinePlayer = player; + } else { + offlinePlayer = Bukkit.getOfflinePlayer(playerName); + } + team.addPlayer(offlinePlayer); + addedPlayers.add(offlinePlayer.getName()); + } + } + sender.sendMessage("Added " + addedPlayers.size() + " player(s) to team " + team.getName() + ": " + stringCollectionToString(addedPlayers)); + } + } else if (args[1].equalsIgnoreCase("leave")) { + if (!(sender instanceof Player) && args.length < 3) { + sender.sendMessage(ChatColor.RED + "/scoreboard teams leave [player...]"); + return false; + } + Set left = new HashSet(); + Set noTeam = new HashSet(); + if ((sender instanceof Player) && args.length == 2) { + Team team = mainScoreboard.getPlayerTeam((Player) sender); + if (team != null) { + team.removePlayer((Player) sender); + left.add(sender.getName()); + } else { + noTeam.add(sender.getName()); + } + } else { + for (int i = 2; i < args.length; i++) { + String playerName = args[i]; + OfflinePlayer offlinePlayer; + Player player = Bukkit.getPlayerExact(playerName); + if (player != null) { + offlinePlayer = player; + } else { + offlinePlayer = Bukkit.getOfflinePlayer(playerName); + } + Team team = mainScoreboard.getPlayerTeam(offlinePlayer); + if (team != null) { + team.removePlayer(offlinePlayer); + left.add(offlinePlayer.getName()); + } else { + noTeam.add(offlinePlayer.getName()); + } + } + } + if (!left.isEmpty()) { + sender.sendMessage("Removed " + left.size() + " player(s) from their teams: " + stringCollectionToString(left)); + } + if (!noTeam.isEmpty()) { + sender.sendMessage("Could not remove " + noTeam.size() + " player(s) from their teams: " + stringCollectionToString(noTeam)); + } + } else if (args[1].equalsIgnoreCase("option")) { + if (args.length != 4 && args.length != 5) { + sender.sendMessage(ChatColor.RED + "/scoreboard teams option "); + return false; + } + String teamName = args[2]; + Team team = mainScoreboard.getTeam(teamName); + if (team == null) { + sender.sendMessage(ChatColor.RED + "No team was found by the name '" + teamName + "'"); + return false; + } + String option = args[3].toLowerCase(); + if (!option.equals("friendlyfire") && !option.equals("color") && !option.equals("seefriendlyinvisibles")) { + sender.sendMessage(ChatColor.RED + "/scoreboard teams option "); + return false; + } + if (args.length == 4) { + if (option.equals("color")) { + sender.sendMessage(ChatColor.RED + "Valid values for option color are: " + stringCollectionToString(TEAMS_OPTION_COLOR.keySet())); + } else { + sender.sendMessage(ChatColor.RED + "Valid values for option " + option + " are: true and false"); + } + } else { + String value = args[4].toLowerCase(); + if (option.equals("color")) { + ChatColor color = TEAMS_OPTION_COLOR.get(value); + if (color == null) { + sender.sendMessage(ChatColor.RED + "Valid values for option color are: " + stringCollectionToString(TEAMS_OPTION_COLOR.keySet())); + return false; + } + team.setPrefix(color.toString()); + team.setSuffix(ChatColor.RESET.toString()); + } else { + if (!value.equals("true") && !value.equals("false")) { + sender.sendMessage(ChatColor.RED + "Valid values for option " + option + " are: true and false"); + return false; + } + if (option.equals("friendlyfire")) { + team.setAllowFriendlyFire(value.equals("true")); + } else { + team.setCanSeeFriendlyInvisibles(value.equals("true")); + } + } + sender.sendMessage("Set option " + option + " for team " + team.getName() + " to " + value); + } + } + } else { + sender.sendMessage(ChatColor.RED + "Usage: /scoreboard "); + return false; + } + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], MAIN_CHOICES, new ArrayList()); + } + if (args.length > 1) { + if (args[0].equalsIgnoreCase("objectives")) { + if (args.length == 2) { + return StringUtil.copyPartialMatches(args[1], OBJECTIVES_CHOICES, new ArrayList()); + } + if (args[1].equalsIgnoreCase("add")) { + if (args.length == 4) { + return StringUtil.copyPartialMatches(args[3], OBJECTIVES_CRITERIA, new ArrayList()); + } + } else if (args[1].equalsIgnoreCase("remove")) { + if (args.length == 3) { + return StringUtil.copyPartialMatches(args[2], this.getCurrentObjectives(), new ArrayList()); + } + } else if (args[1].equalsIgnoreCase("setdisplay")) { + if (args.length == 3) { + return StringUtil.copyPartialMatches(args[2], OBJECTIVES_DISPLAYSLOT.keySet(), new ArrayList()); + } + if (args.length == 4) { + return StringUtil.copyPartialMatches(args[3], this.getCurrentObjectives(), new ArrayList()); + } + } + } else if (args[0].equalsIgnoreCase("players")) { + if (args.length == 2) { + return StringUtil.copyPartialMatches(args[1], PLAYERS_CHOICES, new ArrayList()); + } + if (args[1].equalsIgnoreCase("set") || args[1].equalsIgnoreCase("add") || args[1].equalsIgnoreCase("remove")) { + if (args.length == 3) { + return super.tabComplete(sender, alias, args); + } + if (args.length == 4) { + return StringUtil.copyPartialMatches(args[3], this.getCurrentObjectives(), new ArrayList()); + } + } else { + if (args.length == 3) { + return StringUtil.copyPartialMatches(args[2], this.getCurrentEntries(), new ArrayList()); + } + } + } else if (args[0].equalsIgnoreCase("teams")) { + if (args.length == 2) { + return StringUtil.copyPartialMatches(args[1], TEAMS_CHOICES, new ArrayList()); + } + if (args[1].equalsIgnoreCase("join")) { + if (args.length == 3) { + return StringUtil.copyPartialMatches(args[2], this.getCurrentTeams(), new ArrayList()); + } + if (args.length >= 4) { + return super.tabComplete(sender, alias, args); + } + } else if (args[1].equalsIgnoreCase("leave")) { + return super.tabComplete(sender, alias, args); + } else if (args[1].equalsIgnoreCase("option")) { + if (args.length == 3) { + return StringUtil.copyPartialMatches(args[2], this.getCurrentTeams(), new ArrayList()); + } + if (args.length == 4) { + return StringUtil.copyPartialMatches(args[3], TEAMS_OPTION_CHOICES, new ArrayList()); + } + if (args.length == 5) { + if (args[3].equalsIgnoreCase("color")) { + return StringUtil.copyPartialMatches(args[4], TEAMS_OPTION_COLOR.keySet(), new ArrayList()); + } else { + return StringUtil.copyPartialMatches(args[4], BOOLEAN, new ArrayList()); + } + } + } else { + if (args.length == 3) { + return StringUtil.copyPartialMatches(args[2], this.getCurrentTeams(), new ArrayList()); + } + } + } + } + + return ImmutableList.of(); + } + + private static String offlinePlayerSetToString(Set set) { + StringBuilder string = new StringBuilder(); + String lastValue = null; + for (OfflinePlayer value : set) { + string.append(lastValue = value.getName()).append(", "); + } + string.delete(string.length() - 2, Integer.MAX_VALUE); + if (string.length() != lastValue.length()) { + string.insert(string.length() - lastValue.length(), "and "); + } + return string.toString(); + + } + + private static String stringCollectionToString(Collection set) { + StringBuilder string = new StringBuilder(); + String lastValue = null; + for (String value : set) { + string.append(lastValue = value).append(", "); + } + string.delete(string.length() - 2, Integer.MAX_VALUE); + if (string.length() != lastValue.length()) { + string.insert(string.length() - lastValue.length(), "and "); + } + return string.toString(); + } + + private List getCurrentObjectives() { + List list = new ArrayList(); + for (Objective objective : Bukkit.getScoreboardManager().getMainScoreboard().getObjectives()) { + list.add(objective.getName()); + } + Collections.sort(list, String.CASE_INSENSITIVE_ORDER); + return list; + } + + private List getCurrentEntries() { + List list = new ArrayList(); + for (String entry : Bukkit.getScoreboardManager().getMainScoreboard().getEntries()) { + list.add(entry); + } + Collections.sort(list, String.CASE_INSENSITIVE_ORDER); + return list; + } + + private List getCurrentTeams() { + List list = new ArrayList(); + for (Team team : Bukkit.getScoreboardManager().getMainScoreboard().getTeams()) { + list.add(team.getName()); + } + Collections.sort(list, String.CASE_INSENSITIVE_ORDER); + return list; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SeedCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SeedCommand.java new file mode 100644 index 0000000..3fb0639 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SeedCommand.java @@ -0,0 +1,42 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class SeedCommand extends VanillaCommand { + public SeedCommand() { + super("seed"); + this.description = "Shows the world seed"; + this.usageMessage = "/seed"; + this.setPermission("bukkit.command.seed"); + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + if (!testPermission(sender)) return true; + long seed; + if (sender instanceof Player) { + seed = ((Player) sender).getWorld().getSeed(); + } else { + seed = Bukkit.getWorlds().get(0).getSeed(); + } + sender.sendMessage("Seed: " + seed); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SetIdleTimeoutCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SetIdleTimeoutCommand.java new file mode 100644 index 0000000..f6cbe03 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SetIdleTimeoutCommand.java @@ -0,0 +1,54 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.ImmutableList; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +import java.util.List; + +@Deprecated +public class SetIdleTimeoutCommand extends VanillaCommand { + + public SetIdleTimeoutCommand() { + super("setidletimeout"); + this.description = "Sets the server's idle timeout"; + this.usageMessage = "/setidletimeout "; + this.setPermission("bukkit.command.setidletimeout"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + if (args.length == 1) { + int minutes; + + try { + minutes = getInteger(sender, args[0], 0, Integer.MAX_VALUE, true); + } catch (NumberFormatException ex) { + sender.sendMessage(ex.getMessage()); + return true; + } + + Bukkit.getServer().setIdleTimeout(minutes); + + Command.broadcastCommandMessage(sender, "Successfully set the idle timeout to " + minutes + " minutes."); + return true; + } + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SetWorldSpawnCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SetWorldSpawnCommand.java new file mode 100644 index 0000000..8bec19c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SetWorldSpawnCommand.java @@ -0,0 +1,80 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +@Deprecated +public class SetWorldSpawnCommand extends VanillaCommand { + + public SetWorldSpawnCommand() { + super("setworldspawn"); + this.description = "Sets a worlds's spawn point. If no coordinates are specified, the player's coordinates will be used."; + this.usageMessage = "/setworldspawn OR /setworldspawn "; + this.setPermission("bukkit.command.setworldspawn"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + Player player = null; + World world; + if (sender instanceof Player) { + player = (Player) sender; + world = player.getWorld(); + } else { + world = Bukkit.getWorlds().get(0); + } + + final int x, y, z; + + if (args.length == 0) { + if (player == null) { + sender.sendMessage("You can only perform this command as a player"); + return true; + } + + Location location = player.getLocation(); + + x = location.getBlockX(); + y = location.getBlockY(); + z = location.getBlockZ(); + } else if (args.length == 3) { + try { + x = getInteger(sender, args[0], MIN_COORD, MAX_COORD, true); + y = getInteger(sender, args[1], 0, world.getMaxHeight(), true); + z = getInteger(sender, args[2], MIN_COORD, MAX_COORD, true); + } catch (NumberFormatException ex) { + sender.sendMessage(ex.getMessage()); + return true; + } + } else { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + world.setSpawnLocation(x, y, z); + + Command.broadcastCommandMessage(sender, "Set world " + world.getName() + "'s spawnpoint to (" + x + ", " + y + ", " + z + ")"); + return true; + + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SpawnpointCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SpawnpointCommand.java new file mode 100644 index 0000000..be15f7e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SpawnpointCommand.java @@ -0,0 +1,88 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +@Deprecated +public class SpawnpointCommand extends VanillaCommand { + + public SpawnpointCommand() { + super("spawnpoint"); + this.description = "Sets a player's spawn point"; + this.usageMessage = "/spawnpoint OR /spawnpoint OR /spawnpoint "; + this.setPermission("bukkit.command.spawnpoint"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + Player player; + + if (args.length == 0) { + if (sender instanceof Player) { + player = (Player) sender; + } else { + sender.sendMessage("Please provide a player!"); + return true; + } + } else { + player = Bukkit.getPlayerExact(args[0]); + if (player == null) { + sender.sendMessage("Can't find player " + args[0]); + return true; + } + } + + World world = player.getWorld(); + + if (args.length == 4) { + if (world != null) { + int pos = 1; + final int x, y, z; + try { + x = getInteger(sender, args[pos++], MIN_COORD, MAX_COORD, true); + y = getInteger(sender, args[pos++], 0, world.getMaxHeight()); + z = getInteger(sender, args[pos], MIN_COORD, MAX_COORD, true); + } catch(NumberFormatException ex) { + sender.sendMessage(ex.getMessage()); + return true; + } + + player.setBedSpawnLocation(new Location(world, x, y, z), true); + Command.broadcastCommandMessage(sender, "Set " + player.getDisplayName() + "'s spawnpoint to " + x + ", " + y + ", " + z); + } + } else if (args.length <= 1) { + Location location = player.getLocation(); + player.setBedSpawnLocation(location, true); + Command.broadcastCommandMessage(sender, "Set " + player.getDisplayName() + "'s spawnpoint to " + location.getX() + ", " + location.getY() + ", " + location.getZ()); + } else { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return super.tabComplete(sender, alias, args); + } + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SpreadPlayersCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SpreadPlayersCommand.java new file mode 100644 index 0000000..0c5a14c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/SpreadPlayersCommand.java @@ -0,0 +1,267 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import net.jafama.FastMath; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Team; + +@Deprecated +public class SpreadPlayersCommand extends VanillaCommand { + private static final Random random = new Random(); + + public SpreadPlayersCommand() { + super("spreadplayers"); + this.description = "Spreads players around a point"; + this.usageMessage = "/spreadplayers "; + this.setPermission("bukkit.command.spreadplayers"); + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + if (!testPermission(sender)) { + return true; + } + + if (args.length < 6) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + final double x = getDouble(sender, args[0], -30000000, 30000000); + final double z = getDouble(sender, args[1], -30000000, 30000000); + final double distance = getDouble(sender, args[2]); + final double range = getDouble(sender, args[3]); + + if (distance < 0.0D) { + sender.sendMessage(ChatColor.RED + "Distance is too small."); + return false; + } + + if (range < distance + 1.0D) { + sender.sendMessage(ChatColor.RED + "Max range is too small."); + return false; + } + + final String respectTeams = args[4]; + boolean teams = false; + + if (respectTeams.equalsIgnoreCase("true")) { + teams = true; + } else if (!respectTeams.equalsIgnoreCase("false")) { + sender.sendMessage(String.format(ChatColor.RED + "'%s' is not true or false", args[4])); + return false; + } + + List players = Lists.newArrayList(); + World world = null; + + for (int i = 5; i < args.length; i++) { + Player player = Bukkit.getPlayerExact(args[i]); + if (player == null) { + continue; + } + + if (world == null) { + world = player.getWorld(); + } + players.add(player); + } + + if (world == null) { + return true; + } + + final double xRangeMin = x - range; + final double zRangeMin = z - range; + final double xRangeMax = x + range; + final double zRangeMax = z + range; + + final int spreadSize = teams ? getTeams(players) : players.size(); + + final Location[] locations = getSpreadLocations(world, spreadSize, xRangeMin, zRangeMin, xRangeMax, zRangeMax); + final int rangeSpread = range(world, distance, xRangeMin, zRangeMin, xRangeMax, zRangeMax, locations); + + if (rangeSpread == -1) { + sender.sendMessage(String.format("Could not spread %d %s around %s,%s (too many players for space - try using spread of at most %s)", spreadSize, teams ? "teams" : "players", x, z)); + return false; + } + + final double distanceSpread = spread(world, players, locations, teams); + + sender.sendMessage(String.format("Succesfully spread %d %s around %s,%s", locations.length, teams ? "teams" : "players", x, z)); + if (locations.length > 1) { + sender.sendMessage(String.format("(Average distance between %s is %s blocks apart after %s iterations)", teams ? "teams" : "players", String.format("%.2f", distanceSpread), rangeSpread)); + } + return true; + } + + private int range(World world, double distance, double xRangeMin, double zRangeMin, double xRangeMax, double zRangeMax, Location[] locations) { + boolean flag = true; + double max; + + int i; + + for (i = 0; i < 10000 && flag; ++i) { + flag = false; + max = Float.MAX_VALUE; + + Location loc1; + int j; + + for (int k = 0; k < locations.length; ++k) { + Location loc2 = locations[k]; + + j = 0; + loc1 = new Location(world, 0, 0, 0); + + for (int l = 0; l < locations.length; ++l) { + if (k != l) { + Location loc3 = locations[l]; + double dis = loc2.distanceSquared(loc3); + + max = FastMath.min(dis, max); + if (dis < distance) { + ++j; + loc1.add(loc3.getX() - loc2.getX(), 0, 0); + loc1.add(loc3.getZ() - loc2.getZ(), 0, 0); + } + } + } + + if (j > 0) { + loc2.setX(loc2.getX() / j); + loc2.setZ(loc2.getZ() / j); + double d7 = FastMath.sqrt(loc1.getX() * loc1.getX() + loc1.getZ() * loc1.getZ()); + + if (d7 > 0.0D) { + loc1.setX(loc1.getX() / d7); + loc2.add(-loc1.getX(), 0, -loc1.getZ()); + } else { + double x = xRangeMin >= xRangeMax ? xRangeMin : random.nextDouble() * (xRangeMax - xRangeMin) + xRangeMin; + double z = zRangeMin >= zRangeMax ? zRangeMin : random.nextDouble() * (zRangeMax - zRangeMin) + zRangeMin; + loc2.setX(x); + loc2.setZ(z); + } + + flag = true; + } + + boolean swap = false; + + if (loc2.getX() < xRangeMin) { + loc2.setX(xRangeMin); + swap = true; + } else if (loc2.getX() > xRangeMax) { + loc2.setX(xRangeMax); + swap = true; + } + + if (loc2.getZ() < zRangeMin) { + loc2.setZ(zRangeMin); + swap = true; + } else if (loc2.getZ() > zRangeMax) { + loc2.setZ(zRangeMax); + swap = true; + } + if (swap) { + flag = true; + } + } + + if (!flag) { + Location[] locs = locations; + int i1 = locations.length; + + for (j = 0; j < i1; ++j) { + loc1 = locs[j]; + if (world.getHighestBlockYAt(loc1) == 0) { + double x = xRangeMin >= xRangeMax ? xRangeMin : random.nextDouble() * (xRangeMax - xRangeMin) + xRangeMin; + double z = zRangeMin >= zRangeMax ? zRangeMin : random.nextDouble() * (zRangeMax - zRangeMin) + zRangeMin; + locations[i] = (new Location(world, x, 0, z)); + loc1.setX(x); + loc1.setZ(z); + flag = true; + } + } + } + } + + if (i >= 10000) { + return -1; + } else { + return i; + } + } + + private double spread(World world, List list, Location[] locations, boolean teams) { + double distance = 0.0D; + int i = 0; + Map hashmap = Maps.newHashMap(); + + for (int j = 0; j < list.size(); ++j) { + Player player = list.get(j); + Location location; + + if (teams) { + Team team = player.getScoreboard().getPlayerTeam(player); + + if (!hashmap.containsKey(team)) { + hashmap.put(team, locations[i++]); + } + + location = hashmap.get(team); + } else { + location = locations[i++]; + } + + player.teleport(new Location(world, FastMath.floor(location.getX()) + 0.5D, world.getHighestBlockYAt((int) location.getX(), (int) location.getZ()), Math.floor(location.getZ()) + 0.5D)); + double value = Double.MAX_VALUE; + + for (int k = 0; k < locations.length; ++k) { + if (location != locations[k]) { + double d = location.distanceSquared(locations[k]); + value = FastMath.min(d, value); + } + } + + distance += value; + } + + distance /= list.size(); + return distance; + } + + private int getTeams(List players) { + Set teams = Sets.newHashSet(); + + for (Player player : players) { + teams.add(player.getScoreboard().getPlayerTeam(player)); + } + + return teams.size(); + } + + private Location[] getSpreadLocations(World world, int size, double xRangeMin, double zRangeMin, double xRangeMax, double zRangeMax) { + Location[] locations = new Location[size]; + + for (int i = 0; i < size; ++i) { + double x = xRangeMin >= xRangeMax ? xRangeMin : random.nextDouble() * (xRangeMax - xRangeMin) + xRangeMin; + double z = zRangeMin >= zRangeMax ? zRangeMin : random.nextDouble() * (zRangeMax - zRangeMin) + zRangeMin; + locations[i] = (new Location(world, x, 0, z)); + } + + return locations; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/StopCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/StopCommand.java new file mode 100644 index 0000000..a9467e1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/StopCommand.java @@ -0,0 +1,49 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class StopCommand extends VanillaCommand { + public StopCommand() { + super("stop"); + this.description = "Stops the server with optional reason"; + this.usageMessage = "/stop [reason]"; + this.setPermission("bukkit.command.stop"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + Command.broadcastCommandMessage(sender, "Stopping the server.."); + Bukkit.shutdown(); + + String reason = this.createString(args, 0); + if (StringUtils.isNotEmpty(reason)) { + for (Player player : Bukkit.getOnlinePlayers()) { + player.kickPlayer(reason); + } + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TeleportCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TeleportCommand.java new file mode 100644 index 0000000..7460196 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TeleportCommand.java @@ -0,0 +1,125 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class TeleportCommand extends VanillaCommand { + + public TeleportCommand() { + super("tp"); + this.description = "Teleports the given player (or yourself) to another player or coordinates"; + this.usageMessage = "/tp [player] and/or "; + this.setPermission("bukkit.command.teleport"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length < 1 || args.length > 4) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + Player player; + + if (args.length == 1 || args.length == 3) { + if (sender instanceof Player) { + player = (Player) sender; + } else { + sender.sendMessage("Please provide a player!"); + return true; + } + } else { + player = Bukkit.getPlayerExact(args[0]); + } + + if (player == null) { + sender.sendMessage("Player not found: " + args[0]); + return true; + } + + if (args.length < 3) { + Player target = Bukkit.getPlayerExact(args[args.length - 1]); + if (target == null) { + sender.sendMessage("Can't find player " + args[args.length - 1] + ". No tp."); + return true; + } + player.teleport(target, TeleportCause.COMMAND); + Command.broadcastCommandMessage(sender, "Teleported " + player.getDisplayName() + " to " + target.getDisplayName()); + } else if (player.getWorld() != null) { + Location playerLocation = player.getLocation(); + double x = getCoordinate(sender, playerLocation.getX(), args[args.length - 3]); + double y = getCoordinate(sender, playerLocation.getY(), args[args.length - 2], 0, 0); + double z = getCoordinate(sender, playerLocation.getZ(), args[args.length - 1]); + + if (x == MIN_COORD_MINUS_ONE || y == MIN_COORD_MINUS_ONE || z == MIN_COORD_MINUS_ONE) { + sender.sendMessage("Please provide a valid location!"); + return true; + } + + playerLocation.setX(x); + playerLocation.setY(y); + playerLocation.setZ(z); + + player.teleport(playerLocation, TeleportCause.COMMAND); + Command.broadcastCommandMessage(sender, String.format("Teleported %s to %.2f, %.2f, %.2f", player.getDisplayName(), x, y, z)); + } + return true; + } + + private double getCoordinate(CommandSender sender, double current, String input) { + return getCoordinate(sender, current, input, MIN_COORD, MAX_COORD); + } + + private double getCoordinate(CommandSender sender, double current, String input, int min, int max) { + boolean relative = input.startsWith("~"); + double result = relative ? current : 0; + + if (!relative || input.length() > 1) { + boolean exact = input.contains("."); + if (relative) input = input.substring(1); + + double testResult = getDouble(sender, input); + if (testResult == MIN_COORD_MINUS_ONE) { + return MIN_COORD_MINUS_ONE; + } + result += testResult; + + if (!exact && !relative) result += 0.5f; + } + if (min != 0 || max != 0) { + if (result < min) { + result = MIN_COORD_MINUS_ONE; + } + + if (result > max) { + result = MIN_COORD_MINUS_ONE; + } + } + + return result; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1 || args.length == 2) { + return super.tabComplete(sender, alias, args); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TellCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TellCommand.java new file mode 100644 index 0000000..af95633 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TellCommand.java @@ -0,0 +1,61 @@ +package org.bukkit.command.defaults; + +import java.util.Arrays; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@Deprecated +public class TellCommand extends VanillaCommand { + public TellCommand() { + super("tell"); + this.description = "Sends a private message to the given player"; + this.usageMessage = "/tell "; + this.setAliases(Arrays.asList("w", "msg")); + this.setPermission("bukkit.command.tell"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length < 2) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + Player player = Bukkit.getPlayerExact(args[0]); + + // If a player is hidden from the sender pretend they are offline + if (player == null || (sender instanceof Player && !((Player) sender).canSee(player))) { + sender.sendMessage("There's no player by that name online."); + } else { + StringBuilder message = new StringBuilder(); + + for (int i = 1; i < args.length; i++) { + if (i > 1) message.append(" "); + message.append(args[i]); + } + + String result = ChatColor.GRAY + sender.getName() + " whispers " + message; + + sender.sendMessage("[" + sender.getName() + "->" + player.getName() + "] " + message); + player.sendMessage(result); + } + + return true; + } + + // Spigot Start + @Override + public java.util.List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException + { + if ( args.length == 0 ) + { + return super.tabComplete( sender, alias, args ); + } + return java.util.Collections.emptyList(); + } + // Spigot End +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TestForCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TestForCommand.java new file mode 100644 index 0000000..e168b49 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TestForCommand.java @@ -0,0 +1,39 @@ +package org.bukkit.command.defaults; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +@Deprecated +public class TestForCommand extends VanillaCommand { + public TestForCommand() { + super("testfor"); + this.description = "Tests whether a specifed player is online"; + this.usageMessage = "/testfor "; + this.setPermission("bukkit.command.testfor"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length < 1) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + sender.sendMessage(ChatColor.RED + "/testfor is only usable by commandblocks with analog output."); + return true; + } + + // Spigot Start + @Override + public java.util.List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException + { + if ( args.length == 0 ) + { + return super.tabComplete( sender, alias, args ); + } + return java.util.Collections.emptyList(); + } + // Spigot End +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TimeCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TimeCommand.java new file mode 100644 index 0000000..edce68a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TimeCommand.java @@ -0,0 +1,89 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class TimeCommand extends VanillaCommand { + private static final List TABCOMPLETE_ADD_SET = ImmutableList.of("add", "set"); + private static final List TABCOMPLETE_DAY_NIGHT = ImmutableList.of("day", "night"); + + public TimeCommand() { + super("time"); + this.description = "Changes the time on each world"; + this.usageMessage = "/time set \n/time add "; + this.setPermission("bukkit.command.time.add;bukkit.command.time.set"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (args.length < 2) { + sender.sendMessage(ChatColor.RED + "Incorrect usage. Correct usage:\n" + usageMessage); + return false; + } + + int value; + + if (args[0].equals("set")) { + if (!sender.hasPermission("bukkit.command.time.set")) { + sender.sendMessage(ChatColor.RED + "You don't have permission to set the time"); + return true; + } + + if (args[1].equals("day")) { + value = 0; + } else if (args[1].equals("night")) { + value = 12500; + } else { + value = getInteger(sender, args[1], 0); + } + + for (World world : Bukkit.getWorlds()) { + world.setTime(value); + } + + Command.broadcastCommandMessage(sender, "Set time to " + value); + } else if (args[0].equals("add")) { + if (!sender.hasPermission("bukkit.command.time.add")) { + sender.sendMessage(ChatColor.RED + "You don't have permission to set the time"); + return true; + } + + value = getInteger(sender, args[1], 0); + + for (World world : Bukkit.getWorlds()) { + world.setFullTime(world.getFullTime() + value); + } + + Command.broadcastCommandMessage(sender, "Added " + value + " to time"); + } else { + sender.sendMessage("Unknown method. Usage: " + usageMessage); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], TABCOMPLETE_ADD_SET, new ArrayList(TABCOMPLETE_ADD_SET.size())); + } else if (args.length == 2 && args[0].equalsIgnoreCase("set")) { + return StringUtil.copyPartialMatches(args[1], TABCOMPLETE_DAY_NIGHT, new ArrayList(TABCOMPLETE_DAY_NIGHT.size())); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TimingsCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TimingsCommand.java new file mode 100644 index 0000000..65c65dd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/TimingsCommand.java @@ -0,0 +1,136 @@ +package org.bukkit.command.defaults; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; +import org.bukkit.plugin.TimedRegisteredListener; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +// Spigot start +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.logging.Level; + +import org.bukkit.command.RemoteConsoleCommandSender; +import org.bukkit.plugin.SimplePluginManager; +// Spigot end + +public class TimingsCommand extends BukkitCommand { + public static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate"); + + public TimingsCommand(String name) { + super(name); + this.description = "Records timings for all plugin events"; + this.usageMessage = "/timings "; + this.setPermission("bukkit.command.timings"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length != 1) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + if (!sender.getServer().getPluginManager().useTimings()) { + sender.sendMessage("Please enable timings by setting \"settings.plugin-profiling\" to true in bukkit.yml"); + return true; + } + + boolean separate = "separate".equalsIgnoreCase(args[0]); + if ("reset".equalsIgnoreCase(args[0])) { + for (HandlerList handlerList : HandlerList.getHandlerLists()) { + for (RegisteredListener listener : handlerList.getRegisteredListeners()) { + if (listener instanceof TimedRegisteredListener) { + ((TimedRegisteredListener)listener).reset(); + } + } + } + sender.sendMessage("Timings reset"); + } else if ("merged".equalsIgnoreCase(args[0]) || separate) { + + int index = 0; + int pluginIdx = 0; + File timingFolder = new File("timings"); + timingFolder.mkdirs(); + File timings = new File(timingFolder, "timings.txt"); + File names = null; + while (timings.exists()) timings = new File(timingFolder, "timings" + (++index) + ".txt"); + PrintStream fileTimings = null; + PrintStream fileNames = null; + try { + fileTimings = new PrintStream(timings); + if (separate) { + names = new File(timingFolder, "names" + index + ".txt"); + fileNames = new PrintStream(names); + } + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + pluginIdx++; + long totalTime = 0; + if (separate) { + fileNames.println(pluginIdx + " " + plugin.getDescription().getFullName()); + fileTimings.println("Plugin " + pluginIdx); + } + else fileTimings.println(plugin.getDescription().getFullName()); + for (RegisteredListener listener : HandlerList.getRegisteredListeners(plugin)) { + if (listener instanceof TimedRegisteredListener) { + TimedRegisteredListener trl = (TimedRegisteredListener) listener; + long time = trl.getTotalTime(); + int count = trl.getCount(); + if (count == 0) continue; + long avg = time / count; + totalTime += time; + Class eventClass = trl.getEventClass(); + if (count > 0 && eventClass != null) { + fileTimings.println(" " + eventClass.getSimpleName() + (trl.hasMultiple() ? " (and sub-classes)" : "") + " Time: " + time + " Count: " + count + " Avg: " + avg); + } + } + } + fileTimings.println(" Total time " + totalTime + " (" + totalTime / 1000000000 + "s)"); + } + sender.sendMessage("Timings written to " + timings.getPath()); + if (separate) sender.sendMessage("Names written to " + names.getPath()); + } catch (IOException e) { + } finally { + if (fileTimings != null) { + fileTimings.close(); + } + if (fileNames != null) { + fileNames.close(); + } + } + } else { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], TIMINGS_SUBCOMMANDS, new ArrayList(TIMINGS_SUBCOMMANDS.size())); + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ToggleDownfallCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ToggleDownfallCommand.java new file mode 100644 index 0000000..91268a6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/ToggleDownfallCommand.java @@ -0,0 +1,57 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class ToggleDownfallCommand extends VanillaCommand { + public ToggleDownfallCommand() { + super("toggledownfall"); + this.description = "Toggles rain on/off on a given world"; + this.usageMessage = "/toggledownfall"; + this.setPermission("bukkit.command.toggledownfall"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + World world = null; + + if (args.length == 1) { + world = Bukkit.getWorld(args[0]); + + if (world == null) { + sender.sendMessage(ChatColor.RED + "No world exists with the name '" + args[0] + "'"); + return true; + } + } else if (sender instanceof Player) { + world = ((Player) sender).getWorld(); + } else { + world = Bukkit.getWorlds().get(0); + } + + Command.broadcastCommandMessage(sender, "Toggling downfall " + (world.hasStorm() ? "off" : "on") + " for world '" + world.getName() + "'"); + world.setStorm(!world.hasStorm()); + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/VanillaCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/VanillaCommand.java new file mode 100644 index 0000000..9105712 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/VanillaCommand.java @@ -0,0 +1,111 @@ +package org.bukkit.command.defaults; + +import java.util.List; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +@Deprecated +public abstract class VanillaCommand extends Command { + static final int MAX_COORD = 30000000; + static final int MIN_COORD_MINUS_ONE = -30000001; + static final int MIN_COORD = -30000000; + + protected VanillaCommand(String name) { + super(name); + } + + protected VanillaCommand(String name, String description, String usageMessage, List aliases) { + super(name, description, usageMessage, aliases); + } + + public boolean matches(String input) { + return input.equalsIgnoreCase(this.getName()); + } + + protected int getInteger(CommandSender sender, String value, int min) { + return getInteger(sender, value, min, Integer.MAX_VALUE); + } + + int getInteger(CommandSender sender, String value, int min, int max) { + return getInteger(sender, value, min, max, false); + } + + int getInteger(CommandSender sender, String value, int min, int max, boolean Throws) { + int i = min; + + try { + i = Integer.valueOf(value); + } catch (NumberFormatException ex) { + if (Throws) { + throw new NumberFormatException(String.format("%s is not a valid number", value)); + } + } + + if (i < min) { + i = min; + } else if (i > max) { + i = max; + } + + return i; + } + + Integer getInteger(String value) { + try { + return Integer.valueOf(value); + } catch (NumberFormatException ex) { + return null; + } + } + + public static double getRelativeDouble(double original, CommandSender sender, String input) { + if (input.startsWith("~")) { + double value = getDouble(sender, input.substring(1)); + if (value == MIN_COORD_MINUS_ONE) { + return MIN_COORD_MINUS_ONE; + } + return original + value; + } else { + return getDouble(sender, input); + } + } + + public static double getDouble(CommandSender sender, String input) { + try { + return Double.parseDouble(input); + } catch (NumberFormatException ex) { + return MIN_COORD_MINUS_ONE; + } + } + + public static double getDouble(CommandSender sender, String input, double min, double max) { + double result = getDouble(sender, input); + + // TODO: This should throw an exception instead. + if (result < min) { + result = min; + } else if (result > max) { + result = max; + } + + return result; + } + + String createString(String[] args, int start) { + return createString(args, start, " "); + } + + String createString(String[] args, int start, String glue) { + StringBuilder string = new StringBuilder(); + + for (int x = start; x < args.length; x++) { + string.append(args[x]); + if (x != args.length - 1) { + string.append(glue); + } + } + + return string.toString(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/VersionCommand.java new file mode 100644 index 0000000..904214d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/VersionCommand.java @@ -0,0 +1,135 @@ +package org.bukkit.command.defaults; + +import com.google.common.base.Charsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.Resources; +import java.io.BufferedReader; +import java.io.IOException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +// TacoSpigot start +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +// TacoSpigot end + +public class VersionCommand extends BukkitCommand { + public VersionCommand(String name) { + super(name); + + this.description = "Gets the version of this server including any plugins in use"; + this.usageMessage = "/version [plugin name]"; + this.setPermission("group.default"); + this.setAliases(Arrays.asList("ver", "about")); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + if (args.length == 0) { + sender.sendMessage("This server is powered by " + ChatColor.DARK_PURPLE + "mySpigot"); + // sendVersion(sender); + } else { + if (!sender.hasPermission("group.admin")) { + sender.sendMessage("This server is powered by " + ChatColor.DARK_PURPLE + "mySpigot"); + return true; + } + + StringBuilder name = new StringBuilder(); + + for (String arg : args) { + if (name.length() > 0) { + name.append(' '); + } + + name.append(arg); + } + + String pluginName = name.toString(); + Plugin exactPlugin = Bukkit.getPluginManager().getPlugin(pluginName); + if (exactPlugin != null) { + describeToSender(exactPlugin, sender); + return true; + } + + boolean found = false; + pluginName = pluginName.toLowerCase(); + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + if (plugin.getName().toLowerCase().contains(pluginName)) { + describeToSender(plugin, sender); + found = true; + } + } + + if (!found) { + sender.sendMessage("This server is not running any plugin by that name."); + sender.sendMessage("Use /plugins to get a list of plugins."); + } + } + return true; + } + + private void describeToSender(Plugin plugin, CommandSender sender) { + PluginDescriptionFile desc = plugin.getDescription(); + sender.sendMessage(ChatColor.GREEN + desc.getName() + ChatColor.WHITE + " version " + ChatColor.GREEN + desc.getVersion()); + + if (desc.getDescription() != null) { + sender.sendMessage(desc.getDescription()); + } + + if (desc.getWebsite() != null) { + sender.sendMessage("Website: " + ChatColor.GREEN + desc.getWebsite()); + } + + if (!desc.getAuthors().isEmpty()) { + if (desc.getAuthors().size() == 1) { + sender.sendMessage("Author: " + getAuthors(desc)); + } else { + sender.sendMessage("Authors: " + getAuthors(desc)); + } + } + } + + private String getAuthors(final PluginDescriptionFile desc) { + StringBuilder result = new StringBuilder(); + List authors = desc.getAuthors(); + + for (int i = 0; i < authors.size(); i++) { + if (result.length() > 0) { + result.append(ChatColor.WHITE); + + if (i < authors.size() - 1) { + result.append(", "); + } else { + result.append(" and "); + } + } + + result.append(ChatColor.GREEN); + result.append(authors.get(i)); + } + + return result.toString(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/WeatherCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/WeatherCommand.java new file mode 100644 index 0000000..b86a508 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/WeatherCommand.java @@ -0,0 +1,74 @@ +package org.bukkit.command.defaults; + +import com.google.common.collect.ImmutableList; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +@Deprecated +public class WeatherCommand extends VanillaCommand { + private static final List WEATHER_TYPES = ImmutableList.of("clear", "rain", "thunder"); + + public WeatherCommand() { + super("weather"); + this.description = "Changes the weather"; + this.usageMessage = "/weather [duration in seconds]"; + this.setPermission("bukkit.command.weather"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } + + int duration = (300 + new Random().nextInt(600)) * 20; + if (args.length >= 2) { + duration = getInteger(sender, args[1], 1, 1000000) * 20; + } + + World world = Bukkit.getWorlds().get(0); + + world.setWeatherDuration(duration); + world.setThunderDuration(duration); + + if ("clear".equalsIgnoreCase(args[0])) { + world.setStorm(false); + world.setThundering(false); + Command.broadcastCommandMessage(sender, "Changed weather to clear for " + (duration / 20) + " seconds."); + } else if ("rain".equalsIgnoreCase(args[0])) { + world.setStorm(true); + world.setThundering(false); + Command.broadcastCommandMessage(sender, "Changed weather to rainy for " + (duration / 20) + " seconds."); + } else if ("thunder".equalsIgnoreCase(args[0])) { + world.setStorm(true); + world.setThundering(true); + Command.broadcastCommandMessage(sender, "Changed weather to thundering " + (duration / 20) + " seconds."); + } + + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], WEATHER_TYPES, new ArrayList(WEATHER_TYPES.size())); + } + + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/WhitelistCommand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/WhitelistCommand.java new file mode 100644 index 0000000..855f560 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/command/defaults/WhitelistCommand.java @@ -0,0 +1,128 @@ +package org.bukkit.command.defaults; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + +import com.google.common.collect.ImmutableList; + +@Deprecated +public class WhitelistCommand extends VanillaCommand { + private static final List WHITELIST_SUBCOMMANDS = ImmutableList.of("add", "remove", "on", "off", "list", "reload"); + + public WhitelistCommand() { + super("whitelist"); + this.description = "Manages the list of players allowed to use this server"; + this.usageMessage = "/whitelist (add|remove) \n/whitelist (on|off|list|reload)"; + this.setPermission("bukkit.command.whitelist.reload;bukkit.command.whitelist.enable;bukkit.command.whitelist.disable;bukkit.command.whitelist.list;bukkit.command.whitelist.add;bukkit.command.whitelist.remove"); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; + + if (args.length == 1) { + if (args[0].equalsIgnoreCase("reload")) { + if (badPerm(sender, "reload")) return true; + + Bukkit.reloadWhitelist(); + Command.broadcastCommandMessage(sender, "Reloaded white-list from file"); + return true; + } else if (args[0].equalsIgnoreCase("on")) { + if (badPerm(sender, "enable")) return true; + + Bukkit.setWhitelist(true); + Command.broadcastCommandMessage(sender, "Turned on white-listing"); + return true; + } else if (args[0].equalsIgnoreCase("off")) { + if (badPerm(sender, "disable")) return true; + + Bukkit.setWhitelist(false); + Command.broadcastCommandMessage(sender, "Turned off white-listing"); + return true; + } else if (args[0].equalsIgnoreCase("list")) { + if (badPerm(sender, "list")) return true; + + StringBuilder result = new StringBuilder(); + + for (OfflinePlayer player : Bukkit.getWhitelistedPlayers()) { + if (result.length() > 0) { + result.append(", "); + } + + result.append(player.getName()); + } + + sender.sendMessage("White-listed players: " + result.toString()); + return true; + } + } else if (args.length == 2) { + if (args[0].equalsIgnoreCase("add")) { + if (badPerm(sender, "add")) return true; + + Bukkit.getOfflinePlayer(args[1]).setWhitelisted(true); + + Command.broadcastCommandMessage(sender, "Added " + args[1] + " to white-list"); + return true; + } else if (args[0].equalsIgnoreCase("remove")) { + if (badPerm(sender, "remove")) return true; + + Bukkit.getOfflinePlayer(args[1]).setWhitelisted(false); + + Command.broadcastCommandMessage(sender, "Removed " + args[1] + " from white-list"); + return true; + } + } + + sender.sendMessage(ChatColor.RED + "Correct command usage:\n" + usageMessage); + return false; + } + + private boolean badPerm(CommandSender sender, String perm) { + if (!sender.hasPermission("bukkit.command.whitelist." + perm)) { + sender.sendMessage(ChatColor.RED + "You do not have permission to perform this action."); + return true; + } + + return false; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + + if (args.length == 1) { + return StringUtil.copyPartialMatches(args[0], WHITELIST_SUBCOMMANDS, new ArrayList(WHITELIST_SUBCOMMANDS.size())); + } else if (args.length == 2) { + if (args[0].equalsIgnoreCase("add")) { + List completions = new ArrayList(); + for (OfflinePlayer player : Bukkit.getOnlinePlayers()) { // Spigot - well maybe sometimes you haven't turned the whitelist on just yet. + String name = player.getName(); + if (StringUtil.startsWithIgnoreCase(name, args[1]) && !player.isWhitelisted()) { + completions.add(name); + } + } + return completions; + } else if (args[0].equalsIgnoreCase("remove")) { + List completions = new ArrayList(); + for (OfflinePlayer player : Bukkit.getWhitelistedPlayers()) { + String name = player.getName(); + if (StringUtil.startsWithIgnoreCase(name, args[1])) { + completions.add(name); + } + } + return completions; + } + } + return ImmutableList.of(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/Configuration.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/Configuration.java new file mode 100644 index 0000000..52e3ac4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/Configuration.java @@ -0,0 +1,84 @@ +package org.bukkit.configuration; + +import java.util.Map; + +/** + * Represents a source of configurable options and settings + */ +public interface Configuration extends ConfigurationSection { + /** + * Sets the default value of the given path as provided. + *

+ * If no source {@link Configuration} was provided as a default + * collection, then a new {@link MemoryConfiguration} will be created to + * hold the new default value. + *

+ * If value is null, the value will be removed from the default + * Configuration source. + * + * @param path Path of the value to set. + * @param value Value to set the default to. + * @throws IllegalArgumentException Thrown if path is null. + */ + public void addDefault(String path, Object value); + + /** + * Sets the default values of the given paths as provided. + *

+ * If no source {@link Configuration} was provided as a default + * collection, then a new {@link MemoryConfiguration} will be created to + * hold the new default values. + * + * @param defaults A map of Path{@literal ->}Values to add to defaults. + * @throws IllegalArgumentException Thrown if defaults is null. + */ + public void addDefaults(Map defaults); + + /** + * Sets the default values of the given paths as provided. + *

+ * If no source {@link Configuration} was provided as a default + * collection, then a new {@link MemoryConfiguration} will be created to + * hold the new default value. + *

+ * This method will not hold a reference to the specified Configuration, + * nor will it automatically update if that Configuration ever changes. If + * you require this, you should set the default source with {@link + * #setDefaults(org.bukkit.configuration.Configuration)}. + * + * @param defaults A configuration holding a list of defaults to copy. + * @throws IllegalArgumentException Thrown if defaults is null or this. + */ + public void addDefaults(Configuration defaults); + + /** + * Sets the source of all default values for this {@link Configuration}. + *

+ * If a previous source was set, or previous default values were defined, + * then they will not be copied to the new source. + * + * @param defaults New source of default values for this configuration. + * @throws IllegalArgumentException Thrown if defaults is null or this. + */ + public void setDefaults(Configuration defaults); + + /** + * Gets the source {@link Configuration} for this configuration. + *

+ * If no configuration source was set, but default values were added, then + * a {@link MemoryConfiguration} will be returned. If no source was set + * and no defaults were set, then this method will return null. + * + * @return Configuration source for default values, or null if none exist. + */ + public Configuration getDefaults(); + + /** + * Gets the {@link ConfigurationOptions} for this {@link Configuration}. + *

+ * All setters through this method are chainable. + * + * @return Options for this configuration + */ + public ConfigurationOptions options(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/ConfigurationOptions.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/ConfigurationOptions.java new file mode 100644 index 0000000..2f59382 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/ConfigurationOptions.java @@ -0,0 +1,90 @@ +package org.bukkit.configuration; + +/** + * Various settings for controlling the input and output of a {@link + * Configuration} + */ +public class ConfigurationOptions { + private char pathSeparator = '.'; + private boolean copyDefaults = false; + private final Configuration configuration; + + protected ConfigurationOptions(Configuration configuration) { + this.configuration = configuration; + } + + /** + * Returns the {@link Configuration} that this object is responsible for. + * + * @return Parent configuration + */ + public Configuration configuration() { + return configuration; + } + + /** + * Gets the char that will be used to separate {@link + * ConfigurationSection}s + *

+ * This value does not affect how the {@link Configuration} is stored, + * only in how you access the data. The default value is '.'. + * + * @return Path separator + */ + public char pathSeparator() { + return pathSeparator; + } + + /** + * Sets the char that will be used to separate {@link + * ConfigurationSection}s + *

+ * This value does not affect how the {@link Configuration} is stored, + * only in how you access the data. The default value is '.'. + * + * @param value Path separator + * @return This object, for chaining + */ + public ConfigurationOptions pathSeparator(char value) { + this.pathSeparator = value; + return this; + } + + /** + * Checks if the {@link Configuration} should copy values from its default + * {@link Configuration} directly. + *

+ * If this is true, all values in the default Configuration will be + * directly copied, making it impossible to distinguish between values + * that were set and values that are provided by default. As a result, + * {@link ConfigurationSection#contains(java.lang.String)} will always + * return the same value as {@link + * ConfigurationSection#isSet(java.lang.String)}. The default value is + * false. + * + * @return Whether or not defaults are directly copied + */ + public boolean copyDefaults() { + return copyDefaults; + } + + /** + * Sets if the {@link Configuration} should copy values from its default + * {@link Configuration} directly. + *

+ * If this is true, all values in the default Configuration will be + * directly copied, making it impossible to distinguish between values + * that were set and values that are provided by default. As a result, + * {@link ConfigurationSection#contains(java.lang.String)} will always + * return the same value as {@link + * ConfigurationSection#isSet(java.lang.String)}. The default value is + * false. + * + * @param value Whether or not defaults are directly copied + * @return This object, for chaining + */ + public ConfigurationOptions copyDefaults(boolean value) { + this.copyDefaults = value; + return this; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/ConfigurationSection.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/ConfigurationSection.java new file mode 100644 index 0000000..9afc1dc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/ConfigurationSection.java @@ -0,0 +1,851 @@ +package org.bukkit.configuration; + +import java.util.Map; +import java.util.Set; +import java.util.List; + +import org.bukkit.Color; +import org.bukkit.OfflinePlayer; +import org.bukkit.util.Vector; +import org.bukkit.inventory.ItemStack; + +/** + * Represents a section of a {@link Configuration} + */ +public interface ConfigurationSection { + /** + * Gets a set containing all keys in this section. + *

+ * If deep is set to true, then this will contain all the keys within any + * child {@link ConfigurationSection}s (and their children, etc). These + * will be in a valid path notation for you to use. + *

+ * If deep is set to false, then this will contain only the keys of any + * direct children, and not their own children. + * + * @param deep Whether or not to get a deep list, as opposed to a shallow + * list. + * @return Set of keys contained within this ConfigurationSection. + */ + public Set getKeys(boolean deep); + + /** + * Gets a Map containing all keys and their values for this section. + *

+ * If deep is set to true, then this will contain all the keys and values + * within any child {@link ConfigurationSection}s (and their children, + * etc). These keys will be in a valid path notation for you to use. + *

+ * If deep is set to false, then this will contain only the keys and + * values of any direct children, and not their own children. + * + * @param deep Whether or not to get a deep list, as opposed to a shallow + * list. + * @return Map of keys and values of this section. + */ + public Map getValues(boolean deep); + + /** + * Checks if this {@link ConfigurationSection} contains the given path. + *

+ * If the value for the requested path does not exist but a default value + * has been specified, this will return true. + * + * @param path Path to check for existence. + * @return True if this section contains the requested path, either via + * default or being set. + * @throws IllegalArgumentException Thrown when path is null. + */ + public boolean contains(String path); + + /** + * Checks if this {@link ConfigurationSection} has a value set for the + * given path. + *

+ * If the value for the requested path does not exist but a default value + * has been specified, this will still return false. + * + * @param path Path to check for existence. + * @return True if this section contains the requested path, regardless of + * having a default. + * @throws IllegalArgumentException Thrown when path is null. + */ + public boolean isSet(String path); + + /** + * Gets the path of this {@link ConfigurationSection} from its root {@link + * Configuration} + *

+ * For any {@link Configuration} themselves, this will return an empty + * string. + *

+ * If the section is no longer contained within its root for any reason, + * such as being replaced with a different value, this may return null. + *

+ * To retrieve the single name of this section, that is, the final part of + * the path returned by this method, you may use {@link #getName()}. + * + * @return Path of this section relative to its root + */ + public String getCurrentPath(); + + /** + * Gets the name of this individual {@link ConfigurationSection}, in the + * path. + *

+ * This will always be the final part of {@link #getCurrentPath()}, unless + * the section is orphaned. + * + * @return Name of this section + */ + public String getName(); + + /** + * Gets the root {@link Configuration} that contains this {@link + * ConfigurationSection} + *

+ * For any {@link Configuration} themselves, this will return its own + * object. + *

+ * If the section is no longer contained within its root for any reason, + * such as being replaced with a different value, this may return null. + * + * @return Root configuration containing this section. + */ + public Configuration getRoot(); + + /** + * Gets the parent {@link ConfigurationSection} that directly contains + * this {@link ConfigurationSection}. + *

+ * For any {@link Configuration} themselves, this will return null. + *

+ * If the section is no longer contained within its parent for any reason, + * such as being replaced with a different value, this may return null. + * + * @return Parent section containing this section. + */ + public ConfigurationSection getParent(); + + /** + * Gets the requested Object by path. + *

+ * If the Object does not exist but a default value has been specified, + * this will return the default value. If the Object does not exist and no + * default value was specified, this will return null. + * + * @param path Path of the Object to get. + * @return Requested Object. + */ + public Object get(String path); + + /** + * Gets the requested Object by path, returning a default value if not + * found. + *

+ * If the Object does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the Object to get. + * @param def The default value to return if the path is not found. + * @return Requested Object. + */ + public Object get(String path, Object def); + + /** + * Sets the specified path to the given value. + *

+ * If value is null, the entry will be removed. Any existing entry will be + * replaced, regardless of what the new value is. + *

+ * Some implementations may have limitations on what you may store. See + * their individual javadocs for details. No implementations should allow + * you to store {@link Configuration}s or {@link ConfigurationSection}s, + * please use {@link #createSection(java.lang.String)} for that. + * + * @param path Path of the object to set. + * @param value New value to set the path to. + */ + public void set(String path, Object value); + + /** + * Creates an empty {@link ConfigurationSection} at the specified path. + *

+ * Any value that was previously set at this path will be overwritten. If + * the previous value was itself a {@link ConfigurationSection}, it will + * be orphaned. + * + * @param path Path to create the section at. + * @return Newly created section + */ + public ConfigurationSection createSection(String path); + + /** + * Creates a {@link ConfigurationSection} at the specified path, with + * specified values. + *

+ * Any value that was previously set at this path will be overwritten. If + * the previous value was itself a {@link ConfigurationSection}, it will + * be orphaned. + * + * @param path Path to create the section at. + * @param map The values to used. + * @return Newly created section + */ + public ConfigurationSection createSection(String path, Map map); + + // Primitives + /** + * Gets the requested String by path. + *

+ * If the String does not exist but a default value has been specified, + * this will return the default value. If the String does not exist and no + * default value was specified, this will return null. + * + * @param path Path of the String to get. + * @return Requested String. + */ + public String getString(String path); + + /** + * Gets the requested String by path, returning a default value if not + * found. + *

+ * If the String does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the String to get. + * @param def The default value to return if the path is not found or is + * not a String. + * @return Requested String. + */ + public String getString(String path, String def); + + /** + * Checks if the specified path is a String. + *

+ * If the path exists but is not a String, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a String and return appropriately. + * + * @param path Path of the String to check. + * @return Whether or not the specified path is a String. + */ + public boolean isString(String path); + + /** + * Gets the requested int by path. + *

+ * If the int does not exist but a default value has been specified, this + * will return the default value. If the int does not exist and no default + * value was specified, this will return 0. + * + * @param path Path of the int to get. + * @return Requested int. + */ + public int getInt(String path); + + /** + * Gets the requested int by path, returning a default value if not found. + *

+ * If the int does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the int to get. + * @param def The default value to return if the path is not found or is + * not an int. + * @return Requested int. + */ + public int getInt(String path, int def); + + /** + * Checks if the specified path is an int. + *

+ * If the path exists but is not a int, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a int and return appropriately. + * + * @param path Path of the int to check. + * @return Whether or not the specified path is an int. + */ + public boolean isInt(String path); + + /** + * Gets the requested boolean by path. + *

+ * If the boolean does not exist but a default value has been specified, + * this will return the default value. If the boolean does not exist and + * no default value was specified, this will return false. + * + * @param path Path of the boolean to get. + * @return Requested boolean. + */ + public boolean getBoolean(String path); + + /** + * Gets the requested boolean by path, returning a default value if not + * found. + *

+ * If the boolean does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the boolean to get. + * @param def The default value to return if the path is not found or is + * not a boolean. + * @return Requested boolean. + */ + public boolean getBoolean(String path, boolean def); + + /** + * Checks if the specified path is a boolean. + *

+ * If the path exists but is not a boolean, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a boolean and return appropriately. + * + * @param path Path of the boolean to check. + * @return Whether or not the specified path is a boolean. + */ + public boolean isBoolean(String path); + + /** + * Gets the requested double by path. + *

+ * If the double does not exist but a default value has been specified, + * this will return the default value. If the double does not exist and no + * default value was specified, this will return 0. + * + * @param path Path of the double to get. + * @return Requested double. + */ + public double getDouble(String path); + + /** + * Gets the requested double by path, returning a default value if not + * found. + *

+ * If the double does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the double to get. + * @param def The default value to return if the path is not found or is + * not a double. + * @return Requested double. + */ + public double getDouble(String path, double def); + + /** + * Checks if the specified path is a double. + *

+ * If the path exists but is not a double, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a double and return appropriately. + * + * @param path Path of the double to check. + * @return Whether or not the specified path is a double. + */ + public boolean isDouble(String path); + + // PaperSpigot start - Add getFloat + /** + * Gets the requested float by path. + *

+ * If the float does not exist but a default value has been specified, + * this will return the default value. If the float does not exist and no + * default value was specified, this will return 0. + * + * @param path Path of the float to get. + * @return Requested float. + */ + public float getFloat(String path); + + /** + * Gets the requested float by path, returning a default value if not + * found. + *

+ * If the float does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the float to get. + * @param def The default value to return if the path is not found or is + * not a float. + * @return Requested float. + */ + public float getFloat(String path, float def); + + /** + * Checks if the specified path is a float. + *

+ * If the path exists but is not a float, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a gloat and return appropriately. + * + * @param path Path of the float to check. + * @return Whether or not the specified path is a float. + */ + public boolean isFloat(String path); + // PaperSpigot end + + /** + * Gets the requested long by path. + *

+ * If the long does not exist but a default value has been specified, this + * will return the default value. If the long does not exist and no + * default value was specified, this will return 0. + * + * @param path Path of the long to get. + * @return Requested long. + */ + public long getLong(String path); + + /** + * Gets the requested long by path, returning a default value if not + * found. + *

+ * If the long does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the long to get. + * @param def The default value to return if the path is not found or is + * not a long. + * @return Requested long. + */ + public long getLong(String path, long def); + + /** + * Checks if the specified path is a long. + *

+ * If the path exists but is not a long, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a long and return appropriately. + * + * @param path Path of the long to check. + * @return Whether or not the specified path is a long. + */ + public boolean isLong(String path); + + // Java + /** + * Gets the requested List by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return null. + * + * @param path Path of the List to get. + * @return Requested List. + */ + public List getList(String path); + + /** + * Gets the requested List by path, returning a default value if not + * found. + *

+ * If the List does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the List to get. + * @param def The default value to return if the path is not found or is + * not a List. + * @return Requested List. + */ + public List getList(String path, List def); + + /** + * Checks if the specified path is a List. + *

+ * If the path exists but is not a List, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a List and return appropriately. + * + * @param path Path of the List to check. + * @return Whether or not the specified path is a List. + */ + public boolean isList(String path); + + /** + * Gets the requested List of String by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a String if possible, + * but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of String. + */ + public List getStringList(String path); + + /** + * Gets the requested List of Integer by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Integer if possible, + * but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Integer. + */ + public List getIntegerList(String path); + + /** + * Gets the requested List of Boolean by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Boolean if possible, + * but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Boolean. + */ + public List getBooleanList(String path); + + /** + * Gets the requested List of Double by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Double if possible, + * but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Double. + */ + public List getDoubleList(String path); + + /** + * Gets the requested List of Float by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Float if possible, + * but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Float. + */ + public List getFloatList(String path); + + /** + * Gets the requested List of Long by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Long if possible, + * but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Long. + */ + public List getLongList(String path); + + /** + * Gets the requested List of Byte by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Byte if possible, + * but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Byte. + */ + public List getByteList(String path); + + /** + * Gets the requested List of Character by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Character if + * possible, but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Character. + */ + public List getCharacterList(String path); + + /** + * Gets the requested List of Short by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Short if possible, + * but may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Short. + */ + public List getShortList(String path); + + /** + * Gets the requested List of Maps by path. + *

+ * If the List does not exist but a default value has been specified, this + * will return the default value. If the List does not exist and no + * default value was specified, this will return an empty List. + *

+ * This method will attempt to cast any values into a Map if possible, but + * may miss any values out if they are not compatible. + * + * @param path Path of the List to get. + * @return Requested List of Maps. + */ + public List> getMapList(String path); + + // Bukkit + /** + * Gets the requested Vector by path. + *

+ * If the Vector does not exist but a default value has been specified, + * this will return the default value. If the Vector does not exist and no + * default value was specified, this will return null. + * + * @param path Path of the Vector to get. + * @return Requested Vector. + */ + public Vector getVector(String path); + + /** + * Gets the requested {@link Vector} by path, returning a default value if + * not found. + *

+ * If the Vector does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the Vector to get. + * @param def The default value to return if the path is not found or is + * not a Vector. + * @return Requested Vector. + */ + public Vector getVector(String path, Vector def); + + /** + * Checks if the specified path is a Vector. + *

+ * If the path exists but is not a Vector, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a Vector and return appropriately. + * + * @param path Path of the Vector to check. + * @return Whether or not the specified path is a Vector. + */ + public boolean isVector(String path); + + /** + * Gets the requested OfflinePlayer by path. + *

+ * If the OfflinePlayer does not exist but a default value has been + * specified, this will return the default value. If the OfflinePlayer + * does not exist and no default value was specified, this will return + * null. + * + * @param path Path of the OfflinePlayer to get. + * @return Requested OfflinePlayer. + */ + public OfflinePlayer getOfflinePlayer(String path); + + /** + * Gets the requested {@link OfflinePlayer} by path, returning a default + * value if not found. + *

+ * If the OfflinePlayer does not exist then the specified default value + * will returned regardless of if a default has been identified in the + * root {@link Configuration}. + * + * @param path Path of the OfflinePlayer to get. + * @param def The default value to return if the path is not found or is + * not an OfflinePlayer. + * @return Requested OfflinePlayer. + */ + public OfflinePlayer getOfflinePlayer(String path, OfflinePlayer def); + + /** + * Checks if the specified path is an OfflinePlayer. + *

+ * If the path exists but is not a OfflinePlayer, this will return false. + * If the path does not exist, this will return false. If the path does + * not exist but a default value has been specified, this will check if + * that default value is a OfflinePlayer and return appropriately. + * + * @param path Path of the OfflinePlayer to check. + * @return Whether or not the specified path is an OfflinePlayer. + */ + public boolean isOfflinePlayer(String path); + + /** + * Gets the requested ItemStack by path. + *

+ * If the ItemStack does not exist but a default value has been specified, + * this will return the default value. If the ItemStack does not exist and + * no default value was specified, this will return null. + * + * @param path Path of the ItemStack to get. + * @return Requested ItemStack. + */ + public ItemStack getItemStack(String path); + + /** + * Gets the requested {@link ItemStack} by path, returning a default value + * if not found. + *

+ * If the ItemStack does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the ItemStack to get. + * @param def The default value to return if the path is not found or is + * not an ItemStack. + * @return Requested ItemStack. + */ + public ItemStack getItemStack(String path, ItemStack def); + + /** + * Checks if the specified path is an ItemStack. + *

+ * If the path exists but is not a ItemStack, this will return false. If + * the path does not exist, this will return false. If the path does not + * exist but a default value has been specified, this will check if that + * default value is a ItemStack and return appropriately. + * + * @param path Path of the ItemStack to check. + * @return Whether or not the specified path is an ItemStack. + */ + public boolean isItemStack(String path); + + /** + * Gets the requested Color by path. + *

+ * If the Color does not exist but a default value has been specified, + * this will return the default value. If the Color does not exist and no + * default value was specified, this will return null. + * + * @param path Path of the Color to get. + * @return Requested Color. + */ + public Color getColor(String path); + + /** + * Gets the requested {@link Color} by path, returning a default value if + * not found. + *

+ * If the Color does not exist then the specified default value will + * returned regardless of if a default has been identified in the root + * {@link Configuration}. + * + * @param path Path of the Color to get. + * @param def The default value to return if the path is not found or is + * not a Color. + * @return Requested Color. + */ + public Color getColor(String path, Color def); + + /** + * Checks if the specified path is a Color. + *

+ * If the path exists but is not a Color, this will return false. If the + * path does not exist, this will return false. If the path does not exist + * but a default value has been specified, this will check if that default + * value is a Color and return appropriately. + * + * @param path Path of the Color to check. + * @return Whether or not the specified path is a Color. + */ + public boolean isColor(String path); + + /** + * Gets the requested ConfigurationSection by path. + *

+ * If the ConfigurationSection does not exist but a default value has been + * specified, this will return the default value. If the + * ConfigurationSection does not exist and no default value was specified, + * this will return null. + * + * @param path Path of the ConfigurationSection to get. + * @return Requested ConfigurationSection. + */ + public ConfigurationSection getConfigurationSection(String path); + + /** + * Checks if the specified path is a ConfigurationSection. + *

+ * If the path exists but is not a ConfigurationSection, this will return + * false. If the path does not exist, this will return false. If the path + * does not exist but a default value has been specified, this will check + * if that default value is a ConfigurationSection and return + * appropriately. + * + * @param path Path of the ConfigurationSection to check. + * @return Whether or not the specified path is a ConfigurationSection. + */ + public boolean isConfigurationSection(String path); + + /** + * Gets the equivalent {@link ConfigurationSection} from the default + * {@link Configuration} defined in {@link #getRoot()}. + *

+ * If the root contains no defaults, or the defaults doesn't contain a + * value for this path, or the value at this path is not a {@link + * ConfigurationSection} then this will return null. + * + * @return Equivalent section in root configuration + */ + public ConfigurationSection getDefaultSection(); + + /** + * Sets the default value in the root at the given path as provided. + *

+ * If no source {@link Configuration} was provided as a default + * collection, then a new {@link MemoryConfiguration} will be created to + * hold the new default value. + *

+ * If value is null, the value will be removed from the default + * Configuration source. + *

+ * If the value as returned by {@link #getDefaultSection()} is null, then + * this will create a new section at the path, replacing anything that may + * have existed there previously. + * + * @param path Path of the value to set. + * @param value Value to set the default to. + * @throws IllegalArgumentException Thrown if path is null. + */ + public void addDefault(String path, Object value); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/InvalidConfigurationException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/InvalidConfigurationException.java new file mode 100644 index 0000000..d23480e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/InvalidConfigurationException.java @@ -0,0 +1,45 @@ +package org.bukkit.configuration; + +/** + * Exception thrown when attempting to load an invalid {@link Configuration} + */ +@SuppressWarnings("serial") +public class InvalidConfigurationException extends Exception { + + /** + * Creates a new instance of InvalidConfigurationException without a + * message or cause. + */ + public InvalidConfigurationException() {} + + /** + * Constructs an instance of InvalidConfigurationException with the + * specified message. + * + * @param msg The details of the exception. + */ + public InvalidConfigurationException(String msg) { + super(msg); + } + + /** + * Constructs an instance of InvalidConfigurationException with the + * specified cause. + * + * @param cause The cause of the exception. + */ + public InvalidConfigurationException(Throwable cause) { + super(cause); + } + + /** + * Constructs an instance of InvalidConfigurationException with the + * specified message and cause. + * + * @param cause The cause of the exception. + * @param msg The details of the exception. + */ + public InvalidConfigurationException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemoryConfiguration.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemoryConfiguration.java new file mode 100644 index 0000000..19c27a1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemoryConfiguration.java @@ -0,0 +1,79 @@ +package org.bukkit.configuration; + +import java.util.Map; + +import org.apache.commons.lang.Validate; + +/** + * This is a {@link Configuration} implementation that does not save or load + * from any source, and stores all values in memory only. + * This is useful for temporary Configurations for providing defaults. + */ +public class MemoryConfiguration extends MemorySection implements Configuration { + protected Configuration defaults; + protected MemoryConfigurationOptions options; + + /** + * Creates an empty {@link MemoryConfiguration} with no default values. + */ + public MemoryConfiguration() {} + + /** + * Creates an empty {@link MemoryConfiguration} using the specified {@link + * Configuration} as a source for all default values. + * + * @param defaults Default value provider + * @throws IllegalArgumentException Thrown if defaults is null + */ + public MemoryConfiguration(Configuration defaults) { + this.defaults = defaults; + } + + @Override + public void addDefault(String path, Object value) { + Validate.notNull(path, "Path may not be null"); + + if (defaults == null) { + defaults = new MemoryConfiguration(); + } + + defaults.set(path, value); + } + + public void addDefaults(Map defaults) { + Validate.notNull(defaults, "Defaults may not be null"); + + for (Map.Entry entry : defaults.entrySet()) { + addDefault(entry.getKey(), entry.getValue()); + } + } + + public void addDefaults(Configuration defaults) { + Validate.notNull(defaults, "Defaults may not be null"); + + addDefaults(defaults.getValues(true)); + } + + public void setDefaults(Configuration defaults) { + Validate.notNull(defaults, "Defaults may not be null"); + + this.defaults = defaults; + } + + public Configuration getDefaults() { + return defaults; + } + + @Override + public ConfigurationSection getParent() { + return null; + } + + public MemoryConfigurationOptions options() { + if (options == null) { + options = new MemoryConfigurationOptions(this); + } + + return options; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemoryConfigurationOptions.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemoryConfigurationOptions.java new file mode 100644 index 0000000..44c046c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemoryConfigurationOptions.java @@ -0,0 +1,28 @@ +package org.bukkit.configuration; + +/** + * Various settings for controlling the input and output of a {@link + * MemoryConfiguration} + */ +public class MemoryConfigurationOptions extends ConfigurationOptions { + protected MemoryConfigurationOptions(MemoryConfiguration configuration) { + super(configuration); + } + + @Override + public MemoryConfiguration configuration() { + return (MemoryConfiguration) super.configuration(); + } + + @Override + public MemoryConfigurationOptions copyDefaults(boolean value) { + super.copyDefaults(value); + return this; + } + + @Override + public MemoryConfigurationOptions pathSeparator(char value) { + super.pathSeparator(value); + return this; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemorySection.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemorySection.java new file mode 100644 index 0000000..0e2b26a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/MemorySection.java @@ -0,0 +1,837 @@ +package org.bukkit.configuration; + +import static org.bukkit.util.NumberConversions.*; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.Color; +import org.bukkit.OfflinePlayer; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +/** + * A type of {@link ConfigurationSection} that is stored in memory. + */ +public class MemorySection implements ConfigurationSection { + protected final Map map = new LinkedHashMap(); + private final Configuration root; + private final ConfigurationSection parent; + private final String path; + private final String fullPath; + + /** + * Creates an empty MemorySection for use as a root {@link Configuration} + * section. + *

+ * Note that calling this without being yourself a {@link Configuration} + * will throw an exception! + * + * @throws IllegalStateException Thrown if this is not a {@link + * Configuration} root. + */ + protected MemorySection() { + if (!(this instanceof Configuration)) { + throw new IllegalStateException("Cannot construct a root MemorySection when not a Configuration"); + } + + this.path = ""; + this.fullPath = ""; + this.parent = null; + this.root = (Configuration) this; + } + + /** + * Creates an empty MemorySection with the specified parent and path. + * + * @param parent Parent section that contains this own section. + * @param path Path that you may access this section from via the root + * {@link Configuration}. + * @throws IllegalArgumentException Thrown is parent or path is null, or + * if parent contains no root Configuration. + */ + protected MemorySection(ConfigurationSection parent, String path) { + Validate.notNull(parent, "Parent cannot be null"); + Validate.notNull(path, "Path cannot be null"); + + this.path = path; + this.parent = parent; + this.root = parent.getRoot(); + + Validate.notNull(root, "Path cannot be orphaned"); + + this.fullPath = createPath(parent, path); + } + + public Set getKeys(boolean deep) { + Set result = new LinkedHashSet(); + + Configuration root = getRoot(); + if (root != null && root.options().copyDefaults()) { + ConfigurationSection defaults = getDefaultSection(); + + if (defaults != null) { + result.addAll(defaults.getKeys(deep)); + } + } + + mapChildrenKeys(result, this, deep); + + return result; + } + + public Map getValues(boolean deep) { + Map result = new LinkedHashMap(); + + Configuration root = getRoot(); + if (root != null && root.options().copyDefaults()) { + ConfigurationSection defaults = getDefaultSection(); + + if (defaults != null) { + result.putAll(defaults.getValues(deep)); + } + } + + mapChildrenValues(result, this, deep); + + return result; + } + + public boolean contains(String path) { + return get(path) != null; + } + + public boolean isSet(String path) { + Configuration root = getRoot(); + if (root == null) { + return false; + } + if (root.options().copyDefaults()) { + return contains(path); + } + return get(path, null) != null; + } + + public String getCurrentPath() { + return fullPath; + } + + public String getName() { + return path; + } + + public Configuration getRoot() { + return root; + } + + public ConfigurationSection getParent() { + return parent; + } + + public void addDefault(String path, Object value) { + Validate.notNull(path, "Path cannot be null"); + + Configuration root = getRoot(); + if (root == null) { + throw new IllegalStateException("Cannot add default without root"); + } + if (root == this) { + throw new UnsupportedOperationException("Unsupported addDefault(String, Object) implementation"); + } + root.addDefault(createPath(this, path), value); + } + + public ConfigurationSection getDefaultSection() { + Configuration root = getRoot(); + Configuration defaults = root == null ? null : root.getDefaults(); + + if (defaults != null) { + if (defaults.isConfigurationSection(getCurrentPath())) { + return defaults.getConfigurationSection(getCurrentPath()); + } + } + + return null; + } + + public void set(String path, Object value) { + Validate.notEmpty(path, "Cannot set to an empty path"); + + Configuration root = getRoot(); + if (root == null) { + throw new IllegalStateException("Cannot use section without a root"); + } + + final char separator = root.options().pathSeparator(); + // i1 is the leading (higher) index + // i2 is the trailing (lower) index + int i1 = -1, i2; + ConfigurationSection section = this; + while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) { + String node = path.substring(i2, i1); + ConfigurationSection subSection = section.getConfigurationSection(node); + if (subSection == null) { + section = section.createSection(node); + } else { + section = subSection; + } + } + + String key = path.substring(i2); + if (section == this) { + if (value == null) { + map.remove(key); + } else { + map.put(key, value); + } + } else { + section.set(key, value); + } + } + + public Object get(String path) { + return get(path, getDefault(path)); + } + + public Object get(String path, Object def) { + Validate.notNull(path, "Path cannot be null"); + + if (path.length() == 0) { + return this; + } + + Configuration root = getRoot(); + if (root == null) { + throw new IllegalStateException("Cannot access section without a root"); + } + + final char separator = root.options().pathSeparator(); + // i1 is the leading (higher) index + // i2 is the trailing (lower) index + int i1 = -1, i2; + ConfigurationSection section = this; + while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) { + section = section.getConfigurationSection(path.substring(i2, i1)); + if (section == null) { + return def; + } + } + + String key = path.substring(i2); + if (section == this) { + Object result = map.get(key); + return (result == null) ? def : result; + } + return section.get(key, def); + } + + public ConfigurationSection createSection(String path) { + Validate.notEmpty(path, "Cannot create section at empty path"); + Configuration root = getRoot(); + if (root == null) { + throw new IllegalStateException("Cannot create section without a root"); + } + + final char separator = root.options().pathSeparator(); + // i1 is the leading (higher) index + // i2 is the trailing (lower) index + int i1 = -1, i2; + ConfigurationSection section = this; + while ((i1 = path.indexOf(separator, i2 = i1 + 1)) != -1) { + String node = path.substring(i2, i1); + ConfigurationSection subSection = section.getConfigurationSection(node); + if (subSection == null) { + section = section.createSection(node); + } else { + section = subSection; + } + } + + String key = path.substring(i2); + if (section == this) { + ConfigurationSection result = new MemorySection(this, key); + map.put(key, result); + return result; + } + return section.createSection(key); + } + + public ConfigurationSection createSection(String path, Map map) { + ConfigurationSection section = createSection(path); + + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue() instanceof Map) { + section.createSection(entry.getKey().toString(), (Map) entry.getValue()); + } else { + section.set(entry.getKey().toString(), entry.getValue()); + } + } + + return section; + } + + // Primitives + public String getString(String path) { + Object def = getDefault(path); + return getString(path, def != null ? def.toString() : null); + } + + public String getString(String path, String def) { + Object val = get(path, def); + return (val != null) ? val.toString() : def; + } + + public boolean isString(String path) { + Object val = get(path); + return val instanceof String; + } + + public int getInt(String path) { + Object def = getDefault(path); + return getInt(path, (def instanceof Number) ? toInt(def) : 0); + } + + public int getInt(String path, int def) { + Object val = get(path, def); + return (val instanceof Number) ? toInt(val) : def; + } + + public boolean isInt(String path) { + Object val = get(path); + return val instanceof Integer; + } + + public boolean getBoolean(String path) { + Object def = getDefault(path); + return getBoolean(path, (def instanceof Boolean) ? (Boolean) def : false); + } + + public boolean getBoolean(String path, boolean def) { + Object val = get(path, def); + return (val instanceof Boolean) ? (Boolean) val : def; + } + + public boolean isBoolean(String path) { + Object val = get(path); + return val instanceof Boolean; + } + + public double getDouble(String path) { + Object def = getDefault(path); + return getDouble(path, (def instanceof Number) ? toDouble(def) : 0); + } + + public double getDouble(String path, double def) { + Object val = get(path, def); + return (val instanceof Number) ? toDouble(val) : def; + } + + public boolean isDouble(String path) { + Object val = get(path); + return val instanceof Double; + } + + // PaperSpigot start - Add getFloat + public float getFloat(String path) { + Object def = getDefault(path); + return getFloat(path, (def instanceof Float) ? toFloat(def) : 0); + } + + public float getFloat(String path, float def) { + Object val = get(path, def); + return (val instanceof Float) ? toFloat(val) : def; + } + + public boolean isFloat(String path) { + Object val = get(path); + return val instanceof Float; + } + // PaperSpigot end + + public long getLong(String path) { + Object def = getDefault(path); + return getLong(path, (def instanceof Number) ? toLong(def) : 0); + } + + public long getLong(String path, long def) { + Object val = get(path, def); + return (val instanceof Number) ? toLong(val) : def; + } + + public boolean isLong(String path) { + Object val = get(path); + return val instanceof Long; + } + + // Java + public List getList(String path) { + Object def = getDefault(path); + return getList(path, (def instanceof List) ? (List) def : null); + } + + public List getList(String path, List def) { + Object val = get(path, def); + return (List) ((val instanceof List) ? val : def); + } + + public boolean isList(String path) { + Object val = get(path); + return val instanceof List; + } + + public List getStringList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if ((object instanceof String) || (isPrimitiveWrapper(object))) { + result.add(String.valueOf(object)); + } + } + + return result; + } + + public List getIntegerList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if (object instanceof Integer) { + result.add((Integer) object); + } else if (object instanceof String) { + try { + result.add(Integer.valueOf((String) object)); + } catch (Exception ex) { + } + } else if (object instanceof Character) { + result.add((int) ((Character) object).charValue()); + } else if (object instanceof Number) { + result.add(((Number) object).intValue()); + } + } + + return result; + } + + public List getBooleanList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if (object instanceof Boolean) { + result.add((Boolean) object); + } else if (object instanceof String) { + if (Boolean.TRUE.toString().equals(object)) { + result.add(true); + } else if (Boolean.FALSE.toString().equals(object)) { + result.add(false); + } + } + } + + return result; + } + + public List getDoubleList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if (object instanceof Double) { + result.add((Double) object); + } else if (object instanceof String) { + try { + result.add(Double.valueOf((String) object)); + } catch (Exception ex) { + } + } else if (object instanceof Character) { + result.add((double) ((Character) object).charValue()); + } else if (object instanceof Number) { + result.add(((Number) object).doubleValue()); + } + } + + return result; + } + + public List getFloatList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if (object instanceof Float) { + result.add((Float) object); + } else if (object instanceof String) { + try { + result.add(Float.valueOf((String) object)); + } catch (Exception ex) { + } + } else if (object instanceof Character) { + result.add((float) ((Character) object).charValue()); + } else if (object instanceof Number) { + result.add(((Number) object).floatValue()); + } + } + + return result; + } + + public List getLongList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if (object instanceof Long) { + result.add((Long) object); + } else if (object instanceof String) { + try { + result.add(Long.valueOf((String) object)); + } catch (Exception ex) { + } + } else if (object instanceof Character) { + result.add((long) ((Character) object).charValue()); + } else if (object instanceof Number) { + result.add(((Number) object).longValue()); + } + } + + return result; + } + + public List getByteList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if (object instanceof Byte) { + result.add((Byte) object); + } else if (object instanceof String) { + try { + result.add(Byte.valueOf((String) object)); + } catch (Exception ex) { + } + } else if (object instanceof Character) { + result.add((byte) ((Character) object).charValue()); + } else if (object instanceof Number) { + result.add(((Number) object).byteValue()); + } + } + + return result; + } + + public List getCharacterList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if (object instanceof Character) { + result.add((Character) object); + } else if (object instanceof String) { + String str = (String) object; + + if (str.length() == 1) { + result.add(str.charAt(0)); + } + } else if (object instanceof Number) { + result.add((char) ((Number) object).intValue()); + } + } + + return result; + } + + public List getShortList(String path) { + List list = getList(path); + + if (list == null) { + return new ArrayList(0); + } + + List result = new ArrayList(); + + for (Object object : list) { + if (object instanceof Short) { + result.add((Short) object); + } else if (object instanceof String) { + try { + result.add(Short.valueOf((String) object)); + } catch (Exception ex) { + } + } else if (object instanceof Character) { + result.add((short) ((Character) object).charValue()); + } else if (object instanceof Number) { + result.add(((Number) object).shortValue()); + } + } + + return result; + } + + public List> getMapList(String path) { + List list = getList(path); + List> result = new ArrayList>(); + + if (list == null) { + return result; + } + + for (Object object : list) { + if (object instanceof Map) { + result.add((Map) object); + } + } + + return result; + } + + // Bukkit + public Vector getVector(String path) { + Object def = getDefault(path); + return getVector(path, (def instanceof Vector) ? (Vector) def : null); + } + + public Vector getVector(String path, Vector def) { + Object val = get(path, def); + return (val instanceof Vector) ? (Vector) val : def; + } + + public boolean isVector(String path) { + Object val = get(path); + return val instanceof Vector; + } + + public OfflinePlayer getOfflinePlayer(String path) { + Object def = getDefault(path); + return getOfflinePlayer(path, (def instanceof OfflinePlayer) ? (OfflinePlayer) def : null); + } + + public OfflinePlayer getOfflinePlayer(String path, OfflinePlayer def) { + Object val = get(path, def); + return (val instanceof OfflinePlayer) ? (OfflinePlayer) val : def; + } + + public boolean isOfflinePlayer(String path) { + Object val = get(path); + return val instanceof OfflinePlayer; + } + + public ItemStack getItemStack(String path) { + Object def = getDefault(path); + return getItemStack(path, (def instanceof ItemStack) ? (ItemStack) def : null); + } + + public ItemStack getItemStack(String path, ItemStack def) { + Object val = get(path, def); + return (val instanceof ItemStack) ? (ItemStack) val : def; + } + + public boolean isItemStack(String path) { + Object val = get(path); + return val instanceof ItemStack; + } + + public Color getColor(String path) { + Object def = getDefault(path); + return getColor(path, (def instanceof Color) ? (Color) def : null); + } + + public Color getColor(String path, Color def) { + Object val = get(path, def); + return (val instanceof Color) ? (Color) val : def; + } + + public boolean isColor(String path) { + Object val = get(path); + return val instanceof Color; + } + + public ConfigurationSection getConfigurationSection(String path) { + Object val = get(path, null); + if (val != null) { + return (val instanceof ConfigurationSection) ? (ConfigurationSection) val : null; + } + + val = get(path, getDefault(path)); + return (val instanceof ConfigurationSection) ? createSection(path) : null; + } + + public boolean isConfigurationSection(String path) { + Object val = get(path); + return val instanceof ConfigurationSection; + } + + protected boolean isPrimitiveWrapper(Object input) { + return input instanceof Integer || input instanceof Boolean || + input instanceof Character || input instanceof Byte || + input instanceof Short || input instanceof Double || + input instanceof Long || input instanceof Float; + } + + protected Object getDefault(String path) { + Validate.notNull(path, "Path cannot be null"); + + Configuration root = getRoot(); + Configuration defaults = root == null ? null : root.getDefaults(); + return (defaults == null) ? null : defaults.get(createPath(this, path)); + } + + protected void mapChildrenKeys(Set output, ConfigurationSection section, boolean deep) { + if (section instanceof MemorySection) { + MemorySection sec = (MemorySection) section; + + for (Map.Entry entry : sec.map.entrySet()) { + output.add(createPath(section, entry.getKey(), this)); + + if ((deep) && (entry.getValue() instanceof ConfigurationSection)) { + ConfigurationSection subsection = (ConfigurationSection) entry.getValue(); + mapChildrenKeys(output, subsection, deep); + } + } + } else { + Set keys = section.getKeys(deep); + + for (String key : keys) { + output.add(createPath(section, key, this)); + } + } + } + + protected void mapChildrenValues(Map output, ConfigurationSection section, boolean deep) { + if (section instanceof MemorySection) { + MemorySection sec = (MemorySection) section; + + for (Map.Entry entry : sec.map.entrySet()) { + output.put(createPath(section, entry.getKey(), this), entry.getValue()); + + if (entry.getValue() instanceof ConfigurationSection) { + if (deep) { + mapChildrenValues(output, (ConfigurationSection) entry.getValue(), deep); + } + } + } + } else { + Map values = section.getValues(deep); + + for (Map.Entry entry : values.entrySet()) { + output.put(createPath(section, entry.getKey(), this), entry.getValue()); + } + } + } + + /** + * Creates a full path to the given {@link ConfigurationSection} from its + * root {@link Configuration}. + *

+ * You may use this method for any given {@link ConfigurationSection}, not + * only {@link MemorySection}. + * + * @param section Section to create a path for. + * @param key Name of the specified section. + * @return Full path of the section from its root. + */ + public static String createPath(ConfigurationSection section, String key) { + return createPath(section, key, (section == null) ? null : section.getRoot()); + } + + /** + * Creates a relative path to the given {@link ConfigurationSection} from + * the given relative section. + *

+ * You may use this method for any given {@link ConfigurationSection}, not + * only {@link MemorySection}. + * + * @param section Section to create a path for. + * @param key Name of the specified section. + * @param relativeTo Section to create the path relative to. + * @return Full path of the section from its root. + */ + public static String createPath(ConfigurationSection section, String key, ConfigurationSection relativeTo) { + Validate.notNull(section, "Cannot create path without a section"); + Configuration root = section.getRoot(); + if (root == null) { + throw new IllegalStateException("Cannot create path without a root"); + } + char separator = root.options().pathSeparator(); + + StringBuilder builder = new StringBuilder(); + if (section != null) { + for (ConfigurationSection parent = section; (parent != null) && (parent != relativeTo); parent = parent.getParent()) { + if (builder.length() > 0) { + builder.insert(0, separator); + } + + builder.insert(0, parent.getName()); + } + } + + if ((key != null) && (key.length() > 0)) { + if (builder.length() > 0) { + builder.append(separator); + } + + builder.append(key); + } + + return builder.toString(); + } + + @Override + public String toString() { + Configuration root = getRoot(); + return new StringBuilder() + .append(getClass().getSimpleName()) + .append("[path='") + .append(getCurrentPath()) + .append("', root='") + .append(root == null ? null : root.getClass().getSimpleName()) + .append("']") + .toString(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/FileConfiguration.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/FileConfiguration.java new file mode 100644 index 0000000..9cbe0ca --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/FileConfiguration.java @@ -0,0 +1,290 @@ +package org.bukkit.configuration.file; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.InvalidConfigurationException; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.Charset; + +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.MemoryConfiguration; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +/** + * This is a base class for all File based implementations of {@link + * Configuration} + */ +public abstract class FileConfiguration extends MemoryConfiguration { + /** + * This value specified that the system default encoding should be + * completely ignored, as it cannot handle the ASCII character set, or it + * is a strict-subset of UTF8 already (plain ASCII). + * + * @deprecated temporary compatibility measure + */ + @Deprecated + public static final boolean UTF8_OVERRIDE; + /** + * This value specifies if the system default encoding is unicode, but + * cannot parse standard ASCII. + * + * @deprecated temporary compatibility measure + */ + @Deprecated + public static final boolean UTF_BIG; + /** + * This value specifies if the system supports unicode. + * + * @deprecated temporary compatibility measure + */ + @Deprecated + public static final boolean SYSTEM_UTF; + static { + final byte[] testBytes = Base64Coder.decode("ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX4NCg=="); + final String testString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\r\n"; + final Charset defaultCharset = Charset.defaultCharset(); + final String resultString = new String(testBytes, defaultCharset); + final boolean trueUTF = defaultCharset.name().contains("UTF"); + UTF8_OVERRIDE = !testString.equals(resultString) || defaultCharset.equals(Charset.forName("US-ASCII")); + SYSTEM_UTF = trueUTF || UTF8_OVERRIDE; + UTF_BIG = trueUTF && UTF8_OVERRIDE; + } + + /** + * Creates an empty {@link FileConfiguration} with no default values. + */ + public FileConfiguration() { + super(); + } + + /** + * Creates an empty {@link FileConfiguration} using the specified {@link + * Configuration} as a source for all default values. + * + * @param defaults Default value provider + */ + public FileConfiguration(Configuration defaults) { + super(defaults); + } + + /** + * Saves this {@link FileConfiguration} to the specified location. + *

+ * If the file does not exist, it will be created. If already exists, it + * will be overwritten. If it cannot be overwritten or created, an + * exception will be thrown. + *

+ * This method will save using the system default encoding, or possibly + * using UTF8. + * + * @param file File to save to. + * @throws IOException Thrown when the given file cannot be written to for + * any reason. + * @throws IllegalArgumentException Thrown when file is null. + */ + public void save(File file) throws IOException { + Validate.notNull(file, "File cannot be null"); + + Files.createParentDirs(file); + + String data = saveToString(); + + Writer writer = new OutputStreamWriter(new FileOutputStream(file), UTF8_OVERRIDE && !UTF_BIG ? Charsets.UTF_8 : Charset.defaultCharset()); + + try { + writer.write(data); + } finally { + writer.close(); + } + } + + /** + * Saves this {@link FileConfiguration} to the specified location. + *

+ * If the file does not exist, it will be created. If already exists, it + * will be overwritten. If it cannot be overwritten or created, an + * exception will be thrown. + *

+ * This method will save using the system default encoding, or possibly + * using UTF8. + * + * @param file File to save to. + * @throws IOException Thrown when the given file cannot be written to for + * any reason. + * @throws IllegalArgumentException Thrown when file is null. + */ + public void save(String file) throws IOException { + Validate.notNull(file, "File cannot be null"); + + save(new File(file)); + } + + /** + * Saves this {@link FileConfiguration} to a string, and returns it. + * + * @return String containing this configuration. + */ + public abstract String saveToString(); + + /** + * Loads this {@link FileConfiguration} from the specified location. + *

+ * All the values contained within this configuration will be removed, + * leaving only settings and defaults, and the new values will be loaded + * from the given file. + *

+ * If the file cannot be loaded for any reason, an exception will be + * thrown. + *

+ * This will attempt to use the {@link Charset#defaultCharset()} for + * files, unless {@link #UTF8_OVERRIDE} but not {@link #UTF_BIG} is + * specified. + * + * @param file File to load from. + * @throws FileNotFoundException Thrown when the given file cannot be + * opened. + * @throws IOException Thrown when the given file cannot be read. + * @throws InvalidConfigurationException Thrown when the given file is not + * a valid Configuration. + * @throws IllegalArgumentException Thrown when file is null. + */ + public void load(File file) throws FileNotFoundException, IOException, InvalidConfigurationException { + Validate.notNull(file, "File cannot be null"); + + final FileInputStream stream = new FileInputStream(file); + + load(new InputStreamReader(stream, UTF8_OVERRIDE && !UTF_BIG ? Charsets.UTF_8 : Charset.defaultCharset())); + } + + /** + * Loads this {@link FileConfiguration} from the specified stream. + *

+ * All the values contained within this configuration will be removed, + * leaving only settings and defaults, and the new values will be loaded + * from the given stream. + *

+ * This will attempt to use the {@link Charset#defaultCharset()}, unless + * {@link #UTF8_OVERRIDE} or {@link #UTF_BIG} is specified. + * + * @param stream Stream to load from + * @throws IOException Thrown when the given file cannot be read. + * @throws InvalidConfigurationException Thrown when the given file is not + * a valid Configuration. + * @throws IllegalArgumentException Thrown when stream is null. + * @deprecated This does not consider encoding + * @see #load(Reader) + */ + @Deprecated + public void load(InputStream stream) throws IOException, InvalidConfigurationException { + Validate.notNull(stream, "Stream cannot be null"); + + load(new InputStreamReader(stream, UTF8_OVERRIDE ? Charsets.UTF_8 : Charset.defaultCharset())); + } + + /** + * Loads this {@link FileConfiguration} from the specified reader. + *

+ * All the values contained within this configuration will be removed, + * leaving only settings and defaults, and the new values will be loaded + * from the given stream. + * + * @param reader the reader to load from + * @throws IOException thrown when underlying reader throws an IOException + * @throws InvalidConfigurationException thrown when the reader does not + * represent a valid Configuration + * @throws IllegalArgumentException thrown when reader is null + */ + public void load(Reader reader) throws IOException, InvalidConfigurationException { + BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader); + + StringBuilder builder = new StringBuilder(); + + try { + String line; + + while ((line = input.readLine()) != null) { + builder.append(line); + builder.append('\n'); + } + } finally { + input.close(); + } + + loadFromString(builder.toString()); + } + + /** + * Loads this {@link FileConfiguration} from the specified location. + *

+ * All the values contained within this configuration will be removed, + * leaving only settings and defaults, and the new values will be loaded + * from the given file. + *

+ * If the file cannot be loaded for any reason, an exception will be + * thrown. + * + * @param file File to load from. + * @throws FileNotFoundException Thrown when the given file cannot be + * opened. + * @throws IOException Thrown when the given file cannot be read. + * @throws InvalidConfigurationException Thrown when the given file is not + * a valid Configuration. + * @throws IllegalArgumentException Thrown when file is null. + */ + public void load(String file) throws FileNotFoundException, IOException, InvalidConfigurationException { + Validate.notNull(file, "File cannot be null"); + + load(new File(file)); + } + + /** + * Loads this {@link FileConfiguration} from the specified string, as + * opposed to from file. + *

+ * All the values contained within this configuration will be removed, + * leaving only settings and defaults, and the new values will be loaded + * from the given string. + *

+ * If the string is invalid in any way, an exception will be thrown. + * + * @param contents Contents of a Configuration to load. + * @throws InvalidConfigurationException Thrown if the specified string is + * invalid. + * @throws IllegalArgumentException Thrown if contents is null. + */ + public abstract void loadFromString(String contents) throws InvalidConfigurationException; + + /** + * Compiles the header for this {@link FileConfiguration} and returns the + * result. + *

+ * This will use the header from {@link #options()} -> {@link + * FileConfigurationOptions#header()}, respecting the rules of {@link + * FileConfigurationOptions#copyHeader()} if set. + * + * @return Compiled header + */ + protected abstract String buildHeader(); + + @Override + public FileConfigurationOptions options() { + if (options == null) { + options = new FileConfigurationOptions(this); + } + + return (FileConfigurationOptions) options; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/FileConfigurationOptions.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/FileConfigurationOptions.java new file mode 100644 index 0000000..ccf81e0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/FileConfigurationOptions.java @@ -0,0 +1,118 @@ +package org.bukkit.configuration.file; + +import org.bukkit.configuration.*; + +/** + * Various settings for controlling the input and output of a {@link + * FileConfiguration} + */ +public class FileConfigurationOptions extends MemoryConfigurationOptions { + private String header = null; + private boolean copyHeader = true; + + protected FileConfigurationOptions(MemoryConfiguration configuration) { + super(configuration); + } + + @Override + public FileConfiguration configuration() { + return (FileConfiguration) super.configuration(); + } + + @Override + public FileConfigurationOptions copyDefaults(boolean value) { + super.copyDefaults(value); + return this; + } + + @Override + public FileConfigurationOptions pathSeparator(char value) { + super.pathSeparator(value); + return this; + } + + /** + * Gets the header that will be applied to the top of the saved output. + *

+ * This header will be commented out and applied directly at the top of + * the generated output of the {@link FileConfiguration}. It is not + * required to include a newline at the end of the header as it will + * automatically be applied, but you may include one if you wish for extra + * spacing. + *

+ * Null is a valid value which will indicate that no header is to be + * applied. The default value is null. + * + * @return Header + */ + public String header() { + return header; + } + + /** + * Sets the header that will be applied to the top of the saved output. + *

+ * This header will be commented out and applied directly at the top of + * the generated output of the {@link FileConfiguration}. It is not + * required to include a newline at the end of the header as it will + * automatically be applied, but you may include one if you wish for extra + * spacing. + *

+ * Null is a valid value which will indicate that no header is to be + * applied. + * + * @param value New header + * @return This object, for chaining + */ + public FileConfigurationOptions header(String value) { + this.header = value; + return this; + } + + /** + * Gets whether or not the header should be copied from a default source. + *

+ * If this is true, if a default {@link FileConfiguration} is passed to + * {@link + * FileConfiguration#setDefaults(org.bukkit.configuration.Configuration)} + * then upon saving it will use the header from that config, instead of + * the one provided here. + *

+ * If no default is set on the configuration, or the default is not of + * type FileConfiguration, or that config has no header ({@link #header()} + * returns null) then the header specified in this configuration will be + * used. + *

+ * Defaults to true. + * + * @return Whether or not to copy the header + */ + public boolean copyHeader() { + return copyHeader; + } + + /** + * Sets whether or not the header should be copied from a default source. + *

+ * If this is true, if a default {@link FileConfiguration} is passed to + * {@link + * FileConfiguration#setDefaults(org.bukkit.configuration.Configuration)} + * then upon saving it will use the header from that config, instead of + * the one provided here. + *

+ * If no default is set on the configuration, or the default is not of + * type FileConfiguration, or that config has no header ({@link #header()} + * returns null) then the header specified in this configuration will be + * used. + *

+ * Defaults to true. + * + * @param value Whether or not to copy the header + * @return This object, for chaining + */ + public FileConfigurationOptions copyHeader(boolean value) { + copyHeader = value; + + return this; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java new file mode 100644 index 0000000..a3711cf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java @@ -0,0 +1,279 @@ +package org.bukkit.configuration.file; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.error.YAMLException; +import org.yaml.snakeyaml.representer.Representer; + +/** + * An implementation of {@link Configuration} which saves all files in Yaml. + * Note that this implementation is not synchronized. + */ +public class YamlConfiguration extends FileConfiguration { + protected static final String COMMENT_PREFIX = "# "; + protected static final String BLANK_CONFIG = "{}\n"; + private final DumperOptions yamlOptions = new DumperOptions(); + private final Representer yamlRepresenter = new YamlRepresenter(); + private final Yaml yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions); + + private Map> comments = new HashMap<>(); + private String fileName; + + public void setComments(Map> comments) { + this.comments = comments; + } + + public void setFileName(String name) { + this.fileName = name; + } + + @Override + public String saveToString() { + yamlOptions.setIndent(options().indent()); + yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + yamlOptions.setAllowUnicode(SYSTEM_UTF); + yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + + String header = buildHeader(); + String dump = yaml.dump(getValues(false)); + + if (dump.equals(BLANK_CONFIG)) { + dump = ""; + } + + return header + dump; + } + + @Override + public void loadFromString(String contents) throws InvalidConfigurationException { + Validate.notNull(contents, "Contents cannot be null"); + + Map input; + try { + input = (Map) yaml.load(contents); + } catch (YAMLException e) { + throw new InvalidConfigurationException(e); + } catch (ClassCastException e) { + throw new InvalidConfigurationException("Top level is not a Map."); + } + + String header = parseHeader(contents); + if (header.length() > 0) { + options().header(header); + } + + if (input != null) { + convertMapsToSections(input, this); + } + } + + protected void convertMapsToSections(Map input, ConfigurationSection section) { + for (Map.Entry entry : input.entrySet()) { + String key = entry.getKey().toString(); + Object value = entry.getValue(); + + if (value instanceof Map) { + convertMapsToSections((Map) value, section.createSection(key)); + } else { + section.set(key, value); + } + } + } + + protected String parseHeader(String input) { + String[] lines = input.split("\r?\n", -1); + StringBuilder result = new StringBuilder(); + boolean readingHeader = true; + boolean foundHeader = false; + + for (int i = 0; (i < lines.length) && (readingHeader); i++) { + String line = lines[i]; + + if (line.startsWith(COMMENT_PREFIX)) { + if (i > 0) { + result.append("\n"); + } + + if (line.length() > COMMENT_PREFIX.length()) { + result.append(line.substring(COMMENT_PREFIX.length())); + } + + foundHeader = true; + } else if ((foundHeader) && (line.length() == 0)) { + result.append("\n"); + } else if (foundHeader) { + readingHeader = false; + } + } + + return result.toString(); + } + + @Override + protected String buildHeader() { + String header = options().header(); + + if (options().copyHeader()) { + Configuration def = getDefaults(); + + if ((def != null) && (def instanceof FileConfiguration)) { + FileConfiguration filedefaults = (FileConfiguration) def; + String defaultsHeader = filedefaults.buildHeader(); + + if ((defaultsHeader != null) && (defaultsHeader.length() > 0)) { + return defaultsHeader; + } + } + } + + if (header == null) { + return ""; + } + + StringBuilder builder = new StringBuilder(); + String[] lines = header.split("\r?\n", -1); + boolean startedHeader = false; + + for (int i = lines.length - 1; i >= 0; i--) { + builder.insert(0, "\n"); + + if ((startedHeader) || (lines[i].length() != 0)) { + builder.insert(0, lines[i]); + builder.insert(0, COMMENT_PREFIX); + startedHeader = true; + } + } + + return builder.toString(); + } + + @Override + public YamlConfigurationOptions options() { + if (options == null) { + options = new YamlConfigurationOptions(this); + } + + return (YamlConfigurationOptions) options; + } + + /** + * Creates a new {@link YamlConfiguration}, loading from the given file. + *

+ * Any errors loading the Configuration will be logged and then ignored. + * If the specified input is not a valid config, a blank config will be + * returned. + *

+ * The encoding used may follow the system dependent default. + * + * @param file Input file + * @return Resulting configuration + * @throws IllegalArgumentException Thrown if file is null + */ + public static YamlConfiguration loadConfiguration(File file) { + Validate.notNull(file, "File cannot be null"); + + YamlConfiguration config = new YamlConfiguration(); + + config.setFileName(file.getName()); + + try { + config.load(file); + } catch (FileNotFoundException ex) { + } catch (IOException | InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex); + } + + return config; + } + + public static YamlConfiguration loadConfiguration(File file, Map> comments) { + Validate.notNull(file, "File cannot be null"); + + YamlConfiguration config = new YamlConfiguration(); + config.setComments(comments); + config.setFileName(file.getName()); + + try { + config.load(file); + } catch (FileNotFoundException ex) { + } catch (IOException | InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex); + } + + return config; + } + + /** + * Creates a new {@link YamlConfiguration}, loading from the given stream. + *

+ * Any errors loading the Configuration will be logged and then ignored. + * If the specified input is not a valid config, a blank config will be + * returned. + * + * @param stream Input stream + * @return Resulting configuration + * @throws IllegalArgumentException Thrown if stream is null + * @deprecated does not properly consider encoding + * @see #load(InputStream) + * @see #loadConfiguration(Reader) + */ + @Deprecated + public static YamlConfiguration loadConfiguration(InputStream stream) { + Validate.notNull(stream, "Stream cannot be null"); + + YamlConfiguration config = new YamlConfiguration(); + + try { + config.load(stream); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex); + } catch (InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex); + } + + return config; + } + + + /** + * Creates a new {@link YamlConfiguration}, loading from the given reader. + *

+ * Any errors loading the Configuration will be logged and then ignored. + * If the specified input is not a valid config, a blank config will be + * returned. + * + * @param reader input + * @return resulting configuration + * @throws IllegalArgumentException Thrown if stream is null + */ + public static YamlConfiguration loadConfiguration(Reader reader) { + Validate.notNull(reader, "Stream cannot be null"); + + YamlConfiguration config = new YamlConfiguration(); + + try { + config.load(reader); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex); + } catch (InvalidConfigurationException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Cannot load configuration from stream", ex); + } + + return config; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConfigurationOptions.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConfigurationOptions.java new file mode 100644 index 0000000..57894e3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConfigurationOptions.java @@ -0,0 +1,71 @@ +package org.bukkit.configuration.file; + +import org.apache.commons.lang.Validate; + +/** + * Various settings for controlling the input and output of a {@link + * YamlConfiguration} + */ +public class YamlConfigurationOptions extends FileConfigurationOptions { + private int indent = 2; + + protected YamlConfigurationOptions(YamlConfiguration configuration) { + super(configuration); + } + + @Override + public YamlConfiguration configuration() { + return (YamlConfiguration) super.configuration(); + } + + @Override + public YamlConfigurationOptions copyDefaults(boolean value) { + super.copyDefaults(value); + return this; + } + + @Override + public YamlConfigurationOptions pathSeparator(char value) { + super.pathSeparator(value); + return this; + } + + @Override + public YamlConfigurationOptions header(String value) { + super.header(value); + return this; + } + + @Override + public YamlConfigurationOptions copyHeader(boolean value) { + super.copyHeader(value); + return this; + } + + /** + * Gets how much spaces should be used to indent each line. + *

+ * The minimum value this may be is 2, and the maximum is 9. + * + * @return How much to indent by + */ + public int indent() { + return indent; + } + + /** + * Sets how much spaces should be used to indent each line. + *

+ * The minimum value this may be is 2, and the maximum is 9. + * + * @param value New indent + * @return This object, for chaining + */ + public YamlConfigurationOptions indent(int value) { + Validate.isTrue(value >= 2, "Indent must be at least 2 characters"); + Validate.isTrue(value <= 9, "Indent cannot be greater than 9 characters"); + + this.indent = value; + return this; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConstructor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConstructor.java new file mode 100644 index 0000000..73ad722 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlConstructor.java @@ -0,0 +1,49 @@ +package org.bukkit.configuration.file; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.yaml.snakeyaml.nodes.Node; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import org.yaml.snakeyaml.error.YAMLException; +import org.yaml.snakeyaml.nodes.Tag; + +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +public class YamlConstructor extends SafeConstructor { + + public YamlConstructor() { + this.yamlConstructors.put(Tag.MAP, new ConstructCustomObject()); + } + + private class ConstructCustomObject extends ConstructYamlMap { + @Override + public Object construct(Node node) { + if (node.isTwoStepsConstruction()) { + throw new YAMLException("Unexpected referential mapping structure. Node: " + node); + } + + Map raw = (Map) super.construct(node); + + if (raw.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) { + Map typed = new LinkedHashMap(raw.size()); + for (Map.Entry entry : raw.entrySet()) { + typed.put(entry.getKey().toString(), entry.getValue()); + } + + try { + return ConfigurationSerialization.deserializeObject(typed); + } catch (IllegalArgumentException ex) { + throw new YAMLException("Could not deserialize object", ex); + } + } + + return raw; + } + + @Override + public void construct2ndStep(Node node, Object object) { + throw new YAMLException("Unexpected referential mapping structure. Node: " + node); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlRepresenter.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlRepresenter.java new file mode 100644 index 0000000..bc9c098 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/file/YamlRepresenter.java @@ -0,0 +1,38 @@ +package org.bukkit.configuration.file; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +import org.yaml.snakeyaml.nodes.Node; +import org.yaml.snakeyaml.representer.Representer; + +public class YamlRepresenter extends Representer { + + public YamlRepresenter() { + this.multiRepresenters.put(ConfigurationSection.class, new RepresentConfigurationSection()); + this.multiRepresenters.put(ConfigurationSerializable.class, new RepresentConfigurationSerializable()); + } + + private class RepresentConfigurationSection extends RepresentMap { + @Override + public Node representData(Object data) { + return super.representData(((ConfigurationSection) data).getValues(false)); + } + } + + private class RepresentConfigurationSerializable extends RepresentMap { + @Override + public Node representData(Object data) { + ConfigurationSerializable serializable = (ConfigurationSerializable) data; + Map values = new LinkedHashMap(); + values.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(serializable.getClass())); + values.putAll(serializable.serialize()); + + return super.representData(values); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerializable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerializable.java new file mode 100644 index 0000000..74b73f9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerializable.java @@ -0,0 +1,35 @@ +package org.bukkit.configuration.serialization; + +import java.util.Map; + +/** + * Represents an object that may be serialized. + *

+ * These objects MUST implement one of the following, in addition to the + * methods as defined by this interface: + *

    + *
  • A static method "deserialize" that accepts a single {@link Map}< + * {@link String}, {@link Object}> and returns the class.
  • + *
  • A static method "valueOf" that accepts a single {@link Map}<{@link + * String}, {@link Object}> and returns the class.
  • + *
  • A constructor that accepts a single {@link Map}<{@link String}, + * {@link Object}>.
  • + *
+ * In addition to implementing this interface, you must register the class + * with {@link ConfigurationSerialization#registerClass(Class)}. + * + * @see DelegateDeserialization + * @see SerializableAs + */ +public interface ConfigurationSerializable { + + /** + * Creates a Map representation of this class. + *

+ * This class must provide a method to restore this class, as defined in + * the {@link ConfigurationSerializable} interface javadocs. + * + * @return Map containing the current state of this class + */ + public Map serialize(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerialization.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerialization.java new file mode 100644 index 0000000..e5ddef2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/ConfigurationSerialization.java @@ -0,0 +1,285 @@ +package org.bukkit.configuration.serialization; + +import java.lang.reflect.Constructor; +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; +import java.util.logging.Logger; + +import org.apache.commons.lang.Validate; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Location; +import org.bukkit.block.banner.Pattern; +import org.bukkit.configuration.Configuration; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.util.BlockVector; +import org.bukkit.util.Vector; + +/** + * Utility class for storing and retrieving classes for {@link Configuration}. + */ +public class ConfigurationSerialization { + public static final String SERIALIZED_TYPE_KEY = "=="; + private final Class clazz; + private static Map> aliases = new HashMap>(); + + static { + registerClass(Vector.class); + registerClass(BlockVector.class); + registerClass(ItemStack.class); + registerClass(Color.class); + registerClass(PotionEffect.class); + registerClass(FireworkEffect.class); + registerClass(Pattern.class); + registerClass(Location.class); + } + + protected ConfigurationSerialization(Class clazz) { + this.clazz = clazz; + } + + protected Method getMethod(String name, boolean isStatic) { + try { + Method method = clazz.getDeclaredMethod(name, Map.class); + + if (!ConfigurationSerializable.class.isAssignableFrom(method.getReturnType())) { + return null; + } + if (Modifier.isStatic(method.getModifiers()) != isStatic) { + return null; + } + + return method; + } catch (NoSuchMethodException ex) { + return null; + } catch (SecurityException ex) { + return null; + } + } + + protected Constructor getConstructor() { + try { + return clazz.getConstructor(Map.class); + } catch (NoSuchMethodException ex) { + return null; + } catch (SecurityException ex) { + return null; + } + } + + protected ConfigurationSerializable deserializeViaMethod(Method method, Map args) { + try { + ConfigurationSerializable result = (ConfigurationSerializable) method.invoke(null, args); + + if (result == null) { + Logger.getLogger(ConfigurationSerialization.class.getName()).log(Level.SEVERE, "Could not call method '" + method.toString() + "' of " + clazz + " for deserialization: method returned null"); + } else { + return result; + } + } catch (Throwable ex) { + Logger.getLogger(ConfigurationSerialization.class.getName()).log( + Level.SEVERE, + "Could not call method '" + method.toString() + "' of " + clazz + " for deserialization", + ex instanceof InvocationTargetException ? ex.getCause() : ex); + } + + return null; + } + + protected ConfigurationSerializable deserializeViaCtor(Constructor ctor, Map args) { + try { + return ctor.newInstance(args); + } catch (Throwable ex) { + Logger.getLogger(ConfigurationSerialization.class.getName()).log( + Level.SEVERE, + "Could not call constructor '" + ctor.toString() + "' of " + clazz + " for deserialization", + ex instanceof InvocationTargetException ? ex.getCause() : ex); + } + + return null; + } + + public ConfigurationSerializable deserialize(Map args) { + Validate.notNull(args, "Args must not be null"); + + ConfigurationSerializable result = null; + Method method = null; + + if (result == null) { + method = getMethod("deserialize", true); + + if (method != null) { + result = deserializeViaMethod(method, args); + } + } + + if (result == null) { + method = getMethod("valueOf", true); + + if (method != null) { + result = deserializeViaMethod(method, args); + } + } + + if (result == null) { + Constructor constructor = getConstructor(); + + if (constructor != null) { + result = deserializeViaCtor(constructor, args); + } + } + + return result; + } + + /** + * Attempts to deserialize the given arguments into a new instance of the + * given class. + *

+ * The class must implement {@link ConfigurationSerializable}, including + * the extra methods as specified in the javadoc of + * ConfigurationSerializable. + *

+ * If a new instance could not be made, an example being the class not + * fully implementing the interface, null will be returned. + * + * @param args Arguments for deserialization + * @param clazz Class to deserialize into + * @return New instance of the specified class + */ + public static ConfigurationSerializable deserializeObject(Map args, Class clazz) { + return new ConfigurationSerialization(clazz).deserialize(args); + } + + /** + * Attempts to deserialize the given arguments into a new instance of the + * given class. + *

+ * The class must implement {@link ConfigurationSerializable}, including + * the extra methods as specified in the javadoc of + * ConfigurationSerializable. + *

+ * If a new instance could not be made, an example being the class not + * fully implementing the interface, null will be returned. + * + * @param args Arguments for deserialization + * @return New instance of the specified class + */ + public static ConfigurationSerializable deserializeObject(Map args) { + Class clazz = null; + + if (args.containsKey(SERIALIZED_TYPE_KEY)) { + try { + String alias = (String) args.get(SERIALIZED_TYPE_KEY); + + if (alias == null) { + throw new IllegalArgumentException("Cannot have null alias"); + } + clazz = getClassByAlias(alias); + if (clazz == null) { + throw new IllegalArgumentException("Specified class does not exist ('" + alias + "')"); + } + } catch (ClassCastException ex) { + ex.fillInStackTrace(); + throw ex; + } + } else { + throw new IllegalArgumentException("Args doesn't contain type key ('" + SERIALIZED_TYPE_KEY + "')"); + } + + return new ConfigurationSerialization(clazz).deserialize(args); + } + + /** + * Registers the given {@link ConfigurationSerializable} class by its + * alias + * + * @param clazz Class to register + */ + public static void registerClass(Class clazz) { + DelegateDeserialization delegate = clazz.getAnnotation(DelegateDeserialization.class); + + if (delegate == null) { + registerClass(clazz, getAlias(clazz)); + registerClass(clazz, clazz.getName()); + } + } + + /** + * Registers the given alias to the specified {@link + * ConfigurationSerializable} class + * + * @param clazz Class to register + * @param alias Alias to register as + * @see SerializableAs + */ + public static void registerClass(Class clazz, String alias) { + aliases.put(alias, clazz); + } + + /** + * Unregisters the specified alias to a {@link ConfigurationSerializable} + * + * @param alias Alias to unregister + */ + public static void unregisterClass(String alias) { + aliases.remove(alias); + } + + /** + * Unregisters any aliases for the specified {@link + * ConfigurationSerializable} class + * + * @param clazz Class to unregister + */ + public static void unregisterClass(Class clazz) { + while (aliases.values().remove(clazz)) { + ; + } + } + + /** + * Attempts to get a registered {@link ConfigurationSerializable} class by + * its alias + * + * @param alias Alias of the serializable + * @return Registered class, or null if not found + */ + public static Class getClassByAlias(String alias) { + return aliases.get(alias); + } + + /** + * Gets the correct alias for the given {@link ConfigurationSerializable} + * class + * + * @param clazz Class to get alias for + * @return Alias to use for the class + */ + public static String getAlias(Class clazz) { + DelegateDeserialization delegate = clazz.getAnnotation(DelegateDeserialization.class); + + if (delegate != null) { + if ((delegate.value() == null) || (delegate.value() == clazz)) { + delegate = null; + } else { + return getAlias(delegate.value()); + } + } + + if (delegate == null) { + SerializableAs alias = clazz.getAnnotation(SerializableAs.class); + + if ((alias != null) && (alias.value() != null)) { + return alias.value(); + } + } + + return clazz.getName(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/DelegateDeserialization.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/DelegateDeserialization.java new file mode 100644 index 0000000..1cfae94 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/DelegateDeserialization.java @@ -0,0 +1,22 @@ +package org.bukkit.configuration.serialization; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Applies to a {@link ConfigurationSerializable} that will delegate all + * deserialization to another {@link ConfigurationSerializable}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface DelegateDeserialization { + /** + * Which class should be used as a delegate for this classes + * deserialization + * + * @return Delegate class + */ + public Class value(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/SerializableAs.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/SerializableAs.java new file mode 100644 index 0000000..c5ee998 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/configuration/serialization/SerializableAs.java @@ -0,0 +1,34 @@ +package org.bukkit.configuration.serialization; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Represents an "alias" that a {@link ConfigurationSerializable} may be + * stored as. + * If this is not present on a {@link ConfigurationSerializable} class, it + * will use the fully qualified name of the class. + *

+ * This value will be stored in the configuration so that the configuration + * deserialization can determine what type it is. + *

+ * Using this annotation on any other class than a {@link + * ConfigurationSerializable} will have no effect. + * + * @see ConfigurationSerialization#registerClass(Class, String) + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SerializableAs { + /** + * This is the name your class will be stored and retrieved as. + *

+ * This name MUST be unique. We recommend using names such as + * "MyPluginThing" instead of "Thing". + * + * @return Name to serialize the class as. + */ + public String value(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/BooleanPrompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/BooleanPrompt.java new file mode 100644 index 0000000..81ef78c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/BooleanPrompt.java @@ -0,0 +1,37 @@ +package org.bukkit.conversations; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.BooleanUtils; + +/** + * BooleanPrompt is the base class for any prompt that requires a boolean + * response from the user. + */ +public abstract class BooleanPrompt extends ValidatingPrompt{ + + public BooleanPrompt() { + super(); + } + + @Override + protected boolean isInputValid(ConversationContext context, String input) { + String[] accepted = {"true", "false", "on", "off", "yes", "no" /* Spigot: */, "y", "n", "1", "0", "right", "wrong", "correct", "incorrect", "valid", "invalid"}; // Spigot + return ArrayUtils.contains(accepted, input.toLowerCase()); + } + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, String input) { + if (input.equalsIgnoreCase("y") || input.equals("1") || input.equalsIgnoreCase("right") || input.equalsIgnoreCase("correct") || input.equalsIgnoreCase("valid")) input = "true"; // Spigot + return acceptValidatedInput(context, BooleanUtils.toBoolean(input)); + } + + /** + * Override this method to perform some action with the user's boolean + * response. + * + * @param context Context information about the conversation. + * @param input The user's boolean response. + * @return The next {@link Prompt} in the prompt graph. + */ + protected abstract Prompt acceptValidatedInput(ConversationContext context, boolean input); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Conversable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Conversable.java new file mode 100644 index 0000000..55674b5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Conversable.java @@ -0,0 +1,57 @@ +package org.bukkit.conversations; + +import org.bukkit.command.CommandSender; + +/** + * The Conversable interface is used to indicate objects that can have + * conversations. + */ +public interface Conversable { + + /** + * Tests to see of a Conversable object is actively engaged in a + * conversation. + * + * @return True if a conversation is in progress + */ + public boolean isConversing(); + + /** + * Accepts input into the active conversation. If no conversation is in + * progress, this method does nothing. + * + * @param input The input message into the conversation + */ + public void acceptConversationInput(String input); + + /** + * Enters into a dialog with a Conversation object. + * + * @param conversation The conversation to begin + * @return True if the conversation should proceed, false if it has been + * enqueued + */ + public boolean beginConversation(Conversation conversation); + + /** + * Abandons an active conversation. + * + * @param conversation The conversation to abandon + */ + public void abandonConversation(Conversation conversation); + + /** + * Abandons an active conversation. + * + * @param conversation The conversation to abandon + * @param details Details about why the conversation was abandoned + */ + public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details); + + /** + * Sends this sender a message raw + * + * @param message Message to be displayed + */ + public void sendRawMessage(String message); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Conversation.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Conversation.java new file mode 100644 index 0000000..46912c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Conversation.java @@ -0,0 +1,304 @@ +package org.bukkit.conversations; + +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * The Conversation class is responsible for tracking the current state of a + * conversation, displaying prompts to the user, and dispatching the user's + * response to the appropriate place. Conversation objects are not typically + * instantiated directly. Instead a {@link ConversationFactory} is used to + * construct identical conversations on demand. + *

+ * Conversation flow consists of a directed graph of {@link Prompt} objects. + * Each time a prompt gets input from the user, it must return the next prompt + * in the graph. Since each Prompt chooses the next Prompt, complex + * conversation trees can be implemented where the nature of the player's + * response directs the flow of the conversation. + *

+ * Each conversation has a {@link ConversationPrefix} that prepends all output + * from the conversation to the player. The ConversationPrefix can be used to + * display the plugin name or conversation status as the conversation evolves. + *

+ * Each conversation has a timeout measured in the number of inactive seconds + * to wait before abandoning the conversation. If the inactivity timeout is + * reached, the conversation is abandoned and the user's incoming and outgoing + * chat is returned to normal. + *

+ * You should not construct a conversation manually. Instead, use the {@link + * ConversationFactory} for access to all available options. + */ +public class Conversation { + + private Prompt firstPrompt; + private boolean abandoned; + protected Prompt currentPrompt; + protected ConversationContext context; + protected boolean modal; + protected boolean localEchoEnabled; + protected ConversationPrefix prefix; + protected List cancellers; + protected List abandonedListeners; + + /** + * Initializes a new Conversation. + * + * @param plugin The plugin that owns this conversation. + * @param forWhom The entity for whom this conversation is mediating. + * @param firstPrompt The first prompt in the conversation graph. + */ + public Conversation(Plugin plugin, Conversable forWhom, Prompt firstPrompt) { + this(plugin, forWhom, firstPrompt, new HashMap()); + } + + /** + * Initializes a new Conversation. + * + * @param plugin The plugin that owns this conversation. + * @param forWhom The entity for whom this conversation is mediating. + * @param firstPrompt The first prompt in the conversation graph. + * @param initialSessionData Any initial values to put in the conversation + * context sessionData map. + */ + public Conversation(Plugin plugin, Conversable forWhom, Prompt firstPrompt, Map initialSessionData) { + this.firstPrompt = firstPrompt; + this.context = new ConversationContext(plugin, forWhom, initialSessionData); + this.modal = true; + this.localEchoEnabled = true; + this.prefix = new NullConversationPrefix(); + this.cancellers = new ArrayList(); + this.abandonedListeners = new ArrayList(); + } + + /** + * Gets the entity for whom this conversation is mediating. + * + * @return The entity. + */ + public Conversable getForWhom() { + return context.getForWhom(); + } + + /** + * Gets the modality of this conversation. If a conversation is modal, all + * messages directed to the player are suppressed for the duration of the + * conversation. + * + * @return The conversation modality. + */ + public boolean isModal() { + return modal; + } + + /** + * Sets the modality of this conversation. If a conversation is modal, + * all messages directed to the player are suppressed for the duration of + * the conversation. + * + * @param modal The new conversation modality. + */ + void setModal(boolean modal) { + this.modal = modal; + } + + /** + * Gets the status of local echo for this conversation. If local echo is + * enabled, any text submitted to a conversation gets echoed back into the + * submitter's chat window. + * + * @return The status of local echo. + */ + public boolean isLocalEchoEnabled() { + return localEchoEnabled; + } + + /** + * Sets the status of local echo for this conversation. If local echo is + * enabled, any text submitted to a conversation gets echoed back into the + * submitter's chat window. + * + * @param localEchoEnabled The status of local echo. + */ + public void setLocalEchoEnabled(boolean localEchoEnabled) { + this.localEchoEnabled = localEchoEnabled; + } + + /** + * Gets the {@link ConversationPrefix} that prepends all output from this + * conversation. + * + * @return The ConversationPrefix in use. + */ + public ConversationPrefix getPrefix() { + return prefix; + } + + /** + * Sets the {@link ConversationPrefix} that prepends all output from this + * conversation. + * + * @param prefix The ConversationPrefix to use. + */ + void setPrefix(ConversationPrefix prefix) { + this.prefix = prefix; + } + + /** + * Adds a {@link ConversationCanceller} to the cancellers collection. + * + * @param canceller The {@link ConversationCanceller} to add. + */ + void addConversationCanceller(ConversationCanceller canceller) { + canceller.setConversation(this); + this.cancellers.add(canceller); + } + + /** + * Gets the list of {@link ConversationCanceller}s + * + * @return The list. + */ + public List getCancellers() { + return cancellers; + } + + /** + * Returns the Conversation's {@link ConversationContext}. + * + * @return The ConversationContext. + */ + public ConversationContext getContext() { + return context; + } + + /** + * Displays the first prompt of this conversation and begins redirecting + * the user's chat responses. + */ + public void begin() { + if (currentPrompt == null) { + abandoned = false; + currentPrompt = firstPrompt; + context.getForWhom().beginConversation(this); + } + } + + /** + * Returns Returns the current state of the conversation. + * + * @return The current state of the conversation. + */ + public ConversationState getState() { + if (currentPrompt != null) { + return ConversationState.STARTED; + } else if (abandoned) { + return ConversationState.ABANDONED; + } else { + return ConversationState.UNSTARTED; + } + } + + /** + * Passes player input into the current prompt. The next prompt (as + * determined by the current prompt) is then displayed to the user. + * + * @param input The user's chat text. + */ + public void acceptInput(String input) { + try { // Spigot + if (currentPrompt != null) { + + // Echo the user's input + if (localEchoEnabled) { + context.getForWhom().sendRawMessage(prefix.getPrefix(context) + input); + } + + // Test for conversation abandonment based on input + for(ConversationCanceller canceller : cancellers) { + if (canceller.cancelBasedOnInput(context, input)) { + abandon(new ConversationAbandonedEvent(this, canceller)); + return; + } + } + + // Not abandoned, output the next prompt + currentPrompt = currentPrompt.acceptInput(context, input); + outputNextPrompt(); + } + // Spigot Start + } catch ( Throwable t ) + { + org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.SEVERE, "Error handling conversation prompt", t ); + } + // Spigot End + } + + /** + * Adds a {@link ConversationAbandonedListener}. + * + * @param listener The listener to add. + */ + public synchronized void addConversationAbandonedListener(ConversationAbandonedListener listener) { + abandonedListeners.add(listener); + } + + /** + * Removes a {@link ConversationAbandonedListener}. + * + * @param listener The listener to remove. + */ + public synchronized void removeConversationAbandonedListener(ConversationAbandonedListener listener) { + abandonedListeners.remove(listener); + } + + /** + * Abandons and resets the current conversation. Restores the user's + * normal chat behavior. + */ + public void abandon() { + abandon(new ConversationAbandonedEvent(this, new ManuallyAbandonedConversationCanceller())); + } + + /** + * Abandons and resets the current conversation. Restores the user's + * normal chat behavior. + * + * @param details Details about why the conversation was abandoned + */ + public synchronized void abandon(ConversationAbandonedEvent details) { + if (!abandoned) { + abandoned = true; + currentPrompt = null; + context.getForWhom().abandonConversation(this); + for (ConversationAbandonedListener listener : abandonedListeners) { + listener.conversationAbandoned(details); + } + } + } + + /** + * Displays the next user prompt and abandons the conversation if the next + * prompt is null. + */ + public void outputNextPrompt() { + if (currentPrompt == null) { + abandon(new ConversationAbandonedEvent(this)); + } else { + context.getForWhom().sendRawMessage(prefix.getPrefix(context) + currentPrompt.getPromptText(context)); + if (!currentPrompt.blocksForInput(context)) { + currentPrompt = currentPrompt.acceptInput(context, null); + outputNextPrompt(); + } + } + } + + public enum ConversationState { + UNSTARTED, + STARTED, + ABANDONED + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationAbandonedEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationAbandonedEvent.java new file mode 100644 index 0000000..63c4a2a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationAbandonedEvent.java @@ -0,0 +1,53 @@ +package org.bukkit.conversations; + +import java.util.EventObject; + +/** + * ConversationAbandonedEvent contains information about an abandoned + * conversation. + */ +public class ConversationAbandonedEvent extends EventObject { + + private ConversationContext context; + private ConversationCanceller canceller; + + public ConversationAbandonedEvent(Conversation conversation) { + this(conversation, null); + } + + public ConversationAbandonedEvent(Conversation conversation, ConversationCanceller canceller) { + super(conversation); + this.context = conversation.getContext(); + this.canceller = canceller; + } + + /** + * Gets the object that caused the conversation to be abandoned. + * + * @return The object that abandoned the conversation. + */ + public ConversationCanceller getCanceller() { + return canceller; + } + + /** + * Gets the abandoned conversation's conversation context. + * + * @return The abandoned conversation's conversation context. + */ + public ConversationContext getContext() { + return context; + } + + /** + * Indicates how the conversation was abandoned - naturally as part of the + * prompt chain or prematurely via a {@link ConversationCanceller}. + * + * @return True if the conversation is abandoned gracefully by a {@link + * Prompt} returning null or the next prompt. False of the + * conversations is abandoned prematurely by a ConversationCanceller. + */ + public boolean gracefulExit() { + return canceller == null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationAbandonedListener.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationAbandonedListener.java new file mode 100644 index 0000000..dc046b1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationAbandonedListener.java @@ -0,0 +1,15 @@ +package org.bukkit.conversations; + +import java.util.EventListener; + +/** + */ +public interface ConversationAbandonedListener extends EventListener { + /** + * Called whenever a {@link Conversation} is abandoned. + * + * @param abandonedEvent Contains details about the abandoned + * conversation. + */ + public void conversationAbandoned(ConversationAbandonedEvent abandonedEvent); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationCanceller.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationCanceller.java new file mode 100644 index 0000000..db43bb1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationCanceller.java @@ -0,0 +1,34 @@ +package org.bukkit.conversations; + +/** + * A ConversationCanceller is a class that cancels an active {@link + * Conversation}. A Conversation can have more than one ConversationCanceller. + */ +public interface ConversationCanceller extends Cloneable { + + /** + * Sets the conversation this ConversationCanceller can optionally cancel. + * + * @param conversation A conversation. + */ + public void setConversation(Conversation conversation); + + /** + * Cancels a conversation based on user input. + * + * @param context Context information about the conversation. + * @param input The input text from the user. + * @return True to cancel the conversation, False otherwise. + */ + public boolean cancelBasedOnInput(ConversationContext context, String input); + + /** + * Allows the {@link ConversationFactory} to duplicate this + * ConversationCanceller when creating a new {@link Conversation}. + *

+ * Implementing this method should reset any internal object state. + * + * @return A clone. + */ + public ConversationCanceller clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationContext.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationContext.java new file mode 100644 index 0000000..7390a77 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationContext.java @@ -0,0 +1,79 @@ +package org.bukkit.conversations; + +import org.bukkit.plugin.Plugin; + +import java.util.Map; + +/** + * A ConversationContext provides continuity between nodes in the prompt graph + * by giving the developer access to the subject of the conversation and a + * generic map for storing values that are shared between all {@link Prompt} + * invocations. + */ +public class ConversationContext { + private Conversable forWhom; + private Map sessionData; + private Plugin plugin; + + /** + * @param plugin The owning plugin. + * @param forWhom The subject of the conversation. + * @param initialSessionData Any initial values to put in the sessionData + * map. + */ + public ConversationContext(Plugin plugin, Conversable forWhom, Map initialSessionData) { + this.plugin = plugin; + this.forWhom = forWhom; + this.sessionData = initialSessionData; + } + + /** + * Gets the plugin that owns this conversation. + * + * @return The owning plugin. + */ + public Plugin getPlugin() { + return plugin; + } + + /** + * Gets the subject of the conversation. + * + * @return The subject of the conversation. + */ + public Conversable getForWhom() { + return forWhom; + } + + /** + * Gets the entire sessionData map. + * @return The full sessionData map. + */ + public Map getAllSessionData() { + return sessionData; + } + + /** + * Gets session data shared between all {@link Prompt} invocations. Use + * this as a way to pass data through each Prompt as the conversation + * develops. + * + * @param key The session data key. + * @return The requested session data. + */ + public Object getSessionData(Object key) { + return sessionData.get(key); + } + + /** + * Sets session data shared between all {@link Prompt} invocations. Use + * this as a way to pass data through each prompt as the conversation + * develops. + * + * @param key The session data key. + * @param value The session data value. + */ + public void setSessionData(Object key, Object value) { + sessionData.put(key, value); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationFactory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationFactory.java new file mode 100644 index 0000000..e7cbd52 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationFactory.java @@ -0,0 +1,228 @@ +package org.bukkit.conversations; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A ConversationFactory is responsible for creating a {@link Conversation} + * from a predefined template. A ConversationFactory is typically created when + * a plugin is instantiated and builds a Conversation each time a user + * initiates a conversation with the plugin. Each Conversation maintains its + * own state and calls back as needed into the plugin. + *

+ * The ConversationFactory implements a fluid API, allowing parameters to be + * set as an extension to the constructor. + */ +public class ConversationFactory { + + protected Plugin plugin; + protected boolean isModal; + protected boolean localEchoEnabled; + protected ConversationPrefix prefix; + protected Prompt firstPrompt; + protected Map initialSessionData; + protected String playerOnlyMessage; + protected List cancellers; + protected List abandonedListeners; + + /** + * Constructs a ConversationFactory. + * + * @param plugin The plugin that owns the factory. + */ + public ConversationFactory(Plugin plugin) + { + this.plugin = plugin; + isModal = true; + localEchoEnabled = true; + prefix = new NullConversationPrefix(); + firstPrompt = Prompt.END_OF_CONVERSATION; + initialSessionData = new HashMap(); + playerOnlyMessage = null; + cancellers = new ArrayList(); + abandonedListeners = new ArrayList(); + } + + /** + * Sets the modality of all {@link Conversation}s created by this factory. + * If a conversation is modal, all messages directed to the player are + * suppressed for the duration of the conversation. + *

+ * The default is True. + * + * @param modal The modality of all conversations to be created. + * @return This object. + */ + public ConversationFactory withModality(boolean modal) + { + isModal = modal; + return this; + } + + /** + * Sets the local echo status for all {@link Conversation}s created by + * this factory. If local echo is enabled, any text submitted to a + * conversation gets echoed back into the submitter's chat window. + * + * @param localEchoEnabled The status of local echo. + * @return This object. + */ + public ConversationFactory withLocalEcho(boolean localEchoEnabled) { + this.localEchoEnabled = localEchoEnabled; + return this; + } + + /** + * Sets the {@link ConversationPrefix} that prepends all output from all + * generated conversations. + *

+ * The default is a {@link NullConversationPrefix}; + * + * @param prefix The ConversationPrefix to use. + * @return This object. + */ + public ConversationFactory withPrefix(ConversationPrefix prefix) { + this.prefix = prefix; + return this; + } + + /** + * Sets the number of inactive seconds to wait before automatically + * abandoning all generated conversations. + *

+ * The default is 600 seconds (5 minutes). + * + * @param timeoutSeconds The number of seconds to wait. + * @return This object. + */ + public ConversationFactory withTimeout(int timeoutSeconds) { + return withConversationCanceller(new InactivityConversationCanceller(plugin, timeoutSeconds)); + } + + /** + * Sets the first prompt to use in all generated conversations. + *

+ * The default is Prompt.END_OF_CONVERSATION. + * + * @param firstPrompt The first prompt. + * @return This object. + */ + public ConversationFactory withFirstPrompt(Prompt firstPrompt) { + this.firstPrompt = firstPrompt; + return this; + } + + /** + * Sets any initial data with which to populate the conversation context + * sessionData map. + * + * @param initialSessionData The conversation context's initial + * sessionData. + * @return This object. + */ + public ConversationFactory withInitialSessionData(Map initialSessionData) { + this.initialSessionData = initialSessionData; + return this; + } + + /** + * Sets the player input that, when received, will immediately terminate + * the conversation. + * + * @param escapeSequence Input to terminate the conversation. + * @return This object. + */ + public ConversationFactory withEscapeSequence(String escapeSequence) { + return withConversationCanceller(new ExactMatchConversationCanceller(escapeSequence)); + } + + + /** + * Adds a {@link ConversationCanceller} to constructed conversations. + * + * @param canceller The {@link ConversationCanceller} to add. + * @return This object. + */ + public ConversationFactory withConversationCanceller(ConversationCanceller canceller) { + cancellers.add(canceller); + return this; + } + + /** + * Prevents this factory from creating a conversation for non-player + * {@link Conversable} objects. + * + * @param playerOnlyMessage The message to return to a non-play in lieu of + * starting a conversation. + * @return This object. + */ + public ConversationFactory thatExcludesNonPlayersWithMessage(String playerOnlyMessage) { + this.playerOnlyMessage = playerOnlyMessage; + return this; + } + + /** + * Adds a {@link ConversationAbandonedListener} to all conversations + * constructed by this factory. + * + * @param listener The listener to add. + * @return This object. + */ + public ConversationFactory addConversationAbandonedListener(ConversationAbandonedListener listener) { + abandonedListeners.add(listener); + return this; + } + + /** + * Constructs a {@link Conversation} in accordance with the defaults set + * for this factory. + * + * @param forWhom The entity for whom the new conversation is mediating. + * @return A new conversation. + */ + public Conversation buildConversation(Conversable forWhom) { + //Abort conversation construction if we aren't supposed to talk to non-players + if (playerOnlyMessage != null && !(forWhom instanceof Player)) { + return new Conversation(plugin, forWhom, new NotPlayerMessagePrompt()); + } + + //Clone any initial session data + Map copiedInitialSessionData = new HashMap(); + copiedInitialSessionData.putAll(initialSessionData); + + //Build and return a conversation + Conversation conversation = new Conversation(plugin, forWhom, firstPrompt, copiedInitialSessionData); + conversation.setModal(isModal); + conversation.setLocalEchoEnabled(localEchoEnabled); + conversation.setPrefix(prefix); + + //Clone the conversation cancellers + for (ConversationCanceller canceller : cancellers) { + conversation.addConversationCanceller(canceller.clone()); + } + + //Add the ConversationAbandonedListeners + for (ConversationAbandonedListener listener : abandonedListeners) { + conversation.addConversationAbandonedListener(listener); + } + + return conversation; + } + + private class NotPlayerMessagePrompt extends MessagePrompt { + + public String getPromptText(ConversationContext context) { + return playerOnlyMessage; + } + + @Override + protected Prompt getNextPrompt(ConversationContext context) { + return Prompt.END_OF_CONVERSATION; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationPrefix.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationPrefix.java new file mode 100644 index 0000000..9889f17 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ConversationPrefix.java @@ -0,0 +1,19 @@ +package org.bukkit.conversations; + +import org.bukkit.command.CommandSender; + +/** + * A ConversationPrefix implementation prepends all output from the + * conversation to the player. The ConversationPrefix can be used to display + * the plugin name or conversation status as the conversation evolves. + */ +public interface ConversationPrefix { + + /** + * Gets the prefix to use before each message to the player. + * + * @param context Context information about the conversation. + * @return The prefix text. + */ + String getPrefix(ConversationContext context); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ExactMatchConversationCanceller.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ExactMatchConversationCanceller.java new file mode 100644 index 0000000..327b9d9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ExactMatchConversationCanceller.java @@ -0,0 +1,29 @@ +package org.bukkit.conversations; + +/** + * An ExactMatchConversationCanceller cancels a conversation if the user + * enters an exact input string + */ +public class ExactMatchConversationCanceller implements ConversationCanceller { + private String escapeSequence; + + /** + * Builds an ExactMatchConversationCanceller. + * + * @param escapeSequence The string that, if entered by the user, will + * cancel the conversation. + */ + public ExactMatchConversationCanceller(String escapeSequence) { + this.escapeSequence = escapeSequence; + } + + public void setConversation(Conversation conversation) {} + + public boolean cancelBasedOnInput(ConversationContext context, String input) { + return input.equals(escapeSequence); + } + + public ConversationCanceller clone() { + return new ExactMatchConversationCanceller(escapeSequence); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/FixedSetPrompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/FixedSetPrompt.java new file mode 100644 index 0000000..b867c11 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/FixedSetPrompt.java @@ -0,0 +1,46 @@ +package org.bukkit.conversations; + +import org.apache.commons.lang.StringUtils; + +import java.util.Arrays; +import java.util.List; + +/** + * FixedSetPrompt is the base class for any prompt that requires a fixed set + * response from the user. + */ +public abstract class FixedSetPrompt extends ValidatingPrompt { + + protected List fixedSet; + + /** + * Creates a FixedSetPrompt from a set of strings. + *

+ * foo = new FixedSetPrompt("bar", "cheese", "panda"); + * + * @param fixedSet A fixed set of strings, one of which the user must + * type. + */ + public FixedSetPrompt(String... fixedSet) { + super(); + this.fixedSet = Arrays.asList(fixedSet); + } + + private FixedSetPrompt() {} + + @Override + protected boolean isInputValid(ConversationContext context, String input) { + return fixedSet.contains(input); + } + + /** + * Utility function to create a formatted string containing all the + * options declared in the constructor. + * + * @return the options formatted like "[bar, cheese, panda]" if bar, + * cheese, and panda were the options used + */ + protected String formatFixedSet() { + return "[" + StringUtils.join(fixedSet, ", ") + "]"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/InactivityConversationCanceller.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/InactivityConversationCanceller.java new file mode 100644 index 0000000..760a518 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/InactivityConversationCanceller.java @@ -0,0 +1,79 @@ +package org.bukkit.conversations; + +import org.bukkit.Server; +import org.bukkit.plugin.Plugin; + +/** + * An InactivityConversationCanceller will cancel a {@link Conversation} after + * a period of inactivity by the user. + */ +public class InactivityConversationCanceller implements ConversationCanceller { + protected Plugin plugin; + protected int timeoutSeconds; + protected Conversation conversation; + private int taskId = -1; + + /** + * Creates an InactivityConversationCanceller. + * + * @param plugin The owning plugin. + * @param timeoutSeconds The number of seconds of inactivity to wait. + */ + public InactivityConversationCanceller(Plugin plugin, int timeoutSeconds) { + this.plugin = plugin; + this.timeoutSeconds = timeoutSeconds; + } + + public void setConversation(Conversation conversation) { + this.conversation = conversation; + startTimer(); + } + + public boolean cancelBasedOnInput(ConversationContext context, String input) { + // Reset the inactivity timer + stopTimer(); + startTimer(); + return false; + } + + public ConversationCanceller clone() { + return new InactivityConversationCanceller(plugin, timeoutSeconds); + } + + /** + * Starts an inactivity timer. + */ + private void startTimer() { + taskId = plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + public void run() { + if (conversation.getState() == Conversation.ConversationState.UNSTARTED) { + startTimer(); + } else if (conversation.getState() == Conversation.ConversationState.STARTED) { + cancelling(conversation); + conversation.abandon(new ConversationAbandonedEvent(conversation, InactivityConversationCanceller.this)); + } + } + }, timeoutSeconds * 20); + } + + /** + * Stops the active inactivity timer. + */ + private void stopTimer() { + if (taskId != -1) { + plugin.getServer().getScheduler().cancelTask(taskId); + taskId = -1; + } + } + + /** + * Subclasses of InactivityConversationCanceller can override this method + * to take additional actions when the inactivity timer abandons the + * conversation. + * + * @param conversation The conversation being abandoned. + */ + protected void cancelling(Conversation conversation) { + + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ManuallyAbandonedConversationCanceller.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ManuallyAbandonedConversationCanceller.java new file mode 100644 index 0000000..3e80de1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ManuallyAbandonedConversationCanceller.java @@ -0,0 +1,20 @@ +package org.bukkit.conversations; + +/** + * The ManuallyAbandonedConversationCanceller is only used as part of a {@link + * ConversationAbandonedEvent} to indicate that the conversation was manually + * abandoned by programmatically calling the abandon() method on it. + */ +public class ManuallyAbandonedConversationCanceller implements ConversationCanceller{ + public void setConversation(Conversation conversation) { + throw new UnsupportedOperationException(); + } + + public boolean cancelBasedOnInput(ConversationContext context, String input) { + throw new UnsupportedOperationException(); + } + + public ConversationCanceller clone() { + throw new UnsupportedOperationException(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/MessagePrompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/MessagePrompt.java new file mode 100644 index 0000000..fa1775a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/MessagePrompt.java @@ -0,0 +1,42 @@ +package org.bukkit.conversations; + +/** + * MessagePrompt is the base class for any prompt that only displays a message + * to the user and requires no input. + */ +public abstract class MessagePrompt implements Prompt{ + + public MessagePrompt() { + super(); + } + + /** + * Message prompts never wait for user input before continuing. + * + * @param context Context information about the conversation. + * @return Always false. + */ + public boolean blocksForInput(ConversationContext context) { + return false; + } + + /** + * Accepts and ignores any user input, returning the next prompt in the + * prompt graph instead. + * + * @param context Context information about the conversation. + * @param input Ignored. + * @return The next prompt in the prompt graph. + */ + public Prompt acceptInput(ConversationContext context, String input) { + return getNextPrompt(context); + } + + /** + * Override this method to return the next prompt in the prompt graph. + * + * @param context Context information about the conversation. + * @return The next prompt in the prompt graph. + */ + protected abstract Prompt getNextPrompt(ConversationContext context); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/NullConversationPrefix.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/NullConversationPrefix.java new file mode 100644 index 0000000..7d8a7d8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/NullConversationPrefix.java @@ -0,0 +1,20 @@ +package org.bukkit.conversations; + +import org.bukkit.command.CommandSender; + +/** + * NullConversationPrefix is a {@link ConversationPrefix} implementation that + * displays nothing in front of conversation output. + */ +public class NullConversationPrefix implements ConversationPrefix{ + + /** + * Prepends each conversation message with an empty string. + * + * @param context Context information about the conversation. + * @return An empty string. + */ + public String getPrefix(ConversationContext context) { + return ""; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/NumericPrompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/NumericPrompt.java new file mode 100644 index 0000000..f0fdea1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/NumericPrompt.java @@ -0,0 +1,83 @@ +package org.bukkit.conversations; + +import org.apache.commons.lang.math.NumberUtils; + +/** + * NumericPrompt is the base class for any prompt that requires a {@link + * Number} response from the user. + */ +public abstract class NumericPrompt extends ValidatingPrompt{ + public NumericPrompt() { + super(); + } + + @Override + protected boolean isInputValid(ConversationContext context, String input) { + return NumberUtils.isNumber(input) && isNumberValid(context, NumberUtils.createNumber(input)); + } + + /** + * Override this method to do further validation on the numeric player + * input after the input has been determined to actually be a number. + * + * @param context Context information about the conversation. + * @param input The number the player provided. + * @return The validity of the player's input. + */ + protected boolean isNumberValid(ConversationContext context, Number input) { + return true; + } + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, String input) { + try + { + return acceptValidatedInput(context, NumberUtils.createNumber(input)); + } catch (NumberFormatException e) { + return acceptValidatedInput(context, NumberUtils.INTEGER_ZERO); + } + } + + /** + * Override this method to perform some action with the user's integer + * response. + * + * @param context Context information about the conversation. + * @param input The user's response as a {@link Number}. + * @return The next {@link Prompt} in the prompt graph. + */ + protected abstract Prompt acceptValidatedInput(ConversationContext context, Number input); + + @Override + protected String getFailedValidationText(ConversationContext context, String invalidInput) { + if (NumberUtils.isNumber(invalidInput)) { + return getFailedValidationText(context, NumberUtils.createNumber(invalidInput)); + } else { + return getInputNotNumericText(context, invalidInput); + } + } + + /** + * Optionally override this method to display an additional message if the + * user enters an invalid number. + * + * @param context Context information about the conversation. + * @param invalidInput The invalid input provided by the user. + * @return A message explaining how to correct the input. + */ + protected String getInputNotNumericText(ConversationContext context, String invalidInput) { + return null; + } + + /** + * Optionally override this method to display an additional message if the + * user enters an invalid numeric input. + * + * @param context Context information about the conversation. + * @param invalidInput The invalid input provided by the user. + * @return A message explaining how to correct the input. + */ + protected String getFailedValidationText(ConversationContext context, Number invalidInput) { + return null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/PlayerNamePrompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/PlayerNamePrompt.java new file mode 100644 index 0000000..feeb715 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/PlayerNamePrompt.java @@ -0,0 +1,38 @@ +package org.bukkit.conversations; + +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +/** + * PlayerNamePrompt is the base class for any prompt that requires the player + * to enter another player's name. + */ +public abstract class PlayerNamePrompt extends ValidatingPrompt{ + private Plugin plugin; + + public PlayerNamePrompt(Plugin plugin) { + super(); + this.plugin = plugin; + } + + @Override + protected boolean isInputValid(ConversationContext context, String input) { + return plugin.getServer().getPlayer(input) != null; + + } + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, String input) { + return acceptValidatedInput(context, plugin.getServer().getPlayer(input)); + } + + /** + * Override this method to perform some action with the user's player name + * response. + * + * @param context Context information about the conversation. + * @param input The user's player name response. + * @return The next {@link Prompt} in the prompt graph. + */ + protected abstract Prompt acceptValidatedInput(ConversationContext context, Player input); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/PluginNameConversationPrefix.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/PluginNameConversationPrefix.java new file mode 100644 index 0000000..2290979 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/PluginNameConversationPrefix.java @@ -0,0 +1,40 @@ +package org.bukkit.conversations; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.Plugin; + +/** + * PluginNameConversationPrefix is a {@link ConversationPrefix} implementation + * that displays the plugin name in front of conversation output. + */ +public class PluginNameConversationPrefix implements ConversationPrefix { + + protected String separator; + protected ChatColor prefixColor; + protected Plugin plugin; + + private String cachedPrefix; + + public PluginNameConversationPrefix(Plugin plugin) { + this(plugin, " > ", ChatColor.LIGHT_PURPLE); + } + + public PluginNameConversationPrefix(Plugin plugin, String separator, ChatColor prefixColor) { + this.separator = separator; + this.prefixColor = prefixColor; + this.plugin = plugin; + + cachedPrefix = prefixColor + plugin.getDescription().getName() + separator + ChatColor.WHITE; + } + + /** + * Prepends each conversation message with the plugin name. + * + * @param context Context information about the conversation. + * @return An empty string. + */ + public String getPrefix(ConversationContext context) { + return cachedPrefix; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Prompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Prompt.java new file mode 100644 index 0000000..7519c84 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/Prompt.java @@ -0,0 +1,45 @@ +package org.bukkit.conversations; + +/** + * A Prompt is the main constituent of a {@link Conversation}. Each prompt + * displays text to the user and optionally waits for a user's response. + * Prompts are chained together into a directed graph that represents the + * conversation flow. To halt a conversation, END_OF_CONVERSATION is returned + * in liu of another Prompt object. + */ +public interface Prompt extends Cloneable { + + /** + * A convenience constant for indicating the end of a conversation. + */ + static final Prompt END_OF_CONVERSATION = null; + + /** + * Gets the text to display to the user when this prompt is first + * presented. + * + * @param context Context information about the conversation. + * @return The text to display. + */ + String getPromptText(ConversationContext context); + + /** + * Checks to see if this prompt implementation should wait for user input + * or immediately display the next prompt. + * + * @param context Context information about the conversation. + * @return If true, the {@link Conversation} will wait for input before + * continuing. + */ + boolean blocksForInput(ConversationContext context); + + /** + * Accepts and processes input from the user. Using the input, the next + * Prompt in the prompt graph is returned. + * + * @param context Context information about the conversation. + * @param input The input text from the user. + * @return The next Prompt in the prompt graph. + */ + Prompt acceptInput(ConversationContext context, String input); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/RegexPrompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/RegexPrompt.java new file mode 100644 index 0000000..a3c7d1f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/RegexPrompt.java @@ -0,0 +1,28 @@ +package org.bukkit.conversations; + +import java.util.regex.Pattern; + +/** + * RegexPrompt is the base class for any prompt that requires an input + * validated by a regular expression. + */ +public abstract class RegexPrompt extends ValidatingPrompt { + + private Pattern pattern; + + public RegexPrompt(String regex) { + this(Pattern.compile(regex)); + } + + public RegexPrompt(Pattern pattern) { + super(); + this.pattern = pattern; + } + + private RegexPrompt() {} + + @Override + protected boolean isInputValid(ConversationContext context, String input) { + return pattern.matcher(input).matches(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/StringPrompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/StringPrompt.java new file mode 100644 index 0000000..2934459 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/StringPrompt.java @@ -0,0 +1,18 @@ +package org.bukkit.conversations; + +/** + * StringPrompt is the base class for any prompt that accepts an arbitrary + * string from the user. + */ +public abstract class StringPrompt implements Prompt{ + + /** + * Ensures that the prompt waits for the user to provide input. + * + * @param context Context information about the conversation. + * @return True. + */ + public boolean blocksForInput(ConversationContext context) { + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ValidatingPrompt.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ValidatingPrompt.java new file mode 100644 index 0000000..f41adb4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/conversations/ValidatingPrompt.java @@ -0,0 +1,78 @@ +package org.bukkit.conversations; + +import org.bukkit.ChatColor; + +/** + * ValidatingPrompt is the base class for any prompt that requires validation. + * ValidatingPrompt will keep replaying the prompt text until the user enters + * a valid response. + */ +public abstract class ValidatingPrompt implements Prompt { + public ValidatingPrompt() { + super(); + } + + /** + * Accepts and processes input from the user and validates it. If + * validation fails, this prompt is returned for re-execution, otherwise + * the next Prompt in the prompt graph is returned. + * + * @param context Context information about the conversation. + * @param input The input text from the user. + * @return This prompt or the next Prompt in the prompt graph. + */ + public Prompt acceptInput(ConversationContext context, String input) { + if (isInputValid(context, input)) { + return acceptValidatedInput(context, input); + } else { + String failPrompt = getFailedValidationText(context, input); + if (failPrompt != null) { + context.getForWhom().sendRawMessage(ChatColor.RED + failPrompt); + } + // Redisplay this prompt to the user to re-collect input + return this; + } + } + + /** + * Ensures that the prompt waits for the user to provide input. + * + * @param context Context information about the conversation. + * @return True. + */ + public boolean blocksForInput(ConversationContext context) { + return true; + } + + /** + * Override this method to check the validity of the player's input. + * + * @param context Context information about the conversation. + * @param input The player's raw console input. + * @return True or false depending on the validity of the input. + */ + protected abstract boolean isInputValid(ConversationContext context, String input); + + /** + * Override this method to accept and processes the validated input from + * the user. Using the input, the next Prompt in the prompt graph should + * be returned. + * + * @param context Context information about the conversation. + * @param input The validated input text from the user. + * @return The next Prompt in the prompt graph. + */ + protected abstract Prompt acceptValidatedInput(ConversationContext context, String input); + + /** + * Optionally override this method to display an additional message if the + * user enters an invalid input. + * + * @param context Context information about the conversation. + * @param invalidInput The invalid input provided by the user. + * @return A message explaining how to correct the input. + */ + protected String getFailedValidationText(ConversationContext context, String invalidInput) { + return null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/Enchantment.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/Enchantment.java new file mode 100644 index 0000000..c82d679 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/Enchantment.java @@ -0,0 +1,297 @@ +package org.bukkit.enchantments; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.command.defaults.EnchantCommand; +import org.bukkit.inventory.ItemStack; + +/** + * The various type of enchantments that may be added to armour or weapons + */ +public abstract class Enchantment { + /** + * Provides protection against environmental damage + */ + public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentWrapper(0); + + /** + * Provides protection against fire damage + */ + public static final Enchantment PROTECTION_FIRE = new EnchantmentWrapper(1); + + /** + * Provides protection against fall damage + */ + public static final Enchantment PROTECTION_FALL = new EnchantmentWrapper(2); + + /** + * Provides protection against explosive damage + */ + public static final Enchantment PROTECTION_EXPLOSIONS = new EnchantmentWrapper(3); + + /** + * Provides protection against projectile damage + */ + public static final Enchantment PROTECTION_PROJECTILE = new EnchantmentWrapper(4); + + /** + * Decreases the rate of air loss whilst underwater + */ + public static final Enchantment OXYGEN = new EnchantmentWrapper(5); + + /** + * Increases the speed at which a player may mine underwater + */ + public static final Enchantment WATER_WORKER = new EnchantmentWrapper(6); + + /** + * Damages the attacker + */ + public static final Enchantment THORNS = new EnchantmentWrapper(7); + + /** + * Increases walking speed while in water + */ + public static final Enchantment DEPTH_STRIDER = new EnchantmentWrapper(8); + + /** + * Increases damage against all targets + */ + public static final Enchantment DAMAGE_ALL = new EnchantmentWrapper(16); + + /** + * Increases damage against undead targets + */ + public static final Enchantment DAMAGE_UNDEAD = new EnchantmentWrapper(17); + + /** + * Increases damage against arthropod targets + */ + public static final Enchantment DAMAGE_ARTHROPODS = new EnchantmentWrapper(18); + + /** + * All damage to other targets will knock them back when hit + */ + public static final Enchantment KNOCKBACK = new EnchantmentWrapper(19); + + /** + * When attacking a target, has a chance to set them on fire + */ + public static final Enchantment FIRE_ASPECT = new EnchantmentWrapper(20); + + /** + * Provides a chance of gaining extra loot when killing monsters + */ + public static final Enchantment LOOT_BONUS_MOBS = new EnchantmentWrapper(21); + + /** + * Increases the rate at which you mine/dig + */ + public static final Enchantment DIG_SPEED = new EnchantmentWrapper(32); + + /** + * Allows blocks to drop themselves instead of fragments (for example, + * stone instead of cobblestone) + */ + public static final Enchantment SILK_TOUCH = new EnchantmentWrapper(33); + + /** + * Decreases the rate at which a tool looses durability + */ + public static final Enchantment DURABILITY = new EnchantmentWrapper(34); + + /** + * Provides a chance of gaining extra loot when destroying blocks + */ + public static final Enchantment LOOT_BONUS_BLOCKS = new EnchantmentWrapper(35); + + /** + * Provides extra damage when shooting arrows from bows + */ + public static final Enchantment ARROW_DAMAGE = new EnchantmentWrapper(48); + + /** + * Provides a knockback when an entity is hit by an arrow from a bow + */ + public static final Enchantment ARROW_KNOCKBACK = new EnchantmentWrapper(49); + + /** + * Sets entities on fire when hit by arrows shot from a bow + */ + public static final Enchantment ARROW_FIRE = new EnchantmentWrapper(50); + + /** + * Provides infinite arrows when shooting a bow + */ + public static final Enchantment ARROW_INFINITE = new EnchantmentWrapper(51); + + /** + * Decreases odds of catching worthless junk + */ + public static final Enchantment LUCK = new EnchantmentWrapper(61); + + /** + * Increases rate of fish biting your hook + */ + public static final Enchantment LURE = new EnchantmentWrapper(62); + + private static final Map byId = new HashMap(); + private static final Map byName = new HashMap(); + private static boolean acceptingNew = true; + private final int id; + + public Enchantment(int id) { + this.id = id; + } + + /** + * Gets the unique ID of this enchantment + * + * @return Unique ID + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + + /** + * Gets the unique name of this enchantment + * + * @return Unique name + */ + public abstract String getName(); + + /** + * Gets the maximum level that this Enchantment may become. + * + * @return Maximum level of the Enchantment + */ + public abstract int getMaxLevel(); + + /** + * Gets the level that this Enchantment should start at + * + * @return Starting level of the Enchantment + */ + public abstract int getStartLevel(); + + /** + * Gets the type of {@link ItemStack} that may fit this Enchantment. + * + * @return Target type of the Enchantment + */ + public abstract EnchantmentTarget getItemTarget(); + + /** + * Check if this enchantment conflicts with another enchantment. + * + * @param other The enchantment to check against + * @return True if there is a conflict. + */ + public abstract boolean conflictsWith(Enchantment other); + + /** + * Checks if this Enchantment may be applied to the given {@link + * ItemStack}. + *

+ * This does not check if it conflicts with any enchantments already + * applied to the item. + * + * @param item Item to test + * @return True if the enchantment may be applied, otherwise False + */ + public abstract boolean canEnchantItem(ItemStack item); + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof Enchantment)) { + return false; + } + final Enchantment other = (Enchantment) obj; + if (this.id != other.id) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return id; + } + + @Override + public String toString() { + return "Enchantment[" + id + ", " + getName() + "]"; + } + + /** + * Registers an enchantment with the given ID and object. + *

+ * Generally not to be used from within a plugin. + * + * @param enchantment Enchantment to register + */ + public static void registerEnchantment(Enchantment enchantment) { + if (byId.containsKey(enchantment.id) || byName.containsKey(enchantment.getName())) { + throw new IllegalArgumentException("Cannot set already-set enchantment"); + } else if (!isAcceptingRegistrations()) { + throw new IllegalStateException("No longer accepting new enchantments (can only be done by the server implementation)"); + } + + byId.put(enchantment.id, enchantment); + byName.put(enchantment.getName(), enchantment); + } + + /** + * Checks if this is accepting Enchantment registrations. + * + * @return True if the server Implementation may add enchantments + */ + public static boolean isAcceptingRegistrations() { + return acceptingNew; + } + + /** + * Stops accepting any enchantment registrations + */ + public static void stopAcceptingRegistrations() { + acceptingNew = false; + EnchantCommand.buildEnchantments(); + } + + /** + * Gets the Enchantment at the specified ID + * + * @param id ID to fetch + * @return Resulting Enchantment, or null if not found + * @deprecated Magic value + */ + @Deprecated + public static Enchantment getById(int id) { + return byId.get(id); + } + + /** + * Gets the Enchantment at the specified name + * + * @param name Name to fetch + * @return Resulting Enchantment, or null if not found + */ + public static Enchantment getByName(String name) { + return byName.get(name); + } + + /** + * Gets an array of all the registered {@link Enchantment}s + * + * @return Array of enchantments + */ + public static Enchantment[] values() { + return byId.values().toArray(new Enchantment[byId.size()]); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java new file mode 100644 index 0000000..d9b98ed --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/EnchantmentTarget.java @@ -0,0 +1,172 @@ +package org.bukkit.enchantments; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +/** + * Represents the applicable target for a {@link Enchantment} + */ +public enum EnchantmentTarget { + /** + * Allows the Enchantment to be placed on all items + */ + ALL { + @Override + public boolean includes(Material item) { + return true; + } + }, + + /** + * Allows the Enchantment to be placed on armor + */ + ARMOR { + @Override + public boolean includes(Material item) { + return ARMOR_FEET.includes(item) + || ARMOR_LEGS.includes(item) + || ARMOR_HEAD.includes(item) + || ARMOR_TORSO.includes(item); + } + }, + + /** + * Allows the Enchantment to be placed on feet slot armor + */ + ARMOR_FEET { + @Override + public boolean includes(Material item) { + return item.equals(Material.LEATHER_BOOTS) + || item.equals(Material.CHAINMAIL_BOOTS) + || item.equals(Material.IRON_BOOTS) + || item.equals(Material.DIAMOND_BOOTS) + || item.equals(Material.GOLD_BOOTS); + } + }, + + /** + * Allows the Enchantment to be placed on leg slot armor + */ + ARMOR_LEGS { + @Override + public boolean includes(Material item) { + return item.equals(Material.LEATHER_LEGGINGS) + || item.equals(Material.CHAINMAIL_LEGGINGS) + || item.equals(Material.IRON_LEGGINGS) + || item.equals(Material.DIAMOND_LEGGINGS) + || item.equals(Material.GOLD_LEGGINGS); + } + }, + + /** + * Allows the Enchantment to be placed on torso slot armor + */ + ARMOR_TORSO { + @Override + public boolean includes(Material item) { + return item.equals(Material.LEATHER_CHESTPLATE) + || item.equals(Material.CHAINMAIL_CHESTPLATE) + || item.equals(Material.IRON_CHESTPLATE) + || item.equals(Material.DIAMOND_CHESTPLATE) + || item.equals(Material.GOLD_CHESTPLATE); + } + }, + + /** + * Allows the Enchantment to be placed on head slot armor + */ + ARMOR_HEAD { + @Override + public boolean includes(Material item) { + return item.equals(Material.LEATHER_HELMET) + || item.equals(Material.CHAINMAIL_HELMET) + || item.equals(Material.DIAMOND_HELMET) + || item.equals(Material.IRON_HELMET) + || item.equals(Material.GOLD_HELMET); + } + }, + + /** + * Allows the Enchantment to be placed on weapons (swords) + */ + WEAPON { + @Override + public boolean includes(Material item) { + return item.equals(Material.WOOD_SWORD) + || item.equals(Material.STONE_SWORD) + || item.equals(Material.IRON_SWORD) + || item.equals(Material.DIAMOND_SWORD) + || item.equals(Material.GOLD_SWORD); + } + }, + + /** + * Allows the Enchantment to be placed on tools (spades, pickaxe, hoes, + * axes) + */ + TOOL { + @Override + public boolean includes(Material item) { + return item.equals(Material.WOOD_SPADE) + || item.equals(Material.STONE_SPADE) + || item.equals(Material.IRON_SPADE) + || item.equals(Material.DIAMOND_SPADE) + || item.equals(Material.GOLD_SPADE) + || item.equals(Material.WOOD_PICKAXE) + || item.equals(Material.STONE_PICKAXE) + || item.equals(Material.IRON_PICKAXE) + || item.equals(Material.DIAMOND_PICKAXE) + || item.equals(Material.GOLD_PICKAXE) + || item.equals(Material.WOOD_HOE) // NOTE: No vanilla enchantments for this + || item.equals(Material.STONE_HOE) // NOTE: No vanilla enchantments for this + || item.equals(Material.IRON_HOE) // NOTE: No vanilla enchantments for this + || item.equals(Material.DIAMOND_HOE) // NOTE: No vanilla enchantments for this + || item.equals(Material.GOLD_HOE) // NOTE: No vanilla enchantments for this + || item.equals(Material.WOOD_AXE) + || item.equals(Material.STONE_AXE) + || item.equals(Material.IRON_AXE) + || item.equals(Material.DIAMOND_AXE) + || item.equals(Material.GOLD_AXE) + || item.equals(Material.SHEARS) // NOTE: No vanilla enchantments for this + || item.equals(Material.FLINT_AND_STEEL); // NOTE: No vanilla enchantments for this + } + }, + + /** + * Allows the Enchantment to be placed on bows. + */ + BOW { + @Override + public boolean includes(Material item) { + return item.equals(Material.BOW); + } + }, + + /** + * Allows the Enchantment to be placed on fishing rods. + */ + FISHING_ROD { + @Override + public boolean includes(Material item) { + return item.equals(Material.FISHING_ROD); + } + }; + + /** + * Check whether this target includes the specified item. + * + * @param item The item to check + * @return True if the target includes the item + */ + public abstract boolean includes(Material item); + + /** + * Check whether this target includes the specified item. + * + * @param item The item to check + * @return True if the target includes the item + */ + public boolean includes(ItemStack item) { + return includes(item.getType()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java new file mode 100644 index 0000000..6a0aeb3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/enchantments/EnchantmentWrapper.java @@ -0,0 +1,51 @@ +package org.bukkit.enchantments; + +import org.bukkit.inventory.ItemStack; + +/** + * A simple wrapper for ease of selecting {@link Enchantment}s + */ +public class EnchantmentWrapper extends Enchantment { + public EnchantmentWrapper(int id) { + super(id); + } + + /** + * Gets the enchantment bound to this wrapper + * + * @return Enchantment + */ + public Enchantment getEnchantment() { + return Enchantment.getById(getId()); + } + + @Override + public int getMaxLevel() { + return getEnchantment().getMaxLevel(); + } + + @Override + public int getStartLevel() { + return getEnchantment().getStartLevel(); + } + + @Override + public EnchantmentTarget getItemTarget() { + return getEnchantment().getItemTarget(); + } + + @Override + public boolean canEnchantItem(ItemStack item) { + return getEnchantment().canEnchantItem(item); + } + + @Override + public String getName() { + return getEnchantment().getName(); + } + + @Override + public boolean conflictsWith(Enchantment other) { + return getEnchantment().conflictsWith(other); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ageable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ageable.java new file mode 100644 index 0000000..e9fccb2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ageable.java @@ -0,0 +1,67 @@ +package org.bukkit.entity; + +/** + * Represents an entity that can age and breed. + */ +public interface Ageable extends Creature { + /** + * Gets the age of this animal. + * + * @return Age + */ + public int getAge(); + + /** + * Sets the age of this animal. + * + * @param age New age + */ + public void setAge(int age); + + /** + * Lock the age of the animal, setting this will prevent the animal from + * maturing or getting ready for mating. + * + * @param lock new lock + */ + public void setAgeLock(boolean lock); + + /** + * Gets the current agelock. + * + * @return the current agelock + */ + public boolean getAgeLock(); + + /** + * Sets the age of the animal to a baby + */ + public void setBaby(); + + /** + * Sets the age of the animal to an adult + */ + public void setAdult(); + + /** + * Returns true if the animal is an adult. + * + * @return return true if the animal is an adult + */ + public boolean isAdult(); + + /** + * Return the ability to breed of the animal. + * + * @return the ability to breed of the animal + */ + public boolean canBreed(); + + /** + * Set breedability of the animal, if the animal is a baby and set to + * breed it will instantly grow up. + * + * @param breed breedability of the animal + */ + public void setBreed(boolean breed); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ambient.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ambient.java new file mode 100644 index 0000000..779e389 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ambient.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents an ambient mob + */ +public interface Ambient extends LivingEntity {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/AnimalTamer.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/AnimalTamer.java new file mode 100644 index 0000000..5f74f0d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/AnimalTamer.java @@ -0,0 +1,20 @@ +package org.bukkit.entity; + +import java.util.UUID; + +public interface AnimalTamer { + + /** + * This is the name of the specified AnimalTamer. + * + * @return The name to reference on tamed animals or null if a name cannot be obtained + */ + public String getName(); + + /** + * This is the UUID of the specified AnimalTamer. + * + * @return The UUID to reference on tamed animals + */ + public UUID getUniqueId(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Animals.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Animals.java new file mode 100644 index 0000000..f0dc157 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Animals.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents an Animal. + */ +public interface Animals extends Ageable {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ArmorStand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ArmorStand.java new file mode 100644 index 0000000..ad77d59 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ArmorStand.java @@ -0,0 +1,277 @@ +package org.bukkit.entity; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.EulerAngle; + +public interface ArmorStand extends LivingEntity { + + /** + * Returns the item the armor stand is + * currently holding + * + * @return the held item + */ + ItemStack getItemInHand(); + + /** + * Sets the item the armor stand is currently + * holding + * + * @param item the item to hold + */ + void setItemInHand(ItemStack item); + + /** + * Returns the item currently being worn + * by the armor stand on its feet + * + * @return the worn item + */ + ItemStack getBoots(); + + /** + * Sets the item currently being worn + * by the armor stand on its feet + * + * @param item the item to wear + */ + void setBoots(ItemStack item); + + /** + * Returns the item currently being worn + * by the armor stand on its legs + * + * @return the worn item + */ + ItemStack getLeggings(); + + /** + * Sets the item currently being worn + * by the armor stand on its legs + * + * @param item the item to wear + */ + void setLeggings(ItemStack item); + + /** + * Returns the item currently being worn + * by the armor stand on its chest + * + * @return the worn item + */ + ItemStack getChestplate(); + + /** + * Sets the item currently being worn + * by the armor stand on its chest + * + * @param item the item to wear + */ + void setChestplate(ItemStack item); + + /** + * Returns the item currently being worn + * by the armor stand on its head + * + * @return the worn item + */ + ItemStack getHelmet(); + + /** + * Sets the item currently being worn + * by the armor stand on its head + * + * @param item the item to wear + */ + void setHelmet(ItemStack item); + + /** + * Returns the armor stand's body's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @return the current pose + */ + EulerAngle getBodyPose(); + + /** + * Sets the armor stand's body's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @param pose the current pose + */ + void setBodyPose(EulerAngle pose); + + /** + * Returns the armor stand's left arm's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @return the current pose + */ + EulerAngle getLeftArmPose(); + + /** + * Sets the armor stand's left arm's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @param pose the current pose + */ + void setLeftArmPose(EulerAngle pose); + + /** + * Returns the armor stand's right arm's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @return the current pose + */ + EulerAngle getRightArmPose(); + + /** + * Sets the armor stand's right arm's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @param pose the current pose + */ + void setRightArmPose(EulerAngle pose); + + /** + * Returns the armor stand's left leg's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @return the current pose + */ + EulerAngle getLeftLegPose(); + + /** + * Sets the armor stand's left leg's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @param pose the current pose + */ + void setLeftLegPose(EulerAngle pose); + + /** + * Returns the armor stand's right leg's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @return the current pose + */ + EulerAngle getRightLegPose(); + + /** + * Sets the armor stand's right leg's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @param pose the current pose + */ + void setRightLegPose(EulerAngle pose); + + /** + * Returns the armor stand's head's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @return the current pose + */ + EulerAngle getHeadPose(); + + /** + * Sets the armor stand's head's + * current pose as a {@link org.bukkit.util.EulerAngle} + * + * @param pose the current pose + */ + void setHeadPose(EulerAngle pose); + + /** + * Returns whether the armor stand has + * a base plate + * + * @return whether it has a base plate + */ + boolean hasBasePlate(); + + /** + * Sets whether the armor stand has a + * base plate + * + * @param basePlate whether is has a base plate + */ + void setBasePlate(boolean basePlate); + + /** + * Returns whether gravity applies to + * this armor stand + * + * @return whether gravity applies + */ + boolean hasGravity(); + + /** + * Sets whether gravity applies to + * this armor stand + * + * @param gravity whether gravity should apply + */ + void setGravity(boolean gravity); + + /** + * Returns whether the armor stand should be + * visible or not + * + * @return whether the stand is visible or not + */ + boolean isVisible(); + + /** + * Sets whether the armor stand should be + * visible or not + * + * @param visible whether the stand is visible or not + */ + void setVisible(boolean visible); + + /** + * Returns whether this armor stand has arms + * + * @return whether this has arms or not + */ + boolean hasArms(); + + /** + * Sets whether this armor stand has arms + * + * @param arms whether this has arms or not + */ + void setArms(boolean arms); + + /** + * Returns whether this armor stand is scaled + * down + * + * @return whether this is scaled down + */ + boolean isSmall(); + + /** + * Sets whether this armor stand is scaled + * down + * + * @param small whether this is scaled down + */ + void setSmall(boolean small); + + /** + * Returns whether this armor stand is a marker, + * meaning it has a very small collision box + * + * @return whether this is a marker + */ + boolean isMarker(); + + /** + * Sets whether this armor stand is a marker, + * meaning it has a very small collision box + * + * @param marker whether this is a marker + */ + void setMarker(boolean marker); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Arrow.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Arrow.java new file mode 100644 index 0000000..e7a32f7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Arrow.java @@ -0,0 +1,58 @@ +package org.bukkit.entity; + +/** + * Represents an arrow. + */ +public interface Arrow extends Projectile { + + /** + * Gets the knockback strength for an arrow, which is the + * {@link org.bukkit.enchantments.Enchantment#KNOCKBACK KnockBack} level + * of the bow that shot it. + * + * @return the knockback strength value + */ + public int getKnockbackStrength(); + + /** + * Sets the knockback strength for an arrow. + * + * @param knockbackStrength the knockback strength value + */ + public void setKnockbackStrength(int knockbackStrength); + + /** + * Gets whether this arrow is critical. + *

+ * Critical arrows have increased damage and cause particle effects. + *

+ * Critical arrows generally occur when a player fully draws a bow before + * firing. + * + * @return true if it is critical + */ + public boolean isCritical(); + + /** + * Sets whether or not this arrow should be critical. + * + * @param critical whether or not it should be critical + */ + public void setCritical(boolean critical); + + public class Spigot extends Entity.Spigot + { + + public double getDamage() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + public void setDamage(double damage) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Bat.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Bat.java new file mode 100644 index 0000000..bd73f22 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Bat.java @@ -0,0 +1,27 @@ +package org.bukkit.entity; + +/** + * Represents a Bat + */ +public interface Bat extends Ambient { + + /** + * Checks the current waking state of this bat. + *

+ * This does not imply any persistence of state past the method call. + * + * @return true if the bat is awake or false if it is currently hanging + * from a block + */ + boolean isAwake(); + + /** + * This method modifies the current waking state of this bat. + *

+ * This does not prevent a bat from spontaneously awaking itself, or from + * reattaching itself to a block. + * + * @param state the new state + */ + void setAwake(boolean state); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Blaze.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Blaze.java new file mode 100644 index 0000000..7a5505b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Blaze.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents a Blaze monster + */ +public interface Blaze extends Monster { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Boat.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Boat.java new file mode 100644 index 0000000..ed2d178 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Boat.java @@ -0,0 +1,72 @@ +package org.bukkit.entity; + +/** + * Represents a boat entity. + */ +public interface Boat extends Vehicle { + + /** + * Gets the maximum speed of a boat. The speed is unrelated to the + * velocity. + * + * @return The max speed. + */ + public double getMaxSpeed(); + + /** + * Sets the maximum speed of a boat. Must be nonnegative. Default is 0.4D. + * + * @param speed The max speed. + */ + public void setMaxSpeed(double speed); + + /** + * Gets the deceleration rate (newSpeed = curSpeed * rate) of occupied + * boats. The default is 0.2. + * + * @return The rate of deceleration + */ + public double getOccupiedDeceleration(); + + /** + * Sets the deceleration rate (newSpeed = curSpeed * rate) of occupied + * boats. Setting this to a higher value allows for quicker acceleration. + * The default is 0.2. + * + * @param rate deceleration rate + */ + public void setOccupiedDeceleration(double rate); + + /** + * Gets the deceleration rate (newSpeed = curSpeed * rate) of unoccupied + * boats. The default is -1. Values below 0 indicate that no additional + * deceleration is imposed. + * + * @return The rate of deceleration + */ + public double getUnoccupiedDeceleration(); + + /** + * Sets the deceleration rate (newSpeed = curSpeed * rate) of unoccupied + * boats. Setting this to a higher value allows for quicker deceleration + * of boats when a player disembarks. The default is -1. Values below 0 + * indicate that no additional deceleration is imposed. + * + * @param rate deceleration rate + */ + public void setUnoccupiedDeceleration(double rate); + + /** + * Get whether boats can work on land. + * + * @return whether boats can work on land + */ + public boolean getWorkOnLand(); + + /** + * Set whether boats can work on land. + * + * @param workOnLand whether boats can work on land + */ + public void setWorkOnLand(boolean workOnLand); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/CaveSpider.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/CaveSpider.java new file mode 100644 index 0000000..9c37646 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/CaveSpider.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Spider. + */ +public interface CaveSpider extends Spider {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Chicken.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Chicken.java new file mode 100644 index 0000000..cb3ec6e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Chicken.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Chicken. + */ +public interface Chicken extends Animals {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ComplexEntityPart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ComplexEntityPart.java new file mode 100644 index 0000000..f4ab0bb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ComplexEntityPart.java @@ -0,0 +1,14 @@ +package org.bukkit.entity; + +/** + * Represents a single part of a {@link ComplexLivingEntity} + */ +public interface ComplexEntityPart extends Entity { + + /** + * Gets the parent {@link ComplexLivingEntity} of this part. + * + * @return Parent complex entity + */ + public ComplexLivingEntity getParent(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ComplexLivingEntity.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ComplexLivingEntity.java new file mode 100644 index 0000000..f74411c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ComplexLivingEntity.java @@ -0,0 +1,16 @@ +package org.bukkit.entity; + +import java.util.Set; + +/** + * Represents a complex living entity - one that is made up of various smaller + * parts + */ +public interface ComplexLivingEntity extends LivingEntity { + /** + * Gets a list of parts that belong to this complex entity + * + * @return List of parts + */ + public Set getParts(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Cow.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Cow.java new file mode 100644 index 0000000..cd4ed4d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Cow.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Cow. + */ +public interface Cow extends Animals {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Creature.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Creature.java new file mode 100644 index 0000000..f223f55 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Creature.java @@ -0,0 +1,26 @@ +package org.bukkit.entity; + +/** + * Represents a Creature. Creatures are non-intelligent monsters or animals + * which have very simple abilities. + */ +public interface Creature extends LivingEntity { + + /** + * Instructs this Creature to set the specified LivingEntity as its + * target. + *

+ * Hostile creatures may attack their target, and friendly creatures may + * follow their target. + * + * @param target New LivingEntity to target, or null to clear the target + */ + public void setTarget(LivingEntity target); + + /** + * Gets the current target of this Creature + * + * @return Current target of this creature, or null if none exists + */ + public LivingEntity getTarget(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/CreatureType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/CreatureType.java new file mode 100644 index 0000000..127d475 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/CreatureType.java @@ -0,0 +1,108 @@ +package org.bukkit.entity; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a type of creature. + * + * @deprecated Use EntityType instead. + */ +@Deprecated +public enum CreatureType { + // These strings MUST match the strings in nms.EntityTypes and are case sensitive. + CREEPER("Creeper", Creeper.class, 50), + SKELETON("Skeleton", Skeleton.class, 51), + SPIDER("Spider", Spider.class, 52), + GIANT("Giant", Giant.class, 53), + ZOMBIE("Zombie", Zombie.class, 54), + SLIME("Slime", Slime.class, 55), + GHAST("Ghast", Ghast.class, 56), + PIG_ZOMBIE("PigZombie", PigZombie.class, 57), + ENDERMAN("Enderman", Enderman.class, 58), + CAVE_SPIDER("CaveSpider", CaveSpider.class, 59), + SILVERFISH("Silverfish", Silverfish.class, 60), + BLAZE("Blaze", Blaze.class, 61), + MAGMA_CUBE("LavaSlime", MagmaCube.class, 62), + ENDER_DRAGON("EnderDragon", EnderDragon.class, 63), + ENDERMITE("Endermite", Endermite.class, 67), + GUARDIAN("Guardian", Guardian.class, 68), + PIG("Pig", Pig.class, 90), + SHEEP("Sheep", Sheep.class, 91), + COW("Cow", Cow.class, 92), + CHICKEN("Chicken", Chicken.class, 93), + SQUID("Squid", Squid.class, 94), + WOLF("Wolf", Wolf.class, 95), + MUSHROOM_COW("MushroomCow", MushroomCow.class, 96), + SNOWMAN("SnowMan", Snowman.class, 97), + RABBIT("Rabbit", Rabbit.class, 101), + VILLAGER("Villager", Villager.class, 120); + + private String name; + private Class clazz; + private short typeId; + + private static final Map NAME_MAP = new HashMap(); + private static final Map ID_MAP = new HashMap(); + + static { + for (CreatureType type : EnumSet.allOf(CreatureType.class)) { + NAME_MAP.put(type.name, type); + if (type.typeId != 0) { + ID_MAP.put(type.typeId, type); + } + } + } + + private CreatureType(String name, Class clazz, int typeId) { + this.name = name; + this.clazz = clazz; + this.typeId = (short) typeId; + } + + public String getName() { + return name; + } + + public Class getEntityClass() { + return clazz; + } + + /** + * + * @return the raw type id + * @deprecated Magic value + */ + @Deprecated + public short getTypeId() { + return typeId; + } + + public static CreatureType fromName(String name) { + return NAME_MAP.get(name); + } + + /** + * + * @param id the raw type id + * @return the matching CreatureType or null + * @deprecated Magic value + */ + @Deprecated + public static CreatureType fromId(int id) { + if (id > Short.MAX_VALUE) { + return null; + } + return ID_MAP.get((short) id); + } + + @Deprecated + public EntityType toEntityType() { + return EntityType.fromName(getName()); + } + + public static CreatureType fromEntityType(EntityType creatureType) { + return fromName(creatureType.getName()); + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Creeper.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Creeper.java new file mode 100644 index 0000000..a2f7809 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Creeper.java @@ -0,0 +1,21 @@ +package org.bukkit.entity; + +/** + * Represents a Creeper + */ +public interface Creeper extends Monster { + + /** + * Checks if this Creeper is powered (Electrocuted) + * + * @return true if this creeper is powered + */ + public boolean isPowered(); + + /** + * Sets the Powered status of this Creeper + * + * @param value New Powered status + */ + public void setPowered(boolean value); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Damageable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Damageable.java new file mode 100644 index 0000000..d0599cf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Damageable.java @@ -0,0 +1,127 @@ +package org.bukkit.entity; + +/** + * Represents an {@link Entity} that has health and can take damage. + */ +public interface Damageable extends Entity { + /** + * Deals the given amount of damage to this entity. + * + * @param amount Amount of damage to deal + */ + void damage(double amount); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param amount Amount of damage to deal + */ + @Deprecated + void _INVALID_damage(int amount); + + /** + * Deals the given amount of damage to this entity, from a specified + * entity. + * + * @param amount Amount of damage to deal + * @param source Entity which to attribute this damage from + */ + void damage(double amount, Entity source); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param amount Amount of damage to deal + * @param source Entity which to attribute this damage from + */ + @Deprecated + void _INVALID_damage(int amount, Entity source); + + /** + * Gets the entity's health from 0 to {@link #getMaxHealth()}, where 0 is dead. + * + * @return Health represented from 0 to max + */ + double getHealth(); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @return Health represented from 0 to max + */ + @Deprecated + int _INVALID_getHealth(); + + /** + * Sets the entity's health from 0 to {@link #getMaxHealth()}, where 0 is + * dead. + * + * @param health New health represented from 0 to max + * @throws IllegalArgumentException Thrown if the health is {@literal < 0 or >} + * {@link #getMaxHealth()} + */ + void setHealth(double health); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param health New health represented from 0 to max + * @throws IllegalArgumentException Thrown if the health is {@literal < 0 or >} + * {@link #getMaxHealth()} + */ + @Deprecated + void _INVALID_setHealth(int health); + + /** + * Gets the maximum health this entity has. + * + * @return Maximum health + */ + double getMaxHealth(); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @return Maximum health + */ + @Deprecated + int _INVALID_getMaxHealth(); + + /** + * Sets the maximum health this entity can have. + *

+ * If the health of the entity is above the value provided it will be set + * to that value. + *

+ * Note: An entity with a health bar ({@link Player}, {@link EnderDragon}, + * {@link Wither}, etc...} will have their bar scaled accordingly. + * + * @param health amount of health to set the maximum to + */ + void setMaxHealth(double health); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param health amount of health to set the maximum to + */ + @Deprecated + void _INVALID_setMaxHealth(int health); + + /** + * Resets the max health to the original amount. + */ + void resetMaxHealth(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Egg.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Egg.java new file mode 100644 index 0000000..2dcc00b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Egg.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a thrown egg. + */ +public interface Egg extends Projectile {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderCrystal.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderCrystal.java new file mode 100644 index 0000000..bac547e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderCrystal.java @@ -0,0 +1,7 @@ +package org.bukkit.entity; + +/** + * A crystal that heals nearby EnderDragons + */ +public interface EnderCrystal extends Entity { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderDragon.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderDragon.java new file mode 100644 index 0000000..609f3ba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderDragon.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents an Ender Dragon + */ +public interface EnderDragon extends ComplexLivingEntity { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderDragonPart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderDragonPart.java new file mode 100644 index 0000000..9516f56 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderDragonPart.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents an ender dragon part + */ +public interface EnderDragonPart extends ComplexEntityPart, Damageable { + public EnderDragon getParent(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderPearl.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderPearl.java new file mode 100644 index 0000000..db18a90 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderPearl.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents a thrown Ender Pearl entity + */ +public interface EnderPearl extends Projectile { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderSignal.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderSignal.java new file mode 100644 index 0000000..3d2d76c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EnderSignal.java @@ -0,0 +1,9 @@ +package org.bukkit.entity; + +/** + * Represents an Ender Signal, which is often created upon throwing an ender + * eye + */ +public interface EnderSignal extends Entity { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Enderman.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Enderman.java new file mode 100644 index 0000000..0b66a92 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Enderman.java @@ -0,0 +1,23 @@ +package org.bukkit.entity; + +import org.bukkit.material.MaterialData; + +/** + * Represents an Enderman. + */ +public interface Enderman extends Monster { + + /** + * Get the id and data of the block that the Enderman is carrying. + * + * @return MaterialData containing the id and data of the block + */ + public MaterialData getCarriedMaterial(); + + /** + * Set the id and data of the block that the Enderman is carring. + * + * @param material data to set the carried block to + */ + public void setCarriedMaterial(MaterialData material); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Endermite.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Endermite.java new file mode 100644 index 0000000..dc1fa54 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Endermite.java @@ -0,0 +1,4 @@ +package org.bukkit.entity; + +public interface Endermite extends Monster { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Entity.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Entity.java new file mode 100644 index 0000000..7fb08af --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Entity.java @@ -0,0 +1,363 @@ +package org.bukkit.entity; + +import org.bukkit.Location; +import org.bukkit.EntityEffect; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.metadata.Metadatable; +import org.bukkit.util.Vector; + +import java.util.List; +import java.util.UUID; +import org.bukkit.command.CommandSender; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + +/** + * Represents a base entity in the world + */ +public interface Entity extends Metadatable, CommandSender { + + /** + * Gets the entity's current position + * + * @return a new copy of Location containing the position of this entity + */ + public Location getLocation(); + + /** + * Stores the entity's current position in the provided Location object. + *

+ * If the provided Location is null this method does nothing and returns + * null. + * + * @param loc the location to copy into + * @return The Location object provided or null + */ + public Location getLocation(Location loc); + + /** + * Sets this entity's velocity + * + * @param velocity New velocity to travel with + */ + public void setVelocity(Vector velocity); + + /** + * Gets this entity's current velocity + * + * @return Current travelling velocity of this entity + */ + public Vector getVelocity(); + + /** + * Returns true if the entity is supported by a block. This value is a + * state updated by the server and is not recalculated unless the entity + * moves. + * + * @return True if entity is on ground. + */ + public boolean isOnGround(); + + /** + * Gets the current world this entity resides in + * + * @return World + */ + public World getWorld(); + + /** + * Teleports this entity to the given location. If this entity is riding a + * vehicle, it will be dismounted prior to teleportation. + * + * @param location New location to teleport this entity to + * @return true if the teleport was successful + */ + public boolean teleport(Location location); + + /** + * Teleports this entity to the given location. If this entity is riding a + * vehicle, it will be dismounted prior to teleportation. + * + * @param location New location to teleport this entity to + * @param cause The cause of this teleportation + * @return true if the teleport was successful + */ + public boolean teleport(Location location, TeleportCause cause); + + /** + * Teleports this entity to the target Entity. If this entity is riding a + * vehicle, it will be dismounted prior to teleportation. + * + * @param destination Entity to teleport this entity to + * @return true if the teleport was successful + */ + public boolean teleport(Entity destination); + + /** + * Teleports this entity to the target Entity. If this entity is riding a + * vehicle, it will be dismounted prior to teleportation. + * + * @param destination Entity to teleport this entity to + * @param cause The cause of this teleportation + * @return true if the teleport was successful + */ + public boolean teleport(Entity destination, TeleportCause cause); + + /** + * Returns a list of entities within a bounding box centered around this + * entity + * + * @param x 1/2 the size of the box along x axis + * @param y 1/2 the size of the box along y axis + * @param z 1/2 the size of the box along z axis + * @return {@code List} List of entities nearby + */ + public List getNearbyEntities(double x, double y, double z); + + /** + * Returns a unique id for this entity + * + * @return Entity id + */ + public int getEntityId(); + + /** + * Returns the entity's current fire ticks (ticks before the entity stops + * being on fire). + * + * @return int fireTicks + */ + public int getFireTicks(); + + /** + * Returns the entity's maximum fire ticks. + * + * @return int maxFireTicks + */ + public int getMaxFireTicks(); + + /** + * Sets the entity's current fire ticks (ticks before the entity stops + * being on fire). + * + * @param ticks Current ticks remaining + */ + public void setFireTicks(int ticks); + + /** + * Mark the entity's removal. + */ + public void remove(); + + /** + * Returns true if this entity has been marked for removal. + * + * @return True if it is dead. + */ + public boolean isDead(); + + /** + * Returns false if the entity has died or been despawned for some other + * reason. + * + * @return True if valid. + */ + public boolean isValid(); + + /** + * Gets the {@link Server} that contains this Entity + * + * @return Server instance running this Entity + */ + public Server getServer(); + + /** + * Gets the primary passenger of a vehicle. For vehicles that could have + * multiple passengers, this will only return the primary passenger. + * + * @return an entity + */ + public abstract Entity getPassenger(); + + /** + * Set the passenger of a vehicle. + * + * @param passenger The new passenger. + * @return false if it could not be done for whatever reason + */ + public abstract boolean setPassenger(Entity passenger); + + /** + * Check if a vehicle has passengers. + * + * @return True if the vehicle has no passengers. + */ + public abstract boolean isEmpty(); + + /** + * Eject any passenger. + * + * @return True if there was a passenger. + */ + public abstract boolean eject(); + + /** + * Returns the distance this entity has fallen + * + * @return The distance. + */ + public float getFallDistance(); + + /** + * Sets the fall distance for this entity + * + * @param distance The new distance. + */ + public void setFallDistance(float distance); + + /** + * Record the last {@link EntityDamageEvent} inflicted on this entity + * + * @param event a {@link EntityDamageEvent} + */ + public void setLastDamageCause(EntityDamageEvent event); + + /** + * Retrieve the last {@link EntityDamageEvent} inflicted on this entity. + * This event may have been cancelled. + * + * @return the last known {@link EntityDamageEvent} or null if hitherto + * unharmed + */ + public EntityDamageEvent getLastDamageCause(); + + /** + * Returns a unique and persistent id for this entity + * + * @return unique id + */ + public UUID getUniqueId(); + + /** + * Gets the amount of ticks this entity has lived for. + *

+ * This is the equivalent to "age" in entities. + * + * @return Age of entity + */ + public int getTicksLived(); + + /** + * Sets the amount of ticks this entity has lived for. + *

+ * This is the equivalent to "age" in entities. May not be less than one + * tick. + * + * @param value Age of entity + */ + public void setTicksLived(int value); + + /** + * Performs the specified {@link EntityEffect} for this entity. + *

+ * This will be viewable to all players near the entity. + * + * @param type Effect to play. + */ + public void playEffect(EntityEffect type); + + /** + * Get the type of the entity. + * + * @return The entity type. + */ + public EntityType getType(); + + /** + * Returns whether this entity is inside a vehicle. + * + * @return True if the entity is in a vehicle. + */ + public boolean isInsideVehicle(); + + /** + * Leave the current vehicle. If the entity is currently in a vehicle (and + * is removed from it), true will be returned, otherwise false will be + * returned. + * + * @return True if the entity was in a vehicle. + */ + public boolean leaveVehicle(); + + /** + * Get the vehicle that this player is inside. If there is no vehicle, + * null will be returned. + * + * @return The current vehicle. + */ + public Entity getVehicle(); + + /** + * Sets a custom name on a mob. This name will be used in death messages + * and can be sent to the client as a nameplate over the mob. + *

+ * Setting the name to null or an empty string will clear it. + *

+ * This value has no effect on players, they will always use their real + * name. + * + * @param name the name to set + */ + public void setCustomName(String name); + + /** + * Gets the custom name on a mob. If there is no name this method will + * return null. + *

+ * This value has no effect on players, they will always use their real + * name. + * + * @return name of the mob or null + */ + public String getCustomName(); + + /** + * Sets whether or not to display the mob's custom name client side. The + * name will be displayed above the mob similarly to a player. + *

+ * This value has no effect on players, they will always display their + * name. + * + * @param flag custom name or not + */ + public void setCustomNameVisible(boolean flag); + + /** + * Gets whether or not the mob's custom name is displayed client side. + *

+ * This value has no effect on players, they will always display their + * name. + * + * @return if the custom name is displayed + */ + public boolean isCustomNameVisible(); + + // Spigot Start + public class Spigot + { + + /** + * Returns whether this entity is invulnerable. + * + * @return True if the entity is invulnerable. + */ + public boolean isInvulnerable() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); + // Spigot End +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EntityType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EntityType.java new file mode 100644 index 0000000..ccc024b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/EntityType.java @@ -0,0 +1,277 @@ +package org.bukkit.entity; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.entity.minecart.CommandMinecart; +import org.bukkit.entity.minecart.HopperMinecart; +import org.bukkit.entity.minecart.SpawnerMinecart; +import org.bukkit.entity.minecart.RideableMinecart; +import org.bukkit.entity.minecart.ExplosiveMinecart; +import org.bukkit.entity.minecart.PoweredMinecart; +import org.bukkit.entity.minecart.StorageMinecart; +import org.bukkit.inventory.ItemStack; +import org.bukkit.Location; +import org.bukkit.World; + +public enum EntityType { + + // These strings MUST match the strings in nms.EntityTypes and are case sensitive. + /** + * An item resting on the ground. + *

+ * Spawn with {@link World#dropItem(Location, ItemStack)} or {@link + * World#dropItemNaturally(Location, ItemStack)} + */ + DROPPED_ITEM("Item", Item.class, 1, false), + /** + * An experience orb. + */ + EXPERIENCE_ORB("XPOrb", ExperienceOrb.class, 2), + /** + * A leash attached to a fencepost. + */ + LEASH_HITCH("LeashKnot", LeashHitch.class, 8), + /** + * A painting on a wall. + */ + PAINTING("Painting", Painting.class, 9), + /** + * An arrow projectile; may get stuck in the ground. + */ + ARROW("Arrow", Arrow.class, 10), + /** + * A flying snowball. + */ + SNOWBALL("Snowball", Snowball.class, 11), + /** + * A flying large fireball, as thrown by a Ghast for example. + */ + FIREBALL("Fireball", LargeFireball.class, 12), + /** + * A flying small fireball, such as thrown by a Blaze or player. + */ + SMALL_FIREBALL("SmallFireball", SmallFireball.class, 13), + /** + * A flying ender pearl. + */ + ENDER_PEARL("ThrownEnderpearl", EnderPearl.class, 14), + /** + * An ender eye signal. + */ + ENDER_SIGNAL("EyeOfEnderSignal", EnderSignal.class, 15), + /** + * A flying experience bottle. + */ + THROWN_EXP_BOTTLE("ThrownExpBottle", ThrownExpBottle.class, 17), + /** + * An item frame on a wall. + */ + ITEM_FRAME("ItemFrame", ItemFrame.class, 18), + /** + * A flying wither skull projectile. + */ + WITHER_SKULL("WitherSkull", WitherSkull.class, 19), + /** + * Primed TNT that is about to explode. + */ + PRIMED_TNT("PrimedTnt", TNTPrimed.class, 20), + /** + * A block that is going to or is about to fall. + */ + FALLING_BLOCK("FallingSand", FallingBlock.class, 21, false), + FIREWORK("FireworksRocketEntity", Firework.class, 22, false), + ARMOR_STAND("ArmorStand", ArmorStand.class, 30, false), + /** + * @see CommandMinecart + */ + MINECART_COMMAND("MinecartCommandBlock", CommandMinecart.class, 40), + /** + * A placed boat. + */ + BOAT("Boat", Boat.class, 41), + /** + * @see RideableMinecart + */ + MINECART("MinecartRideable", RideableMinecart.class, 42), + /** + * @see StorageMinecart + */ + MINECART_CHEST("MinecartChest", StorageMinecart.class, 43), + /** + * @see PoweredMinecart + */ + MINECART_FURNACE("MinecartFurnace", PoweredMinecart.class, 44), + /** + * @see ExplosiveMinecart + */ + MINECART_TNT("MinecartTNT", ExplosiveMinecart.class, 45), + /** + * @see HopperMinecart + */ + MINECART_HOPPER("MinecartHopper", HopperMinecart.class, 46), + /** + * @see SpawnerMinecart + */ + MINECART_MOB_SPAWNER("MinecartMobSpawner", SpawnerMinecart.class, 47), + CREEPER("Creeper", Creeper.class, 50), + SKELETON("Skeleton", Skeleton.class, 51), + SPIDER("Spider", Spider.class, 52), + GIANT("Giant", Giant.class, 53), + ZOMBIE("Zombie", Zombie.class, 54), + SLIME("Slime", Slime.class, 55), + GHAST("Ghast", Ghast.class, 56), + PIG_ZOMBIE("PigZombie", PigZombie.class, 57), + ENDERMAN("Enderman", Enderman.class, 58), + CAVE_SPIDER("CaveSpider", CaveSpider.class, 59), + SILVERFISH("Silverfish", Silverfish.class, 60), + BLAZE("Blaze", Blaze.class, 61), + MAGMA_CUBE("LavaSlime", MagmaCube.class, 62), + ENDER_DRAGON("EnderDragon", EnderDragon.class, 63), + WITHER("WitherBoss", Wither.class, 64), + BAT("Bat", Bat.class, 65), + WITCH("Witch", Witch.class, 66), + ENDERMITE("Endermite", Endermite.class, 67), + GUARDIAN("Guardian", Guardian.class, 68), + PIG("Pig", Pig.class, 90), + SHEEP("Sheep", Sheep.class, 91), + COW("Cow", Cow.class, 92), + CHICKEN("Chicken", Chicken.class, 93), + SQUID("Squid", Squid.class, 94), + WOLF("Wolf", Wolf.class, 95), + MUSHROOM_COW("MushroomCow", MushroomCow.class, 96), + SNOWMAN("SnowMan", Snowman.class, 97), + OCELOT("Ozelot", Ocelot.class, 98), + IRON_GOLEM("VillagerGolem", IronGolem.class, 99), + HORSE("EntityHorse", Horse.class, 100), + RABBIT("Rabbit", Rabbit.class, 101), + VILLAGER("Villager", Villager.class, 120), + ENDER_CRYSTAL("EnderCrystal", EnderCrystal.class, 200), + // These don't have an entity ID in nms.EntityTypes. + /** + * A flying splash potion. + */ + SPLASH_POTION(null, ThrownPotion.class, -1, false), + /** + * A flying chicken egg. + */ + EGG(null, Egg.class, -1, false), + /** + * A fishing line and bobber. + */ + FISHING_HOOK(null, Fish.class, -1, false), + /** + * A bolt of lightning. + *

+ * Spawn with {@link World#strikeLightning(Location)}. + */ + LIGHTNING(null, LightningStrike.class, -1, false), + WEATHER(null, Weather.class, -1, false), + PLAYER(null, Player.class, -1, false), + COMPLEX_PART(null, ComplexEntityPart.class, -1, false), + /** + * An unknown entity without an Entity Class + */ + UNKNOWN(null, null, -1, false); + + private String name; + private Class clazz; + private short typeId; + private boolean independent, living; + + private static final Map NAME_MAP = new HashMap(); + private static final Map ID_MAP = new HashMap(); + + static { + for (EntityType type : values()) { + if (type.name != null) { + NAME_MAP.put(type.name.toLowerCase(), type); + } + if (type.typeId > 0) { + ID_MAP.put(type.typeId, type); + } + } + } + + private EntityType(String name, Class clazz, int typeId) { + this(name, clazz, typeId, true); + } + + private EntityType(String name, Class clazz, int typeId, boolean independent) { + this.name = name; + this.clazz = clazz; + this.typeId = (short) typeId; + this.independent = independent; + if (clazz != null) { + this.living = LivingEntity.class.isAssignableFrom(clazz); + } + } + + /** + * + * @return the entity type's name + * @deprecated Magic value + */ + @Deprecated + public String getName() { + return name; + } + + public Class getEntityClass() { + return clazz; + } + + /** + * + * @return the raw type id + * @deprecated Magic value + */ + @Deprecated + public short getTypeId() { + return typeId; + } + + /** + * + * @param name the entity type's name + * @return the matching entity type or null + * @deprecated Magic value + */ + @Deprecated + public static EntityType fromName(String name) { + if (name == null) { + return null; + } + return NAME_MAP.get(name.toLowerCase()); + } + + /** + * + * @param id the raw type id + * @return the matching entity type or null + * @deprecated Magic value + */ + @Deprecated + public static EntityType fromId(int id) { + if (id > Short.MAX_VALUE) { + return null; + } + return ID_MAP.get((short) id); + } + + /** + * Some entities cannot be spawned using {@link + * World#spawnEntity(Location, EntityType)} or {@link + * World#spawn(Location, Class)}, usually because they require additional + * information in order to spawn. + * + * @return False if the entity type cannot be spawned + */ + public boolean isSpawnable() { + return independent; + } + + public boolean isAlive() { + return living; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ExperienceOrb.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ExperienceOrb.java new file mode 100644 index 0000000..c286edf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ExperienceOrb.java @@ -0,0 +1,21 @@ +package org.bukkit.entity; + +/** + * Represents an Experience Orb. + */ +public interface ExperienceOrb extends Entity { + + /** + * Gets how much experience is contained within this orb + * + * @return Amount of experience + */ + public int getExperience(); + + /** + * Sets how much experience is contained within this orb + * + * @param value Amount of experience + */ + public void setExperience(int value); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Explosive.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Explosive.java new file mode 100644 index 0000000..48650f6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Explosive.java @@ -0,0 +1,35 @@ +package org.bukkit.entity; + +/** + * A representation of an explosive entity + */ +public interface Explosive extends Entity { + + /** + * Set the radius affected by this explosive's explosion + * + * @param yield The explosive yield + */ + public void setYield(float yield); + + /** + * Return the radius or yield of this explosive's explosion + * + * @return the radius of blocks affected + */ + public float getYield(); + + /** + * Set whether or not this explosive's explosion causes fire + * + * @param isIncendiary Whether it should cause fire + */ + public void setIsIncendiary(boolean isIncendiary); + + /** + * Return whether or not this explosive creates a fire when exploding + * + * @return true if the explosive creates fire, false otherwise + */ + public boolean isIncendiary(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FallingBlock.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FallingBlock.java new file mode 100644 index 0000000..240a278 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FallingBlock.java @@ -0,0 +1,69 @@ +package org.bukkit.entity; + +import org.bukkit.Material; + +/** + * Represents a falling block + */ +public interface FallingBlock extends Entity { + + /** + * Get the Material of the falling block + * + * @return Material of the block + */ + Material getMaterial(); + + /** + * Get the ID of the falling block + * + * @return ID type of the block + * @deprecated Magic value + */ + @Deprecated + int getBlockId(); + + /** + * Get the data for the falling block + * + * @return data of the block + * @deprecated Magic value + */ + @Deprecated + byte getBlockData(); + + /** + * Get if the falling block will break into an item if it cannot be placed + * + * @return true if the block will break into an item when obstructed + */ + boolean getDropItem(); + + /** + * Set if the falling block will break into an item if it cannot be placed + * + * @param drop true to break into an item when obstructed + */ + void setDropItem(boolean drop); + + /** + * Get the HurtEntities state of this block. + * + * @return whether entities will be damaged by this block. + */ + boolean canHurtEntities(); + + /** + * Set the HurtEntities state of this block. + * + * @param hurtEntities whether entities will be damaged by this block. + */ + void setHurtEntities(boolean hurtEntities); + + /** + * Gets the source block location of the falling block + * + * @return the source block location the falling block was spawned from + */ + org.bukkit.Location getSourceLoc(); // PaperSpigot - Add FallingBlock source location API +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FallingSand.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FallingSand.java new file mode 100644 index 0000000..758d47d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FallingSand.java @@ -0,0 +1,9 @@ +package org.bukkit.entity; + +/** + * Represents a falling block. + * + * @deprecated See {@link FallingBlock} + */ +@Deprecated +public interface FallingSand extends FallingBlock {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Fireball.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Fireball.java new file mode 100644 index 0000000..56ed578 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Fireball.java @@ -0,0 +1,24 @@ +package org.bukkit.entity; + +import org.bukkit.util.Vector; + +/** + * Represents a Fireball. + */ +public interface Fireball extends Projectile, Explosive { + + /** + * Fireballs fly straight and do not take setVelocity(...) well. + * + * @param direction the direction this fireball is flying toward + */ + public void setDirection(Vector direction); + + /** + * Retrieve the direction this fireball is heading toward + * + * @return the direction + */ + public Vector getDirection(); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Firework.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Firework.java new file mode 100644 index 0000000..b8a8c07 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Firework.java @@ -0,0 +1,26 @@ +package org.bukkit.entity; + +import org.bukkit.inventory.meta.FireworkMeta; + +public interface Firework extends Entity { + + /** + * Get a copy of the fireworks meta + * + * @return A copy of the current Firework meta + */ + FireworkMeta getFireworkMeta(); + + /** + * Apply the provided meta to the fireworks + * + * @param meta The FireworkMeta to apply + */ + void setFireworkMeta(FireworkMeta meta); + + /** + * Cause this firework to explode at earliest opportunity, as if it has no + * remaining fuse. + */ + void detonate(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Fish.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Fish.java new file mode 100644 index 0000000..12ed1ed --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Fish.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents a fishing hook. + * @deprecated in favor of {@link FishHook} + */ +public interface Fish extends FishHook { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FishHook.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FishHook.java new file mode 100644 index 0000000..45b7f03 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/FishHook.java @@ -0,0 +1,28 @@ +package org.bukkit.entity; + +/** + * Represents a fishing hook. + */ +public interface FishHook extends Projectile { + /** + * Gets the chance of a fish biting. + *

+ * 0.0 = No Chance.
+ * 1.0 = Instant catch. + * + * @return chance the bite chance + */ + public double getBiteChance(); + + /** + * Sets the chance of a fish biting. + *

+ * 0.0 = No Chance.
+ * 1.0 = Instant catch. + * + * @param chance the bite chance + * @throws IllegalArgumentException if the bite chance is not between 0 + * and 1 + */ + public void setBiteChance(double chance) throws IllegalArgumentException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Flying.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Flying.java new file mode 100644 index 0000000..4f16a26 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Flying.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Flying Entity. + */ +public interface Flying extends LivingEntity {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ghast.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ghast.java new file mode 100644 index 0000000..3f5edf7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ghast.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Ghast. + */ +public interface Ghast extends Flying {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Giant.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Giant.java new file mode 100644 index 0000000..610de57 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Giant.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Giant. + */ +public interface Giant extends Monster {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Golem.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Golem.java new file mode 100644 index 0000000..4165977 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Golem.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * A mechanical creature that may harm enemies. + */ +public interface Golem extends Creature { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Guardian.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Guardian.java new file mode 100644 index 0000000..31f3c6a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Guardian.java @@ -0,0 +1,18 @@ +package org.bukkit.entity; + +public interface Guardian extends Monster { + + /** + * Check if the Guardian is an elder Guardian + * + * @return true if the Guardian is an Elder Guardian, false if not + */ + public boolean isElder(); + + /** + * Set the Guardian to an elder Guardian or not + * + * @param shouldBeElder True if this Guardian should be a elder Guardian, false if not + */ + public void setElder(boolean shouldBeElder); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Hanging.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Hanging.java new file mode 100644 index 0000000..67e9b61 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Hanging.java @@ -0,0 +1,22 @@ +package org.bukkit.entity; + +import org.bukkit.block.BlockFace; +import org.bukkit.material.Attachable; + +/** + * Represents a Hanging entity + */ +public interface Hanging extends Entity, Attachable { + + /** + * Sets the direction of the hanging entity, potentially overriding rules + * of placement. Note that if the result is not valid the object would + * normally drop as an item. + * + * @param face The new direction. + * @param force Whether to force it. + * @return False if force was false and there was no block for it to + * attach to in order to face the given direction. + */ + public boolean setFacingDirection(BlockFace face, boolean force); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Horse.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Horse.java new file mode 100644 index 0000000..e90d318 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Horse.java @@ -0,0 +1,256 @@ +package org.bukkit.entity; + +import org.bukkit.inventory.HorseInventory; +import org.bukkit.inventory.InventoryHolder; + +/** + * Represents a Horse. + */ +public interface Horse extends Animals, Vehicle, InventoryHolder, Tameable { + + /** + * Represents the different types of horses that may exist. + */ + public enum Variant { + /** + * A normal horse + */ + HORSE, + /** + * A donkey + */ + DONKEY, + /** + * A mule + */ + MULE, + /** + * An undead horse + */ + UNDEAD_HORSE, + /** + * A skeleton horse + */ + SKELETON_HORSE, + ; + } + + /** + * Represents the base color that the horse has. + */ + public enum Color { + /** + * Snow white + */ + WHITE, + /** + * Very light brown + */ + CREAMY, + /** + * Chestnut + */ + CHESTNUT, + /** + * Light brown + */ + BROWN, + /** + * Pitch black + */ + BLACK, + /** + * Gray + */ + GRAY, + /** + * Dark brown + */ + DARK_BROWN, + ; + } + + /** + * Represents the style, or markings, that the horse has. + */ + public enum Style { + /** + * No markings + */ + NONE, + /** + * White socks or stripes + */ + WHITE, + /** + * Milky splotches + */ + WHITEFIELD, + /** + * Round white dots + */ + WHITE_DOTS, + /** + * Small black dots + */ + BLACK_DOTS, + ; + } + + /** + * Gets the horse's variant. + *

+ * A horse's variant defines its physical appearance and capabilities. + * Whether a horse is a regular horse, donkey, mule, or other kind of + * horse is determined using the variant. + * + * @return a {@link Variant} representing the horse's variant + */ + public Variant getVariant(); + + /** + * Sets the horse's variant. + *

+ * A horse's variant defines its physical appearance and capabilities. + * Whether a horse is a regular horse, donkey, mule, or other kind of + * horse can be set using the variant. + *

+ * Setting a horse's variant does not change its attributes such as + * its owner and its tamed status, but changing a mule or donkey + * with a chest to another variant which does not support a chest + * will remove the chest and its contents. + * + * @param variant a {@link Variant} for this horse + */ + public void setVariant(Variant variant); + + /** + * Gets the horse's color. + *

+ * Colors only apply to horses, not to donkeys, mules, skeleton horses + * or undead horses. + * + * @return a {@link Color} representing the horse's group + */ + public Color getColor(); + + /** + * Sets the horse's color. + *

+ * Attempting to set a color for any donkey, mule, skeleton horse or + * undead horse will not result in a change. + * + * @param color a {@link Color} for this horse + */ + public void setColor(Color color); + + /** + * Gets the horse's style. + * Styles determine what kind of markings or patterns a horse has. + *

+ * Styles only apply to horses, not to donkeys, mules, skeleton horses + * or undead horses. + * + * @return a {@link Style} representing the horse's style + */ + public Style getStyle(); + + /** + * Sets the style of this horse. + * Styles determine what kind of markings or patterns a horse has. + *

+ * Attempting to set a style for any donkey, mule, skeleton horse or + * undead horse will not result in a change. + * + * @param style a {@link Style} for this horse + */ + public void setStyle(Style style); + + /** + * Gets whether the horse has a chest equipped. + * + * @return true if the horse has chest storage + */ + public boolean isCarryingChest(); + + /** + * Sets whether the horse has a chest equipped. + * Removing a chest will also clear the chest's inventory. + * + * @param chest true if the horse should have a chest + */ + public void setCarryingChest(boolean chest); + + /** + * Gets the domestication level of this horse. + *

+ * A higher domestication level indicates that the horse is closer to + * becoming tame. As the domestication level gets closer to the max + * domestication level, the chance of the horse becoming tame increases. + * + * @return domestication level + */ + public int getDomestication(); + + /** + * Sets the domestication level of this horse. + *

+ * Setting the domestication level to a high value will increase the + * horse's chances of becoming tame. + *

+ * Domestication level must be greater than zero and no greater than + * the max domestication level of the horse, determined with + * {@link #getMaxDomestication()} + * + * @param level domestication level + */ + public void setDomestication(int level); + + /** + * Gets the maximum domestication level of this horse. + *

+ * The higher this level is, the longer it will likely take + * for the horse to be tamed. + * + * @return the max domestication level + */ + public int getMaxDomestication(); + + /** + * Sets the maximum domestication level of this horse. + *

+ * Setting a higher max domestication will increase the amount of + * domesticating (feeding, riding, etc.) necessary in order to tame it, + * while setting a lower max value will have the opposite effect. + *

+ * Maximum domestication must be greater than zero. + * + * @param level the max domestication level + */ + public void setMaxDomestication(int level); + + /** + * Gets the jump strength of this horse. + *

+ * Jump strength defines how high the horse can jump. A higher jump strength + * increases how high a jump will go. + * + * @return the horse's jump strength + */ + public double getJumpStrength(); + + /** + * Sets the jump strength of this horse. + *

+ * A higher jump strength increases how high a jump will go. + * Setting a jump strength to 0 will result in no jump. + * You cannot set a jump strength to a value below 0 or + * above 2. + * + * @param strength jump strength for this horse + */ + public void setJumpStrength(double strength); + + @Override + public HorseInventory getInventory(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/HumanEntity.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/HumanEntity.java new file mode 100644 index 0000000..3f8646d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/HumanEntity.java @@ -0,0 +1,177 @@ +package org.bukkit.entity; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.permissions.Permissible; + +/** + * Represents a human entity, such as an NPC or a player + */ +public interface HumanEntity extends LivingEntity, AnimalTamer, Permissible, InventoryHolder { + + /** + * Returns the name of this player + * + * @return Player name + */ + public String getName(); + + /** + * Get the player's inventory. + * + * @return The inventory of the player, this also contains the armor + * slots. + */ + public PlayerInventory getInventory(); + + /** + * Get the player's EnderChest inventory + * + * @return The EnderChest of the player + */ + public Inventory getEnderChest(); + + /** + * If the player currently has an inventory window open, this method will + * set a property of that window, such as the state of a progress bar. + * + * @param prop The property. + * @param value The value to set the property to. + * @return True if the property was successfully set. + */ + public boolean setWindowProperty(InventoryView.Property prop, int value); + + /** + * Gets the inventory view the player is currently viewing. If they do not + * have an inventory window open, it returns their internal crafting view. + * + * @return The inventory view. + */ + public InventoryView getOpenInventory(); + + /** + * Opens an inventory window with the specified inventory on the top and + * the player's inventory on the bottom. + * + * @param inventory The inventory to open + * @return The newly opened inventory view + */ + public InventoryView openInventory(Inventory inventory); + + /** + * Opens an empty workbench inventory window with the player's inventory + * on the bottom. + * + * @param location The location to attach it to. If null, the player's + * location is used. + * @param force If false, and there is no workbench block at the location, + * no inventory will be opened and null will be returned. + * @return The newly opened inventory view, or null if it could not be + * opened. + */ + public InventoryView openWorkbench(Location location, boolean force); + + /** + * Opens an empty enchanting inventory window with the player's inventory + * on the bottom. + * + * @param location The location to attach it to. If null, the player's + * location is used. + * @param force If false, and there is no enchanting table at the + * location, no inventory will be opened and null will be returned. + * @return The newly opened inventory view, or null if it could not be + * opened. + */ + public InventoryView openEnchanting(Location location, boolean force); + + /** + * Opens an inventory window to the specified inventory view. + * + * @param inventory The view to open + */ + public void openInventory(InventoryView inventory); + + /** + * Force-closes the currently open inventory view for this player, if any. + */ + public void closeInventory(); + + /** + * Returns the ItemStack currently in your hand, can be empty. + * + * @return The ItemStack of the item you are currently holding. + */ + public ItemStack getItemInHand(); + + /** + * Sets the item to the given ItemStack, this will replace whatever the + * user was holding. + * + * @param item The ItemStack which will end up in the hand + */ + public void setItemInHand(ItemStack item); + + /** + * Returns the ItemStack currently on your cursor, can be empty. Will + * always be empty if the player currently has no open window. + * + * @return The ItemStack of the item you are currently moving around. + */ + public ItemStack getItemOnCursor(); + + /** + * Sets the item to the given ItemStack, this will replace whatever the + * user was moving. Will always be empty if the player currently has no + * open window. + * + * @param item The ItemStack which will end up in the hand + */ + public void setItemOnCursor(ItemStack item); + + /** + * Returns whether this player is slumbering. + * + * @return slumber state + */ + public boolean isSleeping(); + + /** + * Get the sleep ticks of the player. This value may be capped. + * + * @return slumber ticks + */ + public int getSleepTicks(); + + /** + * Gets this human's current {@link GameMode} + * + * @return Current game mode + */ + public GameMode getGameMode(); + + /** + * Sets this human's current {@link GameMode} + * + * @param mode New game mode + */ + public void setGameMode(GameMode mode); + + /** + * Check if the player is currently blocking (ie with a sword). + * + * @return Whether they are blocking. + */ + public boolean isBlocking(); + + /** + * Get the total amount of experience required for the player to level + * + * @return Experience required to level up + */ + public int getExpToLevel(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/IronGolem.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/IronGolem.java new file mode 100644 index 0000000..655e37c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/IronGolem.java @@ -0,0 +1,22 @@ +package org.bukkit.entity; + +/** + * An iron Golem that protects Villages. + */ +public interface IronGolem extends Golem { + + /** + * Gets whether this iron golem was built by a player. + * + * @return Whether this iron golem was built by a player + */ + public boolean isPlayerCreated(); + + /** + * Sets whether this iron golem was built by a player or not. + * + * @param playerCreated true if you want to set the iron golem as being + * player created, false if you want it to be a natural village golem. + */ + public void setPlayerCreated(boolean playerCreated); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Item.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Item.java new file mode 100644 index 0000000..90260b7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Item.java @@ -0,0 +1,37 @@ +package org.bukkit.entity; + +import org.bukkit.inventory.ItemStack; + +/** + * Represents an Item. + */ +public interface Item extends Entity { + + /** + * Gets the item stack associated with this item drop. + * + * @return An item stack. + */ + public ItemStack getItemStack(); + + /** + * Sets the item stack associated with this item drop. + * + * @param stack An item stack. + */ + public void setItemStack(ItemStack stack); + + /** + * Gets the delay before this Item is available to be picked up by players + * + * @return Remaining delay + */ + public int getPickupDelay(); + + /** + * Sets the delay before this Item is available to be picked up by players + * + * @param delay New delay + */ + public void setPickupDelay(int delay); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ItemFrame.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ItemFrame.java new file mode 100644 index 0000000..8b86815 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ItemFrame.java @@ -0,0 +1,39 @@ +package org.bukkit.entity; + +import org.bukkit.Rotation; +import org.bukkit.inventory.ItemStack; + +/** + * Represents an Item Frame + */ +public interface ItemFrame extends Hanging { + + /** + * Get the item in this frame + * + * @return a defensive copy the item in this item frame + */ + public ItemStack getItem(); + + /** + * Set the item in this frame + * + * @param item the new item + */ + public void setItem(ItemStack item); + + /** + * Get the rotation of the frame's item + * + * @return the direction + */ + public Rotation getRotation(); + + /** + * Set the rotation of the frame's item + * + * @param rotation the new rotation + * @throws IllegalArgumentException if rotation is null + */ + public void setRotation(Rotation rotation) throws IllegalArgumentException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LargeFireball.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LargeFireball.java new file mode 100644 index 0000000..fc3a109 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LargeFireball.java @@ -0,0 +1,7 @@ +package org.bukkit.entity; + +/** + * Represents a large {@link Fireball} + */ +public interface LargeFireball extends Fireball { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LeashHitch.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LeashHitch.java new file mode 100644 index 0000000..9ac04c1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LeashHitch.java @@ -0,0 +1,7 @@ +package org.bukkit.entity; + +/** + * Represents a Leash Hitch on a fence + */ +public interface LeashHitch extends Hanging { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LightningStrike.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LightningStrike.java new file mode 100644 index 0000000..1ed4ac9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LightningStrike.java @@ -0,0 +1,32 @@ +package org.bukkit.entity; + +/** + * Represents an instance of a lightning strike. May or may not do damage. + */ +public interface LightningStrike extends Weather { + + /** + * Returns whether the strike is an effect that does no damage. + * + * @return whether the strike is an effect + */ + public boolean isEffect(); + + + public class Spigot extends Entity.Spigot + { + + /* + * Returns whether the strike is silent. + * + * @return whether the strike is silent. + */ + public boolean isSilent() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + } + + Spigot spigot(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LivingEntity.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LivingEntity.java new file mode 100644 index 0000000..9e0c005 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/LivingEntity.java @@ -0,0 +1,411 @@ +package org.bukkit.entity; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.projectiles.ProjectileSource; + +/** + * Represents a living entity, such as a monster or player + */ +public interface LivingEntity extends Entity, Damageable, ProjectileSource { + + /** + * Gets the height of the living entity's eyes above its Location. + * + * @return height of the living entity's eyes above its location + */ + public double getEyeHeight(); + + /** + * Gets the height of the living entity's eyes above its Location. + * + * @param ignoreSneaking if set to true, the effects of sneaking will be + * ignored + * @return height of the living entity's eyes above its location + */ + public double getEyeHeight(boolean ignoreSneaking); + + /** + * Get a Location detailing the current eye position of the living entity. + * + * @return a location at the eyes of the living entity + */ + public Location getEyeLocation(); + + /** + * Gets all blocks along the living entity's line of sight. + *

+ * This list contains all blocks from the living entity's eye position to + * target inclusive. + * + * @param transparent HashSet containing all transparent block IDs (set to + * null for only air) + * @param maxDistance this is the maximum distance to scan (may be limited + * by server by at least 100 blocks, no less) + * @return list containing all blocks along the living entity's line of + * sight + * @deprecated Magic value + */ + @Deprecated + public List getLineOfSight(HashSet transparent, int maxDistance); + + /** + * Gets all blocks along the living entity's line of sight. + *

+ * This list contains all blocks from the living entity's eye position to + * target inclusive. + * + * @param transparent HashSet containing all transparent block Materials (set to + * null for only air) + * @param maxDistance this is the maximum distance to scan (may be limited + * by server by at least 100 blocks, no less) + * @return list containing all blocks along the living entity's line of + * sight + */ + public List getLineOfSight(Set transparent, int maxDistance); + + /** + * Gets the block that the living entity has targeted. + * + * @param transparent HashSet containing all transparent block IDs (set to + * null for only air) + * @param maxDistance this is the maximum distance to scan (may be limited + * by server by at least 100 blocks, no less) + * @return block that the living entity has targeted + * @deprecated Magic value + */ + @Deprecated + public Block getTargetBlock(HashSet transparent, int maxDistance); + + /** + * Gets the block that the living entity has targeted. + * + * @param transparent HashSet containing all transparent block Materials (set to + * null for only air) + * @param maxDistance this is the maximum distance to scan (may be limited + * by server by at least 100 blocks, no less) + * @return block that the living entity has targeted + */ + public Block getTargetBlock(Set transparent, int maxDistance); + + /** + * Gets the last two blocks along the living entity's line of sight. + *

+ * The target block will be the last block in the list. + * + * @param transparent HashSet containing all transparent block IDs (set to + * null for only air) + * @param maxDistance this is the maximum distance to scan. This may be + * further limited by the server, but never to less than 100 blocks + * @return list containing the last 2 blocks along the living entity's + * line of sight + * @deprecated Magic value + */ + @Deprecated + public List getLastTwoTargetBlocks(HashSet transparent, int maxDistance); + + /** + * Gets the last two blocks along the living entity's line of sight. + *

+ * The target block will be the last block in the list. + * + * @param transparent HashSet containing all transparent block Materials (set to + * null for only air) + * @param maxDistance this is the maximum distance to scan. This may be + * further limited by the server, but never to less than 100 blocks + * @return list containing the last 2 blocks along the living entity's + * line of sight + */ + public List getLastTwoTargetBlocks(Set transparent, int maxDistance); + + /** + * Throws an egg from the living entity. + * + * @deprecated use launchProjectile(Egg.class) instead + * @return the egg thrown + */ + @Deprecated + public Egg throwEgg(); + + /** + * Throws a snowball from the living entity. + * + * @deprecated use launchProjectile(Snowball.class) instead + * @return the snowball thrown + */ + @Deprecated + public Snowball throwSnowball(); + + /** + * Shoots an arrow from the living entity. + * + * @deprecated use launchProjectile(Arrow.class) instead + * @return the arrow shot + */ + @Deprecated + public Arrow shootArrow(); + + /** + * Returns the amount of air that the living entity has remaining, in + * ticks. + * + * @return amount of air remaining + */ + public int getRemainingAir(); + + /** + * Sets the amount of air that the living entity has remaining, in ticks. + * + * @param ticks amount of air remaining + */ + public void setRemainingAir(int ticks); + + /** + * Returns the maximum amount of air the living entity can have, in ticks. + * + * @return maximum amount of air + */ + public int getMaximumAir(); + + /** + * Sets the maximum amount of air the living entity can have, in ticks. + * + * @param ticks maximum amount of air + */ + public void setMaximumAir(int ticks); + + /** + * Returns the living entity's current maximum no damage ticks. + *

+ * This is the maximum duration in which the living entity will not take + * damage. + * + * @return maximum no damage ticks + */ + public int getMaximumNoDamageTicks(); + + /** + * Sets the living entity's current maximum no damage ticks. + * + * @param ticks maximum amount of no damage ticks + */ + public void setMaximumNoDamageTicks(int ticks); + + /** + * Returns the living entity's last damage taken in the current no damage + * ticks time. + *

+ * Only damage higher than this amount will further damage the living + * entity. + * + * @return damage taken since the last no damage ticks time period + */ + public double getLastDamage(); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @return damage taken since the last no damage ticks time period + */ + @Deprecated + public int _INVALID_getLastDamage(); + + /** + * Sets the damage dealt within the current no damage ticks time period. + * + * @param damage amount of damage + */ + public void setLastDamage(double damage); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param damage amount of damage + */ + @Deprecated + public void _INVALID_setLastDamage(int damage); + + /** + * Returns the living entity's current no damage ticks. + * + * @return amount of no damage ticks + */ + public int getNoDamageTicks(); + + /** + * Sets the living entity's current no damage ticks. + * + * @param ticks amount of no damage ticks + */ + public void setNoDamageTicks(int ticks); + + /** + * Gets the player identified as the killer of the living entity. + *

+ * May be null. + * + * @return killer player, or null if none found + */ + public Player getKiller(); + + /** + * Adds the given {@link PotionEffect} to the living entity. + *

+ * Only one potion effect can be present for a given {@link + * PotionEffectType}. + * + * @param effect PotionEffect to be added + * @return whether the effect could be added + */ + public boolean addPotionEffect(PotionEffect effect); + + /** + * Adds the given {@link PotionEffect} to the living entity. + *

+ * Only one potion effect can be present for a given {@link + * PotionEffectType}. + * + * @param effect PotionEffect to be added + * @param force whether conflicting effects should be removed + * @return whether the effect could be added + */ + public boolean addPotionEffect(PotionEffect effect, boolean force); + + /** + * Attempts to add all of the given {@link PotionEffect} to the living + * entity. + * + * @param effects the effects to add + * @return whether all of the effects could be added + */ + public boolean addPotionEffects(Collection effects); + + /** + * Returns whether the living entity already has an existing effect of + * the given {@link PotionEffectType} applied to it. + * + * @param type the potion type to check + * @return whether the living entity has this potion effect active on them + */ + public boolean hasPotionEffect(PotionEffectType type); + + /** + * Removes any effects present of the given {@link PotionEffectType}. + * + * @param type the potion type to remove + */ + public void removePotionEffect(PotionEffectType type); + + /** + * Returns all currently active {@link PotionEffect}s on the living + * entity. + * + * @return a collection of {@link PotionEffect}s + */ + public Collection getActivePotionEffects(); + + /** + * Checks whether the living entity has block line of sight to another. + *

+ * This uses the same algorithm that hostile mobs use to find the closest + * player. + * + * @param other the entity to determine line of sight to + * @return true if there is a line of sight, false if not + */ + public boolean hasLineOfSight(Entity other); + + /** + * Returns if the living entity despawns when away from players or not. + *

+ * By default, animals are not removed while other mobs are. + * + * @return true if the living entity is removed when away from players + */ + public boolean getRemoveWhenFarAway(); + + /** + * Sets whether or not the living entity despawns when away from players + * or not. + * + * @param remove the removal status + */ + public void setRemoveWhenFarAway(boolean remove); + + /** + * Gets the inventory with the equipment worn by the living entity. + * + * @return the living entity's inventory + */ + public EntityEquipment getEquipment(); + + /** + * Sets whether or not the living entity can pick up items. + * + * @param pickup whether or not the living entity can pick up items + */ + public void setCanPickupItems(boolean pickup); + + /** + * Gets if the living entity can pick up items. + * + * @return whether or not the living entity can pick up items + */ + public boolean getCanPickupItems(); + + /** + * Returns whether the entity is currently leashed. + * + * @return whether the entity is leashed + */ + public boolean isLeashed(); + + /** + * Gets the entity that is currently leading this entity. + * + * @return the entity holding the leash + * @throws IllegalStateException if not currently leashed + */ + public Entity getLeashHolder() throws IllegalStateException; + + /** + * Sets the leash on this entity to be held by the supplied entity. + *

+ * This method has no effect on EnderDragons, Withers, Players, or Bats. + * Non-living entities excluding leashes will not persist as leash + * holders. + * + * @param holder the entity to leash this entity to + * @return whether the operation was successful + */ + public boolean setLeashHolder(Entity holder); + + // Paper start + /** + * Get the number of arrows stuck in this entity + * + * @return Number of arrows stuck + */ + int getArrowsStuck(); + + /** + * Set the number of arrows stuck in this entity + * + * @param arrows Number of arrows to stick in this entity + */ + void setArrowsStuck(int arrows); + // Paper end +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/MagmaCube.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/MagmaCube.java new file mode 100644 index 0000000..714b442 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/MagmaCube.java @@ -0,0 +1,7 @@ +package org.bukkit.entity; + +/** + * Represents a MagmaCube. + */ +public interface MagmaCube extends Slime { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Minecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Minecart.java new file mode 100644 index 0000000..ea64114 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Minecart.java @@ -0,0 +1,144 @@ +package org.bukkit.entity; + +import org.bukkit.Material; +import org.bukkit.material.MaterialData; +import org.bukkit.util.Vector; + +/** + * Represents a minecart entity. + */ +public interface Minecart extends Vehicle { + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param damage over 40 to "kill" a minecart + */ + @Deprecated + public void _INVALID_setDamage(int damage); + + /** + * Sets a minecart's damage. + * + * @param damage over 40 to "kill" a minecart + */ + public void setDamage(double damage); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @return The damage + */ + @Deprecated + public int _INVALID_getDamage(); + + /** + * Gets a minecart's damage. + * + * @return The damage + */ + public double getDamage(); + + /** + * Gets the maximum speed of a minecart. The speed is unrelated to the + * velocity. + * + * @return The max speed + */ + public double getMaxSpeed(); + + /** + * Sets the maximum speed of a minecart. Must be nonnegative. Default is + * 0.4D. + * + * @param speed The max speed + */ + public void setMaxSpeed(double speed); + + /** + * Returns whether this minecart will slow down faster without a passenger + * occupying it + * + * @return Whether it decelerates faster + */ + public boolean isSlowWhenEmpty(); + + /** + * Sets whether this minecart will slow down faster without a passenger + * occupying it + * + * @param slow Whether it will decelerate faster + */ + public void setSlowWhenEmpty(boolean slow); + + /** + * Gets the flying velocity modifier. Used for minecarts that are in + * mid-air. A flying minecart's velocity is multiplied by this factor each + * tick. + * + * @return The vector factor + */ + public Vector getFlyingVelocityMod(); + + /** + * Sets the flying velocity modifier. Used for minecarts that are in + * mid-air. A flying minecart's velocity is multiplied by this factor each + * tick. + * + * @param flying velocity modifier vector + */ + public void setFlyingVelocityMod(Vector flying); + + /** + * Gets the derailed velocity modifier. Used for minecarts that are on the + * ground, but not on rails. + *

+ * A derailed minecart's velocity is multiplied by this factor each tick. + * + * @return derailed visible speed + */ + public Vector getDerailedVelocityMod(); + + /** + * Sets the derailed velocity modifier. Used for minecarts that are on the + * ground, but not on rails. A derailed minecart's velocity is multiplied + * by this factor each tick. + * + * @param derailed visible speed + */ + public void setDerailedVelocityMod(Vector derailed); + + /** + * Sets the display block for this minecart. + * Passing a null value will set the minecart to have no display block. + * + * @param material the material to set as display block. + */ + public void setDisplayBlock(MaterialData material); + + /** + * Gets the display block for this minecart. + * This function will return the type AIR if none is set. + * + * @return the block displayed by this minecart. + */ + public MaterialData getDisplayBlock(); + + /** + * Sets the offset of the display block. + * + * @param offset the block offset to set for this minecart. + */ + public void setDisplayBlockOffset(int offset); + + /** + * Gets the offset of the display block. + * + * @return the current block offset for this minecart. + */ + public int getDisplayBlockOffset(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Monster.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Monster.java new file mode 100644 index 0000000..fce2efd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Monster.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Monster. + */ +public interface Monster extends Creature {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/MushroomCow.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/MushroomCow.java new file mode 100644 index 0000000..84154de --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/MushroomCow.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents a mushroom {@link Cow} + */ +public interface MushroomCow extends Cow { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/NPC.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/NPC.java new file mode 100644 index 0000000..0c6b175 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/NPC.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents a non-player character + */ +public interface NPC extends Creature { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ocelot.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ocelot.java new file mode 100644 index 0000000..d5d034d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Ocelot.java @@ -0,0 +1,83 @@ + +package org.bukkit.entity; + +/** + * A wild tameable cat + */ +public interface Ocelot extends Animals, Tameable { + + /** + * Gets the current type of this cat. + * + * @return Type of the cat. + */ + public Type getCatType(); + + /** + * Sets the current type of this cat. + * + * @param type New type of this cat. + */ + public void setCatType(Type type); + + /** + * Checks if this ocelot is sitting + * + * @return true if sitting + */ + public boolean isSitting(); + + /** + * Sets if this ocelot is sitting. Will remove any path that the ocelot + * was following beforehand. + * + * @param sitting true if sitting + */ + public void setSitting(boolean sitting); + + /** + * Represents the various different cat types there are. + */ + public enum Type { + WILD_OCELOT(0), + BLACK_CAT(1), + RED_CAT(2), + SIAMESE_CAT(3); + + private static final Type[] types = new Type[Type.values().length]; + private final int id; + + static { + for (Type type : values()) { + types[type.getId()] = type; + } + } + + private Type(int id) { + this.id = id; + } + + /** + * Gets the ID of this cat type. + * + * @return Type ID. + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + + /** + * Gets a cat type by its ID. + * + * @param id ID of the cat type to get. + * @return Resulting type, or null if not found. + * @deprecated Magic value + */ + @Deprecated + public static Type getType(int id) { + return (id >= types.length) ? null : types[id]; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Painting.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Painting.java new file mode 100644 index 0000000..ca7a4cf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Painting.java @@ -0,0 +1,39 @@ +package org.bukkit.entity; + +import org.bukkit.Art; +import org.bukkit.event.painting.PaintingBreakEvent; + +/** + * Represents a Painting. + */ +public interface Painting extends Hanging { + + /** + * Get the art on this painting + * + * @return The art + */ + public Art getArt(); + + /** + * Set the art on this painting + * + * @param art The new art + * @return False if the new art won't fit at the painting's current + * location + */ + public boolean setArt(Art art); + + /** + * Set the art on this painting + * + * @param art The new art + * @param force If true, force the new art regardless of whether it fits + * at the current location. Note that forcing it where it can't fit + * normally causes it to drop as an item unless you override this by + * catching the {@link PaintingBreakEvent}. + * @return False if force was false and the new art won't fit at the + * painting's current location + */ + public boolean setArt(Art art, boolean force); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Pig.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Pig.java new file mode 100644 index 0000000..28f59f2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Pig.java @@ -0,0 +1,21 @@ +package org.bukkit.entity; + +/** + * Represents a Pig. + */ +public interface Pig extends Animals, Vehicle { + + /** + * Check if the pig has a saddle. + * + * @return if the pig has been saddled. + */ + public boolean hasSaddle(); + + /** + * Sets if the pig has a saddle or not + * + * @param saddled set if the pig has a saddle or not. + */ + public void setSaddle(boolean saddled); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/PigZombie.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/PigZombie.java new file mode 100644 index 0000000..2f08672 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/PigZombie.java @@ -0,0 +1,36 @@ +package org.bukkit.entity; + +/** + * Represents a Pig Zombie. + */ +public interface PigZombie extends Zombie { + + /** + * Get the pig zombie's current anger level. + * + * @return The anger level. + */ + int getAnger(); + + /** + * Set the pig zombie's current anger level. + * + * @param level The anger level. Higher levels of anger take longer to + * wear off. + */ + void setAnger(int level); + + /** + * Shorthand; sets to either 0 or the default level. + * + * @param angry Whether the zombie should be angry. + */ + void setAngry(boolean angry); + + /** + * Shorthand; gets whether the zombie is angry. + * + * @return True if the zombie is angry, otherwise false. + */ + boolean isAngry(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Player.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Player.java new file mode 100644 index 0000000..9511335 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Player.java @@ -0,0 +1,1404 @@ +package org.bukkit.entity; + +import me.levansj01.mythicspigot.kb.KBProfile; +import org.bukkit.*; +import org.bukkit.command.CommandSender; +import org.bukkit.conversations.Conversable; +import org.bukkit.map.MapView; +import org.bukkit.plugin.messaging.PluginMessageRecipient; +import org.bukkit.scoreboard.Scoreboard; +import org.github.paperspigot.Title; + +import java.net.InetSocketAddress; + +// PaperSpigot start +// PaperSpigot end + +/** + * Represents a player, connected or not + */ +public interface Player extends HumanEntity, Conversable, CommandSender, OfflinePlayer, PluginMessageRecipient { + + /** + * Gets the "friendly" name to display of this player. This may include + * color. + *

+ * Note that this name will not be displayed in game, only in chat and + * places defined by plugins. + * + * @return the friendly name + */ + String getDisplayName(); + + boolean canRecieveCosmetics(); + + boolean setRecieveCosmetics(boolean bool); + + /** + * Sets the "friendly" name to display of this player. This may include + * color. + *

+ * Note that this name will not be displayed in game, only in chat and + * places defined by plugins. + * + * @param name The new display name. + */ + void setDisplayName(String name); + + /** + * Gets the name that is shown on the player list. + * + * @return the player list name + */ + String getPlayerListName(); + + /** + * Sets the name that is shown on the in-game player list. + *

+ * The name cannot be longer than 16 characters, but {@link ChatColor} is + * supported. + *

+ * If the value is null, the name will be identical to {@link #getName()}. + *

+ * This name is case sensitive and unique, two names with different casing + * will appear as two different people. If a player joins afterwards with + * a name that conflicts with a player's custom list name, the joining + * player's player list name will have a random number appended to it (1-2 + * characters long in the default implementation). If the joining player's + * name is 15 or 16 characters long, part of the name will be truncated at + * the end to allow the addition of the two digits. + * + * @param name new player list name + * @throws IllegalArgumentException if the name is already used by someone + * else + * @throws IllegalArgumentException if the length of the name is too long + */ + void setPlayerListName(String name); + + /** + * Set the target of the player's compass. + * + * @param loc Location to point to + */ + void setCompassTarget(Location loc); + + /** + * Get the previously set compass target. + * + * @return location of the target + */ + Location getCompassTarget(); + + /** + * Gets the socket address of this player + * + * @return the player's address + */ + InetSocketAddress getAddress(); + + /** + * Sends this sender a message raw + * + * @param message Message to be displayed + */ + void sendRawMessage(String message); + + /** + * Kicks player with custom kick message. + * + * @param message kick message + */ + void kickPlayer(String message); + + /** + * Says a message (or runs a command). + * + * @param msg message to print + */ + void chat(String msg); + + /** + * Makes the player perform the given command + * + * @param command Command to perform + * @return true if the command was successful, otherwise false + */ + boolean performCommand(String command); + + /** + * Returns if the player is in sneak mode + * + * @return true if player is in sneak mode + */ + boolean isSneaking(); + + /** + * Sets the sneak mode the player + * + * @param sneak true if player should appear sneaking + */ + void setSneaking(boolean sneak); + + /** + * Gets whether the player is sprinting or not. + * + * @return true if player is sprinting. + */ + boolean isSprinting(); + + /** + * Sets whether the player is sprinting or not. + * + * @param sprinting true if the player should be sprinting + */ + void setSprinting(boolean sprinting); + + /** + * Saves the players current location, health, inventory, motion, and + * other information into the username.dat file, in the world/player + * folder + */ + void saveData(); + + /** + * Loads the players current location, health, inventory, motion, and + * other information from the username.dat file, in the world/player + * folder. + *

+ * Note: This will overwrite the players current inventory, health, + * motion, etc, with the state from the saved dat file. + */ + void loadData(); + + /** + * Sets whether the player is ignored as not sleeping. If everyone is + * either sleeping or has this flag set, then time will advance to the + * next day. If everyone has this flag set but no one is actually in bed, + * then nothing will happen. + * + * @param isSleeping Whether to ignore. + */ + void setSleepingIgnored(boolean isSleeping); + + /** + * Returns whether the player is sleeping ignored. + * + * @return Whether player is ignoring sleep. + */ + boolean isSleepingIgnored(); + + /** + * Play a note for a player at a location. This requires a note block + * at the particular location (as far as the client is concerned). This + * will not work without a note block. This will not work with cake. + * + * @param loc The location of a note block. + * @param instrument The instrument ID. + * @param note The note ID. + * @deprecated Magic value + */ + @Deprecated + void playNote(Location loc, byte instrument, byte note); + + /** + * Play a note for a player at a location. This requires a note block + * at the particular location (as far as the client is concerned). This + * will not work without a note block. This will not work with cake. + * + * @param loc The location of a note block + * @param instrument The instrument + * @param note The note + */ + void playNote(Location loc, Instrument instrument, Note note); + + + /** + * Play a sound for a player at the location. + *

+ * This function will fail silently if Location or Sound are null. + * + * @param location The location to play the sound + * @param sound The sound to play + * @param volume The volume of the sound + * @param pitch The pitch of the sound + */ + void playSound(Location location, Sound sound, float volume, float pitch); + + /** + * Play a sound for a player at the location. + *

+ * This function will fail silently if Location or Sound are null. No + * sound will be heard by the player if their client does not have the + * respective sound for the value passed. + * + * @param location the location to play the sound + * @param sound the internal sound name to play + * @param volume the volume of the sound + * @param pitch the pitch of the sound + */ + void playSound(Location location, String sound, float volume, float pitch); + + /** + * Plays an effect to just this player. + * + * @param loc the location to play the effect at + * @param effect the {@link Effect} + * @param data a data bit needed for some effects + * @deprecated Magic value + */ + @Deprecated + void playEffect(Location loc, Effect effect, int data); + + /** + * Plays an effect to just this player. + * + * @param the data based based on the type of the effect + * @param loc the location to play the effect at + * @param effect the {@link Effect} + * @param data a data bit needed for some effects + */ + void playEffect(Location loc, Effect effect, T data); + + /** + * Send a block change. This fakes a block change packet for a user at a + * certain location. This will not actually change the world in any way. + * + * @param loc The location of the changed block + * @param material The new block + * @param data The block data + * @deprecated Magic value + */ + @Deprecated + void sendBlockChange(Location loc, Material material, byte data); + + /** + * Send a chunk change. This fakes a chunk change packet for a user at a + * certain location. The updated cuboid must be entirely within a single + * chunk. This will not actually change the world in any way. + *

+ * At least one of the dimensions of the cuboid must be even. The size of + * the data buffer must be 2.5*sx*sy*sz and formatted in accordance with + * the Packet51 format. + * + * @param loc The location of the cuboid + * @param sx The x size of the cuboid + * @param sy The y size of the cuboid + * @param sz The z size of the cuboid + * @param data The data to be sent + * @return true if the chunk change packet was sent + * @deprecated Magic value + */ + @Deprecated + boolean sendChunkChange(Location loc, int sx, int sy, int sz, byte[] data); + + /** + * Send a block change. This fakes a block change packet for a user at a + * certain location. This will not actually change the world in any way. + * + * @param loc The location of the changed block + * @param material The new block ID + * @param data The block data + * @deprecated Magic value + */ + @Deprecated + void sendBlockChange(Location loc, int material, byte data); + + /** + * Send a sign change. This fakes a sign change packet for a user at + * a certain location. This will not actually change the world in any way. + * This method will use a sign at the location's block or a faked sign + * sent via {@link #sendBlockChange(org.bukkit.Location, int, byte)} or + * {@link #sendBlockChange(org.bukkit.Location, org.bukkit.Material, byte)}. + *

+ * If the client does not have a sign at the given location it will + * display an error message to the user. + * + * @param loc the location of the sign + * @param lines the new text on the sign or null to clear it + * @throws IllegalArgumentException if location is null + * @throws IllegalArgumentException if lines is non-null and has a length less than 4 + */ + void sendSignChange(Location loc, String[] lines) throws IllegalArgumentException; + + /** + * Render a map and send it to the player in its entirety. This may be + * used when streaming the map in the normal manner is not desirable. + * + * @param map The map to be sent + */ + void sendMap(MapView map); + + // Paper start + /** + * Sends the component to the player + * + * @param component the components to send + */ + @Override + void sendMessage(net.md_5.bungee.api.chat.BaseComponent component); + + /** + * Sends an array of components as a single message to the player + * + * @param components the components to send + */ + @Override + void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components); + + /** + * Set the text displayed in the player list header and footer for this player + * + * @param header content for the top of the player list + * @param footer content for the bottom of the player list + */ + void setPlayerListHeaderFooter(net.md_5.bungee.api.chat.BaseComponent[] header, net.md_5.bungee.api.chat.BaseComponent[] footer); + + /** + * Set the text displayed in the player list header and footer for this player + * + * @param header content for the top of the player list + * @param footer content for the bottom of the player list + */ + void setPlayerListHeaderFooter(net.md_5.bungee.api.chat.BaseComponent header, net.md_5.bungee.api.chat.BaseComponent footer); + + /** + * Update the times for titles displayed to the player + * + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out + * @deprecated Use {@link #updateTitle(Title)} + */ + @Deprecated + void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks); + + /** + * Update the subtitle of titles displayed to the player + * @deprecated Use {@link #updateTitle(Title)} + */ + @Deprecated + void setSubtitle(net.md_5.bungee.api.chat.BaseComponent[] subtitle); + + /** + * Update the subtitle of titles displayed to the player + * @deprecated Use {@link #updateTitle(Title)} + */ + @Deprecated + void setSubtitle(net.md_5.bungee.api.chat.BaseComponent subtitle); + + /** + * Show the given title to the player, along with the last subtitle set, using the last set times + * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)} + */ + @Deprecated + void showTitle(net.md_5.bungee.api.chat.BaseComponent[] title); + + /** + * Show the given title to the player, along with the last subtitle set, using the last set times + * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)} + */ + @Deprecated + void showTitle(net.md_5.bungee.api.chat.BaseComponent title); + + /** + * Show the given title and subtitle to the player using the given times + * + * @param title big text + * @param subtitle little text under it + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out + * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)} + */ + @Deprecated + void showTitle(net.md_5.bungee.api.chat.BaseComponent[] title, net.md_5.bungee.api.chat.BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks); + + /** + * Show the given title and subtitle to the player using the given times + * + * @param title big text + * @param subtitle little text under it + * @param fadeInTicks ticks to fade-in + * @param stayTicks ticks to stay visible + * @param fadeOutTicks ticks to fade-out + * @deprecated Use {@link #sendTitle(Title)} or {@link #updateTitle(Title)} + */ + @Deprecated + void showTitle(net.md_5.bungee.api.chat.BaseComponent title, net.md_5.bungee.api.chat.BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks); + + /** + * Show the title to the player, overriding any previously displayed title. + * + *

This method overrides any previous title, use {@link #updateTitle(Title)} to change the existing one.

+ * + * @param title the title to send + * @throws NullPointerException if the title is null + */ + void sendTitle(Title title); + + /** + * Show the title to the player, overriding any previously displayed title. + * + *

This method doesn't override previous titles, but changes their values.

+ * + * @param title the title to send + * @throws NullPointerException if title is null + */ + void updateTitle(Title title); + + /** + * Hide any title that is currently visible to the player + */ + void hideTitle(); + // Paper end + + /** + * Forces an update of the player's entire inventory. + * + */ + //@Deprecated // Spigot - undeprecate + void updateInventory(); + + /** + * Awards the given achievement and any parent achievements that the + * player does not have. + * + * @param achievement Achievement to award + * @throws IllegalArgumentException if achievement is null + */ + void awardAchievement(Achievement achievement); + + /** + * Removes the given achievement and any children achievements that the + * player has. + * + * @param achievement Achievement to remove + * @throws IllegalArgumentException if achievement is null + */ + void removeAchievement(Achievement achievement); + + /** + * Gets whether this player has the given achievement. + * + * @param achievement the achievement to check + * @return whether the player has the achievement + * @throws IllegalArgumentException if achievement is null + */ + boolean hasAchievement(Achievement achievement); + + /** + * Increments the given statistic for this player. + *

+ * This is equivalent to the following code: + * incrementStatistic(Statistic, 1) + * + * @param statistic Statistic to increment + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if the statistic requires an + * additional parameter + */ + void incrementStatistic(Statistic statistic) throws IllegalArgumentException; + + /** + * Decrements the given statistic for this player. + *

+ * This is equivalent to the following code: + * decrementStatistic(Statistic, 1) + * + * @param statistic Statistic to decrement + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if the statistic requires an + * additional parameter + */ + void decrementStatistic(Statistic statistic) throws IllegalArgumentException; + + /** + * Increments the given statistic for this player. + * + * @param statistic Statistic to increment + * @param amount Amount to increment this statistic by + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if amount is negative + * @throws IllegalArgumentException if the statistic requires an + * additional parameter + */ + void incrementStatistic(Statistic statistic, int amount) throws IllegalArgumentException; + + /** + * Decrements the given statistic for this player. + * + * @param statistic Statistic to decrement + * @param amount Amount to decrement this statistic by + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if amount is negative + * @throws IllegalArgumentException if the statistic requires an + * additional parameter + */ + void decrementStatistic(Statistic statistic, int amount) throws IllegalArgumentException; + + /** + * Sets the given statistic for this player. + * + * @param statistic Statistic to set + * @param newValue The value to set this statistic to + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if newValue is negative + * @throws IllegalArgumentException if the statistic requires an + * additional parameter + */ + void setStatistic(Statistic statistic, int newValue) throws IllegalArgumentException; + + /** + * Gets the value of the given statistic for this player. + * + * @param statistic Statistic to check + * @return the value of the given statistic + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if the statistic requires an + * additional parameter + */ + int getStatistic(Statistic statistic) throws IllegalArgumentException; + + /** + * Increments the given statistic for this player for the given material. + *

+ * This is equivalent to the following code: + * incrementStatistic(Statistic, Material, 1) + * + * @param statistic Statistic to increment + * @param material Material to offset the statistic with + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if material is null + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void incrementStatistic(Statistic statistic, Material material) throws IllegalArgumentException; + + /** + * Decrements the given statistic for this player for the given material. + *

+ * This is equivalent to the following code: + * decrementStatistic(Statistic, Material, 1) + * + * @param statistic Statistic to decrement + * @param material Material to offset the statistic with + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if material is null + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void decrementStatistic(Statistic statistic, Material material) throws IllegalArgumentException; + + /** + * Gets the value of the given statistic for this player. + * + * @param statistic Statistic to check + * @param material Material offset of the statistic + * @return the value of the given statistic + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if material is null + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + int getStatistic(Statistic statistic, Material material) throws IllegalArgumentException; + + /** + * Increments the given statistic for this player for the given material. + * + * @param statistic Statistic to increment + * @param material Material to offset the statistic with + * @param amount Amount to increment this statistic by + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if material is null + * @throws IllegalArgumentException if amount is negative + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void incrementStatistic(Statistic statistic, Material material, int amount) throws IllegalArgumentException; + + /** + * Decrements the given statistic for this player for the given material. + * + * @param statistic Statistic to decrement + * @param material Material to offset the statistic with + * @param amount Amount to decrement this statistic by + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if material is null + * @throws IllegalArgumentException if amount is negative + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void decrementStatistic(Statistic statistic, Material material, int amount) throws IllegalArgumentException; + + /** + * Sets the given statistic for this player for the given material. + * + * @param statistic Statistic to set + * @param material Material to offset the statistic with + * @param newValue The value to set this statistic to + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if material is null + * @throws IllegalArgumentException if newValue is negative + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void setStatistic(Statistic statistic, Material material, int newValue) throws IllegalArgumentException; + + /** + * Increments the given statistic for this player for the given entity. + *

+ * This is equivalent to the following code: + * incrementStatistic(Statistic, EntityType, 1) + * + * @param statistic Statistic to increment + * @param entityType EntityType to offset the statistic with + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if entityType is null + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void incrementStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException; + + /** + * Decrements the given statistic for this player for the given entity. + *

+ * This is equivalent to the following code: + * decrementStatistic(Statistic, EntityType, 1) + * + * @param statistic Statistic to decrement + * @param entityType EntityType to offset the statistic with + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if entityType is null + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void decrementStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException; + + /** + * Gets the value of the given statistic for this player. + * + * @param statistic Statistic to check + * @param entityType EntityType offset of the statistic + * @return the value of the given statistic + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if entityType is null + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + int getStatistic(Statistic statistic, EntityType entityType) throws IllegalArgumentException; + + /** + * Increments the given statistic for this player for the given entity. + * + * @param statistic Statistic to increment + * @param entityType EntityType to offset the statistic with + * @param amount Amount to increment this statistic by + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if entityType is null + * @throws IllegalArgumentException if amount is negative + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void incrementStatistic(Statistic statistic, EntityType entityType, int amount) throws IllegalArgumentException; + + /** + * Decrements the given statistic for this player for the given entity. + * + * @param statistic Statistic to decrement + * @param entityType EntityType to offset the statistic with + * @param amount Amount to decrement this statistic by + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if entityType is null + * @throws IllegalArgumentException if amount is negative + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void decrementStatistic(Statistic statistic, EntityType entityType, int amount); + + /** + * Sets the given statistic for this player for the given entity. + * + * @param statistic Statistic to set + * @param entityType EntityType to offset the statistic with + * @param newValue The value to set this statistic to + * @throws IllegalArgumentException if statistic is null + * @throws IllegalArgumentException if entityType is null + * @throws IllegalArgumentException if newValue is negative + * @throws IllegalArgumentException if the given parameter is not valid + * for the statistic + */ + void setStatistic(Statistic statistic, EntityType entityType, int newValue); + + /** + * Sets the current time on the player's client. When relative is true the + * player's time will be kept synchronized to its world time with the + * specified offset. + *

+ * When using non relative time the player's time will stay fixed at the + * specified time parameter. It's up to the caller to continue updating + * the player's time. To restore player time to normal use + * resetPlayerTime(). + * + * @param time The current player's perceived time or the player's time + * offset from the server time. + * @param relative When true the player time is kept relative to its world + * time. + */ + void setPlayerTime(long time, boolean relative); + + /** + * Returns the player's current timestamp. + * + * @return The player's time + */ + long getPlayerTime(); + + /** + * Returns the player's current time offset relative to server time, or + * the current player's fixed time if the player's time is absolute. + * + * @return The player's time + */ + long getPlayerTimeOffset(); + + /** + * Returns true if the player's time is relative to the server time, + * otherwise the player's time is absolute and will not change its current + * time unless done so with setPlayerTime(). + * + * @return true if the player's time is relative to the server time. + */ + boolean isPlayerTimeRelative(); + + /** + * Restores the normal condition where the player's time is synchronized + * with the server time. + *

+ * Equivalent to calling setPlayerTime(0, true). + */ + void resetPlayerTime(); + + /** + * Sets the type of weather the player will see. When used, the weather + * status of the player is locked until {@link #resetPlayerWeather()} is + * used. + * + * @param type The WeatherType enum type the player should experience + */ + void setPlayerWeather(WeatherType type); + + /** + * Returns the type of weather the player is currently experiencing. + * + * @return The WeatherType that the player is currently experiencing or + * null if player is seeing server weather. + */ + WeatherType getPlayerWeather(); + + /** + * Restores the normal condition where the player's weather is controlled + * by server conditions. + */ + void resetPlayerWeather(); + + /** + * Gives the player the amount of experience specified. + * + * @param amount Exp amount to give + */ + void giveExp(int amount); + + /** + * Gives the player the amount of experience levels specified. Levels can + * be taken by specifying a negative amount. + * + * @param amount amount of experience levels to give or take + */ + void giveExpLevels(int amount); + + /** + * Gets the players current experience points towards the next level. + *

+ * This is a percentage value. 0 is "no progress" and 1 is "next level". + * + * @return Current experience points + */ + float getExp(); + + /** + * Sets the players current experience points towards the next level + *

+ * This is a percentage value. 0 is "no progress" and 1 is "next level". + * + * @param exp New experience points + */ + void setExp(float exp); + + /** + * Gets the players current experience level + * + * @return Current experience level + */ + int getLevel(); + + /** + * Sets the players current experience level + * + * @param level New experience level + */ + void setLevel(int level); + + /** + * Gets the players total experience points + * + * @return Current total experience points + */ + int getTotalExperience(); + + /** + * Sets the players current experience level + * + * @param exp New experience level + */ + void setTotalExperience(int exp); + + /** + * Gets the players current exhaustion level. + *

+ * Exhaustion controls how fast the food level drops. While you have a + * certain amount of exhaustion, your saturation will drop to zero, and + * then your food will drop to zero. + * + * @return Exhaustion level + */ + float getExhaustion(); + + /** + * Sets the players current exhaustion level + * + * @param value Exhaustion level + */ + void setExhaustion(float value); + + /** + * Gets the players current saturation level. + *

+ * Saturation is a buffer for food level. Your food level will not drop if + * you are saturated {@literal >} 0. + * + * @return Saturation level + */ + float getSaturation(); + + /** + * Sets the players current saturation level + * + * @param value Saturation level + */ + void setSaturation(float value); + + /** + * Gets the players current food level + * + * @return Food level + */ + int getFoodLevel(); + + /** + * Sets the players current food level + * + * @param value New food level + */ + void setFoodLevel(int value); + + /** + * Gets the Location where the player will spawn at their bed, null if + * they have not slept in one or their current bed spawn is invalid. + * + * @return Bed Spawn Location if bed exists, otherwise null. + */ + Location getBedSpawnLocation(); + + /** + * Sets the Location where the player will spawn at their bed. + * + * @param location where to set the respawn location + */ + void setBedSpawnLocation(Location location); + + /** + * Sets the Location where the player will spawn at their bed. + * + * @param location where to set the respawn location + * @param force whether to forcefully set the respawn location even if a + * valid bed is not present + */ + void setBedSpawnLocation(Location location, boolean force); + + /** + * Determines if the Player is allowed to fly via jump key double-tap like + * in creative mode. + * + * @return True if the player is allowed to fly. + */ + boolean getAllowFlight(); + + /** + * Sets if the Player is allowed to fly via jump key double-tap like in + * creative mode. + * + * @param flight If flight should be allowed. + */ + void setAllowFlight(boolean flight); + + /** + * Hides a player from this player + * + * @param player Player to hide + */ + void hidePlayer(Player player); + + /** + * Allows this player to see a player that was previously hidden + * + * @param player Player to show + */ + void showPlayer(Player player); + + /** + * Checks to see if a player has been hidden from this player + * + * @param player Player to check + * @return True if the provided player is not being hidden from this + * player + */ + boolean canSee(Player player); + + /** + * Checks to see if this player is currently standing on a block. This + * information may not be reliable, as it is a state provided by the + * client, and may therefore not be accurate. + * + * @return True if the player standing on a solid block, else false. + * @deprecated Inconsistent with {@link + * org.bukkit.entity.Entity#isOnGround()} + */ + @Deprecated + boolean isOnGround(); + + /** + * Checks to see if this player is currently flying or not. + * + * @return True if the player is flying, else false. + */ + boolean isFlying(); + + /** + * Makes this player start or stop flying. + * + * @param value True to fly. + */ + void setFlying(boolean value); + + /** + * Sets the speed at which a client will fly. Negative values indicate + * reverse directions. + * + * @param value The new speed, from -1 to 1. + * @throws IllegalArgumentException If new speed is less than -1 or + * greater than 1 + */ + void setFlySpeed(float value) throws IllegalArgumentException; + + /** + * Sets the speed at which a client will walk. Negative values indicate + * reverse directions. + * + * @param value The new speed, from -1 to 1. + * @throws IllegalArgumentException If new speed is less than -1 or + * greater than 1 + */ + void setWalkSpeed(float value) throws IllegalArgumentException; + + /** + * Gets the current allowed speed that a client can fly. + * + * @return The current allowed speed, from -1 to 1 + */ + float getFlySpeed(); + + /** + * Gets the current allowed speed that a client can walk. + * + * @return The current allowed speed, from -1 to 1 + */ + float getWalkSpeed(); + + /** + * Request that the player's client download and switch texture packs. + *

+ * The player's client will download the new texture pack asynchronously + * in the background, and will automatically switch to it once the + * download is complete. If the client has downloaded and cached the same + * texture pack in the past, it will perform a quick timestamp check over + * the network to determine if the texture pack has changed and needs to + * be downloaded again. When this request is sent for the very first time + * from a given server, the client will first display a confirmation GUI + * to the player before proceeding with the download. + *

+ * Notes: + *

    + *
  • Players can disable server textures on their client, in which + * case this method will have no affect on them. + *
  • There is no concept of resetting texture packs back to default + * within Minecraft, so players will have to relog to do so. + *
+ * + * @param url The URL from which the client will download the texture + * pack. The string must contain only US-ASCII characters and should + * be encoded as per RFC 1738. + * @throws IllegalArgumentException Thrown if the URL is null. + * @throws IllegalArgumentException Thrown if the URL is too long. + * @deprecated Minecraft no longer uses textures packs. Instead you + * should use {@link #setResourcePack(String)}. + */ + @Deprecated + void setTexturePack(String url); + + /** + * Request that the player's client download and switch resource packs. + *

+ * The player's client will download the new resource pack asynchronously + * in the background, and will automatically switch to it once the + * download is complete. If the client has downloaded and cached the same + * resource pack in the past, it will perform a quick timestamp check + * over the network to determine if the resource pack has changed and + * needs to be downloaded again. When this request is sent for the very + * first time from a given server, the client will first display a + * confirmation GUI to the player before proceeding with the download. + *

+ * Notes: + *

    + *
  • Players can disable server resources on their client, in which + * case this method will have no affect on them. + *
  • There is no concept of resetting resource packs back to default + * within Minecraft, so players will have to relog to do so. + *
+ * + * @param url The URL from which the client will download the resource + * pack. The string must contain only US-ASCII characters and should + * be encoded as per RFC 1738. + * @throws IllegalArgumentException Thrown if the URL is null. + * @throws IllegalArgumentException Thrown if the URL is too long. The + * length restriction is an implementation specific arbitrary value. + * @deprecated use {@link #setResourcePack(String, String)} + */ + @Deprecated // TacoSpigot + void setResourcePack(String url); + + /** + * Gets the Scoreboard displayed to this player + * + * @return The current scoreboard seen by this player + */ + Scoreboard getScoreboard(); + + /** + * Sets the player's visible Scoreboard. + * + * @param scoreboard New Scoreboard for the player + * @throws IllegalArgumentException if scoreboard is null + * @throws IllegalArgumentException if scoreboard was not created by the + * {@link org.bukkit.scoreboard.ScoreboardManager scoreboard manager} + * @throws IllegalStateException if this is a player that is not logged + * yet or has logged out + */ + void setScoreboard(Scoreboard scoreboard) throws IllegalArgumentException, IllegalStateException; + + /** + * Gets if the client is displayed a 'scaled' health, that is, health on a + * scale from 0-{@link #getHealthScale()}. + * + * @return if client health display is scaled + * @see Player#setHealthScaled(boolean) + */ + boolean isHealthScaled(); + + /** + * Sets if the client is displayed a 'scaled' health, that is, health on a + * scale from 0-{@link #getHealthScale()}. + *

+ * Displayed health follows a simple formula displayedHealth = + * getHealth() / getMaxHealth() * getHealthScale(). + * + * @param scale if the client health display is scaled + */ + void setHealthScaled(boolean scale); + + /** + * Sets the number to scale health to for the client; this will also + * {@link #setHealthScaled(boolean) setHealthScaled(true)}. + *

+ * Displayed health follows a simple formula displayedHealth = + * getHealth() / getMaxHealth() * getHealthScale(). + * + * @param scale the number to scale health to + * @throws IllegalArgumentException if scale is <0 + * @throws IllegalArgumentException if scale is {@link Double#NaN} + * @throws IllegalArgumentException if scale is too high + */ + void setHealthScale(double scale) throws IllegalArgumentException; + + /** + * Gets the number that health is scaled to for the client. + * + * @return the number that health would be scaled to for the client if + * HealthScaling is set to true + * @see Player#setHealthScale(double) + * @see Player#setHealthScaled(boolean) + */ + double getHealthScale(); + + /** + * Gets the entity which is followed by the camera when in + * {@link GameMode#SPECTATOR}. + * + * @return the followed entity, or null if not in spectator mode or not + * following a specific entity. + */ + Entity getSpectatorTarget(); + + /** + * Sets the entity which is followed by the camera when in + * {@link GameMode#SPECTATOR}. + * + * @param entity the entity to follow or null to reset + * @throws IllegalStateException if the player is not in + * {@link GameMode#SPECTATOR} + */ + void setSpectatorTarget(Entity entity); + + /** + * Sends a title and a subtitle message to the player. If either of these + * values are null, they will not be sent and the display will remain + * unchanged. If they are empty strings, the display will be updated as + * such. If the strings contain a new line, only the first line will be + * sent. + * + * @param title Title text + * @param subtitle Subtitle text + * @deprecated API subject to change + */ + @Deprecated + void sendTitle(String title, String subtitle); + + /** + * Resets the title displayed to the player. + */ + // Paper - Undeprecate + void resetTitle(); + + // TacoSpigot start + /** + * Request that the player's client download and switch resource packs. + *

+ * The player's client will download the new resource pack asynchronously + * in the background, and will automatically switch to it once the + * download is complete. If the client has downloaded and cached the same + * resource pack in the past, it will perform a quick timestamp check + * over the network to determine if the resource pack has changed and + * needs to be downloaded again. When this request is sent for the very + * first time from a given server, the client will first display a + * confirmation GUI to the player before proceeding with the download. + *

+ * Notes: + *

    + *
  • Players can disable server resources on their client, in which + * case this method will have no affect on them. + *
  • There is no concept of resetting resource packs back to default + * within Minecraft, so players will have to relog to do so. + *
+ * + * @param url The URL from which the client will download the resource + * pack. The string must contain only US-ASCII characters and should + * be encoded as per RFC 1738. + * @param hash A 40 character hexadecimal and lowercase SHA-1 digest of + * the resource pack file. + * @throws IllegalArgumentException Thrown if the URL is null. + * @throws IllegalArgumentException Thrown if the URL is too long. The + * length restriction is an implementation specific arbitrary value. + */ + void setResourcePack(String url, String hash); + + /** + * @return the most recent resource pack status received from the player, + * or null if no status has ever been received from this player. + */ + org.bukkit.event.player.PlayerResourcePackStatusEvent.Status getResourcePackStatus(); + + /** + * @return the most recent resource pack hash received from the player, + * or null if no hash has ever been received from this player. + */ + String getResourcePackHash(); + + /** + * @return true if the last resource pack status received from this player + * was {@link org.bukkit.event.player.PlayerResourcePackStatusEvent.Status#SUCCESSFULLY_LOADED} + */ + boolean hasResourcePack(); + // TacoSpigot end + + // Mythic - KB Profiles + class Mythic { + public KBProfile getKBProfile() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + public void setKBProfile(KBProfile profile) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Mythic mythic(); + + // Spigot start + class Spigot extends Entity.Spigot + { + + /** + * Gets the connection address of this player, regardless of whether it + * has been spoofed or not. + * + * @return the player's connection address + */ + public InetSocketAddress getRawAddress() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Gets whether the player collides with entities + * + * @return the player's collision toggle state + */ + public boolean getCollidesWithEntities() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Sets whether the player collides with entities + * + * @param collides whether the player should collide with entities or + * not. + */ + public void setCollidesWithEntities(boolean collides) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Respawns the player if dead. + */ + public void respawn() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Gets player locale language. + * + * @return the player's client language settings + */ + public String getLocale() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Gets all players hidden with {@link hidePlayer(org.bukkit.entity.Player)}. + * + * @return a Set with all hidden players + */ + public java.util.Set getHiddenPlayers() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Sends the component to the player + * + * @param component the components to send + */ + public void sendMessage(net.md_5.bungee.api.chat.BaseComponent component) { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Sends an array of components as a single message to the player + * + * @param components the components to send + */ + public void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components) { + throw new UnsupportedOperationException("Not supported yet."); + } + + /** + * Get whether the player affects mob spawning + * + * @return whether or not the player affects + * mob spawning. + */ + public boolean getAffectsSpawning() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Set whether or not the player affects mob spawning + * + * @param affects whether or not the player should affect + * spawning or not. + */ + public void setAffectsSpawning(boolean affects) + { + throw new UnsupportedOperationException( "Not supported yet" ); + } + + /** + * Get the view distance for this player + * + * @return View distance + */ + public int getViewDistance() + { + throw new UnsupportedOperationException( "Not supported yet" ); + } + + /** + * Set the view distance for this player + * + * @param viewDistance View distance + */ + public void setViewDistance(int viewDistance) + { + throw new UnsupportedOperationException( "Not supported yet" ); + } + + public int getPing() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/PoweredMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/PoweredMinecart.java new file mode 100644 index 0000000..38240a9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/PoweredMinecart.java @@ -0,0 +1,9 @@ +package org.bukkit.entity; + +/** + * @deprecated This class has been moved into a sub package; {@link + * org.bukkit.entity.minecart.PoweredMinecart} should be used instead. + * @see org.bukkit.entity.minecart.PoweredMinecart + */ +@Deprecated +public interface PoweredMinecart extends org.bukkit.entity.minecart.PoweredMinecart {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Projectile.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Projectile.java new file mode 100644 index 0000000..a5599fa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Projectile.java @@ -0,0 +1,60 @@ +package org.bukkit.entity; + +import org.bukkit.projectiles.ProjectileSource; + +/** + * Represents a shootable entity. + */ +public interface Projectile extends Entity { + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @return the {@link LivingEntity} that shot this projectile + */ + @Deprecated + public LivingEntity _INVALID_getShooter(); + + /** + * Retrieve the shooter of this projectile. + * + * @return the {@link ProjectileSource} that shot this projectile + */ + public ProjectileSource getShooter(); + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param shooter the {@link LivingEntity} that shot this projectile + */ + @Deprecated + public void _INVALID_setShooter(LivingEntity shooter); + + /** + * Set the shooter of this projectile. + * + * @param source the {@link ProjectileSource} that shot this projectile + */ + public void setShooter(ProjectileSource source); + + /** + * Determine if this projectile should bounce or not when it hits. + *

+ * If a small fireball does not bounce it will set the target on fire. + * + * @return true if it should bounce. + */ + public boolean doesBounce(); + + /** + * Set whether or not this projectile should bounce or not when it hits + * something. + * + * @param doesBounce whether or not it should bounce. + */ + public void setBounce(boolean doesBounce); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Rabbit.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Rabbit.java new file mode 100644 index 0000000..1c8d1fc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Rabbit.java @@ -0,0 +1,49 @@ +package org.bukkit.entity; + +public interface Rabbit extends Animals { + + /** + * @return The type of rabbit. + */ + public Type getRabbitType(); + + /** + * @param type Sets the type of rabbit for this entity. + */ + public void setRabbitType(Type type); + + /** + * Represents the various types a Rabbit might be. + */ + public enum Type { + + /** + * Chocolate colored rabbit. + */ + BROWN, + /** + * Pure white rabbit. + */ + WHITE, + /** + * Black rabbit. + */ + BLACK, + /** + * Black with white patches, or white with black patches? + */ + BLACK_AND_WHITE, + /** + * Golden bunny. + */ + GOLD, + /** + * Salt and pepper colored, whatever that means. + */ + SALT_AND_PEPPER, + /** + * Rabbit with pure white fur, blood red horizontal eyes, and is hostile to players. + */ + THE_KILLER_BUNNY + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Sheep.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Sheep.java new file mode 100644 index 0000000..f4ce312 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Sheep.java @@ -0,0 +1,19 @@ +package org.bukkit.entity; + +import org.bukkit.material.Colorable; + +/** + * Represents a Sheep. + */ +public interface Sheep extends Animals, Colorable { + + /** + * @return Whether the sheep is sheared. + */ + public boolean isSheared(); + + /** + * @param flag Whether to shear the sheep + */ + public void setSheared(boolean flag); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Silverfish.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Silverfish.java new file mode 100644 index 0000000..fe01007 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Silverfish.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Silverfish. + */ +public interface Silverfish extends Monster {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Skeleton.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Skeleton.java new file mode 100644 index 0000000..02b76c3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Skeleton.java @@ -0,0 +1,65 @@ +package org.bukkit.entity; + +/** + * Represents a Skeleton. + */ +public interface Skeleton extends Monster { + + /** + * Gets the current type of this skeleton. + * + * @return Current type + */ + public SkeletonType getSkeletonType(); + + /** + * Sets the new type of this skeleton. + * + * @param type New type + */ + public void setSkeletonType(SkeletonType type); + + /* + * Represents the various different Skeleton types. + */ + public enum SkeletonType { + NORMAL(0), + WITHER(1); + + private static final SkeletonType[] types = new SkeletonType[SkeletonType.values().length]; + private final int id; + + static { + for (SkeletonType type : values()) { + types[type.getId()] = type; + } + } + + private SkeletonType(int id) { + this.id = id; + } + + /** + * Gets the ID of this skeleton type. + * + * @return Skeleton type ID + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + + /** + * Gets a skeleton type by its ID. + * + * @param id ID of the skeleton type to get. + * @return Resulting skeleton type, or null if not found. + * @deprecated Magic value + */ + @Deprecated + public static SkeletonType getType(int id) { + return (id >= types.length) ? null : types[id]; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Slime.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Slime.java new file mode 100644 index 0000000..cbf50c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Slime.java @@ -0,0 +1,17 @@ +package org.bukkit.entity; + +/** + * Represents a Slime. + */ +public interface Slime extends LivingEntity { + + /** + * @return The size of the slime + */ + public int getSize(); + + /** + * @param sz The new size of the slime. + */ + public void setSize(int sz); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/SmallFireball.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/SmallFireball.java new file mode 100644 index 0000000..33f54d3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/SmallFireball.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents a small {@link Fireball} + */ +public interface SmallFireball extends Fireball { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Snowball.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Snowball.java new file mode 100644 index 0000000..8c6b433 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Snowball.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a snowball. + */ +public interface Snowball extends Projectile {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Snowman.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Snowman.java new file mode 100644 index 0000000..c8070ff --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Snowman.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents a snowman entity + */ +public interface Snowman extends Golem { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Spider.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Spider.java new file mode 100644 index 0000000..f9ee8cc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Spider.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Spider. + */ +public interface Spider extends Monster {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Squid.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Squid.java new file mode 100644 index 0000000..fb47968 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Squid.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Squid. + */ +public interface Squid extends WaterMob {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/StorageMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/StorageMinecart.java new file mode 100644 index 0000000..5436d70 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/StorageMinecart.java @@ -0,0 +1,9 @@ +package org.bukkit.entity; + +/** + * @deprecated This class has been moved into a sub package; {@link + * org.bukkit.entity.minecart.StorageMinecart} should be used instead. + * @see org.bukkit.entity.minecart.StorageMinecart + */ +@Deprecated +public interface StorageMinecart extends org.bukkit.entity.minecart.StorageMinecart {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/TNTPrimed.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/TNTPrimed.java new file mode 100644 index 0000000..7b1b6b6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/TNTPrimed.java @@ -0,0 +1,45 @@ +package org.bukkit.entity; + +/** + * Represents a Primed TNT. + */ +public interface TNTPrimed extends Explosive { + + /** + * Set the number of ticks until the TNT blows up after being primed. + * + * @param fuseTicks The fuse ticks + */ + public void setFuseTicks(int fuseTicks); + + /** + * Retrieve the number of ticks until the explosion of this TNTPrimed + * entity + * + * @return the number of ticks until this TNTPrimed explodes + */ + public int getFuseTicks(); + + /** + * Gets the source of this primed TNT. The source is the entity + * responsible for the creation of this primed TNT. (I.E. player ignites + * TNT with flint and steel.) Take note that this can be null if there is + * no suitable source. (created by the {@link + * org.bukkit.World#spawn(Location, Class)} method, for example.) + *

+ * The source will become null if the chunk this primed TNT is in is + * unloaded then reloaded. If the source Entity becomes invalidated for + * any reason, such being removed from the world, the returned value will + * be null. + * + * @return the source of this primed TNT + */ + public Entity getSource(); + + /** + * Gets the source block location of the primed TNT. + * + * @return the source block location the TNT was spawned from + */ + public org.bukkit.Location getSourceLoc(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Tameable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Tameable.java new file mode 100644 index 0000000..014885d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Tameable.java @@ -0,0 +1,44 @@ +package org.bukkit.entity; + +public interface Tameable { + + /** + * Check if this is tamed + *

+ * If something is tamed then a player can not tame it through normal + * methods, even if it does not belong to anyone in particular. + * + * @return true if this has been tamed + */ + public boolean isTamed(); + + /** + * Sets if this has been tamed. Not necessary if the method setOwner has + * been used, as it tames automatically. + *

+ * If something is tamed then a player can not tame it through normal + * methods, even if it does not belong to anyone in particular. + * + * @param tame true if tame + */ + public void setTamed(boolean tame); + + /** + * Gets the current owning AnimalTamer + * + * @return the owning AnimalTamer, or null if not owned + */ + public AnimalTamer getOwner(); + + /** + * Set this to be owned by given AnimalTamer. + *

+ * If the owner is not null, this will be tamed and will have any current + * path it is following removed. If the owner is set to null, this will be + * untamed, and the current owner removed. + * + * @param tamer the AnimalTamer who should own this + */ + public void setOwner(AnimalTamer tamer); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ThrownExpBottle.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ThrownExpBottle.java new file mode 100644 index 0000000..671282e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ThrownExpBottle.java @@ -0,0 +1,8 @@ +package org.bukkit.entity; + +/** + * Represents a thrown Experience bottle. + */ +public interface ThrownExpBottle extends Projectile { + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ThrownPotion.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ThrownPotion.java new file mode 100644 index 0000000..8b382db --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/ThrownPotion.java @@ -0,0 +1,39 @@ +package org.bukkit.entity; + +import java.util.Collection; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; + +/** + * Represents a thrown potion bottle + */ +public interface ThrownPotion extends Projectile { + + /** + * Returns the effects that are applied by this potion. + * + * @return The potion effects + */ + public Collection getEffects(); + + /** + * Returns a copy of the ItemStack for this thrown potion. + *

+ * Altering this copy will not alter the thrown potion directly. If you + * want to alter the thrown potion, you must use the {@link + * #setItem(ItemStack) setItemStack} method. + * + * @return A copy of the ItemStack for this thrown potion. + */ + public ItemStack getItem(); + + /** + * Set the ItemStack for this thrown potion. + *

+ * The ItemStack must be a potion, otherwise an exception is thrown. + * + * @param item New ItemStack + */ + public void setItem(ItemStack item); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Vehicle.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Vehicle.java new file mode 100644 index 0000000..7d7607c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Vehicle.java @@ -0,0 +1,23 @@ +package org.bukkit.entity; + +import org.bukkit.util.Vector; + +/** + * Represents a vehicle entity. + */ +public interface Vehicle extends Entity { + + /** + * Gets the vehicle's velocity. + * + * @return velocity vector + */ + public Vector getVelocity(); + + /** + * Sets the vehicle's velocity. + * + * @param vel velocity vector + */ + public void setVelocity(Vector vel); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Villager.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Villager.java new file mode 100644 index 0000000..51035c9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Villager.java @@ -0,0 +1,69 @@ +package org.bukkit.entity; + +/** + * Represents a villager NPC + */ +public interface Villager extends Ageable, NPC { + + /** + * Gets the current profession of this villager. + * + * @return Current profession. + */ + public Profession getProfession(); + + /** + * Sets the new profession of this villager. + * + * @param profession New profession. + */ + public void setProfession(Profession profession); + + + /** + * Represents the various different Villager professions there may be. + */ + public enum Profession { + FARMER(0), + LIBRARIAN(1), + PRIEST(2), + BLACKSMITH(3), + BUTCHER(4); + + private static final Profession[] professions = new Profession[Profession.values().length]; + private final int id; + + static { + for (Profession type : values()) { + professions[type.getId()] = type; + } + } + + private Profession(int id) { + this.id = id; + } + + /** + * Gets the ID of this profession. + * + * @return Profession ID. + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + + /** + * Gets a profession by its ID. + * + * @param id ID of the profession to get. + * @return Resulting profession, or null if not found. + * @deprecated Magic value + */ + @Deprecated + public static Profession getProfession(int id) { + return (id >= professions.length) ? null : professions[id]; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/WaterMob.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/WaterMob.java new file mode 100644 index 0000000..3e89ca0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/WaterMob.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Water Mob + */ +public interface WaterMob extends LivingEntity {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Weather.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Weather.java new file mode 100644 index 0000000..6d77851 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Weather.java @@ -0,0 +1,6 @@ +package org.bukkit.entity; + +/** + * Represents a Weather related entity, such as a storm + */ +public interface Weather extends Entity {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Witch.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Witch.java new file mode 100644 index 0000000..9c5dc1f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Witch.java @@ -0,0 +1,7 @@ +package org.bukkit.entity; + +/** + * Represents a Witch + */ +public interface Witch extends Monster { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Wither.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Wither.java new file mode 100644 index 0000000..0922c5c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Wither.java @@ -0,0 +1,7 @@ +package org.bukkit.entity; + +/** + * Represents a Wither boss + */ +public interface Wither extends Monster { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/WitherSkull.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/WitherSkull.java new file mode 100644 index 0000000..33d20ab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/WitherSkull.java @@ -0,0 +1,21 @@ +package org.bukkit.entity; + +/** + * Represents a wither skull {@link Fireball}. + */ +public interface WitherSkull extends Fireball { + + /** + * Sets the charged status of the wither skull. + * + * @param charged whether it should be charged + */ + public void setCharged(boolean charged); + + /** + * Gets whether or not the wither skull is charged. + * + * @return whether the wither skull is charged + */ + public boolean isCharged(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Wolf.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Wolf.java new file mode 100644 index 0000000..9d5a896 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Wolf.java @@ -0,0 +1,56 @@ +package org.bukkit.entity; + +import org.bukkit.DyeColor; + +/** + * Represents a Wolf + */ +public interface Wolf extends Animals, Tameable { + + /** + * Checks if this wolf is angry + * + * @return Anger true if angry + */ + public boolean isAngry(); + + /** + * Sets the anger of this wolf. + *

+ * An angry wolf can not be fed or tamed, and will actively look for + * targets to attack. + * + * @param angry true if angry + */ + public void setAngry(boolean angry); + + /** + * Checks if this wolf is sitting + * + * @return true if sitting + */ + public boolean isSitting(); + + /** + * Sets if this wolf is sitting. + *

+ * Will remove any path that the wolf was following beforehand. + * + * @param sitting true if sitting + */ + public void setSitting(boolean sitting); + + /** + * Get the collar color of this wolf + * + * @return the color of the collar + */ + public DyeColor getCollarColor(); + + /** + * Set the collar color of this wolf + * + * @param color the color to apply + */ + public void setCollarColor(DyeColor color); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Zombie.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Zombie.java new file mode 100644 index 0000000..59b52fd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/Zombie.java @@ -0,0 +1,35 @@ +package org.bukkit.entity; + +/** + * Represents a Zombie. + */ +public interface Zombie extends Monster { + + /** + * Gets whether the zombie is a baby + * + * @return Whether the zombie is a baby + */ + public boolean isBaby(); + + /** + * Sets whether the zombie is a baby + * + * @param flag Whether the zombie is a baby + */ + public void setBaby(boolean flag); + + /** + * Gets whether the zombie is a villager + * + * @return Whether the zombie is a villager + */ + public boolean isVillager(); + + /** + * Sets whether the zombie is a villager + * + * @param flag Whether the zombie is a villager + */ + public void setVillager(boolean flag); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java new file mode 100644 index 0000000..e502680 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/CommandMinecart.java @@ -0,0 +1,36 @@ +package org.bukkit.entity.minecart; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Minecart; + +public interface CommandMinecart extends Minecart, CommandSender { + + /** + * Gets the command that this CommandMinecart will run when activated. + * This will never return null. If the CommandMinecart does not have a + * command, an empty String will be returned instead. + * + * @return Command that this CommandMinecart will run when powered. + */ + public String getCommand(); + + /** + * Sets the command that this CommandMinecart will run when activated. + * Setting the command to null is the same as setting it to an empty + * String. + * + * @param command Command that this CommandMinecart will run when + * activated. + */ + public void setCommand(String command); + + /** + * Sets the name of this CommandMinecart. The name is used with commands + * that this CommandMinecart executes. Setting the name to null is the + * same as setting it to "@". + * + * @param name New name for this CommandMinecart. + */ + public void setName(String name); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/ExplosiveMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/ExplosiveMinecart.java new file mode 100644 index 0000000..a4411da --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/ExplosiveMinecart.java @@ -0,0 +1,9 @@ +package org.bukkit.entity.minecart; + +import org.bukkit.entity.Minecart; + +/** + * Represents a Minecart with TNT inside it that can explode when triggered. + */ +public interface ExplosiveMinecart extends Minecart { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java new file mode 100644 index 0000000..5da9ce4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java @@ -0,0 +1,10 @@ +package org.bukkit.entity.minecart; + +import org.bukkit.entity.Minecart; +import org.bukkit.inventory.InventoryHolder; + +/** + * Represents a Minecart with a Hopper inside it + */ +public interface HopperMinecart extends Minecart, InventoryHolder { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/PoweredMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/PoweredMinecart.java new file mode 100644 index 0000000..57e8b1d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/PoweredMinecart.java @@ -0,0 +1,10 @@ +package org.bukkit.entity.minecart; + +import org.bukkit.entity.Minecart; + +/** + * Represents a powered minecart. A powered minecart moves on its own when a + * player deposits {@link org.bukkit.Material#COAL fuel}. + */ +public interface PoweredMinecart extends Minecart { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/RideableMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/RideableMinecart.java new file mode 100644 index 0000000..1b82645 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/RideableMinecart.java @@ -0,0 +1,14 @@ +package org.bukkit.entity.minecart; + +import org.bukkit.entity.Minecart; + +/** + * Represents a minecart that can have certain {@link + * org.bukkit.entity.Entity entities} as passengers. Normal passengers + * include all {@link org.bukkit.entity.LivingEntity living entities} with + * the exception of {@link org.bukkit.entity.IronGolem iron golems}. + * Non-player entities that meet normal passenger criteria automatically + * mount these minecarts when close enough. + */ +public interface RideableMinecart extends Minecart { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/SpawnerMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/SpawnerMinecart.java new file mode 100644 index 0000000..0ce3592 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/SpawnerMinecart.java @@ -0,0 +1,10 @@ +package org.bukkit.entity.minecart; + +import org.bukkit.entity.Minecart; + +/** + * Represents a Minecart with an {@link org.bukkit.block.CreatureSpawner + * entity spawner} inside it. + */ +public interface SpawnerMinecart extends Minecart { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java new file mode 100644 index 0000000..4f04ab4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java @@ -0,0 +1,12 @@ +package org.bukkit.entity.minecart; + +import org.bukkit.entity.Minecart; +import org.bukkit.inventory.InventoryHolder; + +/** + * Represents a minecart with a chest. These types of {@link Minecart + * minecarts} have their own inventory that can be accessed using methods + * from the {@link InventoryHolder} interface. + */ +public interface StorageMinecart extends Minecart, InventoryHolder { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Cancellable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Cancellable.java new file mode 100644 index 0000000..799b0b0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Cancellable.java @@ -0,0 +1,20 @@ +package org.bukkit.event; + +public interface Cancellable { + + /** + * Gets the cancellation state of this event. A cancelled event will not + * be executed in the server, but will still pass to other plugins + * + * @return true if this event is cancelled + */ + public boolean isCancelled(); + + /** + * Sets the cancellation state of this event. A cancelled event will not + * be executed in the server, but will still pass to other plugins. + * + * @param cancel true if you wish to cancel this event + */ + public void setCancelled(boolean cancel); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Event.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Event.java new file mode 100644 index 0000000..6677e1b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Event.java @@ -0,0 +1,98 @@ +package org.bukkit.event; + +import org.bukkit.plugin.PluginManager; + +/** + * Represents an event. + * + * All events require a static method named getHandlerList() which returns the same {@link HandlerList} as {@link #getHandlers()}. + * + * @see PluginManager#callEvent(Event) + * @see PluginManager#registerEvents(Listener,Plugin) + */ +public abstract class Event { + private String name; + private final boolean async; + + /** + * The default constructor is defined for cleaner code. This constructor + * assumes the event is synchronous. + */ + public Event() { + this(false); + } + + /** + * This constructor is used to explicitly declare an event as synchronous + * or asynchronous. + * + * @param isAsync true indicates the event will fire asynchronously, false + * by default from default constructor + */ + public Event(boolean isAsync) { + this.async = isAsync; + } + + /** + * Convenience method for providing a user-friendly identifier. By + * default, it is the event's class's {@linkplain Class#getSimpleName() + * simple name}. + * + * @return name of this event + */ + public String getEventName() { + if (name == null) { + name = getClass().getSimpleName(); + } + return name; + } + + public abstract HandlerList getHandlers(); + + /** + * Any custom event that should not by synchronized with other events must + * use the specific constructor. These are the caveats of using an + * asynchronous event: + *

    + *
  • The event is never fired from inside code triggered by a + * synchronous event. Attempting to do so results in an {@link + * java.lang.IllegalStateException}. + *
  • However, asynchronous event handlers may fire synchronous or + * asynchronous events + *
  • The event may be fired multiple times simultaneously and in any + * order. + *
  • Any newly registered or unregistered handler is ignored after an + * event starts execution. + *
  • The handlers for this event may block for any length of time. + *
  • Some implementations may selectively declare a specific event use + * as asynchronous. This behavior should be clearly defined. + *
  • Asynchronous calls are not calculated in the plugin timing system. + *
+ * + * @return false by default, true if the event fires asynchronously + */ + public final boolean isAsynchronous() { + return async; + } + + public enum Result { + + /** + * Deny the event. Depending on the event, the action indicated by the + * event will either not take place or will be reverted. Some actions + * may not be denied. + */ + DENY, + /** + * Neither deny nor allow the event. The server will proceed with its + * normal handling. + */ + DEFAULT, + /** + * Allow / Force the event. The action indicated by the event will + * take place if possible, even if the server would not normally allow + * the action. Some actions may not be allowed. + */ + ALLOW; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventException.java new file mode 100644 index 0000000..84638e8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventException.java @@ -0,0 +1,53 @@ +package org.bukkit.event; + +public class EventException extends Exception { + private static final long serialVersionUID = 3532808232324183999L; + private final Throwable cause; + + /** + * Constructs a new EventException based on the given Exception + * + * @param throwable Exception that triggered this Exception + */ + public EventException(Throwable throwable) { + cause = throwable; + } + + /** + * Constructs a new EventException + */ + public EventException() { + cause = null; + } + + /** + * Constructs a new EventException with the given message + * + * @param cause The exception that caused this + * @param message The message + */ + public EventException(Throwable cause, String message) { + super(message); + this.cause = cause; + } + + /** + * Constructs a new EventException with the given message + * + * @param message The message + */ + public EventException(String message) { + super(message); + cause = null; + } + + /** + * If applicable, returns the Exception that triggered this Exception + * + * @return Inner exception, or null if one does not exist + */ + @Override + public Throwable getCause() { + return cause; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventHandler.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventHandler.java new file mode 100644 index 0000000..4c9fb3c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventHandler.java @@ -0,0 +1,41 @@ +package org.bukkit.event; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * An annotation to mark methods as being event handler methods + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface EventHandler { + + /** + * Define the priority of the event. + *

+ * First priority to the last priority executed: + *

    + *
  1. LOWEST + *
  2. LOW + *
  3. NORMAL + *
  4. HIGH + *
  5. HIGHEST + *
  6. MONITOR + *
+ * + * @return the priority + */ + EventPriority priority() default EventPriority.NORMAL; + + /** + * Define if the handler ignores a cancelled event. + *

+ * If ignoreCancelled is true and the event is cancelled, the method is + * not called. Otherwise, the method is always called. + * + * @return whether cancelled events should be ignored + */ + boolean ignoreCancelled() default false; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventPriority.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventPriority.java new file mode 100644 index 0000000..61ffa50 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/EventPriority.java @@ -0,0 +1,47 @@ +package org.bukkit.event; + +/** + * Represents an event's priority in execution + */ +public enum EventPriority { + + /** + * Event call is of very low importance and should be ran first, to allow + * other plugins to further customise the outcome + */ + LOWEST(0), + /** + * Event call is of low importance + */ + LOW(1), + /** + * Event call is neither important nor unimportant, and may be ran + * normally + */ + NORMAL(2), + /** + * Event call is of high importance + */ + HIGH(3), + /** + * Event call is critical and must have the final say in what happens + * to the event + */ + HIGHEST(4), + /** + * Event is listened to purely for monitoring the outcome of an event. + *

+ * No modifications to the event should be made under this priority + */ + MONITOR(5); + + private final int slot; + + private EventPriority(int slot) { + this.slot = slot; + } + + public int getSlot() { + return slot; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/HandlerList.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/HandlerList.java new file mode 100644 index 0000000..7d5efff --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/HandlerList.java @@ -0,0 +1,231 @@ +package org.bukkit.event; + +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; + +import java.util.*; +import java.util.Map.Entry; + +/** + * A list of event handlers, stored per-event. Based on lahwran's fevents. + */ +public class HandlerList { + + /** + * Handler array. This field being an array is the key to this system's + * speed. + */ + private volatile RegisteredListener[] handlers = null; + + /** + * Dynamic handler lists. These are changed using register() and + * unregister() and are automatically baked to the handlers array any time + * they have changed. + */ + private final EnumMap> handlerslots; + + /** + * List of all HandlerLists which have been created, for use in bakeAll() + */ + private static ArrayList allLists = new ArrayList(); + + /** + * Bake all handler lists. Best used just after all normal event + * registration is complete, ie just after all plugins are loaded if + * you're using fevents in a plugin system. + */ + public static void bakeAll() { + synchronized (allLists) { + for (HandlerList h : allLists) { + h.bake(); + } + } + } + + /** + * Unregister all listeners from all handler lists. + */ + public static void unregisterAll() { + synchronized (allLists) { + for (HandlerList h : allLists) { + synchronized (h) { + for (List list : h.handlerslots.values()) { + list.clear(); + } + h.handlers = null; + } + } + } + } + + /** + * Unregister a specific plugin's listeners from all handler lists. + * + * @param plugin plugin to unregister + */ + public static void unregisterAll(Plugin plugin) { + synchronized (allLists) { + for (HandlerList h : allLists) { + h.unregister(plugin); + } + } + } + + /** + * Unregister a specific listener from all handler lists. + * + * @param listener listener to unregister + */ + public static void unregisterAll(Listener listener) { + synchronized (allLists) { + for (HandlerList h : allLists) { + h.unregister(listener); + } + } + } + + /** + * Create a new handler list and initialize using EventPriority. + *

+ * The HandlerList is then added to meta-list for use in bakeAll() + */ + public HandlerList() { + handlerslots = new EnumMap>(EventPriority.class); + for (EventPriority o : EventPriority.values()) { + handlerslots.put(o, new ArrayList()); + } + synchronized (allLists) { + allLists.add(this); + } + } + + /** + * Register a new listener in this handler list + * + * @param listener listener to register + */ + public synchronized void register(RegisteredListener listener) { + if (handlerslots.get(listener.getPriority()).contains(listener)) + throw new IllegalStateException("This listener is already registered to priority " + listener.getPriority().toString()); + handlers = null; + handlerslots.get(listener.getPriority()).add(listener); + } + + /** + * Register a collection of new listeners in this handler list + * + * @param listeners listeners to register + */ + public void registerAll(Collection listeners) { + for (RegisteredListener listener : listeners) { + register(listener); + } + } + + /** + * Remove a listener from a specific order slot + * + * @param listener listener to remove + */ + public synchronized void unregister(RegisteredListener listener) { + if (handlerslots.get(listener.getPriority()).remove(listener)) { + handlers = null; + } + } + + /** + * Remove a specific plugin's listeners from this handler + * + * @param plugin plugin to remove + */ + public synchronized void unregister(Plugin plugin) { + boolean changed = false; + for (List list : handlerslots.values()) { + for (ListIterator i = list.listIterator(); i.hasNext();) { + if (i.next().getPlugin().equals(plugin)) { + i.remove(); + changed = true; + } + } + } + if (changed) handlers = null; + } + + /** + * Remove a specific listener from this handler + * + * @param listener listener to remove + */ + public synchronized void unregister(Listener listener) { + boolean changed = false; + for (List list : handlerslots.values()) { + for (ListIterator i = list.listIterator(); i.hasNext();) { + if (i.next().getListener().equals(listener)) { + i.remove(); + changed = true; + } + } + } + if (changed) handlers = null; + } + + /** + * Bake HashMap and ArrayLists to 2d array - does nothing if not necessary + */ + public synchronized void bake() { + if (handlers != null) return; // don't re-bake when still valid + List entries = new ArrayList(); + for (Entry> entry : handlerslots.entrySet()) { + entries.addAll(entry.getValue()); + } + handlers = entries.toArray(new RegisteredListener[entries.size()]); + } + + /** + * Get the baked registered listeners associated with this handler list + * + * @return the array of registered listeners + */ + public RegisteredListener[] getRegisteredListeners() { + RegisteredListener[] handlers; + while ((handlers = this.handlers) == null) bake(); // This prevents fringe cases of returning null + return handlers; + } + + /** + * Get a specific plugin's registered listeners associated with this + * handler list + * + * @param plugin the plugin to get the listeners of + * @return the list of registered listeners + */ + public static ArrayList getRegisteredListeners(Plugin plugin) { + ArrayList listeners = new ArrayList(); + synchronized (allLists) { + for (HandlerList h : allLists) { + synchronized (h) { + for (List list : h.handlerslots.values()) { + for (RegisteredListener listener : list) { + if (listener.getPlugin().equals(plugin)) { + listeners.add(listener); + } + } + } + } + } + } + return listeners; + } + + /** + * Get a list of all handler lists for every event type + * + * @return the list of all handler lists + */ + @SuppressWarnings("unchecked") + public static ArrayList getHandlerLists() { + synchronized (allLists) { + return (ArrayList) allLists.clone(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Listener.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Listener.java new file mode 100644 index 0000000..ff083e6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/Listener.java @@ -0,0 +1,6 @@ +package org.bukkit.event; + +/** + * Simple interface for tagging all EventListeners + */ +public interface Listener {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/Action.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/Action.java new file mode 100644 index 0000000..25d26e3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/Action.java @@ -0,0 +1,33 @@ +package org.bukkit.event.block; + +public enum Action { + + /** + * Left-clicking a block + */ + LEFT_CLICK_BLOCK, + /** + * Right-clicking a block + */ + RIGHT_CLICK_BLOCK, + /** + * Left-clicking the air + */ + LEFT_CLICK_AIR, + /** + * Right-clicking the air + */ + RIGHT_CLICK_AIR, + /** + * Stepping onto or into a block (Ass-pressure) + * + * Examples: + *

    + *
  • Jumping on soil + *
  • Standing on pressure plate + *
  • Triggering redstone ore + *
  • Triggering tripwire + *
+ */ + PHYSICAL, +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockBreakEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockBreakEvent.java new file mode 100644 index 0000000..a011f61 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockBreakEvent.java @@ -0,0 +1,55 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a block is broken by a player. + *

+ * If you wish to have the block drop experience, you must set the experience + * value above 0. By default, experience will be set in the event if: + *

    + *
  1. The player is not in creative or adventure mode + *
  2. The player can loot the block (ie: does not destroy it completely, by + * using the correct tool) + *
  3. The player does not have silk touch + *
  4. The block drops experience in vanilla Minecraft + *
+ *

+ * Note: + * Plugins wanting to simulate a traditional block drop should set the block + * to air and utilize their own methods for determining what the default drop + * for the block being broken is and what to do about it, if anything. + *

+ * If a Block Break event is cancelled, the block will not break and + * experience will not drop. + */ +public class BlockBreakEvent extends BlockExpEvent implements Cancellable { + private final Player player; + private boolean cancel; + + public BlockBreakEvent(final Block theBlock, final Player player) { + super(theBlock, 0); + + this.player = player; + } + + /** + * Gets the Player that is breaking the block involved in this event. + * + * @return The Player that is breaking the block involved in this event + */ + public Player getPlayer() { + return player; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockBurnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockBurnEvent.java new file mode 100644 index 0000000..1592a15 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockBurnEvent.java @@ -0,0 +1,38 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a block is destroyed as a result of being burnt by fire. + *

+ * If a Block Burn event is cancelled, the block will not be destroyed as a + * result of being burnt by fire. + */ +public class BlockBurnEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + + public BlockBurnEvent(final Block block) { + super(block); + this.cancelled = false; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java new file mode 100644 index 0000000..613feb9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java @@ -0,0 +1,93 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.Material; +import org.bukkit.event.HandlerList; + +/** + * Called when we try to place a block, to see if we can build it here or not. + *

+ * Note: + *

    + *
  • The Block returned by getBlock() is the block we are trying to place + * on, not the block we are trying to place. + *
  • If you want to figure out what is being placed, use {@link + * #getMaterial()} or {@link #getMaterialId()} instead. + *
+ */ +public class BlockCanBuildEvent extends BlockEvent { + private static final HandlerList handlers = new HandlerList(); + protected boolean buildable; + + /** + * + * @deprecated Magic value + */ + @Deprecated + protected int material; + + /** + * + * @deprecated Magic value + * @param block the block involved in this event + * @param id the id of the block to place + * @param canBuild whether we can build + */ + @Deprecated + public BlockCanBuildEvent(final Block block, final int id, final boolean canBuild) { + super(block); + buildable = canBuild; + material = id; + } + + /** + * Gets whether or not the block can be built here. + *

+ * By default, returns Minecraft's answer on whether the block can be + * built here or not. + * + * @return boolean whether or not the block can be built + */ + public boolean isBuildable() { + return buildable; + } + + /** + * Sets whether the block can be built here or not. + * + * @param cancel true if you want to allow the block to be built here + * despite Minecraft's default behaviour + */ + public void setBuildable(boolean cancel) { + this.buildable = cancel; + } + + /** + * Gets the Material that we are trying to place. + * + * @return The Material that we are trying to place + */ + public Material getMaterial() { + return Material.getMaterial(material); + } + + /** + * Gets the Material ID for the Material that we are trying to place. + * + * @return The Material ID for the Material that we are trying to place + * @deprecated Magic value + */ + @Deprecated + public int getMaterialId() { + return material; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockDamageEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockDamageEvent.java new file mode 100644 index 0000000..d80e00e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockDamageEvent.java @@ -0,0 +1,83 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * Called when a block is damaged by a player. + *

+ * If a Block Damage event is cancelled, the block will not be damaged. + */ +public class BlockDamageEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Player player; + private boolean instaBreak; + private boolean cancel; + private final ItemStack itemstack; + + public BlockDamageEvent(final Player player, final Block block, final ItemStack itemInHand, final boolean instaBreak) { + super(block); + this.instaBreak = instaBreak; + this.player = player; + this.itemstack = itemInHand; + this.cancel = false; + } + + /** + * Gets the player damaging the block involved in this event. + * + * @return The player damaging the block involved in this event + */ + public Player getPlayer() { + return player; + } + + /** + * Gets if the block is set to instantly break when damaged by the player. + * + * @return true if the block should instantly break when damaged by the + * player + */ + public boolean getInstaBreak() { + return instaBreak; + } + + /** + * Sets if the block should instantly break when damaged by the player. + * + * @param bool true if you want the block to instantly break when damaged + * by the player + */ + public void setInstaBreak(boolean bool) { + this.instaBreak = bool; + } + + /** + * Gets the ItemStack for the item currently in the player's hand. + * + * @return The ItemStack for the item currently in the player's hand + */ + public ItemStack getItemInHand() { + return itemstack; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockDispenseEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockDispenseEvent.java new file mode 100644 index 0000000..16ee59b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockDispenseEvent.java @@ -0,0 +1,84 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +/** + * Called when an item is dispensed from a block. + *

+ * If a Block Dispense event is cancelled, the block will not dispense the + * item. + */ +public class BlockDispenseEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled = false; + private ItemStack item; + private Vector velocity; + + public BlockDispenseEvent(final Block block, final ItemStack dispensed, final Vector velocity) { + super(block); + this.item = dispensed; + this.velocity = velocity; + } + + /** + * Gets the item that is being dispensed. Modifying the returned item will + * have no effect, you must use {@link + * #setItem(org.bukkit.inventory.ItemStack)} instead. + * + * @return An ItemStack for the item being dispensed + */ + public ItemStack getItem() { + return item.clone(); + } + + /** + * Sets the item being dispensed. + * + * @param item the item being dispensed + */ + public void setItem(ItemStack item) { + this.item = item; + } + + /** + * Gets the velocity. + *

+ * Note: Modifying the returned Vector will not change the velocity, you + * must use {@link #setVelocity(org.bukkit.util.Vector)} instead. + * + * @return A Vector for the dispensed item's velocity + */ + public Vector getVelocity() { + return velocity.clone(); + } + + /** + * Sets the velocity of the item being dispensed. + * + * @param vel the velocity of the item being dispensed + */ + public void setVelocity(Vector vel) { + velocity = vel; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockEvent.java new file mode 100644 index 0000000..2405205 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.event.Event; + +/** + * Represents a block related event. + */ +public abstract class BlockEvent extends Event { + protected Block block; + + public BlockEvent(final Block theBlock) { + block = theBlock; + } + + /** + * Gets the block involved in this event. + * + * @return The Block which block is involved in this event + */ + public final Block getBlock() { + return block; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockExpEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockExpEvent.java new file mode 100644 index 0000000..08636a2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockExpEvent.java @@ -0,0 +1,45 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.event.HandlerList; + +/** + * An event that's called when a block yields experience. + */ +public class BlockExpEvent extends BlockEvent { + private static final HandlerList handlers = new HandlerList(); + private int exp; + + public BlockExpEvent(Block block, int exp) { + super(block); + + this.exp = exp; + } + + /** + * Get the experience dropped by the block after the event has processed + * + * @return The experience to drop + */ + public int getExpToDrop() { + return exp; + } + + /** + * Set the amount of experience dropped by the block after the event has + * processed + * + * @param exp 1 or higher to drop experience, else nothing will drop + */ + public void setExpToDrop(int exp) { + this.exp = exp; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java new file mode 100644 index 0000000..5f15e29 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockExplodeEvent.java @@ -0,0 +1,69 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +import java.util.List; + +/** + * Called when a block explodes + */ +public class BlockExplodeEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + private final List blocks; + private float yield; + + public BlockExplodeEvent(final Block what, final List blocks, final float yield) { + super(what); + this.blocks = blocks; + this.yield = yield; + this.cancel = false; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Returns the list of blocks that would have been removed or were removed + * from the explosion event. + * + * @return All blown-up blocks + */ + public List blockList() { + return blocks; + } + + /** + * Returns the percentage of blocks to drop from this explosion + * + * @return The yield. + */ + public float getYield() { + return yield; + } + + /** + * Sets the percentage of blocks to drop from this explosion + * + * @param yield The new yield percentage + */ + public void setYield(float yield) { + this.yield = yield; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFadeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFadeEvent.java new file mode 100644 index 0000000..673bc5f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFadeEvent.java @@ -0,0 +1,59 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a block fades, melts or disappears based on world conditions + *

+ * Examples: + *

    + *
  • Snow melting due to being near a light source. + *
  • Ice melting due to being near a light source. + *
  • Fire burning out after time, without destroying fuel block. + *
+ *

+ * If a Block Fade event is cancelled, the block will not fade, melt or + * disappear. + */ +public class BlockFadeEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final BlockState newState; + + public BlockFadeEvent(final Block block, final BlockState newState) { + super(block); + this.newState = newState; + this.cancelled = false; + } + + /** + * Gets the state of the block that will be fading, melting or + * disappearing. + * + * @return The block state of the block that will be fading, melting or + * disappearing + */ + public BlockState getNewState() { + return newState; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFormEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFormEvent.java new file mode 100644 index 0000000..df0401f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFormEvent.java @@ -0,0 +1,39 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a block is formed or spreads based on world conditions. + *

+ * Use {@link BlockSpreadEvent} to catch blocks that actually spread and don't + * just "randomly" form. + *

+ * Examples: + *

    + *
  • Snow forming due to a snow storm. + *
  • Ice forming in a snowy Biome like Taiga or Tundra. + *
+ *

+ * If a Block Form event is cancelled, the block will not be formed. + * + * @see BlockSpreadEvent + */ +public class BlockFormEvent extends BlockGrowEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + public BlockFormEvent(final Block block, final BlockState newState) { + super(block, newState); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFromToEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFromToEvent.java new file mode 100644 index 0000000..f976bea --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockFromToEvent.java @@ -0,0 +1,71 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Represents events with a source block and a destination block, currently + * only applies to liquid (lava and water) and teleporting dragon eggs. + *

+ * If a Block From To event is cancelled, the block will not move (the liquid + * will not flow). + */ +public class BlockFromToEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + protected Block to; + protected BlockFace face; + protected boolean cancel; + + public BlockFromToEvent(final Block block, final BlockFace face) { + super(block); + this.face = face; + this.cancel = false; + } + + public BlockFromToEvent(final Block block, final Block toBlock) { + super(block); + this.to = toBlock; + this.face = BlockFace.SELF; + this.cancel = false; + } + + /** + * Gets the BlockFace that the block is moving to. + * + * @return The BlockFace that the block is moving to + */ + public BlockFace getFace() { + return face; + } + + /** + * Convenience method for getting the faced Block. + * + * @return The faced Block + */ + public Block getToBlock() { + if (to == null) { + to = block.getRelative(face); + } + return to; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockGrowEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockGrowEvent.java new file mode 100644 index 0000000..2a959fd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockGrowEvent.java @@ -0,0 +1,56 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a block grows naturally in the world. + *

+ * Examples: + *

    + *
  • Wheat + *
  • Sugar Cane + *
  • Cactus + *
  • Watermelon + *
  • Pumpkin + *
+ *

+ * If a Block Grow event is cancelled, the block will not grow. + */ +public class BlockGrowEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final BlockState newState; + private boolean cancelled = false; + + public BlockGrowEvent(final Block block, final BlockState newState) { + super(block); + this.newState = newState; + } + + /** + * Gets the state of the block where it will form or spread to. + * + * @return The block state for this events block + */ + public BlockState getNewState() { + return newState; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockIgniteEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockIgniteEvent.java new file mode 100644 index 0000000..5ea8b07 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockIgniteEvent.java @@ -0,0 +1,134 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a block is ignited. If you want to catch when a Player places + * fire, you need to use {@link BlockPlaceEvent}. + *

+ * If a Block Ignite event is cancelled, the block will not be ignited. + */ +public class BlockIgniteEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final IgniteCause cause; + private final Entity ignitingEntity; + private final Block ignitingBlock; + private boolean cancel; + + @Deprecated + public BlockIgniteEvent(final Block theBlock, final IgniteCause cause, final Player thePlayer) { + this(theBlock, cause, (Entity) thePlayer); + } + + public BlockIgniteEvent(final Block theBlock, final IgniteCause cause, final Entity ignitingEntity) { + this(theBlock, cause, ignitingEntity, null); + } + + public BlockIgniteEvent(final Block theBlock, final IgniteCause cause, final Block ignitingBlock) { + this(theBlock, cause, null, ignitingBlock); + } + + public BlockIgniteEvent(final Block theBlock, final IgniteCause cause, final Entity ignitingEntity, final Block ignitingBlock) { + super(theBlock); + this.cause = cause; + this.ignitingEntity = ignitingEntity; + this.ignitingBlock = ignitingBlock; + this.cancel = false; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the cause of block ignite. + * + * @return An IgniteCause value detailing the cause of block ignition + */ + public IgniteCause getCause() { + return cause; + } + + /** + * Gets the player who ignited this block + * + * @return The Player that placed/ignited the fire block, or null if not ignited by a Player. + */ + public Player getPlayer() { + if (ignitingEntity instanceof Player) { + return (Player) ignitingEntity; + } + + return null; + } + + /** + * Gets the entity who ignited this block + * + * @return The Entity that placed/ignited the fire block, or null if not ignited by a Entity. + */ + public Entity getIgnitingEntity() { + return ignitingEntity; + } + + /** + * Gets the block who ignited this block + * + * @return The Block that placed/ignited the fire block, or null if not ignited by a Block. + */ + public Block getIgnitingBlock() { + return ignitingBlock; + } + + /** + * An enum to specify the cause of the ignite + */ + public enum IgniteCause { + + /** + * Block ignition caused by lava. + */ + LAVA, + /** + * Block ignition caused by a player or dispenser using flint-and-steel. + */ + FLINT_AND_STEEL, + /** + * Block ignition caused by dynamic spreading of fire. + */ + SPREAD, + /** + * Block ignition caused by lightning. + */ + LIGHTNING, + /** + * Block ignition caused by an entity using a fireball. + */ + FIREBALL, + /** + * Block ignition caused by an Ender Crystal. + */ + ENDER_CRYSTAL, + /** + * Block ignition caused by explosion. + */ + EXPLOSION, + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockMultiPlaceEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockMultiPlaceEvent.java new file mode 100644 index 0000000..d16e4be --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockMultiPlaceEvent.java @@ -0,0 +1,36 @@ +package org.bukkit.event.block; + +import com.google.common.collect.ImmutableList; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +/** + * Fired when a single block placement action of a player triggers the + * creation of multiple blocks(e.g. placing a bed block). The block returned + * by {@link #getBlockPlaced()} and its related methods is the block where + * the placed block would exist if the placement only affected a single + * block. + */ +public class BlockMultiPlaceEvent extends BlockPlaceEvent { + private final List states; + + public BlockMultiPlaceEvent(List states, Block clicked, ItemStack itemInHand, Player thePlayer, boolean canBuild) { + super(states.get(0).getBlock(), states.get(0), clicked, itemInHand, thePlayer, canBuild); + this.states = ImmutableList.copyOf(states); + } + + /** + * Gets a list of blockstates for all blocks which were replaced by the + * placement of the new blocks. Most of these blocks will just have a + * Material type of AIR. + * + * @return immutable list of replaced BlockStates + */ + public List getReplacedBlockStates() { + return states; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java new file mode 100644 index 0000000..01a545b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPhysicsEvent.java @@ -0,0 +1,64 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.Material; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Thrown when a block physics check is called + */ +public class BlockPhysicsEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final int changed; + private boolean cancel = false; + + /** + * + * @deprecated Magic value + * @param block the block involved in this event + * @param changed the changed block's type id + */ + @Deprecated + public BlockPhysicsEvent(final Block block, final int changed) { + super(block); + this.changed = changed; + } + + /** + * Gets the type of block that changed, causing this event + * + * @return Changed block's type id + * @deprecated Magic value + */ + @Deprecated + public int getChangedTypeId() { + return changed; + } + + /** + * Gets the type of block that changed, causing this event + * + * @return Changed block's type + */ + public Material getChangedType() { + return Material.getMaterial(changed); + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonEvent.java new file mode 100644 index 0000000..074d71c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonEvent.java @@ -0,0 +1,48 @@ +package org.bukkit.event.block; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.Cancellable; + +/** + * Called when a piston block is triggered + */ +public abstract class BlockPistonEvent extends BlockEvent implements Cancellable { + private boolean cancelled; + private final BlockFace direction; + + public BlockPistonEvent(final Block block, final BlockFace direction) { + super(block); + this.direction = direction; + } + + public boolean isCancelled() { + return this.cancelled; + } + + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + /** + * Returns true if the Piston in the event is sticky. + * + * @return stickiness of the piston + */ + public boolean isSticky() { + return block.getType() == Material.PISTON_STICKY_BASE || block.getType() == Material.PISTON_MOVING_PIECE; + } + + /** + * Return the direction in which the piston will operate. + * + * @return direction of the piston + */ + public BlockFace getDirection() { + // Both are meh! + // return ((PistonBaseMaterial) block.getType().getNewData(block.getData())).getFacing(); + // return ((PistonBaseMaterial) block.getState().getData()).getFacing(); + return direction; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonExtendEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonExtendEvent.java new file mode 100644 index 0000000..682ce60 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonExtendEvent.java @@ -0,0 +1,70 @@ +package org.bukkit.event.block; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.HandlerList; + +/** + * Called when a piston extends + */ +public class BlockPistonExtendEvent extends BlockPistonEvent { + private static final HandlerList handlers = new HandlerList(); + private final int length; + private List blocks; + + @Deprecated + public BlockPistonExtendEvent(final Block block, final int length, final BlockFace direction) { + super(block, direction); + + this.length = length; + } + + public BlockPistonExtendEvent(final Block block, final List blocks, final BlockFace direction) { + super(block, direction); + + this.length = blocks.size(); + this.blocks = blocks; + } + + /** + * Get the amount of blocks which will be moved while extending. + * + * @return the amount of moving blocks + * @deprecated slime blocks make the value of this method + * inaccurate due to blocks being pushed at the side + */ + @Deprecated + public int getLength() { + return this.length; + } + + /** + * Get an immutable list of the blocks which will be moved by the + * extending. + * + * @return Immutable list of the moved blocks. + */ + public List getBlocks() { + if (blocks == null) { + ArrayList tmp = new ArrayList(); + for (int i = 0; i < this.getLength(); i++) { + tmp.add(block.getRelative(getDirection(), i + 1)); + } + blocks = Collections.unmodifiableList(tmp); + } + return blocks; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonRetractEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonRetractEvent.java new file mode 100644 index 0000000..6d42917 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPistonRetractEvent.java @@ -0,0 +1,51 @@ +package org.bukkit.event.block; + +import java.util.List; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.HandlerList; + +/** + * Called when a piston retracts + */ +public class BlockPistonRetractEvent extends BlockPistonEvent { + private static final HandlerList handlers = new HandlerList(); + private List blocks; + + public BlockPistonRetractEvent(final Block block, final List blocks, final BlockFace direction) { + super(block, direction); + + this.blocks = blocks; + } + + /** + * Gets the location where the possible moving block might be if the + * retracting piston is sticky. + * + * @return The possible location of the possibly moving block. + */ + @Deprecated + public Location getRetractLocation() { + return getBlock().getRelative(getDirection(), 2).getLocation(); + } + + /** + * Get an immutable list of the blocks which will be moved by the + * extending. + * + * @return Immutable list of the moved blocks. + */ + public List getBlocks() { + return blocks; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java new file mode 100644 index 0000000..6d0ffe8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java @@ -0,0 +1,121 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * Called when a block is placed by a player. + *

+ * If a Block Place event is cancelled, the block will not be placed. + */ +public class BlockPlaceEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + protected boolean cancel; + protected boolean canBuild; + protected Block placedAgainst; + protected BlockState replacedBlockState; + protected ItemStack itemInHand; + protected Player player; + + public BlockPlaceEvent(final Block placedBlock, final BlockState replacedBlockState, final Block placedAgainst, final ItemStack itemInHand, final Player thePlayer, final boolean canBuild) { + super(placedBlock); + this.placedAgainst = placedAgainst; + this.itemInHand = itemInHand; + this.player = thePlayer; + this.replacedBlockState = replacedBlockState; + this.canBuild = canBuild; + cancel = false; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the player who placed the block involved in this event. + * + * @return The Player who placed the block involved in this event + */ + public Player getPlayer() { + return player; + } + + /** + * Clarity method for getting the placed block. Not really needed except + * for reasons of clarity. + * + * @return The Block that was placed + */ + public Block getBlockPlaced() { + return getBlock(); + } + + /** + * Gets the BlockState for the block which was replaced. Material type air + * mostly. + * + * @return The BlockState for the block which was replaced. + */ + public BlockState getBlockReplacedState() { + return this.replacedBlockState; + } + + /** + * Gets the block that this block was placed against + * + * @return Block the block that the new block was placed against + */ + public Block getBlockAgainst() { + return placedAgainst; + } + + /** + * Gets the item in the player's hand when they placed the block. + * + * @return The ItemStack for the item in the player's hand when they + * placed the block + */ + public ItemStack getItemInHand() { + return itemInHand; + } + + /** + * Gets the value whether the player would be allowed to build here. + * Defaults to spawn if the server was going to stop them (such as, the + * player is in Spawn). Note that this is an entirely different check + * than BLOCK_CANBUILD, as this refers to a player, not universe-physics + * rule like cactus on dirt. + * + * @return boolean whether the server would allow a player to build here + */ + public boolean canBuild() { + return this.canBuild; + } + + /** + * Sets the canBuild state of this event. Set to true if you want the + * player to be able to build. + * + * @param canBuild true if you want the player to be able to build + */ + public void setBuild(boolean canBuild) { + this.canBuild = canBuild; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockRedstoneEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockRedstoneEvent.java new file mode 100644 index 0000000..625ec90 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockRedstoneEvent.java @@ -0,0 +1,55 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.event.HandlerList; + +/** + * Called when a redstone current changes + */ +public class BlockRedstoneEvent extends BlockEvent { + private static final HandlerList handlers = new HandlerList(); + private final int oldCurrent; + private int newCurrent; + + public BlockRedstoneEvent(final Block block, final int oldCurrent, final int newCurrent) { + super(block); + this.oldCurrent = oldCurrent; + this.newCurrent = newCurrent; + } + + /** + * Gets the old current of this block + * + * @return The previous current + */ + public int getOldCurrent() { + return oldCurrent; + } + + /** + * Gets the new current of this block + * + * @return The new current + */ + public int getNewCurrent() { + return newCurrent; + } + + /** + * Sets the new current of this block + * + * @param newCurrent The new current to set + */ + public void setNewCurrent(int newCurrent) { + this.newCurrent = newCurrent; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockSpreadEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockSpreadEvent.java new file mode 100644 index 0000000..a1fb363 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/BlockSpreadEvent.java @@ -0,0 +1,49 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.event.HandlerList; + +/** + * Called when a block spreads based on world conditions. + *

+ * Use {@link BlockFormEvent} to catch blocks that "randomly" form instead of + * actually spread. + *

+ * Examples: + *

    + *
  • Mushrooms spreading. + *
  • Fire spreading. + *
+ *

+ * If a Block Spread event is cancelled, the block will not spread. + * + * @see BlockFormEvent + */ +public class BlockSpreadEvent extends BlockFormEvent { + private static final HandlerList handlers = new HandlerList(); + private final Block source; + + public BlockSpreadEvent(final Block block, final Block source, final BlockState newState) { + super(block, newState); + this.source = source; + } + + /** + * Gets the source block involved in this event. + * + * @return the Block for the source block involved in this event. + */ + public Block getSource() { + return source; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/EntityBlockFormEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/EntityBlockFormEvent.java new file mode 100644 index 0000000..45efc32 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/EntityBlockFormEvent.java @@ -0,0 +1,32 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; + +/** + * Called when a block is formed by entities. + *

+ * Examples: + *

    + *
  • Snow formed by a {@link org.bukkit.entity.Snowman}. + *
+ */ +public class EntityBlockFormEvent extends BlockFormEvent { + private final Entity entity; + + public EntityBlockFormEvent(final Entity entity, final Block block, final BlockState blockstate) { + super(block, blockstate); + + this.entity = entity; + } + + /** + * Get the entity that formed the block. + * + * @return Entity involved in event + */ + public Entity getEntity() { + return entity; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/LeavesDecayEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/LeavesDecayEvent.java new file mode 100644 index 0000000..84d8cfd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/LeavesDecayEvent.java @@ -0,0 +1,36 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when leaves are decaying naturally. + *

+ * If a Leaves Decay event is cancelled, the leaves will not decay. + */ +public class LeavesDecayEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + + public LeavesDecayEvent(final Block block) { + super(block); + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/NotePlayEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/NotePlayEvent.java new file mode 100644 index 0000000..d4d4381 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/NotePlayEvent.java @@ -0,0 +1,83 @@ +package org.bukkit.event.block; + +import org.bukkit.Instrument; +import org.bukkit.Note; +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a note block is being played through player interaction or a + * redstone current. + */ +public class NotePlayEvent extends BlockEvent implements Cancellable { + + private static HandlerList handlers = new HandlerList(); + private Instrument instrument; + private Note note; + private boolean cancelled = false; + + public NotePlayEvent(Block block, Instrument instrument, Note note) { + super(block); + this.instrument = instrument; + this.note = note; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + /** + * Gets the {@link Instrument} to be used. + * + * @return the Instrument; + */ + public Instrument getInstrument() { + return instrument; + } + + /** + * Gets the {@link Note} to be played. + * + * @return the Note. + */ + public Note getNote() { + return note; + } + + /** + * Overrides the {@link Instrument} to be used. + * + * @param instrument the Instrument. Has no effect if null. + */ + public void setInstrument(Instrument instrument) { + if (instrument != null) { + this.instrument = instrument; + } + + } + + /** + * Overrides the {@link Note} to be played. + * + * @param note the Note. Has no effect if null. + */ + public void setNote(Note note) { + if (note != null) { + this.note = note; + } + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/SignChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/SignChangeEvent.java new file mode 100644 index 0000000..83188cf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/block/SignChangeEvent.java @@ -0,0 +1,84 @@ +package org.bukkit.event.block; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a sign is changed by a player. + *

+ * If a Sign Change event is cancelled, the sign will not be changed. + */ +public class SignChangeEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private final Player player; + private final String[] lines; + + public SignChangeEvent(final Block theBlock, final Player thePlayer, final String[] theLines) { + super(theBlock); + this.player = thePlayer; + this.lines = theLines; + } + + /** + * Gets the player changing the sign involved in this event. + * + * @return the Player involved in this event + */ + public Player getPlayer() { + return player; + } + + /** + * Gets all of the lines of text from the sign involved in this event. + * + * @return the String array for the sign's lines new text + */ + public String[] getLines() { + return lines; + } + + /** + * Gets a single line of text from the sign involved in this event. + * + * @param index index of the line to get + * @return the String containing the line of text associated with the + * provided index + * @throws IndexOutOfBoundsException thrown when the provided index is {@literal > 3 + * or < 0} + */ + public String getLine(int index) throws IndexOutOfBoundsException { + return lines[index]; + } + + /** + * Sets a single line for the sign involved in this event + * + * @param index index of the line to set + * @param line text to set + * @throws IndexOutOfBoundsException thrown when the provided index is {@literal > 3 + * or < 0} + */ + public void setLine(int index, String line) throws IndexOutOfBoundsException { + lines[index] = line; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java new file mode 100644 index 0000000..de28f1d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java @@ -0,0 +1,121 @@ +package org.bukkit.event.enchantment; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.block.Block; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.InventoryEvent; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +/** + * Called when an ItemStack is successfully enchanted (currently at + * enchantment table) + */ +public class EnchantItemEvent extends InventoryEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Block table; + private final ItemStack item; + private int level; + private boolean cancelled; + private final Map enchants; + private final Player enchanter; + private int button; + + public EnchantItemEvent(final Player enchanter, final InventoryView view, final Block table, final ItemStack item, final int level, final Map enchants, final int i) { + super(view); + this.enchanter = enchanter; + this.table = table; + this.item = item; + this.level = level; + this.enchants = new HashMap(enchants); + this.cancelled = false; + this.button = i; + } + + /** + * Gets the player enchanting the item + * + * @return enchanting player + */ + public Player getEnchanter() { + return enchanter; + } + + /** + * Gets the block being used to enchant the item + * + * @return the block used for enchanting + */ + public Block getEnchantBlock() { + return table; + } + + /** + * Gets the item to be enchanted (can be modified) + * + * @return ItemStack of item + */ + public ItemStack getItem() { + return item; + } + + /** + * Get cost in exp levels of the enchantment + * + * @return experience level cost + */ + public int getExpLevelCost() { + return level; + } + + /** + * Set cost in exp levels of the enchantment + * + * @param level - cost in levels + */ + public void setExpLevelCost(int level) { + this.level = level; + } + + /** + * Get map of enchantment (levels, keyed by type) to be added to item + * (modify map returned to change values). Note: Any enchantments not + * allowed for the item will be ignored + * + * @return map of enchantment levels, keyed by enchantment + */ + public Map getEnchantsToAdd() { + return enchants; + } + + /** + * Which button was pressed to initiate the enchanting. + * + * @return The button index (0, 1, or 2). + */ + public int whichButton() { + return button; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/enchantment/PrepareItemEnchantEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/enchantment/PrepareItemEnchantEvent.java new file mode 100644 index 0000000..6c0aa9f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/enchantment/PrepareItemEnchantEvent.java @@ -0,0 +1,96 @@ +package org.bukkit.event.enchantment; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.InventoryEvent; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +/** + * Called when an ItemStack is inserted in an enchantment table - can be + * called multiple times + */ +public class PrepareItemEnchantEvent extends InventoryEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Block table; + private final ItemStack item; + private final int[] levelsOffered; + private final int bonus; + private boolean cancelled; + private final Player enchanter; + + public PrepareItemEnchantEvent(final Player enchanter, InventoryView view, final Block table, final ItemStack item, final int[] levelsOffered, final int bonus) { + super(view); + this.enchanter = enchanter; + this.table = table; + this.item = item; + this.levelsOffered = levelsOffered; + this.bonus = bonus; + this.cancelled = false; + } + + /** + * Gets the player enchanting the item + * + * @return enchanting player + */ + public Player getEnchanter() { + return enchanter; + } + + /** + * Gets the block being used to enchant the item + * + * @return the block used for enchanting + */ + public Block getEnchantBlock() { + return table; + } + + /** + * Gets the item to be enchanted (can be modified) + * + * @return ItemStack of item + */ + public ItemStack getItem() { + return item; + } + + /** + * Get list of offered exp level costs of the enchantment (modify values + * to change offer) + * + * @return experience level costs offered + */ + public int[] getExpLevelCostsOffered() { + return levelsOffered; + } + + /** + * Get enchantment bonus in effect - corresponds to number of bookshelves + * + * @return enchantment bonus + */ + public int getEnchantmentBonus() { + return bonus; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java new file mode 100644 index 0000000..8883157 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java @@ -0,0 +1,165 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.entity.CreatureType; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; + +/** + * Called when a creature is spawned into a world. + *

+ * If a Creature Spawn event is cancelled, the creature will not spawn. + */ +public class CreatureSpawnEvent extends EntitySpawnEvent { + private final SpawnReason spawnReason; + + public CreatureSpawnEvent(final LivingEntity spawnee, final SpawnReason spawnReason) { + super(spawnee); + this.spawnReason = spawnReason; + } + + @Deprecated + public CreatureSpawnEvent(Entity spawnee, CreatureType type, Location loc, SpawnReason reason) { + super(spawnee); + spawnReason = reason; + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) entity; + } + + /** + * Gets the type of creature being spawned. + * + * @return A CreatureType value detailing the type of creature being + * spawned + * @deprecated In favour of {@link #getEntityType()}. + */ + @Deprecated + public CreatureType getCreatureType() { + return CreatureType.fromEntityType(getEntityType()); + } + + /** + * Gets the reason for why the creature is being spawned. + * + * @return A SpawnReason value detailing the reason for the creature being + * spawned + */ + public SpawnReason getSpawnReason() { + return spawnReason; + } + + /** + * An enum to specify the type of spawning + */ + public enum SpawnReason { + + /** + * When something spawns from natural means + */ + NATURAL, + /** + * When an entity spawns as a jockey of another entity (mostly spider + * jockeys) + */ + JOCKEY, + /** + * When a creature spawns due to chunk generation + */ + CHUNK_GEN, + /** + * When a creature spawns from a spawner + */ + SPAWNER, + /** + * When a creature spawns from an egg + */ + EGG, + /** + * When a creature spawns from a Spawner Egg + */ + SPAWNER_EGG, + /** + * When a creature spawns because of a lightning strike + */ + LIGHTNING, + /** + * When a creature is spawned by a player that is sleeping + * + * @deprecated No longer used + */ + @Deprecated + BED, + /** + * When a snowman is spawned by being built + */ + BUILD_SNOWMAN, + /** + * When an iron golem is spawned by being built + */ + BUILD_IRONGOLEM, + /** + * When a wither boss is spawned by being built + */ + BUILD_WITHER, + /** + * When an iron golem is spawned to defend a village + */ + VILLAGE_DEFENSE, + /** + * When a zombie is spawned to invade a village + */ + VILLAGE_INVASION, + /** + * When an animal breeds to create a child + */ + BREEDING, + /** + * When a slime splits + */ + SLIME_SPLIT, + /** + * When an entity calls for reinforcements + */ + REINFORCEMENTS, + /** + * When a creature is spawned by nether portal + */ + NETHER_PORTAL, + /** + * When a creature is spawned by a dispenser dispensing an egg + */ + DISPENSE_EGG, + /** + * When a zombie infects a villager + */ + INFECTION, + /** + * When a villager is cured from infection + */ + CURED, + /** + * When an ocelot has a baby spawned along with them + */ + OCELOT_BABY, + /** + * When a silverfish spawns from a block + */ + SILVERFISH_BLOCK, + /** + * When an entity spawns as a mount of another entity (mostly chicken + * jockeys) + */ + MOUNT, + /** + * When a creature is spawned by plugins + */ + CUSTOM, + /** + * When an entity is missing a SpawnReason + */ + DEFAULT + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/CreeperPowerEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/CreeperPowerEvent.java new file mode 100644 index 0000000..b103a6a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/CreeperPowerEvent.java @@ -0,0 +1,93 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Creeper; +import org.bukkit.entity.LightningStrike; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a Creeper is struck by lightning. + *

+ * If a Creeper Power event is cancelled, the Creeper will not be powered. + */ +public class CreeperPowerEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + private final PowerCause cause; + private LightningStrike bolt; + + public CreeperPowerEvent(final Creeper creeper, final LightningStrike bolt, final PowerCause cause) { + this(creeper, cause); + this.bolt = bolt; + } + + public CreeperPowerEvent(final Creeper creeper, final PowerCause cause) { + super(creeper); + this.cause = cause; + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + @Override + public Creeper getEntity() { + return (Creeper) entity; + } + + /** + * Gets the lightning bolt which is striking the Creeper. + * + * @return The Entity for the lightning bolt which is striking the Creeper + */ + public LightningStrike getLightning() { + return bolt; + } + + /** + * Gets the cause of the creeper being (un)powered. + * + * @return A PowerCause value detailing the cause of change in power. + */ + public PowerCause getCause() { + return cause; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * An enum to specify the cause of the change in power + */ + public enum PowerCause { + + /** + * Power change caused by a lightning bolt + *

+ * Powered state: true + */ + LIGHTNING, + /** + * Power change caused by something else (probably a plugin) + *

+ * Powered state: true + */ + SET_ON, + /** + * Power change caused by something else (probably a plugin) + *

+ * Powered state: false + */ + SET_OFF + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EnderPearlEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EnderPearlEvent.java new file mode 100644 index 0000000..a234c82 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EnderPearlEvent.java @@ -0,0 +1,62 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.EnderPearl; +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * @Author Alpha + * @Since 27/04/2020 + * Notix Industries LLC © 2020 + */ +public class EnderPearlEvent extends EntityEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private Reason reason; + private boolean cancel; + private Entity hit; + + + public EnderPearlEvent(EnderPearl enderPearl, Reason reason, Entity hit) { + super(enderPearl); + this.reason = reason; + this.hit = hit; + } + + @Override + public EnderPearl getEntity() { + return (EnderPearl) super.getEntity(); + } + + public Reason getReason() { + return reason; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public boolean isCancelled() { + return cancel; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + public Entity getHit() { + return hit; + } + + public enum Reason { + BLOCK, ENTITY; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityBreakDoorEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityBreakDoorEvent.java new file mode 100644 index 0000000..2cbbc69 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityBreakDoorEvent.java @@ -0,0 +1,22 @@ +package org.bukkit.event.entity; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; + +/** + * Called when an {@link Entity} breaks a door + *

+ * Cancelling the event will cause the event to be delayed + */ +public class EntityBreakDoorEvent extends EntityChangeBlockEvent { + public EntityBreakDoorEvent(final LivingEntity entity, final Block targetBlock) { + super(entity, targetBlock, Material.AIR, (byte) 0); + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) entity; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java new file mode 100644 index 0000000..41be9ca --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java @@ -0,0 +1,95 @@ +package org.bukkit.event.entity; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when any Entity, excluding players, changes a block. + */ +public class EntityChangeBlockEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Block block; + private boolean cancel; + private final Material to; + private final byte data; + + /** + * + * @param what the LivingEntity causing the change + * @param block the block (before the change) + * @param to the future material being changed to + * @deprecated Provided as a backward compatibility before the data byte + * was provided, and type increased to all entities + */ + @Deprecated + public EntityChangeBlockEvent(final LivingEntity what, final Block block, final Material to) { + this (what, block, to, (byte) 0); + } + + /** + * + * @param what the Entity causing the change + * @param block the block (before the change) + * @param to the future material being changed to + * @param data the future block data + * @deprecated Magic value + */ + @Deprecated + public EntityChangeBlockEvent(final Entity what, final Block block, final Material to, final byte data) { + super(what); + this.block = block; + this.cancel = false; + this.to = to; + this.data = data; + } + + /** + * Gets the block the entity is changing + * + * @return the block that is changing + */ + public Block getBlock() { + return block; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the Material that the block is changing into + * + * @return the material that the block is changing into + */ + public Material getTo() { + return to; + } + + /** + * Gets the data for the block that would be changed into + * + * @return the data for the block that would be changed into + * @deprecated Magic value + */ + @Deprecated + public byte getData() { + return data; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustByBlockEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustByBlockEvent.java new file mode 100644 index 0000000..c84bda9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustByBlockEvent.java @@ -0,0 +1,27 @@ +package org.bukkit.event.entity; + +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; + +/** + * Called when a block causes an entity to combust. + */ +public class EntityCombustByBlockEvent extends EntityCombustEvent { + private final Block combuster; + + public EntityCombustByBlockEvent(final Block combuster, final Entity combustee, final int duration) { + super(combustee, duration); + this.combuster = combuster; + } + + /** + * The combuster can be lava or a block that is on fire. + *

+ * WARNING: block may be null. + * + * @return the Block that set the combustee alight. + */ + public Block getCombuster() { + return combuster; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustByEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustByEntityEvent.java new file mode 100644 index 0000000..639567b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustByEntityEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; + +/** + * Called when an entity causes another entity to combust. + */ +public class EntityCombustByEntityEvent extends EntityCombustEvent { + private final Entity combuster; + + public EntityCombustByEntityEvent(final Entity combuster, final Entity combustee, final int duration) { + super(combustee, duration); + this.combuster = combuster; + } + + /** + * Get the entity that caused the combustion event. + * + * @return the Entity that set the combustee alight. + */ + public Entity getCombuster() { + return combuster; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustEvent.java new file mode 100644 index 0000000..43c4482 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCombustEvent.java @@ -0,0 +1,59 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when an entity combusts. + *

+ * If an Entity Combust event is cancelled, the entity will not combust. + */ +public class EntityCombustEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private int duration; + private boolean cancel; + + public EntityCombustEvent(final Entity combustee, final int duration) { + super(combustee); + this.duration = duration; + this.cancel = false; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * @return the amount of time (in seconds) the combustee should be alight + * for + */ + public int getDuration() { + return duration; + } + + /** + * The number of seconds the combustee should be alight for. + *

+ * This value will only ever increase the combustion time, not decrease + * existing combustion times. + * + * @param duration the time in seconds to be alight for. + */ + public void setDuration(int duration) { + this.duration = duration; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCreatePortalEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCreatePortalEvent.java new file mode 100644 index 0000000..286c206 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityCreatePortalEvent.java @@ -0,0 +1,65 @@ +package org.bukkit.event.entity; + +import java.util.List; +import org.bukkit.PortalType; +import org.bukkit.block.BlockState; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Thrown when a Living Entity creates a portal in a world. + */ +public class EntityCreatePortalEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final List blocks; + private boolean cancelled = false; + private PortalType type = PortalType.CUSTOM; + + public EntityCreatePortalEvent(final LivingEntity what, final List blocks, final PortalType type) { + super(what); + + this.blocks = blocks; + this.type = type; + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) entity; + } + + /** + * Gets a list of all blocks associated with the portal. + * + * @return List of blocks that will be changed. + */ + public List getBlocks() { + return blocks; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + /** + * Gets the type of portal that is trying to be created. + * + * @return Type of portal. + */ + public PortalType getPortalType() { + return type; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java new file mode 100644 index 0000000..2ff121e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java @@ -0,0 +1,39 @@ +package org.bukkit.event.entity; + +import java.util.Map; + +import com.google.common.base.Function; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; + +/** + * Called when an entity is damaged by a block + */ +public class EntityDamageByBlockEvent extends EntityDamageEvent { + private final Block damager; + + @Deprecated + public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final int damage) { + this(damager, damagee, cause, (double) damage); + } + + @Deprecated + public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final double damage) { + super(damagee, cause, damage); + this.damager = damager; + } + + public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final Map modifiers, final Map> modifierFunctions) { + super(damagee, cause, modifiers, modifierFunctions); + this.damager = damager; + } + + /** + * Returns the block that damaged the player. + * + * @return Block that damaged the player + */ + public Block getDamager() { + return damager; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java new file mode 100644 index 0000000..49e74c3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java @@ -0,0 +1,38 @@ +package org.bukkit.event.entity; + +import java.util.Map; + +import com.google.common.base.Function; +import org.bukkit.entity.Entity; + +/** + * Called when an entity is damaged by an entity + */ +public class EntityDamageByEntityEvent extends EntityDamageEvent { + private final Entity damager; + + @Deprecated + public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final int damage) { + this(damager, damagee, cause, (double) damage); + } + + @Deprecated + public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final double damage) { + super(damagee, cause, damage); + this.damager = damager; + } + + public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final Map modifiers, final Map> modifierFunctions) { + super(damagee, cause, modifiers, modifierFunctions); + this.damager = damager; + } + + /** + * Returns the entity that damaged the defender. + * + * @return Entity that damaged the defender. + */ + public Entity getDamager() { + return damager; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java new file mode 100644 index 0000000..9ef48c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDamageEvent.java @@ -0,0 +1,417 @@ +package org.bukkit.event.entity; + +import java.util.EnumMap; +import java.util.Map; + +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.util.NumberConversions; + +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.common.collect.ImmutableMap; + +/** + * Stores data for damage events + */ +public class EntityDamageEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private static final DamageModifier[] MODIFIERS = DamageModifier.values(); + private static final Function ZERO = Functions.constant(-0.0); + private final Map modifiers; + private final Map> modifierFunctions; + private final Map originals; + private boolean cancelled; + private final DamageCause cause; + + @Deprecated + public EntityDamageEvent(final Entity damagee, final DamageCause cause, final int damage) { + this(damagee, cause, (double) damage); + } + + @Deprecated + public EntityDamageEvent(final Entity damagee, final DamageCause cause, final double damage) { + this(damagee, cause, new EnumMap(ImmutableMap.of(DamageModifier.BASE, damage)), new EnumMap>(ImmutableMap.of(DamageModifier.BASE, ZERO))); + } + + public EntityDamageEvent(final Entity damagee, final DamageCause cause, final Map modifiers, final Map> modifierFunctions) { + super(damagee); + Validate.isTrue(modifiers.containsKey(DamageModifier.BASE), "BASE DamageModifier missing"); + Validate.isTrue(!modifiers.containsKey(null), "Cannot have null DamageModifier"); + Validate.noNullElements(modifiers.values(), "Cannot have null modifier values"); + Validate.isTrue(modifiers.keySet().equals(modifierFunctions.keySet()), "Must have a modifier function for each DamageModifier"); + Validate.noNullElements(modifierFunctions.values(), "Cannot have null modifier function"); + this.originals = new EnumMap(modifiers); + this.cause = cause; + this.modifiers = modifiers; + this.modifierFunctions = modifierFunctions; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + /** + * Gets the original damage for the specified modifier, as defined at this + * event's construction. + * + * @param type the modifier + * @return the original damage + * @throws IllegalArgumentException if type is null + */ + public double getOriginalDamage(DamageModifier type) throws IllegalArgumentException { + final Double damage = originals.get(type); + if (damage != null) { + return damage; + } + if (type == null) { + throw new IllegalArgumentException("Cannot have null DamageModifier"); + } + return 0; + } + + /** + * Sets the damage for the specified modifier. + * + * @param type the damage modifier + * @param damage the scalar value of the damage's modifier + * @see #getFinalDamage() + * @throws IllegalArgumentException if type is null + * @throws UnsupportedOperationException if the caller does not support + * the particular DamageModifier, or to rephrase, when {@link + * #isApplicable(DamageModifier)} returns false + */ + public void setDamage(DamageModifier type, double damage) throws IllegalArgumentException, UnsupportedOperationException { + if (!modifiers.containsKey(type)) { + throw type == null ? new IllegalArgumentException("Cannot have null DamageModifier") : new UnsupportedOperationException(type + " is not applicable to " + getEntity()); + } + modifiers.put(type, damage); + } + + /** + * Gets the damage change for some modifier + * + * @param type the damage modifier + * @return The raw amount of damage caused by the event + * @throws IllegalArgumentException if type is null + * @see DamageModifier#BASE + */ + public double getDamage(DamageModifier type) throws IllegalArgumentException { + Validate.notNull(type, "Cannot have null DamageModifier"); + final Double damage = modifiers.get(type); + return damage == null ? 0 : damage; + } + + /** + * This checks to see if a particular modifier is valid for this event's + * caller, such that, {@link #setDamage(DamageModifier, double)} will not + * throw an {@link UnsupportedOperationException}. + *

+ * {@link DamageModifier#BASE} is always applicable. + * + * @param type the modifier + * @return true if the modifier is supported by the caller, false otherwise + * @throws IllegalArgumentException if type is null + */ + public boolean isApplicable(DamageModifier type) throws IllegalArgumentException { + Validate.notNull(type, "Cannot have null DamageModifier"); + return modifiers.containsKey(type); + } + + /** + * Gets the raw amount of damage caused by the event + * + * @return The raw amount of damage caused by the event + * @see DamageModifier#BASE + */ + public double getDamage() { + return getDamage(DamageModifier.BASE); + } + + /** + * Gets the amount of damage caused by the event after all damage + * reduction is applied. + * + * @return the amount of damage caused by the event + */ + public final double getFinalDamage() { + double damage = 0; + for (DamageModifier modifier : MODIFIERS) { + damage += getDamage(modifier); + } + return damage; + } + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @return the (rounded) damage + */ + @Deprecated + public int _INVALID_getDamage() { + return NumberConversions.ceil(getDamage()); + } + + /** + * Sets the raw amount of damage caused by the event. + *

+ * For compatibility this also recalculates the modifiers and scales + * them by the difference between the modifier for the previous damage + * value and the new one. + * + * @param damage The raw amount of damage caused by the event + */ + public void setDamage(double damage) { + // These have to happen in the same order as the server calculates them, keep the enum sorted + double remaining = damage; + double oldRemaining = getDamage(DamageModifier.BASE); + for (DamageModifier modifier : MODIFIERS) { + if (!isApplicable(modifier)) { + continue; + } + + Function modifierFunction = modifierFunctions.get(modifier); + double newVanilla = modifierFunction.apply(remaining); + double oldVanilla = modifierFunction.apply(oldRemaining); + double difference = oldVanilla - newVanilla; + + // Don't allow value to cross zero, assume zero values should be negative + double old = getDamage(modifier); + if (old > 0) { + setDamage(modifier, Math.max(0, old - difference)); + } else { + setDamage(modifier, Math.min(0, old - difference)); + } + remaining += newVanilla; + oldRemaining += oldVanilla; + } + + setDamage(DamageModifier.BASE, damage); + } + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param damage the new damage value + */ + @Deprecated + public void _INVALID_setDamage(int damage) { + setDamage(damage); + } + + /** + * Gets the cause of the damage. + * + * @return A DamageCause value detailing the cause of the damage. + */ + public DamageCause getCause() { + return cause; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * An enum to specify the types of modifier + */ + public enum DamageModifier { + /** + * This represents the amount of damage being done, also known as the + * raw {@link EntityDamageEvent#getDamage()}. + */ + BASE, + /** + * This represents the damage reduced by a wearing a helmet when hit + * by a falling block. + */ + HARD_HAT, + /** + * This represents the damage reduction caused by blocking, only present for + * {@link Player Players}. + */ + BLOCKING, + /** + * This represents the damage reduction caused by wearing armor. + */ + ARMOR, + /** + * This represents the damage reduction caused by the Resistance potion effect. + */ + RESISTANCE, + /** + * This represents the damage reduction caused by the combination of: + *

    + *
  • + * Armor enchantments + *
  • + * Witch's potion resistance + *
  • + *
+ */ + MAGIC, + /** + * This represents the damage reduction caused by the absorption potion + * effect. + */ + ABSORPTION, + ; + } + + /** + * An enum to specify the cause of the damage + */ + public enum DamageCause { + + /** + * Damage caused when an entity contacts a block such as a Cactus. + *

+ * Damage: 1 (Cactus) + */ + CONTACT, + /** + * Damage caused when an entity attacks another entity. + *

+ * Damage: variable + */ + ENTITY_ATTACK, + /** + * Damage caused when attacked by a projectile. + *

+ * Damage: variable + */ + PROJECTILE, + /** + * Damage caused by being put in a block + *

+ * Damage: 1 + */ + SUFFOCATION, + /** + * Damage caused when an entity falls a distance greater than 3 blocks + *

+ * Damage: fall height - 3.0 + */ + FALL, + /** + * Damage caused by direct exposure to fire + *

+ * Damage: 1 + */ + FIRE, + /** + * Damage caused due to burns caused by fire + *

+ * Damage: 1 + */ + FIRE_TICK, + /** + * Damage caused due to a snowman melting + *

+ * Damage: 1 + */ + MELTING, + /** + * Damage caused by direct exposure to lava + *

+ * Damage: 4 + */ + LAVA, + /** + * Damage caused by running out of air while in water + *

+ * Damage: 2 + */ + DROWNING, + /** + * Damage caused by being in the area when a block explodes. + *

+ * Damage: variable + */ + BLOCK_EXPLOSION, + /** + * Damage caused by being in the area when an entity, such as a + * Creeper, explodes. + *

+ * Damage: variable + */ + ENTITY_EXPLOSION, + /** + * Damage caused by falling into the void + *

+ * Damage: 4 for players + */ + VOID, + /** + * Damage caused by being struck by lightning + *

+ * Damage: 5 + */ + LIGHTNING, + /** + * Damage caused by committing suicide using the command "/kill" + *

+ * Damage: 1000 + */ + SUICIDE, + /** + * Damage caused by starving due to having an empty hunger bar + *

+ * Damage: 1 + */ + STARVATION, + /** + * Damage caused due to an ongoing poison effect + *

+ * Damage: 1 + */ + POISON, + /** + * Damage caused by being hit by a damage potion or spell + *

+ * Damage: variable + */ + MAGIC, + /** + * Damage caused by Wither potion effect + */ + WITHER, + /** + * Damage caused by being hit by a falling block which deals damage + *

+ * Note: Not every block deals damage + *

+ * Damage: variable + */ + FALLING_BLOCK, + /** + * Damage caused in retaliation to another attack by the Thorns + * enchantment. + *

+ * Damage: 1-4 (Thorns) + */ + THORNS, + /** + * Custom damage. + *

+ * Damage: variable + */ + CUSTOM + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDeathEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDeathEvent.java new file mode 100644 index 0000000..ab9e81f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityDeathEvent.java @@ -0,0 +1,72 @@ +package org.bukkit.event.entity; + +import java.util.List; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * Thrown whenever a LivingEntity dies + */ +public class EntityDeathEvent extends EntityEvent { + private static final HandlerList handlers = new HandlerList(); + private final List drops; + private int dropExp = 0; + + public EntityDeathEvent(final LivingEntity entity, final List drops) { + this(entity, drops, 0); + } + + public EntityDeathEvent(final LivingEntity what, final List drops, final int droppedExp) { + super(what); + this.drops = drops; + this.dropExp = droppedExp; + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) entity; + } + + /** + * Gets how much EXP should be dropped from this death. + *

+ * This does not indicate how much EXP should be taken from the entity in + * question, merely how much should be created after its death. + * + * @return Amount of EXP to drop. + */ + public int getDroppedExp() { + return dropExp; + } + + /** + * Sets how much EXP should be dropped from this death. + *

+ * This does not indicate how much EXP should be taken from the entity in + * question, merely how much should be created after its death. + * + * @param exp Amount of EXP to drop. + */ + public void setDroppedExp(int exp) { + this.dropExp = exp; + } + + /** + * Gets all the items which will drop when the entity dies + * + * @return Items to drop when the entity dies + */ + public List getDrops() { + return drops; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityEvent.java new file mode 100644 index 0000000..c9a4ab3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityEvent.java @@ -0,0 +1,34 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.Event; + +/** + * Represents an Entity-related event + */ +public abstract class EntityEvent extends Event { + protected Entity entity; + + public EntityEvent(final Entity what) { + entity = what; + } + + /** + * Returns the Entity involved in this event + * + * @return Entity who is involved in this event + */ + public Entity getEntity() { + return entity; + } + + /** + * Gets the EntityType of the Entity involved in this event. + * + * @return EntityType of the Entity involved in this event + */ + public EntityType getEntityType() { + return entity.getType(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java new file mode 100644 index 0000000..287035d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java @@ -0,0 +1,85 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +import java.util.List; + +/** + * Called when an entity explodes + */ +public class EntityExplodeEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + private final Location location; + private final List blocks; + private float yield; + + public EntityExplodeEvent(final Entity what, final Location location, final List blocks, final float yield) { + super(what); + this.location = location; + this.blocks = blocks; + this.yield = yield; + this.cancel = false; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Returns the list of blocks that would have been removed or were removed + * from the explosion event. + * + * @return All blown-up blocks + */ + public List blockList() { + return blocks; + } + + /** + * Returns the location where the explosion happened. + *

+ * It is not possible to get this value from the Entity as the Entity no + * longer exists in the world. + * + * @return The location of the explosion + */ + public Location getLocation() { + return location; + } + + /** + * Returns the percentage of blocks to drop from this explosion + * + * @return The yield. + */ + public float getYield() { + return yield; + } + + /** + * Sets the percentage of blocks to drop from this explosion + * + * @param yield The new yield percentage + */ + public void setYield(float yield) { + this.yield = yield; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityInteractEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityInteractEvent.java new file mode 100644 index 0000000..1c4e100 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityInteractEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.entity; + +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when an entity interacts with an object + */ +public class EntityInteractEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + protected Block block; + private boolean cancelled; + + public EntityInteractEvent(final Entity entity, final Block block) { + super(entity); + this.block = block; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + /** + * Returns the involved block + * + * @return the block clicked with this item. + */ + public Block getBlock() { + return block; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java new file mode 100644 index 0000000..87d57b0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java @@ -0,0 +1,36 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.Location; +import org.bukkit.event.HandlerList; + +/** + * Called when an entity comes into contact with a portal + */ +public class EntityPortalEnterEvent extends EntityEvent { + private static final HandlerList handlers = new HandlerList(); + private final Location location; + + public EntityPortalEnterEvent(final Entity entity, final Location location) { + super(entity); + this.location = location; + } + + /** + * Gets the portal block the entity is touching + * + * @return The portal block the entity is touching + */ + public Location getLocation() { + return location; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalEvent.java new file mode 100644 index 0000000..835c054 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalEvent.java @@ -0,0 +1,82 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.TravelAgent; +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; + +/** + * Called when a non-player entity is about to teleport because it is in + * contact with a portal. + *

+ * For players see {@link org.bukkit.event.player.PlayerPortalEvent} + */ +public class EntityPortalEvent extends EntityTeleportEvent { + private static final HandlerList handlers = new HandlerList(); + protected boolean useTravelAgent = true; + protected TravelAgent travelAgent; + + public EntityPortalEvent(final Entity entity, final Location from, final Location to, final TravelAgent pta) { + super(entity, from, to); + this.travelAgent = pta; + } + + /** + * Sets whether or not the Travel Agent will be used. + *

+ * If this is set to true, the TravelAgent will try to find a Portal at + * the {@link #getTo()} Location, and will try to create one if there is + * none. + *

+ * If this is set to false, the {@link #getEntity()} will only be + * teleported to the {@link #getTo()} Location. + * + * @param useTravelAgent whether to use the Travel Agent + */ + public void useTravelAgent(boolean useTravelAgent) { + this.useTravelAgent = useTravelAgent; + } + + /** + * Gets whether or not the Travel Agent will be used. + *

+ * If this is set to true, the TravelAgent will try to find a Portal at + * the {@link #getTo()} Location, and will try to create one if there is + * none. + *

+ * If this is set to false, the {@link #getEntity()} will only be + * teleported to the {@link #getTo()} Location. + * + * @return whether to use the Travel Agent + */ + public boolean useTravelAgent() { + return useTravelAgent; + } + + /** + * Gets the Travel Agent used (or not) in this event. + * + * @return the Travel Agent used (or not) in this event + */ + public TravelAgent getPortalTravelAgent() { + return this.travelAgent; + } + + /** + * Sets the Travel Agent used (or not) in this event. + * + * @param travelAgent the Travel Agent used (or not) in this event + */ + public void setPortalTravelAgent(TravelAgent travelAgent) { + this.travelAgent = travelAgent; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalExitEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalExitEvent.java new file mode 100644 index 0000000..41edef6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityPortalExitEvent.java @@ -0,0 +1,62 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; +import org.bukkit.util.Vector; + +/** + * Called before an entity exits a portal. + *

+ * This event allows you to modify the velocity of the entity after they have + * successfully exited the portal. + */ +public class EntityPortalExitEvent extends EntityTeleportEvent { + private static final HandlerList handlers = new HandlerList(); + private Vector before; + private Vector after; + + public EntityPortalExitEvent(final Entity entity, final Location from, final Location to, final Vector before, final Vector after) { + super(entity, from, to); + this.before = before; + this.after = after; + } + + /** + * Gets a copy of the velocity that the entity has before entering the + * portal. + * + * @return velocity of entity before entering the portal + */ + public Vector getBefore() { + return this.before.clone(); + } + + /** + * Gets a copy of the velocity that the entity will have after exiting the + * portal. + * + * @return velocity of entity after exiting the portal + */ + public Vector getAfter() { + return this.after.clone(); + } + + /** + * Sets the velocity that the entity will have after exiting the portal. + * + * @param after the velocity after exiting the portal + */ + public void setAfter(Vector after) { + this.after = after.clone(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java new file mode 100644 index 0000000..a7b3517 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java @@ -0,0 +1,143 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.util.NumberConversions; + +/** + * Stores data for health-regain events + */ +public class EntityRegainHealthEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private double amount; + private final RegainReason regainReason; + + @Deprecated + public EntityRegainHealthEvent(final Entity entity, final int amount, final RegainReason regainReason) { + this(entity, (double) amount, regainReason); + } + + public EntityRegainHealthEvent(final Entity entity, final double amount, final RegainReason regainReason) { + super(entity); + this.amount = amount; + this.regainReason = regainReason; + } + + /** + * Gets the amount of regained health + * + * @return The amount of health regained + */ + public double getAmount() { + return amount; + } + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @return the (rounded) amount regained + */ + @Deprecated + public int _INVALID_getAmount() { + return NumberConversions.ceil(getAmount()); + } + + /** + * Sets the amount of regained health + * + * @param amount the amount of health the entity will regain + */ + public void setAmount(double amount) { + this.amount = amount; + } + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param amount the amount that will be regained + */ + @Deprecated + public void _INVALID_setAmount(int amount) { + setAmount(amount); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + /** + * Gets the reason for why the entity is regaining health + * + * @return A RegainReason detailing the reason for the entity regaining + * health + */ + public RegainReason getRegainReason() { + return regainReason; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * An enum to specify the type of health regaining that is occurring + */ + public enum RegainReason { + + /** + * When a player regains health from regenerating due to Peaceful mode + * (difficulty=0) + */ + REGEN, + /** + * When a player regains health from regenerating due to their hunger + * being satisfied + */ + SATIATED, + /** + * When a player regains health from eating consumables + */ + EATING, + /** + * When an ender dragon regains health from an ender crystal + */ + ENDER_CRYSTAL, + /** + * When a player is healed by a potion or spell + */ + MAGIC, + /** + * When a player is healed over time by a potion or spell + */ + MAGIC_REGEN, + /** + * When a wither is filling its health during spawning + */ + WITHER_SPAWN, + /** + * When an entity is damaged by the Wither potion effect + */ + WITHER, + /** + * Any other reason not covered by the reasons above + */ + CUSTOM + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java new file mode 100644 index 0000000..f8c91a1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java @@ -0,0 +1,84 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Projectile; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * Called when a LivingEntity shoots a bow firing an arrow + */ +public class EntityShootBowEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final ItemStack bow; + private Entity projectile; + private final float force; + private boolean cancelled; + + public EntityShootBowEvent(final LivingEntity shooter, final ItemStack bow, final Projectile projectile, final float force) { + super(shooter); + this.bow = bow; + this.projectile = projectile; + this.force = force; + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) entity; + } + + /** + * Gets the bow ItemStack used to fire the arrow. + * + * @return the bow involved in this event + */ + public ItemStack getBow() { + return bow; + } + + /** + * Gets the projectile which will be launched by this event + * + * @return the launched projectile + */ + public Entity getProjectile() { + return projectile; + } + + /** + * Replaces the projectile which will be launched + * + * @param projectile the new projectile + */ + public void setProjectile(Entity projectile) { + this.projectile = projectile; + } + + /** + * Gets the force the arrow was launched with + * + * @return bow shooting force, up to 1.0 + */ + public float getForce() { + return force; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java new file mode 100644 index 0000000..5dcf98f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java @@ -0,0 +1,45 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; + +/** + * Called when an entity is spawned into a world. + *

+ * If an Entity Spawn event is cancelled, the entity will not spawn. + */ +public class EntitySpawnEvent extends EntityEvent implements org.bukkit.event.Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + + public EntitySpawnEvent(final Entity spawnee) { + super(spawnee); + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + /** + * Gets the location at which the entity is spawning. + * + * @return The location at which the entity is spawning + */ + public Location getLocation() { + return getEntity().getLocation(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTameEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTameEvent.java new file mode 100644 index 0000000..f105817 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTameEvent.java @@ -0,0 +1,51 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.AnimalTamer; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Thrown when a LivingEntity is tamed + */ +public class EntityTameEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final AnimalTamer owner; + + public EntityTameEvent(final LivingEntity entity, final AnimalTamer owner) { + super(entity); + this.owner = owner; + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) entity; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + /** + * Gets the owning AnimalTamer + * + * @return the owning AnimalTamer + */ + public AnimalTamer getOwner() { + return owner; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTargetEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTargetEvent.java new file mode 100644 index 0000000..cf67251 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTargetEvent.java @@ -0,0 +1,150 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a creature targets or untargets another entity + */ +public class EntityTargetEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private Entity target; + private final TargetReason reason; + + public EntityTargetEvent(final Entity entity, final Entity target, final TargetReason reason) { + super(entity); + this.target = target; + this.reason = reason; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Returns the reason for the targeting + * + * @return The reason + */ + public TargetReason getReason() { + return reason; + } + + /** + * Get the entity that this is targeting. + *

+ * This will be null in the case that the event is called when the mob + * forgets its target. + * + * @return The entity + */ + public Entity getTarget() { + return target; + } + + /** + * Set the entity that you want the mob to target instead. + *

+ * It is possible to be null, null will cause the entity to be + * target-less. + *

+ * This is different from cancelling the event. Cancelling the event will + * cause the entity to keep an original target, while setting to be null + * will cause the entity to be reset. + * + * @param target The entity to target + */ + public void setTarget(Entity target) { + this.target = target; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * An enum to specify the reason for the targeting + */ + public enum TargetReason { + + /** + * When the entity's target has died, and so it no longer targets it + */ + TARGET_DIED, + /** + * When the entity doesn't have a target, so it attacks the nearest + * player + */ + CLOSEST_PLAYER, + /** + * When the target attacks the entity, so entity targets it + */ + TARGET_ATTACKED_ENTITY, + /** + * When the target attacks a fellow pig zombie, so the whole group + * will target him with this reason. + */ + PIG_ZOMBIE_TARGET, + /** + * When the target is forgotten for whatever reason. + *

+ * Currently only occurs in with spiders when there is a high + * brightness. + */ + FORGOT_TARGET, + /** + * When the target attacks the owner of the entity, so the entity + * targets it. + */ + TARGET_ATTACKED_OWNER, + /** + * When the owner of the entity attacks the target attacks, so the + * entity targets it. + */ + OWNER_ATTACKED_TARGET, + /** + * When the entity has no target, so the entity randomly chooses one. + */ + RANDOM_TARGET, + /** + * When an entity selects a target while defending a village. + */ + DEFEND_VILLAGE, + /** + * When the target attacks a nearby entity of the same type, so the entity targets it + */ + TARGET_ATTACKED_NEARBY_ENTITY, + /** + * When a zombie targeting an entity summons reinforcements, so the reinforcements target the same entity + */ + REINFORCEMENT_TARGET, + /** + * When an entity targets another entity after colliding with it. + */ + COLLISION, + /** + * For custom calls to the event. + */ + CUSTOM, + /** + * When the entity doesn't have a target, so it attacks the nearest + * entity + */ + CLOSEST_ENTITY, + /** + * A currently unknown reason for the entity changing target. + */ + UNKNOWN; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTargetLivingEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTargetLivingEntityEvent.java new file mode 100644 index 0000000..cd9aea1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTargetLivingEntityEvent.java @@ -0,0 +1,34 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; + +/** + * Called when an Entity targets a {@link LivingEntity} and can only target + * LivingEntity's. + */ +public class EntityTargetLivingEntityEvent extends EntityTargetEvent{ + public EntityTargetLivingEntityEvent(final Entity entity, final LivingEntity target, final TargetReason reason) { + super(entity, target, reason); + } + + public LivingEntity getTarget() { + return (LivingEntity) super.getTarget(); + } + + /** + * Set the Entity that you want the mob to target. + *

+ * It is possible to be null, null will cause the entity to be + * target-less. + *

+ * Must be a LivingEntity, or null. + * + * @param target The entity to target + */ + public void setTarget(Entity target) { + if (target == null || target instanceof LivingEntity) { + super.setTarget(target); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTeleportEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTeleportEvent.java new file mode 100644 index 0000000..619f8d4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityTeleportEvent.java @@ -0,0 +1,77 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Thrown when a non-player entity (such as an Enderman) tries to teleport + * from one location to another. + */ +public class EntityTeleportEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + private Location from; + private Location to; + + public EntityTeleportEvent(Entity what, Location from, Location to) { + super(what); + this.from = from; + this.to = to; + this.cancel = false; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the location that this entity moved from + * + * @return Location this entity moved from + */ + public Location getFrom() { + return from; + } + + /** + * Sets the location that this entity moved from + * + * @param from New location this entity moved from + */ + public void setFrom(Location from) { + this.from = from; + } + + /** + * Gets the location that this entity moved to + * + * @return Location the entity moved to + */ + public Location getTo() { + return to; + } + + /** + * Sets the location that this entity moved to + * + * @param to New Location this entity moved to + */ + public void setTo(Location to) { + this.to = to; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityUnleashEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityUnleashEvent.java new file mode 100644 index 0000000..da7e46c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/EntityUnleashEvent.java @@ -0,0 +1,52 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; + +/** + * Called immediately prior to an entity being unleashed. + */ +public class EntityUnleashEvent extends EntityEvent { + private static final HandlerList handlers = new HandlerList(); + private final UnleashReason reason; + + public EntityUnleashEvent(Entity entity, UnleashReason reason) { + super(entity); + this.reason = reason; + } + + /** + * Returns the reason for the unleashing. + * + * @return The reason + */ + public UnleashReason getReason() { + return reason; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public enum UnleashReason { + /** + * When the entity's leashholder has died or logged out, and so is + * unleashed + */ + HOLDER_GONE, + /** + * When the entity's leashholder attempts to unleash it + */ + PLAYER_UNLEASH, + /** + * When the entity's leashholder is more than 10 blocks away + */ + DISTANCE, + UNKNOWN; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java new file mode 100644 index 0000000..4f64424 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ExpBottleEvent.java @@ -0,0 +1,75 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.ThrownExpBottle; +import org.bukkit.event.HandlerList; + +/** + * Called when a ThrownExpBottle hits and releases experience. + */ +public class ExpBottleEvent extends ProjectileHitEvent { + private static final HandlerList handlers = new HandlerList(); + private int exp; + private boolean showEffect = true; + + public ExpBottleEvent(final ThrownExpBottle bottle, final int exp) { + super(bottle); + this.exp = exp; + } + + @Override + public ThrownExpBottle getEntity() { + return (ThrownExpBottle) entity; + } + + /** + * This method indicates if the particle effect should be shown. + * + * @return true if the effect will be shown, false otherwise + */ + public boolean getShowEffect() { + return this.showEffect; + } + + /** + * This method sets if the particle effect will be shown. + *

+ * This does not change the experience created. + * + * @param showEffect true indicates the effect will be shown, false + * indicates no effect will be shown + */ + public void setShowEffect(final boolean showEffect) { + this.showEffect = showEffect; + } + + /** + * This method retrieves the amount of experience to be created. + *

+ * The number indicates a total amount to be divided into orbs. + * + * @return the total amount of experience to be created + */ + public int getExperience() { + return exp; + } + + /** + * This method sets the amount of experience to be created. + *

+ * The number indicates a total amount to be divided into orbs. + * + * @param exp the total amount of experience to be created + */ + public void setExperience(final int exp) { + this.exp = exp; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ExplosionPrimeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ExplosionPrimeEvent.java new file mode 100644 index 0000000..7ca6a55 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ExplosionPrimeEvent.java @@ -0,0 +1,80 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Explosive; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when an entity has made a decision to explode. + */ +public class ExplosionPrimeEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + private float radius; + private boolean fire; + + public ExplosionPrimeEvent(final Entity what, final float radius, final boolean fire) { + super(what); + this.cancel = false; + this.radius = radius; + this.fire = fire; + } + + public ExplosionPrimeEvent(final Explosive explosive) { + this(explosive, explosive.getYield(), explosive.isIncendiary()); + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the radius of the explosion + * + * @return returns the radius of the explosion + */ + public float getRadius() { + return radius; + } + + /** + * Sets the radius of the explosion + * + * @param radius the radius of the explosion + */ + public void setRadius(float radius) { + this.radius = radius; + } + + /** + * Gets whether this explosion will create fire or not + * + * @return true if this explosion will create fire + */ + public boolean getFire() { + return fire; + } + + /** + * Sets whether this explosion will create fire or not + * + * @param fire true if you want this explosion to create fire + */ + public void setFire(boolean fire) { + this.fire = fire; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/FireworkExplodeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/FireworkExplodeEvent.java new file mode 100644 index 0000000..81b1c48 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/FireworkExplodeEvent.java @@ -0,0 +1,49 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Firework; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a firework explodes. + */ +public class FireworkExplodeEvent extends EntityEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + + public FireworkExplodeEvent(final Firework what) { + super(what); + } + + @Override + public boolean isCancelled() { + return cancel; + } + + /** + * Set the cancelled state of this event. If the firework explosion is + * cancelled, the firework will still be removed, but no particles will be + * displayed. + * + * @param cancel whether to cancel or not. + */ + @Override + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public Firework getEntity() { + return (Firework) super.getEntity(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/FoodLevelChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/FoodLevelChangeEvent.java new file mode 100644 index 0000000..f6e2472 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/FoodLevelChangeEvent.java @@ -0,0 +1,67 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a human entity's food level changes + */ +public class FoodLevelChangeEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private int level; + + public FoodLevelChangeEvent(final HumanEntity what, final int level) { + super(what); + this.level = level; + } + + @Override + public HumanEntity getEntity() { + return (HumanEntity) entity; + } + + /** + * Gets the resultant food level that the entity involved in this event + * should be set to. + *

+ * Where 20 is a full food bar and 0 is an empty one. + * + * @return The resultant food level + */ + public int getFoodLevel() { + return level; + } + + /** + * Sets the resultant food level that the entity involved in this event + * should be set to + * + * @param level the resultant food level that the entity involved in this + * event should be set to + */ + public void setFoodLevel(int level) { + if (level > 20) level = 20; + else if (level < 0) level = 0; + + this.level = level; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/HorseJumpEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/HorseJumpEvent.java new file mode 100644 index 0000000..fad2468 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/HorseJumpEvent.java @@ -0,0 +1,78 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Horse; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a horse jumps. + */ +public class HorseJumpEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private float power; + + public HorseJumpEvent(final Horse horse, final float power) { + super(horse); + this.power = power; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public Horse getEntity() { + return (Horse) entity; + } + + /** + * Gets the power of the jump. + *

+ * Power is a value that defines how much of the horse's jump strength + * should be used for the jump. Power is effectively multiplied times + * the horse's jump strength to determine how high the jump is; 0 + * represents no jump strength while 1 represents full jump strength. + * Setting power to a value above 1 will use additional jump strength + * that the horse does not usually have. + *

+ * Power does not affect how high the horse is capable of jumping, only + * how much of its jumping capability will be used in this jump. To set + * the horse's overall jump strength, see {@link + * Horse#setJumpStrength(double)}. + * + * @return jump strength + */ + public float getPower() { + return power; + } + + /** + * Sets the power of the jump. + *

+ * Jump power can be set to a value above 1.0 which will increase the + * strength of this jump above the horse's actual jump strength. + *

+ * Setting the jump power to 0 will result in the jump animation still + * playing, but the horse not leaving the ground. Only canceling this + * event will result in no jump animation at all. + * + * @param power power of the jump + */ + public void setPower(float power) { + this.power = power; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java new file mode 100644 index 0000000..356e4bd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java @@ -0,0 +1,55 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.entity.Item; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * This event is called when a {@link org.bukkit.entity.Item} is removed from + * the world because it has existed for 5 minutes. + *

+ * Cancelling the event results in the item being allowed to exist for 5 more + * minutes. This behavior is not guaranteed and may change in future versions. + */ +public class ItemDespawnEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + private final Location location; + + public ItemDespawnEvent(final Item despawnee, final Location loc) { + super(despawnee); + location = loc; + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + @Override + public Item getEntity() { + return (Item) entity; + } + + /** + * Gets the location at which the item is despawning. + * + * @return The location at which the item is despawning + */ + public Location getLocation() { + return location; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemMergeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemMergeEvent.java new file mode 100644 index 0000000..dadf221 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemMergeEvent.java @@ -0,0 +1,50 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Item; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +public class ItemMergeEvent extends EntityEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Item target; + + public ItemMergeEvent(Item item, Item target) { + super(item); + this.target = target; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public Item getEntity() { + return (Item) entity; + } + + /** + * Gets the Item entity the main Item is being merged into. + * + * @return The Item being merged with + */ + public Item getTarget() { + return target; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java new file mode 100644 index 0000000..776f8e7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java @@ -0,0 +1,23 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.entity.Item; + +/** + * Called when an item is spawned into a world + */ +public class ItemSpawnEvent extends EntitySpawnEvent { + public ItemSpawnEvent(final Item spawnee) { + super(spawnee); + } + + @Deprecated + public ItemSpawnEvent(final Item spawnee, final Location loc) { + this(spawnee); + } + + @Override + public Item getEntity() { + return (Item) entity; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PigZapEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PigZapEvent.java new file mode 100644 index 0000000..aa80ebf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PigZapEvent.java @@ -0,0 +1,64 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.LightningStrike; +import org.bukkit.entity.Pig; +import org.bukkit.entity.PigZombie; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Stores data for pigs being zapped + */ +public class PigZapEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + private final PigZombie pigzombie; + private final LightningStrike bolt; + + public PigZapEvent(final Pig pig, final LightningStrike bolt, final PigZombie pigzombie) { + super(pig); + this.bolt = bolt; + this.pigzombie = pigzombie; + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + @Override + public Pig getEntity() { + return (Pig) entity; + } + + /** + * Gets the bolt which is striking the pig. + * + * @return lightning entity + */ + public LightningStrike getLightning() { + return bolt; + } + + /** + * Gets the zombie pig that will replace the pig, provided the event is + * not cancelled first. + * + * @return resulting entity + */ + public PigZombie getPigZombie() { + return pigzombie; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java new file mode 100644 index 0000000..aad0354 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PlayerDeathEvent.java @@ -0,0 +1,161 @@ +package org.bukkit.event.entity; + +import java.util.List; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +/** + * Thrown whenever a {@link Player} dies + */ +public class PlayerDeathEvent extends EntityDeathEvent { + private int newExp = 0; + private String deathMessage = ""; + private int newLevel = 0; + private int newTotalExp = 0; + private boolean keepLevel = false; + private boolean keepInventory = false; + + public PlayerDeathEvent(final Player player, final List drops, final int droppedExp, final String deathMessage) { + this(player, drops, droppedExp, 0, deathMessage); + } + + public PlayerDeathEvent(final Player player, final List drops, final int droppedExp, final int newExp, final String deathMessage) { + this(player, drops, droppedExp, newExp, 0, 0, deathMessage); + } + + public PlayerDeathEvent(final Player player, final List drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final String deathMessage) { + super(player, drops, droppedExp); + this.newExp = newExp; + this.newTotalExp = newTotalExp; + this.newLevel = newLevel; + this.deathMessage = deathMessage; + } + + @Override + public Player getEntity() { + return (Player) entity; + } + + /** + * Set the death message that will appear to everyone on the server. + * + * @param deathMessage Message to appear to other players on the server. + */ + public void setDeathMessage(String deathMessage) { + this.deathMessage = deathMessage; + } + + /** + * Get the death message that will appear to everyone on the server. + * + * @return Message to appear to other players on the server. + */ + public String getDeathMessage() { + return deathMessage; + } + + /** + * Gets how much EXP the Player should have at respawn. + *

+ * This does not indicate how much EXP should be dropped, please see + * {@link #getDroppedExp()} for that. + * + * @return New EXP of the respawned player + */ + public int getNewExp() { + return newExp; + } + + /** + * Sets how much EXP the Player should have at respawn. + *

+ * This does not indicate how much EXP should be dropped, please see + * {@link #setDroppedExp(int)} for that. + * + * @param exp New EXP of the respawned player + */ + public void setNewExp(int exp) { + newExp = exp; + } + + /** + * Gets the Level the Player should have at respawn. + * + * @return New Level of the respawned player + */ + public int getNewLevel() { + return newLevel; + } + + /** + * Sets the Level the Player should have at respawn. + * + * @param level New Level of the respawned player + */ + public void setNewLevel(int level) { + newLevel = level; + } + + /** + * Gets the Total EXP the Player should have at respawn. + * + * @return New Total EXP of the respawned player + */ + public int getNewTotalExp() { + return newTotalExp; + } + + /** + * Sets the Total EXP the Player should have at respawn. + * + * @param totalExp New Total EXP of the respawned player + */ + public void setNewTotalExp(int totalExp) { + newTotalExp = totalExp; + } + + /** + * Gets if the Player should keep all EXP at respawn. + *

+ * This flag overrides other EXP settings + * + * @return True if Player should keep all pre-death exp + */ + public boolean getKeepLevel() { + return keepLevel; + } + + /** + * Sets if the Player should keep all EXP at respawn. + *

+ * This overrides all other EXP settings + *

+ * This doesn't prevent prevent the EXP from dropping. + * {@link #setDroppedExp(int)} should be used stop the + * EXP from dropping. + * + * @param keepLevel True to keep all current value levels + */ + public void setKeepLevel(boolean keepLevel) { + this.keepLevel = keepLevel; + } + + /** + * Sets if the Player keeps inventory on death. + * + * @param keepInventory True to keep the inventory + */ + public void setKeepInventory(boolean keepInventory) { + this.keepInventory = keepInventory; + } + + /** + * Gets if the Player keeps inventory on death. + * + * @return True if the player keeps inventory on death + */ + public boolean getKeepInventory() { + return keepInventory; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java new file mode 100644 index 0000000..74d458a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java @@ -0,0 +1,68 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Called immediately prior to a creature being leashed by a player. + */ +public class PlayerLeashEntityEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Entity leashHolder; + private final Entity entity; + private boolean cancelled = false; + private final Player player; + + public PlayerLeashEntityEvent(Entity what, Entity leashHolder, Player leasher) { + this.leashHolder = leashHolder; + this.entity = what; + this.player = leasher; + } + + /** + * Returns the entity that is holding the leash. + * + * @return The leash holder + */ + public Entity getLeashHolder() { + return leashHolder; + } + + /** + * Returns the entity being leashed. + * + * @return The entity + */ + public Entity getEntity() { + return entity; + } + + /** + * Returns the player involved in this event + * + * @return Player who is involved in this event + */ + public final Player getPlayer() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public boolean isCancelled() { + return this.cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectAddEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectAddEvent.java new file mode 100644 index 0000000..0ba1c84 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectAddEvent.java @@ -0,0 +1,36 @@ +package org.bukkit.event.entity; + +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.potion.PotionEffect; + +/** + * Called when a potion effect is applied to an entity, or an existing effect is extended or upgraded + */ +public class PotionEffectAddEvent extends PotionEffectEvent implements Cancellable { + + private boolean cancelled; + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + public PotionEffectAddEvent(LivingEntity entity, PotionEffect effect) { + super(entity, effect); + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override public HandlerList getHandlers() { return PotionEffectAddEvent.HANDLER_LIST; } + + public static HandlerList getHandlerList() { return PotionEffectAddEvent.HANDLER_LIST; } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectEvent.java new file mode 100644 index 0000000..209dffe --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectEvent.java @@ -0,0 +1,25 @@ +package org.bukkit.event.entity; + +import lombok.Getter; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.potion.PotionEffect; + +public abstract class PotionEffectEvent extends EntityEvent { + + private final PotionEffect effect; + + public PotionEffectEvent(LivingEntity what, PotionEffect effect) { + super(what); + this.effect = effect; + } + + @Override + public LivingEntity getEntity() { + return (LivingEntity) super.getEntity(); + } + + public PotionEffect getEffect() { + return this.effect; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectExpireEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectExpireEvent.java new file mode 100644 index 0000000..7e1c346 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectExpireEvent.java @@ -0,0 +1,48 @@ +package org.bukkit.event.entity; + +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.potion.PotionEffect; + +/** + * Called when a potion effect on an entity runs out. Cancelling the event extends + * the effect with a practically infinite duration. The new duration can also be set + * explicitly by calling {@link #setDuration}. + * + * Handlers of {@link PotionEffectRemoveEvent} will also receive this event. + */ +public class PotionEffectExpireEvent extends PotionEffectRemoveEvent { + + private int duration = 0; + + public PotionEffectExpireEvent(LivingEntity entity, PotionEffect effect) { + super(entity, effect); + } + + /** + * Get the new duration for the potion effect. This is initially 0. + */ + public int getDuration() { + return this.duration; + } + + /** + * Set a new duration for the potion effect. Passing 0 to this method un-cancels + * the event, and passing anything above 0 cancels it. + */ + public void setDuration(int duration) { + this.duration = Math.max(0, duration); + } + + @Override + public boolean isCancelled() { + return this.duration > 0; + } + + @Override + public void setCancelled(boolean cancel) { + this.duration = cancel ? Integer.MAX_VALUE : 0; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectExtendEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectExtendEvent.java new file mode 100644 index 0000000..2045eb9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectExtendEvent.java @@ -0,0 +1,28 @@ +package org.bukkit.event.entity; + +import lombok.Getter; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.potion.PotionEffect; + +/** + * Called when an entity's active potion effect is extended or upgraded. + * + * Handlers of {@link PotionEffectAddEvent} will also receive this event. + */ +public class PotionEffectExtendEvent extends PotionEffectAddEvent { + + private final PotionEffect oldEffect; + + public PotionEffectExtendEvent(LivingEntity entity, PotionEffect effect, PotionEffect oldEffect) { + super(entity, effect); + this.oldEffect = oldEffect; + } + + /** + * Get the state of the potion effect prior to the change + */ + public PotionEffect getOldEffect() { + return this.oldEffect; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectRemoveEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectRemoveEvent.java new file mode 100644 index 0000000..d6aeb4c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionEffectRemoveEvent.java @@ -0,0 +1,37 @@ +package org.bukkit.event.entity; + +import lombok.Getter; +import lombok.Setter; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.potion.PotionEffect; + +/** + * Called when a potion effect is removed from an entity for whatever reason + */ +public class PotionEffectRemoveEvent extends PotionEffectEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private boolean cancelled = false; + + public PotionEffectRemoveEvent(LivingEntity entity, PotionEffect effect) { + super(entity, effect); + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override public HandlerList getHandlers() { return PotionEffectRemoveEvent.HANDLER_LIST; } + + public static HandlerList getHandlerList() { return PotionEffectRemoveEvent.HANDLER_LIST; } + +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java new file mode 100644 index 0000000..b9840de --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/PotionSplashEvent.java @@ -0,0 +1,94 @@ +package org.bukkit.event.entity; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +import org.apache.commons.lang.Validate; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.ThrownPotion; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a splash potion hits an area + */ +public class PotionSplashEvent extends ProjectileHitEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Map affectedEntities; + + public PotionSplashEvent(final ThrownPotion potion, final Map affectedEntities) { + super(potion); + + this.affectedEntities = affectedEntities; + } + + @Override + public ThrownPotion getEntity() { + return (ThrownPotion) entity; + } + + /** + * Gets the potion which caused this event + * + * @return The thrown potion entity + */ + public ThrownPotion getPotion() { + return (ThrownPotion) getEntity(); + } + + /** + * Retrieves a list of all effected entities + * + * @return A fresh copy of the affected entity list + */ + public Collection getAffectedEntities() { + return new ArrayList(affectedEntities.keySet()); + } + + /** + * Gets the intensity of the potion's effects for given entity; This + * depends on the distance to the impact center + * + * @param entity Which entity to get intensity for + * @return intensity relative to maximum effect; 0.0: not affected; 1.0: + * fully hit by potion effects + */ + public double getIntensity(LivingEntity entity) { + Double intensity = affectedEntities.get(entity); + return intensity != null ? intensity : 0.0; + } + + /** + * Overwrites the intensity for a given entity + * + * @param entity For which entity to define a new intensity + * @param intensity relative to maximum effect + */ + public void setIntensity(LivingEntity entity, double intensity) { + Validate.notNull(entity, "You must specify a valid entity."); + if (intensity <= 0.0) { + affectedEntities.remove(entity); + } else { + affectedEntities.put(entity, Math.min(intensity, 1.0)); + } + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ProjectileHitEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ProjectileHitEvent.java new file mode 100644 index 0000000..25ae832 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ProjectileHitEvent.java @@ -0,0 +1,30 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Projectile; +import org.bukkit.event.HandlerList; + +/** + * Called when a projectile hits an object + */ +public class ProjectileHitEvent extends EntityEvent { + private static final HandlerList handlers = new HandlerList(); + + public ProjectileHitEvent(final Projectile projectile) { + super(projectile); + } + + @Override + public Projectile getEntity() { + return (Projectile) entity; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ProjectileLaunchEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ProjectileLaunchEvent.java new file mode 100644 index 0000000..0c9190c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/ProjectileLaunchEvent.java @@ -0,0 +1,40 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Projectile; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a projectile is launched. + */ +public class ProjectileLaunchEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + + public ProjectileLaunchEvent(Entity what) { + super(what); + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public Projectile getEntity() { + return (Projectile) entity; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SheepDyeWoolEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SheepDyeWoolEvent.java new file mode 100644 index 0000000..4c17fea --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SheepDyeWoolEvent.java @@ -0,0 +1,62 @@ +package org.bukkit.event.entity; + +import org.bukkit.DyeColor; +import org.bukkit.entity.Sheep; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a sheep's wool is dyed + */ +public class SheepDyeWoolEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + private DyeColor color; + + public SheepDyeWoolEvent(final Sheep sheep, final DyeColor color) { + super(sheep); + this.cancel = false; + this.color = color; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public Sheep getEntity() { + return (Sheep) entity; + } + + /** + * Gets the DyeColor the sheep is being dyed + * + * @return the DyeColor the sheep is being dyed + */ + public DyeColor getColor() { + return color; + } + + /** + * Sets the DyeColor the sheep is being dyed + * + * @param color the DyeColor the sheep will be dyed + */ + public void setColor(DyeColor color) { + this.color = color; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SheepRegrowWoolEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SheepRegrowWoolEvent.java new file mode 100644 index 0000000..e836f7b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SheepRegrowWoolEvent.java @@ -0,0 +1,41 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Sheep; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a sheep regrows its wool + */ +public class SheepRegrowWoolEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + + public SheepRegrowWoolEvent(final Sheep sheep) { + super(sheep); + this.cancel = false; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public Sheep getEntity() { + return (Sheep) entity; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SlimeSplitEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SlimeSplitEvent.java new file mode 100644 index 0000000..4b99587 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SlimeSplitEvent.java @@ -0,0 +1,59 @@ +package org.bukkit.event.entity; + +import org.bukkit.entity.Slime; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a Slime splits into smaller Slimes upon death + */ +public class SlimeSplitEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private int count; + + public SlimeSplitEvent(final Slime slime, final int count) { + super(slime); + this.count = count; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public Slime getEntity() { + return (Slime) entity; + } + + /** + * Gets the amount of smaller slimes to spawn + * + * @return the amount of slimes to spawn + */ + public int getCount() { + return count; + } + + /** + * Sets how many smaller slimes will spawn on the split + * + * @param count the amount of slimes to spawn + */ + public void setCount(int count) { + this.count = count; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SpawnerSpawnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SpawnerSpawnEvent.java new file mode 100644 index 0000000..1acb3c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/entity/SpawnerSpawnEvent.java @@ -0,0 +1,22 @@ +package org.bukkit.event.entity; + +import org.bukkit.block.CreatureSpawner; +import org.bukkit.entity.Entity; + +/** + * Called when an entity is spawned into a world by a spawner. + *

+ * If a Spawner Spawn event is cancelled, the entity will not spawn. + */ +public class SpawnerSpawnEvent extends EntitySpawnEvent { + private final CreatureSpawner spawner; + + public SpawnerSpawnEvent(final Entity spawnee, final CreatureSpawner spawner) { + super(spawnee); + this.spawner = spawner; + } + + public CreatureSpawner getSpawner() { + return spawner; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingBreakByEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingBreakByEntityEvent.java new file mode 100644 index 0000000..80851ed --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingBreakByEntityEvent.java @@ -0,0 +1,25 @@ +package org.bukkit.event.hanging; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Hanging; + +/** + * Triggered when a hanging entity is removed by an entity + */ +public class HangingBreakByEntityEvent extends HangingBreakEvent { + private final Entity remover; + + public HangingBreakByEntityEvent(final Hanging hanging, final Entity remover) { + super(hanging, HangingBreakEvent.RemoveCause.ENTITY); + this.remover = remover; + } + + /** + * Gets the entity that removed the hanging entity + * + * @return the entity that removed the hanging entity + */ + public Entity getRemover() { + return remover; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingBreakEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingBreakEvent.java new file mode 100644 index 0000000..87bbdcb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingBreakEvent.java @@ -0,0 +1,71 @@ +package org.bukkit.event.hanging; + +import org.bukkit.entity.Hanging; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Triggered when a hanging entity is removed + */ +public class HangingBreakEvent extends HangingEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final HangingBreakEvent.RemoveCause cause; + + public HangingBreakEvent(final Hanging hanging, final HangingBreakEvent.RemoveCause cause) { + super(hanging); + this.cause = cause; + } + + /** + * Gets the cause for the hanging entity's removal + * + * @return the RemoveCause for the hanging entity's removal + */ + public HangingBreakEvent.RemoveCause getCause() { + return cause; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + /** + * An enum to specify the cause of the removal + */ + public enum RemoveCause { + /** + * Removed by an entity + */ + ENTITY, + /** + * Removed by an explosion + */ + EXPLOSION, + /** + * Removed by placing a block on it + */ + OBSTRUCTION, + /** + * Removed by destroying the block behind it, etc + */ + PHYSICS, + /** + * Removed by an uncategorised cause + */ + DEFAULT, + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingEvent.java new file mode 100644 index 0000000..b370afe --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.hanging; + +import org.bukkit.entity.Hanging; +import org.bukkit.event.Event; + +/** + * Represents a hanging entity-related event. + */ +public abstract class HangingEvent extends Event { + protected Hanging hanging; + + protected HangingEvent(final Hanging painting) { + this.hanging = painting; + } + + /** + * Gets the hanging entity involved in this event. + * + * @return the hanging entity + */ + public Hanging getEntity() { + return hanging; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java new file mode 100644 index 0000000..b511c55 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java @@ -0,0 +1,70 @@ +package org.bukkit.event.hanging; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Hanging; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Triggered when a hanging entity is created in the world + */ +public class HangingPlaceEvent extends HangingEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Player player; + private final Block block; + private final BlockFace blockFace; + + public HangingPlaceEvent(final Hanging hanging, final Player player, final Block block, final BlockFace blockFace) { + super(hanging); + this.player = player; + this.block = block; + this.blockFace = blockFace; + } + + /** + * Returns the player placing the hanging entity + * + * @return the player placing the hanging entity + */ + public Player getPlayer() { + return player; + } + + /** + * Returns the block that the hanging entity was placed on + * + * @return the block that the hanging entity was placed on + */ + public Block getBlock() { + return block; + } + + /** + * Returns the face of the block that the hanging entity was placed on + * + * @return the face of the block that the hanging entity was placed on + */ + public BlockFace getBlockFace() { + return blockFace; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/BrewEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/BrewEvent.java new file mode 100644 index 0000000..2295c2d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/BrewEvent.java @@ -0,0 +1,48 @@ +package org.bukkit.event.inventory; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.inventory.BrewerInventory; + +/** + * Called when the brewing of the contents inside the Brewing Stand is + * complete. + */ +public class BrewEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private BrewerInventory contents; + private boolean cancelled; + + public BrewEvent(Block brewer, BrewerInventory contents) { + super(brewer); + this.contents = contents; + } + + /** + * Gets the contents of the Brewing Stand. + * + * @return the contents + */ + public BrewerInventory getContents() { + return contents; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/ClickType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/ClickType.java new file mode 100644 index 0000000..a7440aa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/ClickType.java @@ -0,0 +1,115 @@ +package org.bukkit.event.inventory; + +/** + * What the client did to trigger this action (not the result). + */ +public enum ClickType { + + /** + * The left (or primary) mouse button. + */ + LEFT, + /** + * Holding shift while pressing the left mouse button. + */ + SHIFT_LEFT, + /** + * The right mouse button. + */ + RIGHT, + /** + * Holding shift while pressing the right mouse button. + */ + SHIFT_RIGHT, + /** + * Clicking the left mouse button on the grey area around the inventory. + */ + WINDOW_BORDER_LEFT, + /** + * Clicking the right mouse button on the grey area around the inventory. + */ + WINDOW_BORDER_RIGHT, + /** + * The middle mouse button, or a "scrollwheel click". + */ + MIDDLE, + /** + * One of the number keys 1-9, correspond to slots on the hotbar. + */ + NUMBER_KEY, + /** + * Pressing the left mouse button twice in quick succession. + */ + DOUBLE_CLICK, + /** + * The "Drop" key (defaults to Q). + */ + DROP, + /** + * Holding Ctrl while pressing the "Drop" key (defaults to Q). + */ + CONTROL_DROP, + /** + * Any action done with the Creative inventory open. + */ + CREATIVE, + /** + * A type of inventory manipulation not yet recognized by Bukkit. + *

+ * This is only for transitional purposes on a new Minecraft update, and + * should never be relied upon. + *

+ * Any ClickType.UNKNOWN is called on a best-effort basis. + */ + UNKNOWN, + ; + + /** + * Gets whether this ClickType represents the pressing of a key on a + * keyboard. + * + * @return true if this ClickType represents the pressing of a key + */ + public boolean isKeyboardClick() { + return (this == ClickType.NUMBER_KEY) || (this == ClickType.DROP) || (this == ClickType.CONTROL_DROP); + } + + /** + * Gets whether this ClickType represents an action that can only be + * performed by a Player in creative mode. + * + * @return true if this action requires Creative mode + */ + public boolean isCreativeAction() { + // Why use middle click? + return (this == ClickType.MIDDLE) || (this == ClickType.CREATIVE); + } + + /** + * Gets whether this ClickType represents a right click. + * + * @return true if this ClickType represents a right click + */ + public boolean isRightClick() { + return (this == ClickType.RIGHT) || (this == ClickType.SHIFT_RIGHT); + } + + /** + * Gets whether this ClickType represents a left click. + * + * @return true if this ClickType represents a left click + */ + public boolean isLeftClick() { + return (this == ClickType.LEFT) || (this == ClickType.SHIFT_LEFT) || (this == ClickType.DOUBLE_CLICK) || (this == ClickType.CREATIVE); + } + + /** + * Gets whether this ClickType indicates that the shift key was pressed + * down when the click was made. + * + * @return true if the action uses Shift. + */ + public boolean isShiftClick() { + return (this == ClickType.SHIFT_LEFT) || (this == ClickType.SHIFT_RIGHT) || (this == ClickType.CONTROL_DROP); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/CraftItemEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/CraftItemEvent.java new file mode 100644 index 0000000..ba3f5e5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/CraftItemEvent.java @@ -0,0 +1,40 @@ +package org.bukkit.event.inventory; + +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.Recipe; + +/** + * Called when the recipe of an Item is completed inside a crafting matrix. + */ +public class CraftItemEvent extends InventoryClickEvent { + private Recipe recipe; + + @Deprecated + public CraftItemEvent(Recipe recipe, InventoryView what, SlotType type, int slot, boolean right, boolean shift) { + this(recipe, what, type, slot, right ? (shift ? ClickType.SHIFT_RIGHT : ClickType.RIGHT) : (shift ? ClickType.SHIFT_LEFT : ClickType.LEFT), InventoryAction.PICKUP_ALL); + } + + public CraftItemEvent(Recipe recipe, InventoryView what, SlotType type, int slot, ClickType click, InventoryAction action) { + super(what, type, slot, click, action); + this.recipe = recipe; + } + + public CraftItemEvent(Recipe recipe, InventoryView what, SlotType type, int slot, ClickType click, InventoryAction action, int key) { + super(what, type, slot, click, action, key); + this.recipe = recipe; + } + + /** + * @return A copy of the current recipe on the crafting matrix. + */ + public Recipe getRecipe() { + return recipe; + } + + @Override + public CraftingInventory getInventory() { + return (CraftingInventory) super.getInventory(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/DragType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/DragType.java new file mode 100644 index 0000000..72c2bed --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/DragType.java @@ -0,0 +1,17 @@ +package org.bukkit.event.inventory; + +/** + * Represents the effect of a drag that will be applied to an Inventory in an + * InventoryDragEvent. + */ +public enum DragType { + /** + * One item from the cursor is placed in each selected slot. + */ + SINGLE, + /** + * The cursor is split evenly across all selected slots, not to exceed the + * Material's max stack size, with the remainder going to the cursor. + */ + EVEN, +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/EquipmentSetEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/EquipmentSetEvent.java new file mode 100644 index 0000000..18ab995 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/EquipmentSetEvent.java @@ -0,0 +1,48 @@ +package org.bukkit.event.inventory; + +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +public class EquipmentSetEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + + private final HumanEntity humanEntity; + private final int slot; + private final ItemStack previousItem; + private final ItemStack newItem; + + public EquipmentSetEvent(HumanEntity humanEntity, int slot, ItemStack previousItem, ItemStack newItem) { + this.humanEntity = humanEntity; + this.slot = slot; + this.previousItem = previousItem; + this.newItem = newItem; + } + + public HumanEntity getHumanEntity() { + return this.humanEntity; + } + + public int getSlot() { + return this.slot; + } + + public ItemStack getPreviousItem() { + return this.previousItem; + } + + public ItemStack getNewItem() { + return this.newItem; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java new file mode 100644 index 0000000..8ca1ff7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java @@ -0,0 +1,99 @@ +package org.bukkit.event.inventory; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.inventory.ItemStack; + +/** + * Called when an ItemStack is successfully burned as fuel in a furnace. + */ +public class FurnaceBurnEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final ItemStack fuel; + private int burnTime; + private boolean cancelled; + private boolean burning; + + public FurnaceBurnEvent(final Block furnace, final ItemStack fuel, final int burnTime) { + super(furnace); + this.fuel = fuel; + this.burnTime = burnTime; + this.cancelled = false; + this.burning = true; + } + + /** + * Gets the block for the furnace involved in this event + * + * @return the block of the furnace + * @deprecated In favour of {@link #getBlock()}. + */ + @Deprecated + public Block getFurnace() { + return getBlock(); + } + + /** + * Gets the fuel ItemStack for this event + * + * @return the fuel ItemStack + */ + public ItemStack getFuel() { + return fuel; + } + + /** + * Gets the burn time for this fuel + * + * @return the burn time for this fuel + */ + public int getBurnTime() { + return burnTime; + } + + /** + * Sets the burn time for this fuel + * + * @param burnTime the burn time for this fuel + */ + public void setBurnTime(int burnTime) { + this.burnTime = burnTime; + } + + /** + * Gets whether the furnace's fuel is burning or not. + * + * @return whether the furnace's fuel is burning or not. + */ + public boolean isBurning() { + return this.burning; + } + + /** + * Sets whether the furnace's fuel is burning or not. + * + * @param burning true if the furnace's fuel is burning + */ + public void setBurning(boolean burning) { + this.burning = burning; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceExtractEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceExtractEvent.java new file mode 100644 index 0000000..b7381fa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceExtractEvent.java @@ -0,0 +1,49 @@ +package org.bukkit.event.inventory; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockExpEvent; + +/** + * This event is called when a player takes items out of the furnace + */ +public class FurnaceExtractEvent extends BlockExpEvent { + private final Player player; + private final Material itemType; + private final int itemAmount; + + public FurnaceExtractEvent(Player player, Block block, Material itemType, int itemAmount, int exp) { + super(block, exp); + this.player = player; + this.itemType = itemType; + this.itemAmount = itemAmount; + } + + /** + * Get the player that triggered the event + * + * @return the relevant player + */ + public Player getPlayer() { + return player; + } + + /** + * Get the Material of the item being retrieved + * + * @return the material of the item + */ + public Material getItemType() { + return itemType; + } + + /** + * Get the item count being retrieved + * + * @return the amount of the item + */ + public int getItemAmount() { + return itemAmount; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceSmeltEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceSmeltEvent.java new file mode 100644 index 0000000..e9d1a54 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/FurnaceSmeltEvent.java @@ -0,0 +1,79 @@ +package org.bukkit.event.inventory; + +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.inventory.ItemStack; + +/** + * Called when an ItemStack is successfully smelted in a furnace. + */ +public class FurnaceSmeltEvent extends BlockEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final ItemStack source; + private ItemStack result; + private boolean cancelled; + + public FurnaceSmeltEvent(final Block furnace, final ItemStack source, final ItemStack result) { + super(furnace); + this.source = source; + this.result = result; + this.cancelled = false; + } + + /** + * Gets the block for the furnace involved in this event + * + * @return the block of the furnace + * @deprecated In favour of {@link #getBlock()}. + */ + @Deprecated + public Block getFurnace() { + return getBlock(); + } + + /** + * Gets the smelted ItemStack for this event + * + * @return smelting source ItemStack + */ + public ItemStack getSource() { + return source; + } + + /** + * Gets the resultant ItemStack for this event + * + * @return smelting result ItemStack + */ + public ItemStack getResult() { + return result; + } + + /** + * Sets the resultant ItemStack for this event + * + * @param result new result ItemStack + */ + public void setResult(ItemStack result) { + this.result = result; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryAction.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryAction.java new file mode 100644 index 0000000..a7bc694 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryAction.java @@ -0,0 +1,91 @@ +package org.bukkit.event.inventory; + +/** + * An estimation of what the result will be. + */ +public enum InventoryAction { + + /** + * Nothing will happen from the click. + *

+ * There may be cases where nothing will happen and this is value is not + * provided, but it is guaranteed that this value is accurate when given. + */ + NOTHING, + /** + * All of the items on the clicked slot are moved to the cursor. + */ + PICKUP_ALL, + /** + * Some of the items on the clicked slot are moved to the cursor. + */ + PICKUP_SOME, + /** + * Half of the items on the clicked slot are moved to the cursor. + */ + PICKUP_HALF, + /** + * One of the items on the clicked slot are moved to the cursor. + */ + PICKUP_ONE, + /** + * All of the items on the cursor are moved to the clicked slot. + */ + PLACE_ALL, + /** + * Some of the items from the cursor are moved to the clicked slot + * (usually up to the max stack size). + */ + PLACE_SOME, + /** + * A single item from the cursor is moved to the clicked slot. + */ + PLACE_ONE, + /** + * The clicked item and the cursor are exchanged. + */ + SWAP_WITH_CURSOR, + /** + * The entire cursor item is dropped. + */ + DROP_ALL_CURSOR, + /** + * One item is dropped from the cursor. + */ + DROP_ONE_CURSOR, + /** + * The entire clicked slot is dropped. + */ + DROP_ALL_SLOT, + /** + * One item is dropped from the clicked slot. + */ + DROP_ONE_SLOT, + /** + * The item is moved to the opposite inventory if a space is found. + */ + MOVE_TO_OTHER_INVENTORY, + /** + * The clicked item is moved to the hotbar, and the item currently there + * is re-added to the player's inventory. + */ + HOTBAR_MOVE_AND_READD, + /** + * The clicked slot and the picked hotbar slot are swapped. + */ + HOTBAR_SWAP, + /** + * A max-size stack of the clicked item is put on the cursor. + */ + CLONE_STACK, + /** + * The inventory is searched for the same material, and they are put on + * the cursor up to {@link org.bukkit.Material#getMaxStackSize()}. + */ + COLLECT_TO_CURSOR, + /** + * An unrecognized ClickType. + */ + UNKNOWN, + ; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java new file mode 100644 index 0000000..3313d91 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java @@ -0,0 +1,245 @@ +package org.bukkit.event.inventory; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.plugin.Plugin; + +/** + * This event is called when a player clicks a slot in an inventory. + *

+ * Because InventoryClickEvent occurs within a modification of the Inventory, + * not all Inventory related methods are safe to use. + *

+ * The following should never be invoked by an EventHandler for + * InventoryClickEvent using the HumanEntity or InventoryView associated with + * this event: + *

    + *
  • {@link HumanEntity#closeInventory()} + *
  • {@link HumanEntity#openInventory(Inventory)} + *
  • {@link HumanEntity#openWorkbench(Location, boolean)} + *
  • {@link HumanEntity#openEnchanting(Location, boolean)} + *
  • {@link InventoryView#close()} + *
+ * To invoke one of these methods, schedule a task using + * {@link BukkitScheduler#runTask(Plugin, Runnable)}, which will run the task + * on the next tick. Also be aware that this is not an exhaustive list, and + * other methods could potentially create issues as well. + *

+ * Assuming the EntityHuman associated with this event is an instance of a + * Player, manipulating the MaxStackSize or contents of an Inventory will + * require an Invocation of {@link Player#updateInventory()}. + *

+ * Modifications to slots that are modified by the results of this + * InventoryClickEvent can be overwritten. To change these slots, this event + * should be cancelled and all desired changes to the inventory applied. + * Alternatively, scheduling a task using {@link BukkitScheduler#runTask( + * Plugin, Runnable)}, which would execute the task on the next tick, would + * work as well. + */ +public class InventoryClickEvent extends InventoryInteractEvent { + private static final HandlerList handlers = new HandlerList(); + private final ClickType click; + private final InventoryAction action; + private final Inventory clickedInventory; + private SlotType slot_type; + private int whichSlot; + private int rawSlot; + private ItemStack current = null; + private int hotbarKey = -1; + + @Deprecated + public InventoryClickEvent(InventoryView view, SlotType type, int slot, boolean right, boolean shift) { + this(view, type, slot, right ? (shift ? ClickType.SHIFT_RIGHT : ClickType.RIGHT) : (shift ? ClickType.SHIFT_LEFT : ClickType.LEFT), InventoryAction.SWAP_WITH_CURSOR); + } + + public InventoryClickEvent(InventoryView view, SlotType type, int slot, ClickType click, InventoryAction action) { + super(view); + this.slot_type = type; + this.rawSlot = slot; + if (slot < 0) { + this.clickedInventory = null; + } else if (view.getTopInventory() != null && slot < view.getTopInventory().getSize()) { + this.clickedInventory = view.getTopInventory(); + } else { + this.clickedInventory = view.getBottomInventory(); + } + this.whichSlot = view.convertSlot(slot); + this.click = click; + this.action = action; + } + + public InventoryClickEvent(InventoryView view, SlotType type, int slot, ClickType click, InventoryAction action, int key) { + this(view, type, slot, click, action); + this.hotbarKey = key; + } + + /** + * Gets the inventory that was clicked, or null if outside of window + * @return The clicked inventory + */ + public Inventory getClickedInventory() { + return clickedInventory; + } + + /** + * Gets the type of slot that was clicked. + * + * @return the slot type + */ + public SlotType getSlotType() { + return slot_type; + } + + /** + * Gets the current ItemStack on the cursor. + * + * @return the cursor ItemStack + */ + public ItemStack getCursor() { + return getView().getCursor(); + } + + /** + * Gets the ItemStack currently in the clicked slot. + * + * @return the item in the clicked + */ + public ItemStack getCurrentItem() { + if (slot_type == SlotType.OUTSIDE) { + return current; + } + return getView().getItem(rawSlot); + } + + /** + * Gets whether or not the ClickType for this event represents a right + * click. + * + * @return true if the ClickType uses the right mouse button. + * @see ClickType#isRightClick() + */ + public boolean isRightClick() { + return click.isRightClick(); + } + + /** + * Gets whether or not the ClickType for this event represents a left + * click. + * + * @return true if the ClickType uses the left mouse button. + * @see ClickType#isLeftClick() + */ + public boolean isLeftClick() { + return click.isLeftClick(); + } + + /** + * Gets whether the ClickType for this event indicates that the key was + * pressed down when the click was made. + * + * @return true if the ClickType uses Shift or Ctrl. + * @see ClickType#isShiftClick() + */ + public boolean isShiftClick() { + return click.isShiftClick(); + } + + /** + * Sets the item on the cursor. + * + * @param stack the new cursor item + * @deprecated This changes the ItemStack in their hand before any + * calculations are applied to the Inventory, which has a tendency to + * create inconsistencies between the Player and the server, and to + * make unexpected changes in the behavior of the clicked Inventory. + */ + @Deprecated + public void setCursor(ItemStack stack) { + getView().setCursor(stack); + } + + /** + * Sets the ItemStack currently in the clicked slot. + * + * @param stack the item to be placed in the current slot + */ + public void setCurrentItem(ItemStack stack) { + if (slot_type == SlotType.OUTSIDE) { + current = stack; + } else { + getView().setItem(rawSlot, stack); + } + } + + /** + * The slot number that was clicked, ready for passing to + * {@link Inventory#getItem(int)}. Note that there may be two slots with + * the same slot number, since a view links two different inventories. + * + * @return The slot number. + */ + public int getSlot() { + return whichSlot; + } + + /** + * The raw slot number clicked, ready for passing to {@link InventoryView + * #getItem(int)} This slot number is unique for the view. + * + * @return the slot number + */ + public int getRawSlot() { + return rawSlot; + } + + /** + * If the ClickType is NUMBER_KEY, this method will return the index of + * the pressed key (0-8). + * + * @return the number on the key minus 1 (range 0-8); or -1 if not + * a NUMBER_KEY action + */ + public int getHotbarButton() { + return hotbarKey; + } + + /** + * Gets the InventoryAction that triggered this event. + *

+ * This action cannot be changed, and represents what the normal outcome + * of the event will be. To change the behavior of this + * InventoryClickEvent, changes must be manually applied. + * + * @return the InventoryAction that triggered this event. + */ + public InventoryAction getAction() { + return action; + } + + /** + * Gets the ClickType for this event. + *

+ * This is insulated against changes to the inventory by other plugins. + * + * @return the type of inventory click + */ + public ClickType getClick() { + return click; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java new file mode 100644 index 0000000..19889b2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java @@ -0,0 +1,35 @@ + +package org.bukkit.event.inventory; + +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.InventoryView; + +/** + * Represents a player related inventory event + */ +public class InventoryCloseEvent extends InventoryEvent { + private static final HandlerList handlers = new HandlerList(); + + public InventoryCloseEvent(InventoryView transaction) { + super(transaction); + } + + /** + * Returns the player involved in this event + * + * @return Player who is involved in this event + */ + public final HumanEntity getPlayer() { + return transaction.getPlayer(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryCreativeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryCreativeEvent.java new file mode 100644 index 0000000..da7dffc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryCreativeEvent.java @@ -0,0 +1,27 @@ +package org.bukkit.event.inventory; + +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +/** + * This event is called when a player in creative mode puts down or picks up + * an item in their inventory / hotbar and when they drop items from their + * Inventory while in creative mode. + */ +public class InventoryCreativeEvent extends InventoryClickEvent { + private ItemStack item; + + public InventoryCreativeEvent(InventoryView what, SlotType type, int slot, ItemStack newItem) { + super(what, type, slot, ClickType.CREATIVE, InventoryAction.PLACE_ALL); + this.item = newItem; + } + + public ItemStack getCursor() { + return item; + } + + public void setCursor(ItemStack item) { + this.item = item; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryDragEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryDragEvent.java new file mode 100644 index 0000000..e7e54a7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryDragEvent.java @@ -0,0 +1,164 @@ +package org.bukkit.event.inventory; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitScheduler; + +import com.google.common.collect.ImmutableSet; + +/** + * This event is called when the player drags an item in their cursor across + * the inventory. The ItemStack is distributed across the slots the + * HumanEntity dragged over. The method of distribution is described by the + * DragType returned by {@link #getType()}. + *

+ * Canceling this event will result in none of the changes described in + * {@link #getNewItems()} being applied to the Inventory. + *

+ * Because InventoryDragEvent occurs within a modification of the Inventory, + * not all Inventory related methods are safe to use. + *

+ * The following should never be invoked by an EventHandler for + * InventoryDragEvent using the HumanEntity or InventoryView associated with + * this event. + *

    + *
  • {@link HumanEntity#closeInventory()} + *
  • {@link HumanEntity#openInventory(Inventory)} + *
  • {@link HumanEntity#openWorkbench(Location, boolean)} + *
  • {@link HumanEntity#openEnchanting(Location, boolean)} + *
  • {@link InventoryView#close()} + *
+ * To invoke one of these methods, schedule a task using + * {@link BukkitScheduler#runTask(Plugin, Runnable)}, which will run the task + * on the next tick. Also be aware that this is not an exhaustive list, and + * other methods could potentially create issues as well. + *

+ * Assuming the EntityHuman associated with this event is an instance of a + * Player, manipulating the MaxStackSize or contents of an Inventory will + * require an Invocation of {@link Player#updateInventory()}. + *

+ * Any modifications to slots that are modified by the results of this + * InventoryDragEvent will be overwritten. To change these slots, this event + * should be cancelled and the changes applied. Alternatively, scheduling a + * task using {@link BukkitScheduler#runTask(Plugin, Runnable)}, which would + * execute the task on the next tick, would work as well. + */ +public class InventoryDragEvent extends InventoryInteractEvent { + private static final HandlerList handlers = new HandlerList(); + private final DragType type; + private final Map addedItems; + private final Set containerSlots; + private final ItemStack oldCursor; + private ItemStack newCursor; + + public InventoryDragEvent(InventoryView what, ItemStack newCursor, ItemStack oldCursor, boolean right, Map slots) { + super(what); + + Validate.notNull(oldCursor); + Validate.notNull(slots); + + type = right ? DragType.SINGLE : DragType.EVEN; + this.newCursor = newCursor; + this.oldCursor = oldCursor; + this.addedItems = slots; + ImmutableSet.Builder b = ImmutableSet.builder(); + for (Integer slot : slots.keySet()) { + b.add(what.convertSlot(slot)); + } + this.containerSlots = b.build(); + } + + /** + * Gets all items to be added to the inventory in this drag. + * + * @return map from raw slot id to new ItemStack + */ + public Map getNewItems() { + return Collections.unmodifiableMap(addedItems); + } + + /** + * Gets the raw slot ids to be changed in this drag. + * + * @return list of raw slot ids, suitable for getView().getItem(int) + */ + public Set getRawSlots() { + return addedItems.keySet(); + } + + /** + * Gets the slots to be changed in this drag. + * + * @return list of converted slot ids, suitable for {@link + * org.bukkit.inventory.Inventory#getItem(int)}. + */ + public Set getInventorySlots() { + return containerSlots; + } + + /** + * Gets the result cursor after the drag is done. The returned value is + * mutable. + * + * @return the result cursor + */ + public ItemStack getCursor() { + return newCursor; + } + + /** + * Sets the result cursor after the drag is done. + *

+ * Changing this item stack changes the cursor item. Note that changing + * the affected "dragged" slots does not change this ItemStack, nor does + * changing this ItemStack affect the "dragged" slots. + * + * @param newCursor the new cursor ItemStack + */ + public void setCursor(ItemStack newCursor) { + this.newCursor = newCursor; + } + + /** + * Gets an ItemStack representing the cursor prior to any modifications + * as a result of this drag. + * + * @return the original cursor + */ + public ItemStack getOldCursor() { + return oldCursor.clone(); + } + + /** + * Gets the DragType that describes the behavior of ItemStacks placed + * after this InventoryDragEvent. + *

+ * The ItemStacks and the raw slots that they're being applied to can be + * found using {@link #getNewItems()}. + * + * @return the DragType of this InventoryDragEvent + */ + public DragType getType() { + return type; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryEvent.java new file mode 100644 index 0000000..973c392 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryEvent.java @@ -0,0 +1,59 @@ + +package org.bukkit.event.inventory; + +import java.util.List; + +import org.bukkit.event.HandlerList; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.Event; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; + +/** + * Represents a player related inventory event + */ +public class InventoryEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + protected InventoryView transaction; + + public InventoryEvent(InventoryView transaction) { + this.transaction = transaction; + } + + /** + * Gets the primary Inventory involved in this transaction + * + * @return The upper inventory. + */ + public Inventory getInventory() { + return transaction.getTopInventory(); + } + + /** + * Gets the list of players viewing the primary (upper) inventory involved + * in this event + * + * @return A list of people viewing. + */ + public List getViewers() { + return transaction.getTopInventory().getViewers(); + } + + /** + * Gets the view object itself + * + * @return InventoryView + */ + public InventoryView getView() { + return transaction; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryInteractEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryInteractEvent.java new file mode 100644 index 0000000..8624f8d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryInteractEvent.java @@ -0,0 +1,78 @@ +package org.bukkit.event.inventory; + +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event.Result; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +/** + * An abstract base class for events that describe an interaction between a + * HumanEntity and the contents of an Inventory. + */ +public abstract class InventoryInteractEvent extends InventoryEvent implements Cancellable { + private Result result = Result.DEFAULT; + + public InventoryInteractEvent(InventoryView transaction) { + super(transaction); + } + + /** + * Gets the player who performed the click. + * + * @return The clicking player. + */ + public HumanEntity getWhoClicked() { + return getView().getPlayer(); + } + + /** + * Sets the result of this event. This will change whether or not this + * event is considered cancelled. + * + * @see #isCancelled() + * @param newResult the new {@link Result} for this event + */ + public void setResult(Result newResult) { + result = newResult; + } + + /** + * Gets the {@link Result} of this event. The Result describes the + * behavior that will be applied to the inventory in relation to this + * event. + * + * @return the Result of this event. + */ + public Result getResult() { + return result; + } + + /** + * Gets whether or not this event is cancelled. This is based off of the + * Result value returned by {@link #getResult()}. Result.ALLOW and + * Result.DEFAULT will result in a returned value of false, but + * Result.DENY will result in a returned value of true. + *

+ * {@inheritDoc} + * + * @return whether the event is cancelled + */ + public boolean isCancelled() { + return getResult() == Result.DENY; + } + + /** + * Proxy method to {@link #setResult(Event.Result)} for the Cancellable + * interface. {@link #setResult(Event.Result)} is preferred, as it allows + * you to specify the Result beyond Result.DENY and Result.ALLOW. + *

+ * {@inheritDoc} + * + * @param toCancel result becomes DENY if true, ALLOW if false + */ + public void setCancelled(boolean toCancel) { + setResult(toCancel ? Result.DENY : Result.ALLOW); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryMoveItemEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryMoveItemEvent.java new file mode 100644 index 0000000..06ec99a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryMoveItemEvent.java @@ -0,0 +1,108 @@ +package org.bukkit.event.inventory; + +import org.apache.commons.lang.Validate; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +/** + * Called when some entity or block (e.g. hopper) tries to move items directly + * from one inventory to another. + *

+ * When this event is called, the initiator may already have removed the item + * from the source inventory and is ready to move it into the destination + * inventory. + *

+ * If this event is cancelled, the items will be returned to the source + * inventory, if needed. + *

+ * If this event is not cancelled, the initiator will try to put the ItemStack + * into the destination inventory. If this is not possible and the ItemStack + * has not been modified, the source inventory slot will be restored to its + * former state. Otherwise any additional items will be discarded. + */ +public class InventoryMoveItemEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Inventory sourceInventory; + private final Inventory destinationInventory; + private ItemStack itemStack; + private final boolean didSourceInitiate; + + public InventoryMoveItemEvent(final Inventory sourceInventory, final ItemStack itemStack, final Inventory destinationInventory, final boolean didSourceInitiate) { + Validate.notNull(itemStack, "ItemStack cannot be null"); + this.sourceInventory = sourceInventory; + this.itemStack = itemStack; + this.destinationInventory = destinationInventory; + this.didSourceInitiate = didSourceInitiate; + } + + /** + * Gets the Inventory that the ItemStack is being taken from + * + * @return Inventory that the ItemStack is being taken from + */ + public Inventory getSource() { + return sourceInventory; + } + + /** + * Gets the ItemStack being moved; if modified, the original item will not + * be removed from the source inventory. + * + * @return ItemStack + */ + public ItemStack getItem() { + return itemStack.clone(); + } + + /** + * Sets the ItemStack being moved; if this is different from the original + * ItemStack, the original item will not be removed from the source + * inventory. + * + * @param itemStack The ItemStack + */ + public void setItem(ItemStack itemStack) { + Validate.notNull(itemStack, "ItemStack cannot be null. Cancel the event if you want nothing to be transferred."); + this.itemStack = itemStack.clone(); + } + + /** + * Gets the Inventory that the ItemStack is being put into + * + * @return Inventory that the ItemStack is being put into + */ + public Inventory getDestination() { + return destinationInventory; + } + + /** + * Gets the Inventory that initiated the transfer. This will always be + * either the destination or source Inventory. + * + * @return Inventory that initiated the transfer + */ + public Inventory getInitiator() { + return didSourceInitiate ? sourceInventory : destinationInventory; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java new file mode 100644 index 0000000..c3570aa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java @@ -0,0 +1,63 @@ +package org.bukkit.event.inventory; + +import org.bukkit.inventory.InventoryView; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Represents a player related inventory event + */ +public class InventoryOpenEvent extends InventoryEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + + public InventoryOpenEvent(InventoryView transaction) { + super(transaction); + this.cancelled = false; + } + + /** + * Returns the player involved in this event + * + * @return Player who is involved in this event + */ + public final HumanEntity getPlayer() { + return transaction.getPlayer(); + } + + /** + * Gets the cancellation state of this event. A cancelled event will not + * be executed in the server, but will still pass to other plugins. + *

+ * If an inventory open event is cancelled, the inventory screen will not + * show. + * + * @return true if this event is cancelled + */ + public boolean isCancelled() { + return cancelled; + } + + /** + * Sets the cancellation state of this event. A cancelled event will not + * be executed in the server, but will still pass to other plugins. + *

+ * If an inventory open event is cancelled, the inventory screen will not + * show. + * + * @param cancel true if you wish to cancel this event + */ + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryPickupItemEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryPickupItemEvent.java new file mode 100644 index 0000000..af6ad5b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryPickupItemEvent.java @@ -0,0 +1,58 @@ +package org.bukkit.event.inventory; + +import org.bukkit.entity.Item; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.Inventory; + +/** + * Called when a hopper or hopper minecart picks up a dropped item. + */ +public class InventoryPickupItemEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Inventory inventory; + private final Item item; + + public InventoryPickupItemEvent(final Inventory inventory, final Item item) { + super(); + this.inventory = inventory; + this.item = item; + } + + /** + * Gets the Inventory that picked up the item + * + * @return Inventory + */ + public Inventory getInventory() { + return inventory; + } + + /** + * Gets the Item entity that was picked up + * + * @return Item + */ + public Item getItem() { + return item; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryType.java new file mode 100644 index 0000000..c36e046 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/InventoryType.java @@ -0,0 +1,124 @@ +package org.bukkit.event.inventory; + +public enum InventoryType { + + /** + * A chest inventory, with 0, 9, 18, 27, 36, 45, or 54 slots of type + * CONTAINER. + */ + CHEST(27,"Chest"), + /** + * A dispenser inventory, with 9 slots of type CONTAINER. + */ + DISPENSER(9,"Dispenser"), + /** + * A dropper inventory, with 9 slots of type CONTAINER. + */ + DROPPER(9, "Dropper"), + /** + * A furnace inventory, with a RESULT slot, a CRAFTING slot, and a FUEL + * slot. + */ + FURNACE(3,"Furnace"), + /** + * A workbench inventory, with 9 CRAFTING slots and a RESULT slot. + */ + WORKBENCH(10,"Crafting"), + /** + * A player's crafting inventory, with 4 CRAFTING slots and a RESULT slot. + * Also implies that the 4 ARMOR slots are accessible. + */ + CRAFTING(5,"Crafting"), + /** + * An enchantment table inventory, with two CRAFTING slots and three + * enchanting buttons. + */ + ENCHANTING(2,"Enchanting"), + /** + * A brewing stand inventory, with one FUEL slot and three CRAFTING slots. + */ + BREWING(4,"Brewing"), + /** + * A player's inventory, with 9 QUICKBAR slots, 27 CONTAINER slots, and 4 + * ARMOR slots. The ARMOUR slots may not be visible to the player, though. + */ + PLAYER(36,"Player"), + /** + * The creative mode inventory, with only 9 QUICKBAR slots and nothing + * else. (The actual creative interface with the items is client-side and + * cannot be altered by the server.) + */ + CREATIVE(9,"Creative"), + /** + * The merchant inventory, with 2 TRADE-IN slots, and 1 RESULT slot. + */ + MERCHANT(3,"Villager"), + /** + * The ender chest inventory, with 27 slots. + */ + ENDER_CHEST(27,"Ender Chest"), + /** + * An anvil inventory, with 2 CRAFTING slots and 1 RESULT slot + */ + ANVIL(3, "Repairing"), + /** + * A beacon inventory, with 1 CRAFTING slot + */ + BEACON(1, "container.beacon"), + /** + * A hopper inventory, with 5 slots of type CONTAINER. + */ + HOPPER(5, "Item Hopper"), + ; + + private final int size; + private final String title; + + private InventoryType(int defaultSize, String defaultTitle) { + size = defaultSize; + title = defaultTitle; + } + + public int getDefaultSize() { + return size; + } + + public String getDefaultTitle() { + return title; + } + + public enum SlotType { + /** + * A result slot in a furnace or crafting inventory. + */ + RESULT, + /** + * A slot in the crafting matrix, or the input slot in a furnace + * inventory, the potion slot in the brewing stand, or the enchanting + * slot. + */ + CRAFTING, + /** + * An armour slot in the player's inventory. + */ + ARMOR, + /** + * A regular slot in the container or the player's inventory; anything + * not covered by the other enum values. + */ + CONTAINER, + /** + * A slot in the bottom row or quickbar. + */ + QUICKBAR, + /** + * A pseudo-slot representing the area outside the inventory window. + */ + OUTSIDE, + /** + * The fuel slot in a furnace inventory, or the ingredient slot in a + * brewing stand inventory. + */ + FUEL; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/PrepareItemCraftEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/PrepareItemCraftEvent.java new file mode 100644 index 0000000..5731190 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/inventory/PrepareItemCraftEvent.java @@ -0,0 +1,56 @@ +package org.bukkit.event.inventory; + +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.Recipe; + +public class PrepareItemCraftEvent extends InventoryEvent { + private static final HandlerList handlers = new HandlerList(); + private boolean repair; + private CraftingInventory matrix; + + public PrepareItemCraftEvent(CraftingInventory what, InventoryView view, boolean isRepair) { + super(view); + this.matrix = what; + this.repair = isRepair; + } + + /** + * Get the recipe that has been formed. If this event was triggered by a + * tool repair, this will be a temporary shapeless recipe representing the + * repair. + * + * @return The recipe being crafted. + */ + public Recipe getRecipe() { + return matrix.getRecipe(); + } + + /** + * @return The crafting inventory on which the recipe was formed. + */ + @Override + public CraftingInventory getInventory() { + return matrix; + } + + /** + * Check if this event was triggered by a tool repair operation rather + * than a crafting recipe. + * + * @return True if this is a repair. + */ + public boolean isRepair() { + return repair; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingBreakByEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingBreakByEntityEvent.java new file mode 100644 index 0000000..1dc4987 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingBreakByEntityEvent.java @@ -0,0 +1,31 @@ +package org.bukkit.event.painting; + +import org.bukkit.Warning; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Painting; + +/** + * Triggered when a painting is removed by an entity + * + * @deprecated Use {@link org.bukkit.event.hanging.HangingBreakByEntityEvent} + * instead. + */ +@Deprecated +@Warning(reason="This event has been replaced by HangingBreakByEntityEvent") +public class PaintingBreakByEntityEvent extends PaintingBreakEvent { + private final Entity remover; + + public PaintingBreakByEntityEvent(final Painting painting, final Entity remover) { + super(painting, RemoveCause.ENTITY); + this.remover = remover; + } + + /** + * Gets the entity that removed the painting + * + * @return the entity that removed the painting. + */ + public Entity getRemover() { + return remover; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingBreakEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingBreakEvent.java new file mode 100644 index 0000000..3e27c69 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingBreakEvent.java @@ -0,0 +1,76 @@ +package org.bukkit.event.painting; + +import org.bukkit.Warning; +import org.bukkit.entity.Painting; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Triggered when a painting is removed + * + * @deprecated Use {@link org.bukkit.event.hanging.HangingBreakEvent} instead. + */ +@Deprecated +@Warning(reason="This event has been replaced by HangingBreakEvent") +public class PaintingBreakEvent extends PaintingEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final RemoveCause cause; + + public PaintingBreakEvent(final Painting painting, final RemoveCause cause) { + super(painting); + this.cause = cause; + } + + /** + * Gets the cause for the painting's removal + * + * @return the RemoveCause for the painting's removal + */ + public RemoveCause getCause() { + return cause; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + /** + * An enum to specify the cause of the removal + */ + public enum RemoveCause { + /** + * Removed by an entity + */ + ENTITY, + /** + * Removed by fire + */ + FIRE, + /** + * Removed by placing a block on it + */ + OBSTRUCTION, + /** + * Removed by water flowing over it + */ + WATER, + /** + * Removed by destroying the block behind it, etc + */ + PHYSICS, + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingEvent.java new file mode 100644 index 0000000..3a51348 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingEvent.java @@ -0,0 +1,29 @@ +package org.bukkit.event.painting; + +import org.bukkit.Warning; +import org.bukkit.entity.Painting; +import org.bukkit.event.Event; + +/** + * Represents a painting-related event. + * + * @deprecated Use {@link org.bukkit.event.hanging.HangingEvent} instead. + */ +@Deprecated +@Warning(reason="This event has been replaced by HangingEvent") +public abstract class PaintingEvent extends Event { + protected Painting painting; + + protected PaintingEvent(final Painting painting) { + this.painting = painting; + } + + /** + * Gets the painting involved in this event. + * + * @return the painting + */ + public Painting getPainting() { + return painting; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingPlaceEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingPlaceEvent.java new file mode 100644 index 0000000..3250b29 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/painting/PaintingPlaceEvent.java @@ -0,0 +1,76 @@ +package org.bukkit.event.painting; + +import org.bukkit.Warning; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Painting; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Triggered when a painting is created in the world + * + * @deprecated Use {@link org.bukkit.event.hanging.HangingPlaceEvent} instead. + */ +@Deprecated +@Warning(reason="This event has been replaced by HangingPlaceEvent") +public class PaintingPlaceEvent extends PaintingEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Player player; + private final Block block; + private final BlockFace blockFace; + + public PaintingPlaceEvent(final Painting painting, final Player player, final Block block, final BlockFace blockFace) { + super(painting); + this.player = player; + this.block = block; + this.blockFace = blockFace; + } + + /** + * Returns the player placing the painting + * + * @return Entity returns the player placing the painting + */ + public Player getPlayer() { + return player; + } + + /** + * Returns the block that the painting was placed on + * + * @return Block returns the block painting placed on + */ + public Block getBlock() { + return block; + } + + /** + * Returns the face of the block that the painting was placed on + * + * @return BlockFace returns the face of the block the painting was placed + * on + */ + public BlockFace getBlockFace() { + return blockFace; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/AsyncPlayerChatEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/AsyncPlayerChatEvent.java new file mode 100644 index 0000000..a796292 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/AsyncPlayerChatEvent.java @@ -0,0 +1,140 @@ +package org.bukkit.event.player; + +import java.util.IllegalFormatException; +import java.util.Set; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * This event will sometimes fire synchronously, depending on how it was + * triggered. + *

+ * The constructor provides a boolean to indicate if the event was fired + * synchronously or asynchronously. When asynchronous, this event can be + * called from any thread, sans the main thread, and has limited access to the + * API. + *

+ * If a player is the direct cause of this event by an incoming packet, this + * event will be asynchronous. If a plugin triggers this event by compelling a + * player to chat, this event will be synchronous. + *

+ * Care should be taken to check {@link #isAsynchronous()} and treat the event + * appropriately. + */ +public class AsyncPlayerChatEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private String message; + private String format = "<%1$s> %2$s"; + private final Set recipients; + + /** + * + * @param async This changes the event to a synchronous state. + * @param who the chat sender + * @param message the message sent + * @param players the players to receive the message. This may be a lazy + * or unmodifiable collection. + */ + public AsyncPlayerChatEvent(final boolean async, final Player who, final String message, final Set players) { + super(who, async); + this.message = message; + recipients = players; + } + + /** + * Gets the message that the player is attempting to send. This message + * will be used with {@link #getFormat()}. + * + * @return Message the player is attempting to send + */ + public String getMessage() { + return message; + } + + /** + * Sets the message that the player will send. This message will be used + * with {@link #getFormat()}. + * + * @param message New message that the player will send + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * Gets the format to use to display this chat message. + *

+ * When this event finishes execution, the first format parameter is the + * {@link Player#getDisplayName()} and the second parameter is {@link + * #getMessage()} + * + * @return {@link String#format(String, Object...)} compatible format + * string + */ + public String getFormat() { + return format; + } + + /** + * Sets the format to use to display this chat message. + *

+ * When this event finishes execution, the first format parameter is the + * {@link Player#getDisplayName()} and the second parameter is {@link + * #getMessage()} + * + * @param format {@link String#format(String, Object...)} compatible + * format string + * @throws IllegalFormatException if the underlying API throws the + * exception + * @throws NullPointerException if format is null + * @see String#format(String, Object...) + */ + public void setFormat(final String format) throws IllegalFormatException, NullPointerException { + // Oh for a better way to do this! + try { + String.format(format, player, message); + } catch (RuntimeException ex) { + ex.fillInStackTrace(); + throw ex; + } + + this.format = format; + } + + /** + * Gets a set of recipients that this chat message will be displayed to. + *

+ * The set returned is not guaranteed to be mutable and may auto-populate + * on access. Any listener accessing the returned set should be aware that + * it may reduce performance for a lazy set implementation. + *

+ * Listeners should be aware that modifying the list may throw {@link + * UnsupportedOperationException} if the event caller provides an + * unmodifiable set. + * + * @return All Players who will see this chat message + */ + public Set getRecipients() { + return recipients; + } + + public boolean isCancelled() { + return cancel ; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java new file mode 100644 index 0000000..1d57188 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java @@ -0,0 +1,201 @@ +package org.bukkit.event.player; + +import java.net.InetAddress; +import java.util.UUID; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Stores details for players attempting to log in. + *

+ * This event is asynchronous, and not run using main thread. + */ +public class AsyncPlayerPreLoginEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + private Result result; + private String message; + private final String name; + private final InetAddress ipAddress; + private final UUID uniqueId; + + @Deprecated + public AsyncPlayerPreLoginEvent(final String name, final InetAddress ipAddress) { + this(name, ipAddress, null); + } + + public AsyncPlayerPreLoginEvent(final String name, final InetAddress ipAddress, final UUID uniqueId) { + super(true); + this.result = Result.ALLOWED; + this.message = ""; + this.name = name; + this.ipAddress = ipAddress; + this.uniqueId = uniqueId; + } + + /** + * Gets the current result of the login, as an enum + * + * @return Current Result of the login + */ + public Result getLoginResult() { + return result; + } + + /** + * Gets the current result of the login, as an enum + * + * @return Current Result of the login + * @deprecated This method uses a deprecated enum from {@link + * PlayerPreLoginEvent} + * @see #getLoginResult() + */ + @Deprecated + public PlayerPreLoginEvent.Result getResult() { + return result == null ? null : result.old(); + } + + /** + * Sets the new result of the login, as an enum + * + * @param result New result to set + */ + public void setLoginResult(final Result result) { + this.result = result; + } + + /** + * Sets the new result of the login, as an enum + * + * @param result New result to set + * @deprecated This method uses a deprecated enum from {@link + * PlayerPreLoginEvent} + * @see #setLoginResult(Result) + */ + @Deprecated + public void setResult(final PlayerPreLoginEvent.Result result) { + this.result = result == null ? null : Result.valueOf(result.name()); + } + + /** + * Gets the current kick message that will be used if getResult() != + * Result.ALLOWED + * + * @return Current kick message + */ + public String getKickMessage() { + return message; + } + + /** + * Sets the kick message to display if getResult() != Result.ALLOWED + * + * @param message New kick message + */ + public void setKickMessage(final String message) { + this.message = message; + } + + /** + * Allows the player to log in + */ + public void allow() { + result = Result.ALLOWED; + message = ""; + } + + /** + * Disallows the player from logging in, with the given reason + * + * @param result New result for disallowing the player + * @param message Kick message to display to the user + */ + public void disallow(final Result result, final String message) { + this.result = result; + this.message = message; + } + + /** + * Disallows the player from logging in, with the given reason + * + * @param result New result for disallowing the player + * @param message Kick message to display to the user + * @deprecated This method uses a deprecated enum from {@link + * PlayerPreLoginEvent} + * @see #disallow(Result, String) + */ + @Deprecated + public void disallow(final PlayerPreLoginEvent.Result result, final String message) { + this.result = result == null ? null : Result.valueOf(result.name()); + this.message = message; + } + + /** + * Gets the player's name. + * + * @return the player's name + */ + public String getName() { + return name; + } + + /** + * Gets the player IP address. + * + * @return The IP address + */ + public InetAddress getAddress() { + return ipAddress; + } + + /** + * Gets the player's unique ID. + * + * @return The unique ID + */ + public UUID getUniqueId() { + return uniqueId; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Basic kick reasons for communicating to plugins + */ + public enum Result { + + /** + * The player is allowed to log in + */ + ALLOWED, + /** + * The player is not allowed to log in, due to the server being full + */ + KICK_FULL, + /** + * The player is not allowed to log in, due to them being banned + */ + KICK_BANNED, + /** + * The player is not allowed to log in, due to them not being on the + * white list + */ + KICK_WHITELIST, + /** + * The player is not allowed to log in, for reasons undefined + */ + KICK_OTHER; + + @Deprecated + private PlayerPreLoginEvent.Result old() { + return PlayerPreLoginEvent.Result.valueOf(name()); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAchievementAwardedEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAchievementAwardedEvent.java new file mode 100644 index 0000000..e33fade --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAchievementAwardedEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.player; + +import org.bukkit.Achievement; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a player earns an achievement. + */ +public class PlayerAchievementAwardedEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Achievement achievement; + private boolean isCancelled = false; + + public PlayerAchievementAwardedEvent(Player player, Achievement achievement) { + super(player); + this.achievement = achievement; + } + + /** + * Gets the Achievement being awarded. + * + * @return the achievement being awarded + */ + public Achievement getAchievement() { + return achievement; + } + + public boolean isCancelled() { + return isCancelled; + } + + public void setCancelled(boolean cancel) { + this.isCancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java new file mode 100644 index 0000000..cabe77d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAnimationEvent.java @@ -0,0 +1,52 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Represents a player animation event + */ +public class PlayerAnimationEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final PlayerAnimationType animationType; + private boolean isCancelled = false; + + /** + * Construct a new PlayerAnimation event + * + * @param player The player instance + */ + public PlayerAnimationEvent(final Player player) { + super(player); + + // Only supported animation type for now: + animationType = PlayerAnimationType.ARM_SWING; + } + + /** + * Get the type of this animation event + * + * @return the animation type + */ + public PlayerAnimationType getAnimationType() { + return animationType; + } + + public boolean isCancelled() { + return this.isCancelled; + } + + public void setCancelled(boolean cancel) { + this.isCancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAnimationType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAnimationType.java new file mode 100644 index 0000000..ea4bf26 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerAnimationType.java @@ -0,0 +1,8 @@ +package org.bukkit.event.player; + +/** + * Different types of player animations + */ +public enum PlayerAnimationType { + ARM_SWING +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerArmorStandManipulateEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerArmorStandManipulateEvent.java new file mode 100644 index 0000000..577b284 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerArmorStandManipulateEvent.java @@ -0,0 +1,75 @@ +package org.bukkit.event.player; + +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.entity.Player; +import org.bukkit.entity.ArmorStand; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * Called when a player interacts with an armor stand and will either swap, retrieve or place an item. + */ +public class PlayerArmorStandManipulateEvent extends PlayerInteractEntityEvent { + + private static final HandlerList handlers = new HandlerList(); + + private final ItemStack playerItem; + private final ItemStack armorStandItem; + private final EquipmentSlot slot; + + public PlayerArmorStandManipulateEvent(final Player who, final ArmorStand clickedEntity, final ItemStack playerItem, final ItemStack armorStandItem, final EquipmentSlot slot) { + super(who, clickedEntity); + this.playerItem = playerItem; + this.armorStandItem = armorStandItem; + this.slot = slot; + } + + /** + * Returns the item held by the player. If this Item is null and the armor stand Item is also null, + * there will be no transaction between the player and the armor stand. + * If the Player's item is null, but the armor stand item is not then the player will obtain the armor stand item. + * In the case that the Player's item is not null, but the armor stand item is null, the players item will be placed on the armor stand. + * If both items are not null, the items will be swapped. + * In the case that the event is cancelled the original items will remain the same. + * @return the item held by the player. + */ + public ItemStack getPlayerItem() { + return this.playerItem; + } + + /** + * Returns the item held by the armor stand. + * If this Item is null and the player's Item is also null, there will be no transaction between the player and the armor stand. + * If the Player's item is null, but the armor stand item is not then the player will obtain the armor stand item. + * In the case that the Player's item is not null, but the armor stand item is null, the players item will be placed on the armor stand. + * If both items are not null, the items will be swapped. + * In the case that the event is cancelled the original items will remain the same. + * @return the item held by the armor stand. + */ + public ItemStack getArmorStandItem() { + return this.armorStandItem; + } + + /** + * Returns the raw item slot of the armor stand in this event. + * + * @return the index of the item obtained or placed of the armor stand. + */ + public EquipmentSlot getSlot() { + return this.slot; + } + + @Override + public ArmorStand getRightClicked() { + return (ArmorStand) this.clickedEntity; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBedEnterEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBedEnterEvent.java new file mode 100644 index 0000000..09f1a66 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBedEnterEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.player; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * This event is fired when the player is almost about to enter the bed. + */ +public class PlayerBedEnterEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private final Block bed; + + public PlayerBedEnterEvent(final Player who, final Block bed) { + super(who); + this.bed = bed; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Returns the bed block involved in this event. + * + * @return the bed block involved in this event + */ + public Block getBed() { + return bed; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBedLeaveEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBedLeaveEvent.java new file mode 100644 index 0000000..628ab0b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBedLeaveEvent.java @@ -0,0 +1,36 @@ +package org.bukkit.event.player; + +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * This event is fired when the player is leaving a bed. + */ +public class PlayerBedLeaveEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final Block bed; + + public PlayerBedLeaveEvent(final Player who, final Block bed) { + super(who); + this.bed = bed; + } + + /** + * Returns the bed block involved in this event. + * + * @return the bed block involved in this event + */ + public Block getBed() { + return bed; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java new file mode 100644 index 0000000..8fb121a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketEmptyEvent.java @@ -0,0 +1,28 @@ +package org.bukkit.event.player; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * Called when a player empties a bucket + */ +public class PlayerBucketEmptyEvent extends PlayerBucketEvent { + private static final HandlerList handlers = new HandlerList(); + + public PlayerBucketEmptyEvent(final Player who, final Block blockClicked, final BlockFace blockFace, final Material bucket, final ItemStack itemInHand) { + super(who, blockClicked, blockFace, bucket, itemInHand); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java new file mode 100644 index 0000000..d32c55e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketEvent.java @@ -0,0 +1,80 @@ +package org.bukkit.event.player; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.inventory.ItemStack; + +/** + * Called when a player interacts with a Bucket + */ +public abstract class PlayerBucketEvent extends PlayerEvent implements Cancellable { + private ItemStack itemStack; + private boolean cancelled = false; + private final Block blockClicked; + private final BlockFace blockFace; + private final Material bucket; + + public PlayerBucketEvent(final Player who, final Block blockClicked, final BlockFace blockFace, final Material bucket, final ItemStack itemInHand) { + super(who); + this.blockClicked = blockClicked; + this.blockFace = blockFace; + this.itemStack = itemInHand; + this.bucket = bucket; + } + + /** + * Returns the bucket used in this event + * + * @return the used bucket + */ + public Material getBucket() { + return bucket; + } + + /** + * Get the resulting item in hand after the bucket event + * + * @return Itemstack hold in hand after the event. + */ + public ItemStack getItemStack() { + return itemStack; + } + + /** + * Set the item in hand after the event + * + * @param itemStack the new held itemstack after the bucket event. + */ + public void setItemStack(ItemStack itemStack) { + this.itemStack = itemStack; + } + + /** + * Return the block clicked + * + * @return the blicked block + */ + public Block getBlockClicked() { + return blockClicked; + } + + /** + * Get the face on the clicked block + * + * @return the clicked face + */ + public BlockFace getBlockFace() { + return blockFace; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java new file mode 100644 index 0000000..94e042a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerBucketFillEvent.java @@ -0,0 +1,28 @@ +package org.bukkit.event.player; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * Called when a player fills a bucket + */ +public class PlayerBucketFillEvent extends PlayerBucketEvent { + private static final HandlerList handlers = new HandlerList(); + + public PlayerBucketFillEvent(final Player who, final Block blockClicked, final BlockFace blockFace, final Material bucket, final ItemStack itemInHand) { + super(who, blockClicked, blockFace, bucket, itemInHand); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChangedWorldEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChangedWorldEvent.java new file mode 100644 index 0000000..76c9c20 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChangedWorldEvent.java @@ -0,0 +1,36 @@ +package org.bukkit.event.player; + +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a player switches to another world. + */ +public class PlayerChangedWorldEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final World from; + + public PlayerChangedWorldEvent(final Player player, final World from) { + super(player); + this.from = from; + } + + /** + * Gets the world the player is switching from. + * + * @return player's previous world + */ + public World getFrom() { + return from; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChannelEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChannelEvent.java new file mode 100644 index 0000000..054efbc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChannelEvent.java @@ -0,0 +1,31 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * This event is called after a player registers or unregisters a new plugin + * channel. + */ +public abstract class PlayerChannelEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final String channel; + + public PlayerChannelEvent(final Player player, final String channel) { + super(player); + this.channel = channel; + } + + public final String getChannel() { + return channel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChatEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChatEvent.java new file mode 100644 index 0000000..1fb5cd7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChatEvent.java @@ -0,0 +1,125 @@ +package org.bukkit.event.player; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.Warning; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Holds information for player chat and commands + * + * @deprecated This event will fire from the main thread and allows the use of + * all of the Bukkit API, unlike the {@link AsyncPlayerChatEvent}. + *

+ * Listening to this event forces chat to wait for the main thread which + * causes delays for chat. {@link AsyncPlayerChatEvent} is the encouraged + * alternative for thread safe implementations. + */ +@Deprecated +@Warning(reason="Listening to this event forces chat to wait for the main thread, delaying chat messages.") +public class PlayerChatEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private String message; + private String format; + private final Set recipients; + + public PlayerChatEvent(final Player player, final String message) { + super(player); + this.message = message; + this.format = "<%1$s> %2$s"; + this.recipients = new HashSet(player.getServer().getOnlinePlayers()); + } + + public PlayerChatEvent(final Player player, final String message, final String format, final Set recipients) { + super(player); + this.message = message; + this.format = format; + this.recipients = recipients; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the message that the player is attempting to send + * + * @return Message the player is attempting to send + */ + public String getMessage() { + return message; + } + + /** + * Sets the message that the player will send + * + * @param message New message that the player will send + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * Sets the player that this message will display as, or command will be + * executed as + * + * @param player New player which this event will execute as + */ + public void setPlayer(final Player player) { + Validate.notNull(player, "Player cannot be null"); + this.player = player; + } + + /** + * Gets the format to use to display this chat message + * + * @return String.Format compatible format string + */ + public String getFormat() { + return format; + } + + /** + * Sets the format to use to display this chat message + * + * @param format String.Format compatible format string + */ + public void setFormat(final String format) { + // Oh for a better way to do this! + try { + String.format(format, player, message); + } catch (RuntimeException ex) { + ex.fillInStackTrace(); + throw ex; + } + + this.format = format; + } + + /** + * Gets a set of recipients that this chat message will be displayed to + * + * @return All Players who will see this chat message + */ + public Set getRecipients() { + return recipients; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChatTabCompleteEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChatTabCompleteEvent.java new file mode 100644 index 0000000..7241a9b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerChatTabCompleteEvent.java @@ -0,0 +1,70 @@ +package org.bukkit.event.player; + +import java.util.Collection; + +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a player attempts to tab-complete a chat message. + */ +public class PlayerChatTabCompleteEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final String message; + private final String lastToken; + private final Collection completions; + + public PlayerChatTabCompleteEvent(final Player who, final String message, final Collection completions) { + super(who); + Validate.notNull(message, "Message cannot be null"); + Validate.notNull(completions, "Completions cannot be null"); + this.message = message; + int i = message.lastIndexOf(' '); + if (i < 0) { + this.lastToken = message; + } else { + this.lastToken = message.substring(i + 1); + } + this.completions = completions; + } + + /** + * Gets the chat message being tab-completed. + * + * @return the chat message + */ + public String getChatMessage() { + return message; + } + + /** + * Gets the last 'token' of the message being tab-completed. + *

+ * The token is the substring starting with the character after the last + * space in the message. + * + * @return The last token for the chat message + */ + public String getLastToken() { + return lastToken; + } + + /** + * This is the collection of completions for this event. + * + * @return the current completions + */ + public Collection getTabCompletions() { + return completions; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerCommandPreprocessEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerCommandPreprocessEvent.java new file mode 100644 index 0000000..1ec8173 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerCommandPreprocessEvent.java @@ -0,0 +1,172 @@ +package org.bukkit.event.player; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * This event is called whenever a player runs a command (by placing a slash + * at the start of their message). It is called early in the command handling + * process, and modifications in this event (via {@link #setMessage(String)}) + * will be shown in the behavior. + *

+ * Many plugins will have no use for this event, and you should + * attempt to avoid using it if it is not necessary. + *

+ * Some examples of valid uses for this event are: + *

    + *
  • Logging executed commands to a separate file + *
  • Variable substitution. For example, replacing + * ${nearbyPlayer} with the name of the nearest other + * player, or simulating the @a and @p + * decorators used by Command Blocks in plugins that do not handle it. + *
  • Conditionally blocking commands belonging to other plugins. For + * example, blocking the use of the /home command in a + * combat arena. + *
  • Per-sender command aliases. For example, after a player runs the + * command /calias cr gamemode creative, the next time they + * run /cr, it gets replaced into + * /gamemode creative. (Global command aliases should be + * done by registering the alias.) + *
+ *

+ * Examples of incorrect uses are: + *

    + *
  • Using this event to run command logic + *
+ *

+ * If the event is cancelled, processing of the command will halt. + *

+ * The state of whether or not there is a slash (/) at the + * beginning of the message should be preserved. If a slash is added or + * removed, unexpected behavior may result. + */ +public class PlayerCommandPreprocessEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private String message; + private String format = "<%1$s> %2$s"; + private final Set recipients; + + public PlayerCommandPreprocessEvent(final Player player, final String message) { + super(player); + this.recipients = new HashSet(player.getServer().getOnlinePlayers()); + this.message = message; + } + + public PlayerCommandPreprocessEvent(final Player player, final String message, final Set recipients) { + super(player); + this.recipients = recipients; + this.message = message; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the command that the player is attempting to send. + *

+ * All commands begin with a special character; implementations do not + * consider the first character when executing the content. + * + * @return Message the player is attempting to send + */ + public String getMessage() { + return message; + } + + /** + * Sets the command that the player will send. + *

+ * All commands begin with a special character; implementations do not + * consider the first character when executing the content. + * + * @param command New message that the player will send + * @throws IllegalArgumentException if command is null or empty + */ + public void setMessage(String command) throws IllegalArgumentException { + Validate.notNull(command, "Command cannot be null"); + Validate.notEmpty(command, "Command cannot be empty"); + this.message = command; + } + + /** + * Sets the player that this command will be executed as. + * + * @param player New player which this event will execute as + * @throws IllegalArgumentException if the player provided is null + */ + public void setPlayer(final Player player) throws IllegalArgumentException { + Validate.notNull(player, "Player cannot be null"); + this.player = player; + } + + /** + * Gets the format to use to display this chat message + * + * @deprecated This method is provided for backward compatibility with no + * guarantee to the use of the format. + * @return String.Format compatible format string + */ + @Deprecated + public String getFormat() { + return format; + } + + /** + * Sets the format to use to display this chat message + * + * @deprecated This method is provided for backward compatibility with no + * guarantee to the effect of modifying the format. + * @param format String.Format compatible format string + */ + @Deprecated + public void setFormat(final String format) { + // Oh for a better way to do this! + try { + String.format(format, player, message); + } catch (RuntimeException ex) { + ex.fillInStackTrace(); + throw ex; + } + + this.format = format; + } + + /** + * Gets a set of recipients that this chat message will be displayed to. + *

+ * The set returned is not guaranteed to be mutable and may auto-populate + * on access. Any listener accessing the returned set should be aware that + * it may reduce performance for a lazy set implementation. Listeners + * should be aware that modifying the list may throw {@link + * UnsupportedOperationException} if the event caller provides an + * unmodifiable set. + * + * @deprecated This method is provided for backward compatibility with no + * guarantee to the effect of viewing or modifying the set. + * @return All Players who will see this chat message + */ + @Deprecated + public Set getRecipients() { + return recipients; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerDropItemEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerDropItemEvent.java new file mode 100644 index 0000000..5b41b65 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerDropItemEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Thrown when a player drops an item from their inventory + */ +public class PlayerDropItemEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Item drop; + private boolean cancel = false; + + public PlayerDropItemEvent(final Player player, final Item drop) { + super(player); + this.drop = drop; + } + + /** + * Gets the ItemDrop created by the player + * + * @return ItemDrop created by the player + */ + public Item getItemDrop() { + return drop; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEditBookEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEditBookEvent.java new file mode 100644 index 0000000..ea7ecef --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEditBookEvent.java @@ -0,0 +1,124 @@ +package org.bukkit.event.player; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.meta.BookMeta; + +/** + * Called when a player edits or signs a book and quill item. If the event is + * cancelled, no changes are made to the BookMeta + */ +public class PlayerEditBookEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + private final BookMeta previousBookMeta; + private final int slot; + private BookMeta newBookMeta; + private boolean isSigning; + private boolean cancel; + + public PlayerEditBookEvent(Player who, int slot, BookMeta previousBookMeta, BookMeta newBookMeta, boolean isSigning) { + super(who); + + Validate.isTrue(slot >= 0 && slot <=8, "Slot must be in range 0-8 inclusive"); + Validate.notNull(previousBookMeta, "Previous book meta must not be null"); + Validate.notNull(newBookMeta, "New book meta must not be null"); + + Bukkit.getItemFactory().equals(previousBookMeta, newBookMeta); + + this.previousBookMeta = previousBookMeta; + this.newBookMeta = newBookMeta; + this.slot = slot; + this.isSigning = isSigning; + this.cancel = false; + } + + /** + * Gets the book meta currently on the book. + *

+ * Note: this is a copy of the book meta. You cannot use this object to + * change the existing book meta. + * + * @return the book meta currently on the book + */ + public BookMeta getPreviousBookMeta() { + return previousBookMeta.clone(); + } + + /** + * Gets the book meta that the player is attempting to add to the book. + *

+ * Note: this is a copy of the proposed new book meta. Use {@link + * #setNewBookMeta(BookMeta)} to change what will actually be added to the + * book. + * + * @return the book meta that the player is attempting to add + */ + public BookMeta getNewBookMeta() { + return newBookMeta.clone(); + } + + /** + * Gets the inventory slot number for the book item that triggered this + * event. + *

+ * This is a slot number on the player's hotbar in the range 0-8. + * + * @return the inventory slot number that the book item occupies + */ + public int getSlot() { + return slot; + } + + /** + * Sets the book meta that will actually be added to the book. + * + * @param newBookMeta new book meta + * @throws IllegalArgumentException if the new book meta is null + */ + public void setNewBookMeta(BookMeta newBookMeta) throws IllegalArgumentException { + Validate.notNull(newBookMeta, "New book meta must not be null"); + Bukkit.getItemFactory().equals(newBookMeta, null); + this.newBookMeta = newBookMeta.clone(); + } + + /** + * Gets whether or not the book is being signed. If a book is signed the + * Material changes from BOOK_AND_QUILL to WRITTEN_BOOK. + * + * @return true if the book is being signed + */ + public boolean isSigning() { + return isSigning; + } + + /** + * Sets whether or not the book is being signed. If a book is signed the + * Material changes from BOOK_AND_QUILL to WRITTEN_BOOK. + * + * @param signing whether or not the book is being signed. + */ + public void setSigning(boolean signing) { + isSigning = signing; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEggThrowEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEggThrowEvent.java new file mode 100644 index 0000000..896347e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEggThrowEvent.java @@ -0,0 +1,137 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.CreatureType; +import org.bukkit.entity.Egg; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a player throws an egg and it might hatch + */ +public class PlayerEggThrowEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final Egg egg; + private boolean hatching; + private EntityType hatchType; + private byte numHatches; + + public PlayerEggThrowEvent(final Player player, final Egg egg, final boolean hatching, final byte numHatches, final EntityType hatchingType) { + super(player); + this.egg = egg; + this.hatching = hatching; + this.numHatches = numHatches; + this.hatchType = hatchingType; + } + + @Deprecated + public PlayerEggThrowEvent(Player player, Egg egg, boolean hatching, byte numHatches, CreatureType hatchingType) { + this(player, egg, hatching, numHatches, hatchingType.toEntityType()); + } + + /** + * Gets the egg involved in this event. + * + * @return the egg involved in this event + */ + public Egg getEgg() { + return egg; + } + + /** + * Gets whether the egg is hatching or not. Will be what the server + * would've done without interaction. + * + * @return boolean Whether the egg is going to hatch or not + */ + public boolean isHatching() { + return hatching; + } + + /** + * Sets whether the egg will hatch or not. + * + * @param hatching true if you want the egg to hatch, false if you want it + * not to + */ + public void setHatching(boolean hatching) { + this.hatching = hatching; + } + + /** + * Get the type of the mob being hatched (EntityType.CHICKEN by default) + * + * @return The type of the mob being hatched by the egg + * @deprecated In favour of {@link #getHatchingType()}. + */ + @Deprecated + public CreatureType getHatchType() { + return CreatureType.fromEntityType(hatchType); + } + + /** + * Get the type of the mob being hatched (EntityType.CHICKEN by default) + * + * @return The type of the mob being hatched by the egg + */ + public EntityType getHatchingType() { + return hatchType; + } + + /** + * Change the type of mob being hatched by the egg + * + * @param hatchType The type of the mob being hatched by the egg + * @deprecated In favour of {@link #setHatchingType(EntityType)}. + */ + @Deprecated + public void setHatchType(CreatureType hatchType) { + this.hatchType = hatchType.toEntityType(); + } + + /** + * Change the type of mob being hatched by the egg + * + * @param hatchType The type of the mob being hatched by the egg + */ + public void setHatchingType(EntityType hatchType) { + if(!hatchType.isSpawnable()) throw new IllegalArgumentException("Can't spawn that entity type from an egg!"); + this.hatchType = hatchType; + } + + /** + * Get the number of mob hatches from the egg. By default the number will + * be the number the server would've done + *

    + *
  • 7/8 chance of being 0 + *
  • 31/256 ~= 1/8 chance to be 1 + *
  • 1/256 chance to be 4 + *
+ * + * @return The number of mobs going to be hatched by the egg + */ + public byte getNumHatches() { + return numHatches; + } + + /** + * Change the number of mobs coming out of the hatched egg + *

+ * The boolean hatching will override this number. Ie. If hatching = + * false, this number will not matter + * + * @param numHatches The number of mobs coming out of the egg + */ + public void setNumHatches(byte numHatches) { + this.numHatches = numHatches; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEvent.java new file mode 100644 index 0000000..0d4833f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerEvent.java @@ -0,0 +1,30 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; + +/** + * Represents a player related event + */ +public abstract class PlayerEvent extends Event { + protected Player player; + + public PlayerEvent(final Player who) { + player = who; + } + + PlayerEvent(final Player who, boolean async) { + super(async); + player = who; + + } + + /** + * Returns the player involved in this event + * + * @return Player who is involved in this event + */ + public final Player getPlayer() { + return player; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java new file mode 100644 index 0000000..f37491d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java @@ -0,0 +1,44 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a players experience changes naturally + */ +public class PlayerExpChangeEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private int exp; + + public PlayerExpChangeEvent(final Player player, final int expAmount) { + super(player); + exp = expAmount; + } + + /** + * Get the amount of experience the player will receive + * + * @return The amount of experience + */ + public int getAmount() { + return exp; + } + + /** + * Set the amount of experience the player will receive + * + * @param amount The amount of experience to set + */ + public void setAmount(int amount) { + exp = amount; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerFishEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerFishEvent.java new file mode 100644 index 0000000..5f1ecfe --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerFishEvent.java @@ -0,0 +1,138 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Fish; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; + +/** + * Thrown when a player is fishing + */ +public class PlayerFishEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Entity entity; + private boolean cancel = false; + private int exp; + private final State state; + private final Fish hookEntity; + + /** + * @deprecated replaced by {@link #PlayerFishEvent(Player, Entity, Fish, + * State)} to include the {@link Fish} hook entity. + * @param player the player fishing + * @param entity the caught entity + * @param state the state of fishing + */ + @Deprecated + public PlayerFishEvent(final Player player, final Entity entity, final State state) { + this(player, entity, null, state); + } + + public PlayerFishEvent(final Player player, final Entity entity, final Fish hookEntity, final State state) { + super(player); + this.entity = entity; + this.hookEntity = hookEntity; + this.state = state; + } + + /** + * Gets the entity caught by the player. + *

+ * If player has fished successfully, the result may be cast to {@link + * org.bukkit.entity.Item}. + * + * @return Entity caught by the player, Entity if fishing, and null if + * bobber has gotten stuck in the ground or nothing has been caught + */ + public Entity getCaught() { + return entity; + } + + /** + * Gets the fishing hook. + * + * @return Fish the entity representing the fishing hook/bobber. + */ + public Fish getHook() { + return hookEntity; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the amount of experience received when fishing. + *

+ * Note: This value has no default effect unless the event state is {@link + * State#CAUGHT_FISH}. + * + * @return the amount of experience to drop + */ + public int getExpToDrop() { + return exp; + } + + /** + * Sets the amount of experience received when fishing. + *

+ * Note: This value has no default effect unless the event state is {@link + * State#CAUGHT_FISH}. + * + * @param amount the amount of experience to drop + */ + public void setExpToDrop(int amount) { + exp = amount; + } + + /** + * Gets the state of the fishing + * + * @return A State detailing the state of the fishing + */ + public State getState() { + return state; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * An enum to specify the state of the fishing + */ + public enum State { + + /** + * When a player is fishing, ie casting the line out. + */ + FISHING, + /** + * When a player has successfully caught a fish and is reeling it in. + */ + CAUGHT_FISH, + /** + * When a player has successfully caught an entity + */ + CAUGHT_ENTITY, + /** + * When a bobber is stuck in the ground + */ + IN_GROUND, + /** + * When a player fails to catch anything while fishing usually due to + * poor aiming or timing + */ + FAILED_ATTEMPT, + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerGameModeChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerGameModeChangeEvent.java new file mode 100644 index 0000000..8c9afa8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerGameModeChangeEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.player; + +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when the GameMode of the player is changed. + */ +public class PlayerGameModeChangeEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final GameMode newGameMode; + + public PlayerGameModeChangeEvent(final Player player, final GameMode newGameMode) { + super(player); + this.newGameMode = newGameMode; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + /** + * Gets the GameMode the player is switched to. + * + * @return player's new GameMode + */ + public GameMode getNewGameMode() { + return newGameMode; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInitialSpawnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInitialSpawnEvent.java new file mode 100644 index 0000000..be82593 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInitialSpawnEvent.java @@ -0,0 +1,42 @@ +package org.bukkit.event.player; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +public class PlayerInitialSpawnEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private Location spawnLocation; + + public PlayerInitialSpawnEvent(final Player player, final Location spawnLocation) { + super(player); + this.spawnLocation = spawnLocation; + } + + /** + * Gets the current spawn location + * + * @return Location current spawn location + */ + public Location getSpawnLocation() { + return this.spawnLocation; + } + + /** + * Sets the new spawn location + * + * @param spawnLocation new location for the spawn + */ + public void setSpawnLocation(Location spawnLocation) { + this.spawnLocation = spawnLocation; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractAtEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractAtEntityEvent.java new file mode 100644 index 0000000..3293b11 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractAtEntityEvent.java @@ -0,0 +1,33 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.util.Vector; + +/** + * Represents an event that is called when a player right clicks an entity + * with a location on the entity the was clicked. + */ +public class PlayerInteractAtEntityEvent extends PlayerInteractEntityEvent { + private static final HandlerList handlers = new HandlerList(); + private final Vector position; + + public PlayerInteractAtEntityEvent(Player who, Entity clickedEntity, Vector position) { + super(who, clickedEntity); + this.position = position; + } + + public Vector getClickedPosition() { + return position.clone(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractEntityEvent.java new file mode 100644 index 0000000..935211d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractEntityEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Represents an event that is called when a player right clicks an entity. + */ +public class PlayerInteractEntityEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + protected Entity clickedEntity; + boolean cancelled = false; + + public PlayerInteractEntityEvent(final Player who, final Entity clickedEntity) { + super(who); + this.clickedEntity = clickedEntity; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + /** + * Gets the entity that was rightclicked by the player. + * + * @return entity right clicked by player + */ + public Entity getRightClicked() { + return this.clickedEntity; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractEvent.java new file mode 100644 index 0000000..b12382f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInteractEvent.java @@ -0,0 +1,190 @@ +package org.bukkit.event.player; + +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.block.Action; + +/** + * Called when a player interacts with an object or air. + *

+ * This event will fire as cancelled if the vanilla behavior + * is to do nothing (e.g interacting with air) + */ +public class PlayerInteractEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + protected ItemStack item; + protected Action action; + protected Block blockClicked; + protected BlockFace blockFace; + private Result useClickedBlock; + private Result useItemInHand; + + public PlayerInteractEvent(final Player who, final Action action, final ItemStack item, final Block clickedBlock, final BlockFace clickedFace) { + super(who); + this.action = action; + this.item = item; + this.blockClicked = clickedBlock; + this.blockFace = clickedFace; + + useItemInHand = Result.DEFAULT; + useClickedBlock = clickedBlock == null ? Result.DENY : Result.ALLOW; + } + + /** + * Returns the action type + * + * @return Action returns the type of interaction + */ + public Action getAction() { + return action; + } + + /** + * Gets the cancellation state of this event. Set to true if you want to + * prevent buckets from placing water and so forth + * + * @return boolean cancellation state + */ + public boolean isCancelled() { + return useInteractedBlock() == Result.DENY; + } + + /** + * Sets the cancellation state of this event. A canceled event will not be + * executed in the server, but will still pass to other plugins + *

+ * Canceling this event will prevent use of food (player won't lose the + * food item), prevent bows/snowballs/eggs from firing, etc. (player won't + * lose the ammo) + * + * @param cancel true if you wish to cancel this event + */ + public void setCancelled(boolean cancel) { + setUseInteractedBlock(cancel ? Result.DENY : useInteractedBlock() == Result.DENY ? Result.DEFAULT : useInteractedBlock()); + setUseItemInHand(cancel ? Result.DENY : useItemInHand() == Result.DENY ? Result.DEFAULT : useItemInHand()); + } + + /** + * Returns the item in hand represented by this event + * + * @return ItemStack the item used + */ + public ItemStack getItem() { + return this.item; + } + + /** + * Convenience method. Returns the material of the item represented by + * this event + * + * @return Material the material of the item used + */ + public Material getMaterial() { + if (!hasItem()) { + return Material.AIR; + } + + return item.getType(); + } + + /** + * Check if this event involved a block + * + * @return boolean true if it did + */ + public boolean hasBlock() { + return this.blockClicked != null; + } + + /** + * Check if this event involved an item + * + * @return boolean true if it did + */ + public boolean hasItem() { + return this.item != null; + } + + /** + * Convenience method to inform the user whether this was a block + * placement event. + * + * @return boolean true if the item in hand was a block + */ + public boolean isBlockInHand() { + if (!hasItem()) { + return false; + } + + return item.getType().isBlock(); + } + + /** + * Returns the clicked block + * + * @return Block returns the block clicked with this item. + */ + public Block getClickedBlock() { + return blockClicked; + } + + /** + * Returns the face of the block that was clicked + * + * @return BlockFace returns the face of the block that was clicked + */ + public BlockFace getBlockFace() { + return blockFace; + } + + /** + * This controls the action to take with the block (if any) that was + * clicked on. This event gets processed for all blocks, but most don't + * have a default action + * + * @return the action to take with the interacted block + */ + public Result useInteractedBlock() { + return useClickedBlock; + } + + /** + * @param useInteractedBlock the action to take with the interacted block + */ + public void setUseInteractedBlock(Result useInteractedBlock) { + this.useClickedBlock = useInteractedBlock; + } + + /** + * This controls the action to take with the item the player is holding. + * This includes both blocks and items (such as flint and steel or + * records). When this is set to default, it will be allowed if no action + * is taken on the interacted block. + * + * @return the action to take with the item in hand + */ + public Result useItemInHand() { + return useItemInHand; + } + + /** + * @param useItemInHand the action to take with the item in hand + */ + public void setUseItemInHand(Result useItemInHand) { + this.useItemInHand = useItemInHand; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInventoryEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInventoryEvent.java new file mode 100644 index 0000000..2ec69d7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerInventoryEvent.java @@ -0,0 +1,44 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.inventory.Inventory; + +/** + * Represents a player related inventory event; note that this event never + * actually did anything + * + * @deprecated Use {@link InventoryClickEvent} or {@link InventoryOpenEvent} + * instead, or one of the other inventory events in {@link + * org.bukkit.event.inventory}. + */ +@Deprecated +public class PlayerInventoryEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + protected Inventory inventory; + + public PlayerInventoryEvent(final Player player, final Inventory inventory) { + super(player); + this.inventory = inventory; + } + + /** + * Gets the Inventory involved in this event + * + * @return Inventory + */ + public Inventory getInventory() { + return inventory; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemBreakEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemBreakEvent.java new file mode 100644 index 0000000..176cd91 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemBreakEvent.java @@ -0,0 +1,39 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * Fired when a player's item breaks (such as a shovel or flint and steel). + *

+ * The item that's breaking will exist in the inventory with a stack size of + * 0. After the event, the item's durability will be reset to 0. + */ +public class PlayerItemBreakEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final ItemStack brokenItem; + + public PlayerItemBreakEvent(final Player player, final ItemStack brokenItem) { + super(player); + this.brokenItem = brokenItem; + } + + /** + * Gets the item that broke + * + * @return The broken item + */ + public ItemStack getBrokenItem() { + return brokenItem; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java new file mode 100644 index 0000000..9d68272 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java @@ -0,0 +1,75 @@ +package org.bukkit.event.player; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +/** + * This event will fire when a player is finishing consuming an item (food, + * potion, milk bucket). + *
+ * If the ItemStack is modified the server will use the effects of the new + * item and not remove the original one from the player's inventory. + *
+ * If the event is cancelled the effect will not be applied and the item will + * not be removed from the player's inventory. + */ +public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean isCancelled = false; + private ItemStack item; + // TODO: Add a changeable replacement item + + /** + * @param player the player consuming + * @param item the ItemStack being consumed + */ + public PlayerItemConsumeEvent(final Player player, final ItemStack item) { + super(player); + + this.item = item; + } + + /** + * Gets the item that is being consumed. Modifying the returned item will + * have no effect, you must use {@link + * #setItem(org.bukkit.inventory.ItemStack)} instead. + * + * @return an ItemStack for the item being consumed + */ + public ItemStack getItem() { + return item.clone(); + } + + /** + * Set the item being consumed + * + * @param item the item being consumed + */ + public void setItem(ItemStack item) { + if (item == null) { + this.item = new ItemStack(Material.AIR); + } else { + this.item = item; + } + } + + public boolean isCancelled() { + return this.isCancelled; + } + + public void setCancelled(boolean cancel) { + this.isCancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java new file mode 100644 index 0000000..38a72ab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java @@ -0,0 +1,54 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +public class PlayerItemDamageEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private final ItemStack item; + private int damage; + private boolean cancelled = false; + + public PlayerItemDamageEvent(Player player, ItemStack what, int damage) { + super(player); + this.item = what; + this.damage = damage; + } + + public ItemStack getItem() { + return item; + } + + /** + * Gets the amount of durability damage this item will be taking. + * + * @return durability change + */ + public int getDamage() { + return damage; + } + + public void setDamage(int damage) { + this.damage = damage; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemHeldEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemHeldEvent.java new file mode 100644 index 0000000..f0d055a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerItemHeldEvent.java @@ -0,0 +1,56 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Fired when a player changes their currently held item + */ +public class PlayerItemHeldEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private final int previous; + private final int current; + + public PlayerItemHeldEvent(final Player player, final int previous, final int current) { + super(player); + this.previous = previous; + this.current = current; + } + + /** + * Gets the previous held slot index + * + * @return Previous slot index + */ + public int getPreviousSlot() { + return previous; + } + + /** + * Gets the new held slot index + * + * @return New slot index + */ + public int getNewSlot() { + return current; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java new file mode 100644 index 0000000..e7481f9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerJoinEvent.java @@ -0,0 +1,44 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a player joins a server + */ +public class PlayerJoinEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private String joinMessage; + + public PlayerJoinEvent(final Player playerJoined, final String joinMessage) { + super(playerJoined); + this.joinMessage = joinMessage; + } + + /** + * Gets the join message to send to all online players + * + * @return string join message + */ + public String getJoinMessage() { + return joinMessage; + } + + /** + * Sets the join message to send to all online players + * + * @param joinMessage join message + */ + public void setJoinMessage(String joinMessage) { + this.joinMessage = joinMessage; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerKickEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerKickEvent.java new file mode 100644 index 0000000..39e81b6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerKickEvent.java @@ -0,0 +1,75 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a player gets kicked from the server + */ +public class PlayerKickEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private String leaveMessage; + private String kickReason; + private Boolean cancel; + + public PlayerKickEvent(final Player playerKicked, final String kickReason, final String leaveMessage) { + super(playerKicked); + this.kickReason = kickReason; + this.leaveMessage = leaveMessage; + this.cancel = false; + } + + /** + * Gets the reason why the player is getting kicked + * + * @return string kick reason + */ + public String getReason() { + return kickReason; + } + + /** + * Gets the leave message send to all online players + * + * @return string kick reason + */ + public String getLeaveMessage() { + return leaveMessage; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Sets the reason why the player is getting kicked + * + * @param kickReason kick reason + */ + public void setReason(String kickReason) { + this.kickReason = kickReason; + } + + /** + * Sets the leave message send to all online players + * + * @param leaveMessage leave message + */ + public void setLeaveMessage(String leaveMessage) { + this.leaveMessage = leaveMessage; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLevelChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLevelChangeEvent.java new file mode 100644 index 0000000..730a776 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLevelChangeEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a players level changes + */ +public class PlayerLevelChangeEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final int oldLevel; + private final int newLevel; + + public PlayerLevelChangeEvent(final Player player, final int oldLevel, final int newLevel) { + super(player); + this.oldLevel = oldLevel; + this.newLevel = newLevel; + } + + /** + * Gets the old level of the player + * + * @return The old level of the player + */ + public int getOldLevel() { + return oldLevel; + } + + /** + * Gets the new level of the player + * + * @return The new (current) level of the player + */ + public int getNewLevel() { + return newLevel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java new file mode 100644 index 0000000..3efd159 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLocaleChangeEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when the locale of the player is changed. + */ +public class PlayerLocaleChangeEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final String oldLocale; + private final String newLocale; + + public PlayerLocaleChangeEvent(final Player player, final String oldLocale, final String newLocale) { + super(player); + this.oldLocale = oldLocale; + this.newLocale = newLocale; + } + + /** + * Gets the locale the player switched from. + * + * @return player's old locale + */ + public String getOldLocale() { + return oldLocale; + } + + /** + * Gets the locale the player is changed to. + * + * @return player's new locale + */ + public String getNewLocale() { + return newLocale; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java new file mode 100644 index 0000000..4bc024f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java @@ -0,0 +1,213 @@ +package org.bukkit.event.player; + +import java.net.InetAddress; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Stores details for players attempting to log in + */ +public class PlayerLoginEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private final InetAddress address; + private final String hostname; + private Result result = Result.ALLOWED; + private String message = ""; + private final InetAddress realAddress; // Spigot + + /** + * @deprecated Address should be provided in other constructor + * @param player The {@link Player} for this event + */ + @Deprecated + public PlayerLoginEvent(final Player player) { + this(player, "", null); + } + + /** + * @deprecated Address should be provided in other constructor + * @param player The {@link Player} for this event + * @param hostname The hostname that was used to connect to the server + */ + @Deprecated + public PlayerLoginEvent(final Player player, final String hostname) { + this(player, hostname, null); + } + + /** + * This constructor defaults message to an empty string, and result to + * ALLOWED + * + * @param player The {@link Player} for this event + * @param hostname The hostname that was used to connect to the server + * @param address The address the player used to connect, provided for + * timing issues + */ + public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address, final InetAddress realAddress) { // Spigot + super(player); + this.hostname = hostname; + this.address = address; + // Spigot start + this.realAddress = realAddress; + } + + public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address) { + this(player, hostname, address, address); + // Spigot end + } + + /** + * @deprecated Address and hostname should be provided in other + * constructor + * @param player The {@link Player} for this event + * @param result The result status for this event + * @param message The message to be displayed if result denies login + */ + @Deprecated + public PlayerLoginEvent(final Player player, final Result result, final String message) { + this(player, "", null, result, message, null); // Spigot + } + + /** + * This constructor pre-configures the event with a result and message + * + * @param player The {@link Player} for this event + * @param hostname The hostname that was used to connect to the server + * @param address The address the player used to connect, provided for + * timing issues + * @param result The result status for this event + * @param message The message to be displayed if result denies login + */ + public PlayerLoginEvent(final Player player, String hostname, final InetAddress address, final Result result, final String message, final InetAddress realAddress) { // Spigot + this(player, hostname, address, realAddress); // Spigot + this.result = result; + this.message = message; + } + + // Spigot start + /** + * Gets the connection address of this player, regardless of whether it has been spoofed or not. + * + * @return the player's connection address + */ + public InetAddress getRealAddress() { + return realAddress; + } + // Spigot end + + /** + * Gets the current result of the login, as an enum + * + * @return Current Result of the login + */ + public Result getResult() { + return result; + } + + /** + * Sets the new result of the login, as an enum + * + * @param result New result to set + */ + public void setResult(final Result result) { + this.result = result; + } + + /** + * Gets the current kick message that will be used if getResult() != + * Result.ALLOWED + * + * @return Current kick message + */ + public String getKickMessage() { + return message; + } + + /** + * Sets the kick message to display if getResult() != Result.ALLOWED + * + * @param message New kick message + */ + public void setKickMessage(final String message) { + this.message = message; + } + + /** + * Gets the hostname that the player used to connect to the server, or + * blank if unknown + * + * @return The hostname + */ + public String getHostname() { + return hostname; + } + + /** + * Allows the player to log in + */ + public void allow() { + result = Result.ALLOWED; + message = ""; + } + + /** + * Disallows the player from logging in, with the given reason + * + * @param result New result for disallowing the player + * @param message Kick message to display to the user + */ + public void disallow(final Result result, final String message) { + this.result = result; + this.message = message; + } + + /** + * Gets the {@link InetAddress} for the Player associated with this event. + * This method is provided as a workaround for player.getAddress() + * returning null during PlayerLoginEvent. + * + * @return The address for this player. For legacy compatibility, this may + * be null. + */ + public InetAddress getAddress() { + return address; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Basic kick reasons for communicating to plugins + */ + public enum Result { + + /** + * The player is allowed to log in + */ + ALLOWED, + /** + * The player is not allowed to log in, due to the server being full + */ + KICK_FULL, + /** + * The player is not allowed to log in, due to them being banned + */ + KICK_BANNED, + /** + * The player is not allowed to log in, due to them not being on the + * white list + */ + KICK_WHITELIST, + /** + * The player is not allowed to log in, for reasons undefined + */ + KICK_OTHER + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java new file mode 100644 index 0000000..d56b7e4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java @@ -0,0 +1,103 @@ +package org.bukkit.event.player; + +import com.google.common.base.Preconditions; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Holds information for player movement events + */ +public class PlayerMoveEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private Location from; + private Location to; + + public PlayerMoveEvent(final Player player, final Location from, final Location to) { + super(player); + this.from = from; + this.to = to; + } + + /** + * Gets the cancellation state of this event. A cancelled event will not + * be executed in the server, but will still pass to other plugins + *

+ * If a move or teleport event is cancelled, the player will be moved or + * teleported back to the Location as defined by getFrom(). This will not + * fire an event + * + * @return true if this event is cancelled + */ + public boolean isCancelled() { + return cancel; + } + + /** + * Sets the cancellation state of this event. A cancelled event will not + * be executed in the server, but will still pass to other plugins + *

+ * If a move or teleport event is cancelled, the player will be moved or + * teleported back to the Location as defined by getFrom(). This will not + * fire an event + * + * @param cancel true if you wish to cancel this event + */ + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the location this player moved from + * + * @return Location the player moved from + */ + public Location getFrom() { + return from; + } + + /** + * Sets the location to mark as where the player moved from + * + * @param from New location to mark as the players previous location + */ + public void setFrom(Location from) { + validateLocation(from); + this.from = from; + } + + /** + * Gets the location this player moved to + * + * @return Location the player moved to + */ + public Location getTo() { + return to; + } + + /** + * Sets the location that this player will move to + * + * @param to New Location this player will move to + */ + public void setTo(Location to) { + validateLocation(to); + this.to = to; + } + + private void validateLocation(Location loc) { + Preconditions.checkArgument(loc != null, "Cannot use null location!"); + Preconditions.checkArgument(loc.getWorld() != null, "Cannot use null location with null world!"); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPickupItemEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPickupItemEvent.java new file mode 100644 index 0000000..dfba816 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPickupItemEvent.java @@ -0,0 +1,57 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Thrown when a player picks an item up from the ground + */ +public class PlayerPickupItemEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Item item; + private boolean cancel = false; + private final int remaining; + + public PlayerPickupItemEvent(final Player player, final Item item, final int remaining) { + super(player); + this.item = item; + this.remaining = remaining; + } + + /** + * Gets the Item picked up by the player. + * + * @return Item + */ + public Item getItem() { + return item; + } + + /** + * Gets the amount remaining on the ground, if any + * + * @return amount remaining on the ground + */ + public int getRemaining() { + return remaining; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPortalEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPortalEvent.java new file mode 100644 index 0000000..93752f7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPortalEvent.java @@ -0,0 +1,87 @@ +package org.bukkit.event.player; + +import org.bukkit.Location; +import org.bukkit.TravelAgent; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a player is about to teleport because it is in contact with a + * portal. + *

+ * For other entities see {@link org.bukkit.event.entity.EntityPortalEvent} + */ +public class PlayerPortalEvent extends PlayerTeleportEvent { + private static final HandlerList handlers = new HandlerList(); + protected boolean useTravelAgent = true; + protected TravelAgent travelAgent; + + public PlayerPortalEvent(final Player player, final Location from, final Location to, final TravelAgent pta) { + super(player, from, to); + this.travelAgent = pta; + } + + public PlayerPortalEvent(Player player, Location from, Location to, TravelAgent pta, TeleportCause cause) { + super(player, from, to, cause); + this.travelAgent = pta; + } + + /** + * Sets whether or not the Travel Agent will be used. + *

+ * If this is set to true, the TravelAgent will try to find a Portal at + * the {@link #getTo()} Location, and will try to create one if there is + * none. + *

+ * If this is set to false, the {@link #getPlayer()} will only be + * teleported to the {@link #getTo()} Location. + * + * @param useTravelAgent whether to use the Travel Agent + */ + public void useTravelAgent(boolean useTravelAgent) { + this.useTravelAgent = useTravelAgent; + } + + /** + * Gets whether or not the Travel Agent will be used. + *

+ * If this is set to true, the TravelAgent will try to find a Portal at + * the {@link #getTo()} Location, and will try to create one if there is + * none. + *

+ * If this is set to false, the {@link #getPlayer()}} will only be + * teleported to the {@link #getTo()} Location. + * + * @return whether to use the Travel Agent + */ + public boolean useTravelAgent() { + return useTravelAgent && travelAgent != null; + } + + /** + * Gets the Travel Agent used (or not) in this event. + * + * @return the Travel Agent used (or not) in this event + */ + public TravelAgent getPortalTravelAgent() { + return this.travelAgent; + } + + /** + * Sets the Travel Agent used (or not) in this event. + * + * @param travelAgent the Travel Agent used (or not) in this event + */ + public void setPortalTravelAgent(TravelAgent travelAgent) { + this.travelAgent = travelAgent; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java new file mode 100644 index 0000000..e8553f0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java @@ -0,0 +1,159 @@ +package org.bukkit.event.player; + +import java.net.InetAddress; +import java.util.UUID; + +import org.bukkit.Warning; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * Stores details for players attempting to log in + * + * @deprecated This event causes synchronization from the login thread; {@link + * AsyncPlayerPreLoginEvent} is preferred to keep the secondary threads + * asynchronous. + */ +@Deprecated +@Warning(reason="This event causes a login thread to synchronize with the main thread") +public class PlayerPreLoginEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + private Result result; + private String message; + private final String name; + private final InetAddress ipAddress; + private final UUID uniqueId; + + @Deprecated + public PlayerPreLoginEvent(final String name, final InetAddress ipAddress) { + this(name, ipAddress, null); + } + + public PlayerPreLoginEvent(final String name, final InetAddress ipAddress, final UUID uniqueId) { + this.result = Result.ALLOWED; + this.message = ""; + this.name = name; + this.ipAddress = ipAddress; + this.uniqueId = uniqueId; + } + + /** + * Gets the current result of the login, as an enum + * + * @return Current Result of the login + */ + public Result getResult() { + return result; + } + + /** + * Sets the new result of the login, as an enum + * + * @param result New result to set + */ + public void setResult(final Result result) { + this.result = result; + } + + /** + * Gets the current kick message that will be used if getResult() != + * Result.ALLOWED + * + * @return Current kick message + */ + public String getKickMessage() { + return message; + } + + /** + * Sets the kick message to display if getResult() != Result.ALLOWED + * + * @param message New kick message + */ + public void setKickMessage(final String message) { + this.message = message; + } + + /** + * Allows the player to log in + */ + public void allow() { + result = Result.ALLOWED; + message = ""; + } + + /** + * Disallows the player from logging in, with the given reason + * + * @param result New result for disallowing the player + * @param message Kick message to display to the user + */ + public void disallow(final Result result, final String message) { + this.result = result; + this.message = message; + } + + /** + * Gets the player's name. + * + * @return the player's name + */ + public String getName() { + return name; + } + + /** + * Gets the player IP address. + * + * @return The IP address + */ + public InetAddress getAddress() { + return ipAddress; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + /** + * Gets the player's unique ID. + * + * @return The unique ID + */ + public UUID getUniqueId() { + return uniqueId; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Basic kick reasons for communicating to plugins + */ + public enum Result { + + /** + * The player is allowed to log in + */ + ALLOWED, + /** + * The player is not allowed to log in, due to the server being full + */ + KICK_FULL, + /** + * The player is not allowed to log in, due to them being banned + */ + KICK_BANNED, + /** + * The player is not allowed to log in, due to them not being on the + * white list + */ + KICK_WHITELIST, + /** + * The player is not allowed to log in, for reasons undefined + */ + KICK_OTHER + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java new file mode 100644 index 0000000..5c8dc1b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerQuitEvent.java @@ -0,0 +1,44 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a player leaves a server + */ +public class PlayerQuitEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private String quitMessage; + + public PlayerQuitEvent(final Player who, final String quitMessage) { + super(who); + this.quitMessage = quitMessage; + } + + /** + * Gets the quit message to send to all online players + * + * @return string quit message + */ + public String getQuitMessage() { + return quitMessage; + } + + /** + * Sets the quit message to send to all online players + * + * @param quitMessage quit message + */ + public void setQuitMessage(String quitMessage) { + this.quitMessage = quitMessage; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerRegisterChannelEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerRegisterChannelEvent.java new file mode 100644 index 0000000..442ac7f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerRegisterChannelEvent.java @@ -0,0 +1,13 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; + +/** + * This is called immediately after a player registers for a plugin channel. + */ +public class PlayerRegisterChannelEvent extends PlayerChannelEvent { + + public PlayerRegisterChannelEvent(final Player player, final String channel) { + super(player, channel); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java new file mode 100644 index 0000000..a90d063 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java @@ -0,0 +1,76 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a player takes action on a resource pack request sent via + * {@link Player#setResourcePack(java.lang.String)}. + */ +public class PlayerResourcePackStatusEvent extends PlayerEvent { + + private static final HandlerList handlers = new HandlerList(); + private final String hash; // TacoSpigot + private final Status status; + + @Deprecated // TacoSpigot + public PlayerResourcePackStatusEvent(final Player who, Status resourcePackStatus) { + super(who); + this.hash = null; // TacoSpigot + this.status = resourcePackStatus; + } + + // TacoSpigot start + public PlayerResourcePackStatusEvent(final Player who, Status resourcePackStatus, String hash) { + super(who); + this.hash = hash; + this.status = resourcePackStatus; + } + + public String getHash() { + return this.hash; + } + // TacoSpigot end + + /** + * Gets the status of this pack. + * + * @return the current status + */ + public Status getStatus() { + return status; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * Status of the resource pack. + */ + public enum Status { + + /** + * The resource pack has been successfully downloaded and applied to the + * client. + */ + SUCCESSFULLY_LOADED, + /** + * The client refused to accept the resource pack. + */ + DECLINED, + /** + * The client accepted the pack, but download failed. + */ + FAILED_DOWNLOAD, + /** + * The client accepted the pack and is beginning a download of it. + */ + ACCEPTED; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerRespawnEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerRespawnEvent.java new file mode 100644 index 0000000..35900dd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerRespawnEvent.java @@ -0,0 +1,60 @@ +package org.bukkit.event.player; + +import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Called when a player respawns. + */ +public class PlayerRespawnEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private Location respawnLocation; + private final boolean isBedSpawn; + + public PlayerRespawnEvent(final Player respawnPlayer, final Location respawnLocation, final boolean isBedSpawn) { + super(respawnPlayer); + this.respawnLocation = respawnLocation; + this.isBedSpawn = isBedSpawn; + } + + /** + * Gets the current respawn location + * + * @return Location current respawn location + */ + public Location getRespawnLocation() { + return this.respawnLocation; + } + + /** + * Sets the new respawn location + * + * @param respawnLocation new location for the respawn + */ + public void setRespawnLocation(Location respawnLocation) { + Validate.notNull(respawnLocation, "Respawn location can not be null"); + Validate.notNull(respawnLocation.getWorld(), "Respawn world can not be null"); + + this.respawnLocation = respawnLocation; + } + + /** + * Gets whether the respawn location is the player's bed. + * + * @return true if the respawn location is the player's bed. + */ + public boolean isBedSpawn() { + return this.isBedSpawn; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java new file mode 100644 index 0000000..38afb3c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java @@ -0,0 +1,48 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a player shears an entity + */ +public class PlayerShearEntityEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel; + private final Entity what; + + public PlayerShearEntityEvent(final Player who, final Entity what) { + super(who); + this.cancel = false; + this.what = what; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the entity the player is shearing + * + * @return the entity the player is shearing + */ + public Entity getEntity() { + return what; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerStatisticIncrementEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerStatisticIncrementEvent.java new file mode 100644 index 0000000..3b64d70 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerStatisticIncrementEvent.java @@ -0,0 +1,116 @@ +package org.bukkit.event.player; + +import org.bukkit.Material; +import org.bukkit.Statistic; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a player statistic is incremented. + *

+ * This event is not called for {@link org.bukkit.Statistic#PLAY_ONE_TICK} or + * movement based statistics. + * + */ +public class PlayerStatisticIncrementEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + protected final Statistic statistic; + private final int initialValue; + private final int newValue; + private boolean isCancelled = false; + private final EntityType entityType; + private final Material material; + + public PlayerStatisticIncrementEvent(Player player, Statistic statistic, int initialValue, int newValue) { + super (player); + this.statistic = statistic; + this.initialValue = initialValue; + this.newValue = newValue; + this.entityType = null; + this.material = null; + } + + public PlayerStatisticIncrementEvent(Player player, Statistic statistic, int initialValue, int newValue, EntityType entityType) { + super (player); + this.statistic = statistic; + this.initialValue = initialValue; + this.newValue = newValue; + this.entityType = entityType; + this.material = null; + } + + public PlayerStatisticIncrementEvent(Player player, Statistic statistic, int initialValue, int newValue, Material material) { + super (player); + this.statistic = statistic; + this.initialValue = initialValue; + this.newValue = newValue; + this.entityType = null; + this.material = material; + } + + /** + * Gets the statistic that is being incremented. + * + * @return the incremented statistic + */ + public Statistic getStatistic() { + return statistic; + } + + /** + * Gets the previous value of the statistic. + * + * @return the previous value of the statistic + */ + public int getPreviousValue() { + return initialValue; + } + + /** + * Gets the new value of the statistic. + * + * @return the new value of the statistic + */ + public int getNewValue() { + return newValue; + } + + /** + * Gets the EntityType if {@link #getStatistic() getStatistic()} is an + * entity statistic otherwise returns null. + * + * @return the EntityType of the statistic + */ + public EntityType getEntityType() { + return entityType; + } + + /** + * Gets the Material if {@link #getStatistic() getStatistic()} is a block + * or item statistic otherwise returns null. + * + * @return the Material of the statistic + */ + public Material getMaterial() { + return material; + } + + public boolean isCancelled() { + return isCancelled; + } + + public void setCancelled(boolean cancel) { + this.isCancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerTeleportEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerTeleportEvent.java new file mode 100644 index 0000000..fa9c823 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerTeleportEvent.java @@ -0,0 +1,78 @@ +package org.bukkit.event.player; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; + +/** + * Holds information for player teleport events + */ +public class PlayerTeleportEvent extends PlayerMoveEvent { + private static final HandlerList handlers = new HandlerList(); + private TeleportCause cause = TeleportCause.UNKNOWN; + + public PlayerTeleportEvent(final Player player, final Location from, final Location to) { + super(player, from, to); + } + + public PlayerTeleportEvent(final Player player, final Location from, final Location to, final TeleportCause cause) { + this(player, from, to); + + this.cause = cause; + } + + /** + * Gets the cause of this teleportation event + * + * @return Cause of the event + */ + public TeleportCause getCause() { + return cause; + } + + public enum TeleportCause { + /** + * Indicates the teleporation was caused by a player throwing an Ender + * Pearl + */ + ENDER_PEARL, + /** + * Indicates the teleportation was caused by a player executing a + * command + */ + COMMAND, + /** + * Indicates the teleportation was caused by a plugin + */ + PLUGIN, + /** + * Indicates the teleportation was caused by a player entering a + * Nether portal + */ + NETHER_PORTAL, + /** + * Indicates the teleportation was caused by a player entering an End + * portal + */ + END_PORTAL, + /** + * Indicates the teleportation was caused by a player teleporting to a + * Entity/Player via the specatator menu + */ + SPECTATE, + /** + * Indicates the teleportation was caused by an event not covered by + * this enum + */ + UNKNOWN; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleFlightEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleFlightEvent.java new file mode 100644 index 0000000..1c5ec37 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleFlightEvent.java @@ -0,0 +1,45 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a player toggles their flying state + */ +public class PlayerToggleFlightEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final boolean isFlying; + private boolean cancel = false; + + public PlayerToggleFlightEvent(final Player player, final boolean isFlying) { + super(player); + this.isFlying = isFlying; + } + + /** + * Returns whether the player is trying to start or stop flying. + * + * @return flying state + */ + public boolean isFlying() { + return isFlying; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleSneakEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleSneakEvent.java new file mode 100644 index 0000000..667acad --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleSneakEvent.java @@ -0,0 +1,45 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a player toggles their sneaking state + */ +public class PlayerToggleSneakEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final boolean isSneaking; + private boolean cancel = false; + + public PlayerToggleSneakEvent(final Player player, final boolean isSneaking) { + super(player); + this.isSneaking = isSneaking; + } + + /** + * Returns whether the player is now sneaking or not. + * + * @return sneaking state + */ + public boolean isSneaking() { + return isSneaking; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleSprintEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleSprintEvent.java new file mode 100644 index 0000000..cf065e1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerToggleSprintEvent.java @@ -0,0 +1,45 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a player toggles their sprinting state + */ +public class PlayerToggleSprintEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final boolean isSprinting; + private boolean cancel = false; + + public PlayerToggleSprintEvent(final Player player, final boolean isSprinting) { + super(player); + this.isSprinting = isSprinting; + } + + /** + * Gets whether the player is now sprinting or not. + * + * @return sprinting state + */ + public boolean isSprinting() { + return isSprinting; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java new file mode 100644 index 0000000..f6aebef --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java @@ -0,0 +1,36 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.entity.EntityUnleashEvent; + +/** + * Called prior to an entity being unleashed due to a player's action. + */ +public class PlayerUnleashEntityEvent extends EntityUnleashEvent implements Cancellable { + private final Player player; + private boolean cancelled = false; + + public PlayerUnleashEntityEvent(Entity entity, Player player) { + super(entity, UnleashReason.PLAYER_UNLEASH); + this.player = player; + } + + /** + * Returns the player who is unleashing the entity. + * + * @return The player + */ + public Player getPlayer() { + return player; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerUnregisterChannelEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerUnregisterChannelEvent.java new file mode 100644 index 0000000..11c77e3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerUnregisterChannelEvent.java @@ -0,0 +1,13 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; + +/** + * This is called immediately after a player unregisters for a plugin channel. + */ +public class PlayerUnregisterChannelEvent extends PlayerChannelEvent { + + public PlayerUnregisterChannelEvent(final Player player, final String channel) { + super(player, channel); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerVelocityEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerVelocityEvent.java new file mode 100644 index 0000000..69d2fce --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/player/PlayerVelocityEvent.java @@ -0,0 +1,55 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.util.Vector; + +/** + * Called when the velocity of a player changes. + */ +public class PlayerVelocityEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private Vector velocity; + + public PlayerVelocityEvent(final Player player, final Vector velocity) { + super(player); + this.velocity = velocity; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the velocity vector that will be sent to the player + * + * @return Vector the player will get + */ + public Vector getVelocity() { + return velocity; + } + + /** + * Sets the velocity vector that will be sent to the player + * + * @param velocity The velocity vector that will be sent to the player + */ + public void setVelocity(Vector velocity) { + this.velocity = velocity; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/MapInitializeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/MapInitializeEvent.java new file mode 100644 index 0000000..8834489 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/MapInitializeEvent.java @@ -0,0 +1,34 @@ +package org.bukkit.event.server; + +import org.bukkit.event.HandlerList; +import org.bukkit.map.MapView; + +/** + * Called when a map is initialized. + */ +public class MapInitializeEvent extends ServerEvent { + private static final HandlerList handlers = new HandlerList(); + private final MapView mapView; + + public MapInitializeEvent(final MapView mapView) { + this.mapView = mapView; + } + + /** + * Gets the map initialized in this event. + * + * @return Map for this event + */ + public MapView getMap() { + return mapView; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginDisableEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginDisableEvent.java new file mode 100644 index 0000000..932c4fd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginDisableEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.server; + +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.Plugin; + +/** + * Called when a plugin is disabled. + */ +public class PluginDisableEvent extends PluginEvent { + private static final HandlerList handlers = new HandlerList(); + + public PluginDisableEvent(final Plugin plugin) { + super(plugin); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginEnableEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginEnableEvent.java new file mode 100644 index 0000000..865316d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginEnableEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.server; + +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.Plugin; + +/** + * Called when a plugin is enabled. + */ +public class PluginEnableEvent extends PluginEvent { + private static final HandlerList handlers = new HandlerList(); + + public PluginEnableEvent(final Plugin plugin) { + super(plugin); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginEvent.java new file mode 100644 index 0000000..1ad656d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/PluginEvent.java @@ -0,0 +1,23 @@ +package org.bukkit.event.server; + +import org.bukkit.plugin.Plugin; + +/** + * Used for plugin enable and disable events + */ +public abstract class PluginEvent extends ServerEvent { + private final Plugin plugin; + + public PluginEvent(final Plugin plugin) { + this.plugin = plugin; + } + + /** + * Gets the plugin involved in this event + * + * @return Plugin for this event + */ + public Plugin getPlugin() { + return plugin; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/RemoteServerCommandEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/RemoteServerCommandEvent.java new file mode 100644 index 0000000..2a49237 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/RemoteServerCommandEvent.java @@ -0,0 +1,25 @@ +package org.bukkit.event.server; + +import org.bukkit.command.CommandSender; +import org.bukkit.event.HandlerList; + +/** + * This event is called when a command is recieved over RCON. See the javadocs + * of {@link ServerCommandEvent} for more information. + */ +public class RemoteServerCommandEvent extends ServerCommandEvent { + private static final HandlerList handlers = new HandlerList(); + + public RemoteServerCommandEvent(final CommandSender sender, final String command) { + super(sender, command); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerCommandEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerCommandEvent.java new file mode 100644 index 0000000..10ea0f0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerCommandEvent.java @@ -0,0 +1,98 @@ +package org.bukkit.event.server; + +import org.bukkit.command.CommandSender; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * This event is called when a command is run from the server console. It is + * called early in the command handling process, and modifications in this + * event (via {@link #setCommand(String)}) will be shown in the behavior. + *

+ * Many plugins will have no use for this event, and you should + * attempt to avoid using it if it is not necessary. + *

+ * Some examples of valid uses for this event are: + *

    + *
  • Logging executed commands to a separate file + *
  • Variable substitution. For example, replacing ${ip:Steve} + * with the connection IP of the player named Steve, or simulating the + * @a and @p decorators used by Command Blocks + * for plugins that do not handle it. + *
  • Conditionally blocking commands belonging to other plugins. + *
  • Per-sender command aliases. For example, after the console runs the + * command /calias cr gamemode creative, the next time they + * run /cr, it gets replaced into + * /gamemode creative. (Global command aliases should be + * done by registering the alias.) + *
+ *

+ * Examples of incorrect uses are: + *

    + *
  • Using this event to run command logic + *
+ *

+ * If the event is cancelled, processing of the command will halt. + *

+ * The state of whether or not there is a slash (/) at the + * beginning of the message should be preserved. If a slash is added or + * removed, unexpected behavior may result. + */ +public class ServerCommandEvent extends ServerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private String command; + private final CommandSender sender; + private boolean cancel = false; + + public ServerCommandEvent(final CommandSender sender, final String command) { + this.command = command; + this.sender = sender; + } + + /** + * Gets the command that the user is attempting to execute from the + * console + * + * @return Command the user is attempting to execute + */ + public String getCommand() { + return command; + } + + /** + * Sets the command that the server will execute + * + * @param message New message that the server will execute + */ + public void setCommand(String message) { + this.command = message; + } + + /** + * Get the command sender. + * + * @return The sender + */ + public CommandSender getSender() { + return sender; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public boolean isCancelled() { + return cancel; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerEvent.java new file mode 100644 index 0000000..70416c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerEvent.java @@ -0,0 +1,19 @@ +package org.bukkit.event.server; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; + +/** + * Miscellaneous server events + */ +public abstract class ServerEvent extends Event { + // Paper start + public ServerEvent(boolean isAsync) { + super(isAsync); + } + + public ServerEvent() { + super(!Bukkit.isPrimaryThread()); + } + // Paper end +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerListPingEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerListPingEvent.java new file mode 100644 index 0000000..3c38d85 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServerListPingEvent.java @@ -0,0 +1,148 @@ +package org.bukkit.event.server; + +import java.net.InetAddress; +import java.util.Iterator; + +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.util.CachedServerIcon; + +/** + * Called when a server list ping is coming in. Displayed players can be + * checked and removed by {@link #iterator() iterating} over this event. + */ +public class ServerListPingEvent extends ServerEvent implements Iterable { + private static final int MAGIC_PLAYER_COUNT = Integer.MIN_VALUE; + private static final HandlerList handlers = new HandlerList(); + private final InetAddress address; + private String motd; + private final int numPlayers; + private int maxPlayers; + + public ServerListPingEvent(final InetAddress address, final String motd, final int numPlayers, final int maxPlayers) { + super(); // Paper - Is this event being fired async? + Validate.isTrue(numPlayers >= 0, "Cannot have negative number of players online", numPlayers); + this.address = address; + this.motd = motd; + this.numPlayers = numPlayers; + this.maxPlayers = maxPlayers; + } + + /** + * This constructor is intended for implementations that provide the + * {@link #iterator()} method, thus provided the {@link #getNumPlayers()} + * count. + * + * @param address the address of the pinger + * @param motd the message of the day + * @param maxPlayers the max number of players + */ + protected ServerListPingEvent(final InetAddress address, final String motd, final int maxPlayers) { + super(); // Paper - Is this event being fired async? + this.numPlayers = MAGIC_PLAYER_COUNT; + this.address = address; + this.motd = motd; + this.maxPlayers = maxPlayers; + } + + /** + * Get the address the ping is coming from. + * + * @return the address + */ + public InetAddress getAddress() { + return address; + } + + /** + * Get the message of the day message. + * + * @return the message of the day + */ + public String getMotd() { + return motd; + } + + /** + * Change the message of the day message. + * + * @param motd the message of the day + */ + public void setMotd(String motd) { + this.motd = motd; + } + + /** + * Get the number of players sent. + * + * @return the number of players + */ + public int getNumPlayers() { + int numPlayers = this.numPlayers; + if (numPlayers == MAGIC_PLAYER_COUNT) { + numPlayers = 0; + for (@SuppressWarnings("unused") final Player player : this) { + numPlayers++; + } + } + return numPlayers; + } + + /** + * Get the maximum number of players sent. + * + * @return the maximum number of players + */ + public int getMaxPlayers() { + return maxPlayers; + } + + /** + * Set the maximum number of players sent. + * + * @param maxPlayers the maximum number of player + */ + public void setMaxPlayers(int maxPlayers) { + this.maxPlayers = maxPlayers; + } + + /** + * Sets the server-icon sent to the client. + * + * @param icon the icon to send to the client + * @throws IllegalArgumentException if the {@link CachedServerIcon} is not + * created by the caller of this event; null may be accepted for some + * implementations + * @throws UnsupportedOperationException if the caller of this event does + * not support setting the server icon + */ + public void setServerIcon(CachedServerIcon icon) throws IllegalArgumentException, UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * {@inheritDoc} + *

+ * Calling the {@link Iterator#remove()} method will force that particular + * player to not be displayed on the player list, decrease the size + * returned by {@link #getNumPlayers()}, and will not be returned again by + * any new iterator. + * + * @throws UnsupportedOperationException if the caller of this event does + * not support removing players + */ + @Override + public Iterator iterator() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceEvent.java new file mode 100644 index 0000000..69bf872 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceEvent.java @@ -0,0 +1,19 @@ +package org.bukkit.event.server; + +import org.bukkit.plugin.RegisteredServiceProvider; + +/** + * An event relating to a registered service. This is called in a {@link + * org.bukkit.plugin.ServicesManager} + */ +public abstract class ServiceEvent extends ServerEvent { + private final RegisteredServiceProvider provider; + + public ServiceEvent(final RegisteredServiceProvider provider) { + this.provider = provider; + } + + public RegisteredServiceProvider getProvider() { + return provider; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceRegisterEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceRegisterEvent.java new file mode 100644 index 0000000..7dfadde --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceRegisterEvent.java @@ -0,0 +1,27 @@ +package org.bukkit.event.server; + +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.RegisteredServiceProvider; + +/** + * This event is called when a service is registered. + *

+ * Warning: The order in which register and unregister events are called + * should not be relied upon. + */ +public class ServiceRegisterEvent extends ServiceEvent { + private static final HandlerList handlers = new HandlerList(); + + public ServiceRegisterEvent(RegisteredServiceProvider registeredProvider) { + super(registeredProvider); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceUnregisterEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceUnregisterEvent.java new file mode 100644 index 0000000..db61d23 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/server/ServiceUnregisterEvent.java @@ -0,0 +1,27 @@ +package org.bukkit.event.server; + +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.RegisteredServiceProvider; + +/** + * This event is called when a service is unregistered. + *

+ * Warning: The order in which register and unregister events are called + * should not be relied upon. + */ +public class ServiceUnregisterEvent extends ServiceEvent { + private static final HandlerList handlers = new HandlerList(); + + public ServiceUnregisterEvent(RegisteredServiceProvider serviceProvider) { + super(serviceProvider); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java new file mode 100644 index 0000000..b643b57 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java @@ -0,0 +1,36 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.block.Block; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.HandlerList; + +/** + * Raised when a vehicle collides with a block. + */ +public class VehicleBlockCollisionEvent extends VehicleCollisionEvent { + private static final HandlerList handlers = new HandlerList(); + private final Block block; + + public VehicleBlockCollisionEvent(final Vehicle vehicle, final Block block) { + super(vehicle); + this.block = block; + } + + /** + * Gets the block the vehicle collided with + * + * @return the block the vehicle collided with + */ + public Block getBlock() { + return block; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleCollisionEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleCollisionEvent.java new file mode 100644 index 0000000..9dd0579 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleCollisionEvent.java @@ -0,0 +1,12 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.Vehicle; + +/** + * Raised when a vehicle collides. + */ +public abstract class VehicleCollisionEvent extends VehicleEvent { + public VehicleCollisionEvent(final Vehicle vehicle) { + super(vehicle); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleCreateEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleCreateEvent.java new file mode 100644 index 0000000..22eda72 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleCreateEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.Vehicle; +import org.bukkit.event.HandlerList; + +/** + * Raised when a vehicle is created. + */ +public class VehicleCreateEvent extends VehicleEvent { + private static final HandlerList handlers = new HandlerList(); + + public VehicleCreateEvent(final Vehicle vehicle) { + super(vehicle); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleDamageEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleDamageEvent.java new file mode 100644 index 0000000..c7b9c1a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleDamageEvent.java @@ -0,0 +1,96 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.util.NumberConversions; + +/** + * Raised when a vehicle receives damage. + */ +public class VehicleDamageEvent extends VehicleEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Entity attacker; + private double damage; + private boolean cancelled; + + @Deprecated + public VehicleDamageEvent(final Vehicle vehicle, final Entity attacker, final int damage) { + this(vehicle, attacker, (double) damage); + } + + public VehicleDamageEvent(final Vehicle vehicle, final Entity attacker, final double damage) { + super(vehicle); + this.attacker = attacker; + this.damage = damage; + } + + /** + * Gets the Entity that is attacking the vehicle + * + * @return the Entity that is attacking the vehicle + */ + public Entity getAttacker() { + return attacker; + } + + /** + * Gets the damage done to the vehicle + * + * @return the damage done to the vehicle + */ + public double getDamage() { + return damage; + } + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @return the damage + */ + @Deprecated + public int _INVALID_getDamage() { + return NumberConversions.ceil(getDamage()); + } + + /** + * Sets the damage done to the vehicle + * + * @param damage The damage + */ + public void setDamage(double damage) { + this.damage = damage; + } + + /** + * This method exists for legacy reasons to provide backwards + * compatibility. It will not exist at runtime and should not be used + * under any circumstances. + * + * @param damage the damage + */ + @Deprecated + public void _INVALID_setDamage(int damage) { + setDamage(damage); + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleDestroyEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleDestroyEvent.java new file mode 100644 index 0000000..f1176fd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleDestroyEvent.java @@ -0,0 +1,48 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Raised when a vehicle is destroyed, which could be caused by either a + * player or the environment. This is not raised if the boat is simply + * 'removed' due to other means. + */ +public class VehicleDestroyEvent extends VehicleEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Entity attacker; + private boolean cancelled; + + public VehicleDestroyEvent(final Vehicle vehicle, final Entity attacker) { + super(vehicle); + this.attacker = attacker; + } + + /** + * Gets the Entity that has destroyed the vehicle, potentially null + * + * @return the Entity that has destroyed the vehicle, potentially null + */ + public Entity getAttacker() { + return attacker; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEnterEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEnterEvent.java new file mode 100644 index 0000000..85c9b21 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEnterEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Raised when an entity enters a vehicle. + */ +public class VehicleEnterEvent extends VehicleEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Entity entered; + + public VehicleEnterEvent(final Vehicle vehicle, final Entity entered) { + super(vehicle); + this.entered = entered; + } + + /** + * Gets the Entity that entered the vehicle. + * + * @return the Entity that entered the vehicle + */ + public Entity getEntered() { + return entered; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEntityCollisionEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEntityCollisionEvent.java new file mode 100644 index 0000000..4d4d0e2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEntityCollisionEvent.java @@ -0,0 +1,59 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Raised when a vehicle collides with an entity. + */ +public class VehicleEntityCollisionEvent extends VehicleCollisionEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Entity entity; + private boolean cancelled = false; + private boolean cancelledPickup = false; + private boolean cancelledCollision = false; + + public VehicleEntityCollisionEvent(final Vehicle vehicle, final Entity entity) { + super(vehicle); + this.entity = entity; + } + + public Entity getEntity() { + return entity; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + public boolean isPickupCancelled() { + return cancelledPickup; + } + + public void setPickupCancelled(boolean cancel) { + cancelledPickup = cancel; + } + + public boolean isCollisionCancelled() { + return cancelledCollision; + } + + public void setCollisionCancelled(boolean cancel) { + cancelledCollision = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEvent.java new file mode 100644 index 0000000..b8255c0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.Vehicle; +import org.bukkit.event.Event; + +/** + * Represents a vehicle-related event. + */ +public abstract class VehicleEvent extends Event { + protected Vehicle vehicle; + + public VehicleEvent(final Vehicle vehicle) { + this.vehicle = vehicle; + } + + /** + * Get the vehicle. + * + * @return the vehicle + */ + public final Vehicle getVehicle() { + return vehicle; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleExitEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleExitEvent.java new file mode 100644 index 0000000..364451b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleExitEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Raised when a living entity exits a vehicle. + */ +public class VehicleExitEvent extends VehicleEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final LivingEntity exited; + + public VehicleExitEvent(final Vehicle vehicle, final LivingEntity exited) { + super(vehicle); + this.exited = exited; + } + + /** + * Get the living entity that exited the vehicle. + * + * @return The entity. + */ + public LivingEntity getExited() { + return exited; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java new file mode 100644 index 0000000..9a13e29 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java @@ -0,0 +1,49 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.Location; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.HandlerList; + +/** + * Raised when a vehicle moves. + */ +public class VehicleMoveEvent extends VehicleEvent { + private static final HandlerList handlers = new HandlerList(); + private final Location from; + private final Location to; + + public VehicleMoveEvent(final Vehicle vehicle, final Location from, final Location to) { + super(vehicle); + + this.from = from; + this.to = to; + } + + /** + * Get the previous position. + * + * @return Old position. + */ + public Location getFrom() { + return from; + } + + /** + * Get the next position. + * + * @return New position. + */ + public Location getTo() { + return to; + } + + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleUpdateEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleUpdateEvent.java new file mode 100644 index 0000000..eebfdb1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/vehicle/VehicleUpdateEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.vehicle; + +import org.bukkit.entity.Vehicle; +import org.bukkit.event.HandlerList; + +/** + * Called when a vehicle updates + */ +public class VehicleUpdateEvent extends VehicleEvent { + private static final HandlerList handlers = new HandlerList(); + + public VehicleUpdateEvent(final Vehicle vehicle) { + super(vehicle); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java new file mode 100644 index 0000000..66fd763 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/LightningStrikeEvent.java @@ -0,0 +1,46 @@ +package org.bukkit.event.weather; + +import org.bukkit.World; +import org.bukkit.entity.LightningStrike; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Stores data for lightning striking + */ +public class LightningStrikeEvent extends WeatherEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + private final LightningStrike bolt; + + public LightningStrikeEvent(final World world, final LightningStrike bolt) { + super(world); + this.bolt = bolt; + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + /** + * Gets the bolt which is striking the earth. + * + * @return lightning entity + */ + public LightningStrike getLightning() { + return bolt; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/ThunderChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/ThunderChangeEvent.java new file mode 100644 index 0000000..5e3716e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/ThunderChangeEvent.java @@ -0,0 +1,45 @@ +package org.bukkit.event.weather; + +import org.bukkit.World; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Stores data for thunder state changing in a world + */ +public class ThunderChangeEvent extends WeatherEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + private final boolean to; + + public ThunderChangeEvent(final World world, final boolean to) { + super(world); + this.to = to; + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + /** + * Gets the state of thunder that the world is being set to + * + * @return true if the weather is being set to thundering, false otherwise + */ + public boolean toThunderState() { + return to; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/WeatherChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/WeatherChangeEvent.java new file mode 100644 index 0000000..5d1234e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/WeatherChangeEvent.java @@ -0,0 +1,45 @@ +package org.bukkit.event.weather; + +import org.bukkit.World; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Stores data for weather changing in a world + */ +public class WeatherChangeEvent extends WeatherEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + private final boolean to; + + public WeatherChangeEvent(final World world, final boolean to) { + super(world); + this.to = to; + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + /** + * Gets the state of weather that the world is being set to + * + * @return true if the weather is being set to raining, false otherwise + */ + public boolean toWeatherState() { + return to; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/WeatherEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/WeatherEvent.java new file mode 100644 index 0000000..0cae9bc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/weather/WeatherEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.weather; + +import org.bukkit.World; +import org.bukkit.event.Event; + +/** + * Represents a Weather-related event + */ +public abstract class WeatherEvent extends Event { + protected World world; + + public WeatherEvent(final World where) { + world = where; + } + + /** + * Returns the World where this event is occurring + * + * @return World this event is occurring in + */ + public final World getWorld() { + return world; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkEvent.java new file mode 100644 index 0000000..4710d40 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.world; + +import org.bukkit.Chunk; + +/** + * Represents a Chunk related event + */ +public abstract class ChunkEvent extends WorldEvent { + protected Chunk chunk; + + protected ChunkEvent(final Chunk chunk) { + super(chunk.getWorld()); + this.chunk = chunk; + } + + /** + * Gets the chunk being loaded/unloaded + * + * @return Chunk that triggered this event + */ + public Chunk getChunk() { + return chunk; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkLoadEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkLoadEvent.java new file mode 100644 index 0000000..a45b1cd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkLoadEvent.java @@ -0,0 +1,37 @@ +package org.bukkit.event.world; + +import org.bukkit.Chunk; +import org.bukkit.event.HandlerList; + +/** + * Called when a chunk is loaded + */ +public class ChunkLoadEvent extends ChunkEvent { + private static final HandlerList handlers = new HandlerList(); + private final boolean newChunk; + + public ChunkLoadEvent(final Chunk chunk, final boolean newChunk) { + super(chunk); + this.newChunk = newChunk; + } + + /** + * Gets if this chunk was newly created or not. + *

+ * Note that if this chunk is new, it will not be populated at this time. + * + * @return true if the chunk is new, otherwise false + */ + public boolean isNewChunk() { + return newChunk; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkPopulateEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkPopulateEvent.java new file mode 100644 index 0000000..705d955 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkPopulateEvent.java @@ -0,0 +1,28 @@ +package org.bukkit.event.world; + +import org.bukkit.Chunk; +import org.bukkit.event.HandlerList; +import org.bukkit.generator.BlockPopulator; + +/** + * Thrown when a new chunk has finished being populated. + *

+ * If your intent is to populate the chunk using this event, please see {@link + * BlockPopulator} + */ +public class ChunkPopulateEvent extends ChunkEvent { + private static final HandlerList handlers = new HandlerList(); + + public ChunkPopulateEvent(final Chunk chunk) { + super(chunk); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkUnloadEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkUnloadEvent.java new file mode 100644 index 0000000..f59d091 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/ChunkUnloadEvent.java @@ -0,0 +1,34 @@ +package org.bukkit.event.world; + +import org.bukkit.Chunk; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a chunk is unloaded + */ +public class ChunkUnloadEvent extends ChunkEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + + public ChunkUnloadEvent(final Chunk chunk) { + super(chunk); + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/PortalCreateEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/PortalCreateEvent.java new file mode 100644 index 0000000..d83d7a9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/PortalCreateEvent.java @@ -0,0 +1,77 @@ +package org.bukkit.event.world; + +import org.bukkit.block.Block; +import org.bukkit.World; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * Called when a portal is created + */ +public class PortalCreateEvent extends WorldEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancel = false; + private final ArrayList blocks = new ArrayList(); + private CreateReason reason = CreateReason.FIRE; + + public PortalCreateEvent(final Collection blocks, final World world, CreateReason reason) { + super(world); + + this.blocks.addAll(blocks); + this.reason = reason; + } + + /** + * Gets an array list of all the blocks associated with the created portal + * + * @return array list of all the blocks associated with the created portal + */ + public ArrayList getBlocks() { + return this.blocks; + } + + public boolean isCancelled() { + return cancel; + } + + public void setCancelled(boolean cancel) { + this.cancel = cancel; + } + + /** + * Gets the reason for the portal's creation + * + * @return CreateReason for the portal's creation + */ + public CreateReason getReason() { + return reason; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + /** + * An enum to specify the various reasons for a portal's creation + */ + public enum CreateReason { + /** + * When a portal is created 'traditionally' due to a portal frame + * being set on fire. + */ + FIRE, + /** + * When a portal is created as a destination for an existing portal + * when using the custom PortalTravelAgent + */ + OBC_DESTINATION + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java new file mode 100644 index 0000000..e99c3c0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java @@ -0,0 +1,37 @@ +package org.bukkit.event.world; + +import org.bukkit.World; +import org.bukkit.Location; +import org.bukkit.event.HandlerList; + +/** + * An event that is called when a world's spawn changes. The world's previous + * spawn location is included. + */ +public class SpawnChangeEvent extends WorldEvent { + private static final HandlerList handlers = new HandlerList(); + private final Location previousLocation; + + public SpawnChangeEvent(final World world, final Location previousLocation) { + super(world); + this.previousLocation = previousLocation; + } + + /** + * Gets the previous spawn location + * + * @return Location that used to be spawn + */ + public Location getPreviousLocation() { + return previousLocation; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/StructureGrowEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/StructureGrowEvent.java new file mode 100644 index 0000000..62d300d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/StructureGrowEvent.java @@ -0,0 +1,96 @@ +package org.bukkit.event.world; + +import java.util.List; +import org.bukkit.Location; +import org.bukkit.TreeType; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Event that is called when an organic structure attempts to grow (Sapling {@literal ->} + * Tree), (Mushroom {@literal ->} Huge Mushroom), naturally or using bonemeal. + */ +public class StructureGrowEvent extends WorldEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled = false; + private final Location location; + private final TreeType species; + private final boolean bonemeal; + private final Player player; + private final List blocks; + + public StructureGrowEvent(final Location location, final TreeType species, final boolean bonemeal, final Player player, final List blocks) { + super(location.getWorld()); + this.location = location; + this.species = species; + this.bonemeal = bonemeal; + this.player = player; + this.blocks = blocks; + } + + /** + * Gets the location of the structure. + * + * @return Location of the structure + */ + public Location getLocation() { + return location; + } + + /** + * Gets the species type (birch, normal, pine, red mushroom, brown + * mushroom) + * + * @return Structure species + */ + public TreeType getSpecies() { + return species; + } + + /** + * Checks if structure was grown using bonemeal. + * + * @return True if the structure was grown using bonemeal. + */ + public boolean isFromBonemeal() { + return bonemeal; + } + + /** + * Gets the player that created the structure. + * + * @return Player that created the structure, null if was not created + * manually + */ + public Player getPlayer() { + return player; + } + + /** + * Gets an ArrayList of all blocks associated with the structure. + * + * @return ArrayList of all blocks associated with the structure. + */ + public List getBlocks() { + return blocks; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldEvent.java new file mode 100644 index 0000000..bd89b81 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.world; + +import org.bukkit.World; +import org.bukkit.event.Event; + +/** + * Represents events within a world + */ +public abstract class WorldEvent extends Event { + private final World world; + + public WorldEvent(final World world) { + this.world = world; + } + + /** + * Gets the world primarily involved with this event + * + * @return World which caused this event + */ + public World getWorld() { + return world; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldInitEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldInitEvent.java new file mode 100644 index 0000000..6bf13e0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldInitEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.world; + +import org.bukkit.World; +import org.bukkit.event.HandlerList; + +/** + * Called when a World is initializing + */ +public class WorldInitEvent extends WorldEvent { + private static final HandlerList handlers = new HandlerList(); + + public WorldInitEvent(final World world) { + super(world); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldLoadEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldLoadEvent.java new file mode 100644 index 0000000..c5545aa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldLoadEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.world; + +import org.bukkit.World; +import org.bukkit.event.HandlerList; + +/** + * Called when a World is loaded + */ +public class WorldLoadEvent extends WorldEvent { + private static final HandlerList handlers = new HandlerList(); + + public WorldLoadEvent(final World world) { + super(world); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldSaveEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldSaveEvent.java new file mode 100644 index 0000000..d46b413 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldSaveEvent.java @@ -0,0 +1,24 @@ +package org.bukkit.event.world; + +import org.bukkit.World; +import org.bukkit.event.HandlerList; + +/** + * Called when a World is saved. + */ +public class WorldSaveEvent extends WorldEvent { + private static final HandlerList handlers = new HandlerList(); + + public WorldSaveEvent(final World world) { + super(world); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldUnloadEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldUnloadEvent.java new file mode 100644 index 0000000..110544b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/event/world/WorldUnloadEvent.java @@ -0,0 +1,34 @@ +package org.bukkit.event.world; + +import org.bukkit.World; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/** + * Called when a World is unloaded + */ +public class WorldUnloadEvent extends WorldEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean isCancelled; + + public WorldUnloadEvent(final World world) { + super(world); + } + + public boolean isCancelled() { + return this.isCancelled; + } + + public void setCancelled(boolean cancel) { + this.isCancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/generator/BlockPopulator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/generator/BlockPopulator.java new file mode 100644 index 0000000..6a70bdb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/generator/BlockPopulator.java @@ -0,0 +1,29 @@ +package org.bukkit.generator; + +import java.util.Random; +import org.bukkit.Chunk; +import org.bukkit.World; + +/** + * A block populator is responsible for generating a small area of blocks. + *

+ * For example, generating glowstone inside the nether or generating dungeons + * full of treasure + */ +public abstract class BlockPopulator { + + /** + * Populates an area of blocks at or around the given chunk. + *

+ * The chunks on each side of the specified chunk must already exist; that + * is, there must be one north, east, south and west of the specified + * chunk. The "corner" chunks may not exist, in which scenario the + * populator should record any changes required for those chunks and + * perform the changes when they are ready. + * + * @param world The world to generate in + * @param random The random generator to use + * @param source The chunk to generate for + */ + public abstract void populate(World world, Random random, Chunk source); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/generator/ChunkGenerator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/generator/ChunkGenerator.java new file mode 100644 index 0000000..5137024 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/generator/ChunkGenerator.java @@ -0,0 +1,495 @@ +package org.bukkit.generator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; +import org.bukkit.material.MaterialData; + +/** + * A chunk generator is responsible for the initial shaping of an entire + * chunk. For example, the nether chunk generator should shape netherrack and + * soulsand + */ +public abstract class ChunkGenerator { + + /** + * Interface to biome section for chunk to be generated: initialized with + * default values for world type and seed. + *

+ * Custom generator is free to access and tailor values during + * generateBlockSections() or generateExtBlockSections(). + */ + public interface BiomeGrid { + + /** + * Get biome at x, z within chunk being generated + * + * @param x - 0-15 + * @param z - 0-15 + * @return Biome value + */ + Biome getBiome(int x, int z); + + /** + * Set biome at x, z within chunk being generated + * + * @param x - 0-15 + * @param z - 0-15 + * @param bio - Biome value + */ + void setBiome(int x, int z, Biome bio); + } + @Deprecated + /** + * Shapes the chunk for the given coordinates. + *

+ * This method should return a byte[32768] in the following format: + *

+     * for (int x = 0; x < 16; x++) {
+     *     for (int z = 0; z < 16; z++) {
+     *         for (int y = 0; y < 128; y++) {
+     *             // result[(x * 16 + z) * 128 + y] = ??;
+     *         }
+     *     }
+     * }
+     * 
+ *

+ * Note that this method should never attempt to get the Chunk at + * the passed coordinates, as doing so may cause an infinite loop + *

+ * Note this deprecated method will only be called when both + * generateExtBlockSections() and generateBlockSections() are + * unimplemented and return null. + * + * @param world The world this chunk will be used for + * @param random The random generator to use + * @param x The X-coordinate of the chunk + * @param z The Z-coordinate of the chunk + * @return byte[] containing the types for each block created by this + * generator + */ + public byte[] generate(World world, Random random, int x, int z) { + throw new UnsupportedOperationException("Custom generator is missing required methods: generate(), generateBlockSections() and generateExtBlockSections()"); + } + + /** + * Shapes the chunk for the given coordinates, with extended block IDs + * supported (0-4095). + *

+ * As of 1.2, chunks are represented by a vertical array of chunk + * sections, each of which is 16 x 16 x 16 blocks. If a section is empty + * (all zero), the section does not need to be supplied, reducing memory + * usage. + *

+ * This method must return a short[][] array in the following format: + *

+     *     short[][] result = new short[world-height / 16][];
+     * 
+ * Each section {@code (sectionID = (Y>>4))} that has blocks needs to be allocated + * space for the 4096 blocks in that section: + *
+     *     result[sectionID] = new short[4096];
+     * 
+ * while sections that are not populated can be left null. + *

+ * Setting a block at X, Y, Z within the chunk can be done with the + * following mapping function: + *

+     *    void setBlock(short[][] result, int x, int y, int z, short blkid) {
+     *        {@code if (result[y >> 4] == null) {}
+     *            {@code result[y >> 4] = new short[4096];}
+     *        }
+     *        {@code result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = blkid;}
+     *    }
+     * 
+ * while reading a block ID can be done with the following mapping + * function: + *
+     *    short getBlock(short[][] result, int x, int y, int z) {
+     *        {@code if (result[y >> 4] == null) {}
+     *            return (short)0;
+     *        }
+     *        {@code return result[y >> 4][((y & 0xF) << 8) | (z << 4) | x];}
+     *    }
+     * 
+ * while sections that are not populated can be left null. + *

+ * Setting a block at X, Y, Z within the chunk can be done with the + * following mapping function: + *

+     *    void setBlock(short[][] result, int x, int y, int z, short blkid) {
+     *        {@code if (result[y >> 4) == null) {}
+     *            {@code result[y >> 4] = new short[4096];}
+     *        }
+     *        {@code result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = blkid;}
+     *    }
+     * 
+ * while reading a block ID can be done with the following mapping + * function: + *
+     *    short getBlock(short[][] result, int x, int y, int z) {
+     *        {@code if (result[y >> 4) == null) {}
+     *            return (short)0;
+     *        }
+     *        {@code return result[y >> 4][((y & 0xF) << 8) | (z << 4) | x];}
+     *    }
+     * 
+ *

+ * Note that this method should never attempt to get the Chunk at + * the passed coordinates, as doing so may cause an infinite loop + *

+ * Note generators that do not return block IDs above 255 should not + * implement this method, or should have it return null (which will result + * in the generateBlockSections() method being called). + * + * @param world The world this chunk will be used for + * @param random The random generator to use + * @param x The X-coordinate of the chunk + * @param z The Z-coordinate of the chunk + * @param biomes Proposed biome values for chunk - can be updated by + * generator + * @return short[][] containing the types for each block created by this + * generator + * @deprecated Magic value + */ + @Deprecated + public short[][] generateExtBlockSections(World world, Random random, int x, int z, BiomeGrid biomes) { + return null; // Default - returns null, which drives call to generateBlockSections() + } + + /** + * Shapes the chunk for the given coordinates. + *

+ * As of 1.2, chunks are represented by a vertical array of chunk + * sections, each of which is 16 x 16 x 16 blocks. If a section is empty + * (all zero), the section does not need to be supplied, reducing memory + * usage. + *

+ * This method must return a byte[][] array in the following format: + *

+     *     byte[][] result = new byte[world-height / 16][];
+     * 
+ * Each section {@code (sectionID = (Y>>4))} that has blocks needs to be allocated + * space for the 4096 blocks in that section: + *
+     *     result[sectionID] = new byte[4096];
+     * 
+ * while sections that are not populated can be left null. + *

+ * Setting a block at X, Y, Z within the chunk can be done with the + * following mapping function: + *

+     *    void setBlock(byte[][] result, int x, int y, int z, byte blkid) {
+     *        {@code if (result[y >> 4) == null) {}
+     *            {@code result[y >> 4] = new byte[4096];}
+     *        }
+     *        {@code result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = blkid;}
+     *    }
+     * 
+ * while reading a block ID can be done with the following mapping + * function: + *
+     *    byte getBlock(byte[][] result, int x, int y, int z) {
+     *        {@code if (result[y >> 4) == null) {}
+     *            return (byte)0;
+     *        }
+     *        {@code return result[y >> 4][((y & 0xF) << 8) | (z << 4) | x];}
+     *    }
+     * 
+ * + * Note that this method should never attempt to get the Chunk at + * the passed coordinates, as doing so may cause an infinite loop + * + * @param world The world this chunk will be used for + * @param random The random generator to use + * @param x The X-coordinate of the chunk + * @param z The Z-coordinate of the chunk + * @param biomes Proposed biome values for chunk - can be updated by + * generator + * @return short[][] containing the types for each block created by this + * generator + * @deprecated Magic value + */ + @Deprecated + public byte[][] generateBlockSections(World world, Random random, int x, int z, BiomeGrid biomes) { + return null; // Default - returns null, which drives call to generate() + } + + /** + * Shapes the chunk for the given coordinates. + * + * This method must return a ChunkData. + *

+ * Notes: + *

+ * This method should never attempt to get the Chunk at + * the passed coordinates, as doing so may cause an infinite loop + *

+ * This method should never modify a ChunkData after it has + * been returned. + *

+ * This method must return a ChunkData returned by {@link ChunkGenerator#createChunkData(org.bukkit.World)} + * + * @param world The world this chunk will be used for + * @param random The random generator to use + * @param x The X-coordinate of the chunk + * @param z The Z-coordinate of the chunk + * @param biome Proposed biome values for chunk - can be updated by + * generator + * @return ChunkData containing the types for each block created by this + * generator + */ + public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) { + return null; // Default - returns null, which drives call to generateExtBlockSections() + } + + /** + * Create a ChunkData for a world. + * @param world the world the ChunkData is for + * @return a new ChunkData for world + */ + protected final ChunkData createChunkData(World world) { + return Bukkit.getServer().createChunkData(world); + } + + /** + * Tests if the specified location is valid for a natural spawn position + * + * @param world The world we're testing on + * @param x X-coordinate of the block to test + * @param z Z-coordinate of the block to test + * @return true if the location is valid, otherwise false + */ + public boolean canSpawn(World world, int x, int z) { + Block highest = world.getBlockAt(x, world.getHighestBlockYAt(x, z), z); + + switch (world.getEnvironment()) { + case NETHER: + return true; + case THE_END: + return highest.getType() != Material.AIR && highest.getType() != Material.WATER && highest.getType() != Material.LAVA; + case NORMAL: + default: + return highest.getType() == Material.SAND || highest.getType() == Material.GRAVEL; + } + } + + /** + * Gets a list of default {@link BlockPopulator}s to apply to a given + * world + * + * @param world World to apply to + * @return List containing any amount of BlockPopulators + */ + public List getDefaultPopulators(World world) { + return new ArrayList(); + } + + /** + * Gets a fixed spawn location to use for a given world. + *

+ * A null value is returned if a world should not use a fixed spawn point, + * and will instead attempt to find one randomly. + * + * @param world The world to locate a spawn point for + * @param random Random generator to use in the calculation + * @return Location containing a new spawn point, otherwise null + */ + public Location getFixedSpawnLocation(World world, Random random) { + return null; + } + + /** + * Data for a Chunk. + */ + public static interface ChunkData { + /** + * Get the maximum height for the chunk. + * + * Setting blocks at or above this height will do nothing. + * + * @return the maximum height + */ + public int getMaxHeight(); + + /** + * Set the block at x,y,z in the chunk data to material. + * + * Note: setting blocks outside the chunk's bounds does nothing. + * + * @param x the x location in the chunk from 0-15 inclusive + * @param y the y location in the chunk from 0 (inclusive) - maxHeight (exclusive) + * @param z the z location in the chunk from 0-15 inclusive + * @param material the type to set the block to + */ + public void setBlock(int x, int y, int z, Material material); + + /** + * Set the block at x,y,z in the chunk data to material. + * + * Setting blocks outside the chunk's bounds does nothing. + * + * @param x the x location in the chunk from 0-15 inclusive + * @param y the y location in the chunk from 0 (inclusive) - maxHeight (exclusive) + * @param z the z location in the chunk from 0-15 inclusive + * @param material the type to set the block to + */ + public void setBlock(int x, int y, int z, MaterialData material); + + /** + * Set a region of this chunk from xMin, yMin, zMin (inclusive) + * to xMax, yMax, zMax (exclusive) to material. + * + * Setting blocks outside the chunk's bounds does nothing. + * + * @param xMin minimum x location (inclusive) in the chunk to set + * @param yMin minimum y location (inclusive) in the chunk to set + * @param zMin minimum z location (inclusive) in the chunk to set + * @param xMax maximum x location (exclusive) in the chunk to set + * @param yMax maximum y location (exclusive) in the chunk to set + * @param zMax maximum z location (exclusive) in the chunk to set + * @param material the type to set the blocks to + */ + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, Material material); + + /** + * Set a region of this chunk from xMin, yMin, zMin (inclusive) + * to xMax, yMax, zMax (exclusive) to material. + * + * Setting blocks outside the chunk's bounds does nothing. + * + * @param xMin minimum x location (inclusive) in the chunk to set + * @param yMin minimum y location (inclusive) in the chunk to set + * @param zMin minimum z location (inclusive) in the chunk to set + * @param xMax maximum x location (exclusive) in the chunk to set + * @param yMax maximum y location (exclusive) in the chunk to set + * @param zMax maximum z location (exclusive) in the chunk to set + * @param material the type to set the blocks to + */ + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, MaterialData material); + + /** + * Get the type of the block at x, y, z. + * + * Getting blocks outside the chunk's bounds returns air. + * + * @param x the x location in the chunk from 0-15 inclusive + * @param y the y location in the chunk from 0 (inclusive) - maxHeight (exclusive) + * @param z the z location in the chunk from 0-15 inclusive + * @return the type of the block or Material.AIR if x, y or z are outside the chunk's bounds + */ + public Material getType(int x, int y, int z); + + /** + * Get the type and data of the block at x, y ,z. + * + * Getting blocks outside the chunk's bounds returns air. + * + * @param x the x location in the chunk from 0-15 inclusive + * @param y the y location in the chunk from 0 (inclusive) - maxHeight (exclusive) + * @param z the z location in the chunk from 0-15 inclusive + * @return the type and data of the block or the MaterialData for air if x, y or z are outside the chunk's bounds + */ + public MaterialData getTypeAndData(int x, int y, int z); + + /** + * Set a region of this chunk from xMin, yMin, zMin (inclusive) + * to xMax, yMax, zMax (exclusive) to block id. + * + * Setting blocks outside the chunk's bounds does nothing. + * + * @param xMin minimum x location (inclusive) in the chunk to set + * @param yMin minimum y location (inclusive) in the chunk to set + * @param zMin minimum z location (inclusive) in the chunk to set + * @param xMax maximum x location (exclusive) in the chunk to set + * @param yMax maximum y location (exclusive) in the chunk to set + * @param zMax maximum z location (exclusive) in the chunk to set + * @param blockId the block id to set the blocks to + * @deprecated Uses magic values. + */ + @Deprecated + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId); + + /** + * Set a region of this chunk from xMin, yMin, zMin (inclusive) + * to xMax, yMax, zMax (exclusive) to block id and data. + * + * Setting blocks outside the chunk's bounds does nothing. + * + * @param xMin minimum x location (inclusive) in the chunk to set + * @param yMin minimum y location (inclusive) in the chunk to set + * @param zMin minimum z location (inclusive) in the chunk to set + * @param xMax maximum x location (exclusive) in the chunk to set + * @param yMax maximum y location (exclusive) in the chunk to set + * @param zMax maximum z location (exclusive) in the chunk to set + * @param blockId the block id to set the blocks to + * @param data the block data to set the blocks to + * @deprecated Uses magic values. + */ + @Deprecated + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId, int data); + + /** + * Set the block at x,y,z in the chunk data to blockId. + * + * Setting blocks outside the chunk's bounds does nothing. + * + * @param x the x location in the chunk from 0-15 inclusive + * @param y the y location in the chunk from 0 (inclusive) - maxHeight (exclusive) + * @param z the z location in the chunk from 0-15 inclusive + * @param blockId the blockId to set the block to + * @deprecated Uses magic values + */ + @Deprecated + public void setBlock(int x, int y, int z, int blockId); + + /** + * Set the block at x,y,z in the chunk data to blockId. + * + * Setting blocks outside the chunk's bounds does nothing. + * + * @param x the x location in the chunk from 0-15 inclusive + * @param y the y location in the chunk from 0 (inclusive) - maxHeight (exclusive) + * @param z the z location in the chunk from 0-15 inclusive + * @param blockId the blockId to set the block to + * @param data the block data to set the block to + * @deprecated Uses magic values + */ + @Deprecated + public void setBlock(int x, int y, int z, int blockId, byte data); + + /** + * Get the blockId at x,y,z in the chunk data. + * + * Getting blocks outside the chunk's bounds returns 0. + * + * @param x the x location in the chunk from 0-15 inclusive + * @param y the y location in the chunk from 0 (inclusive) - maxHeight (exclusive) + * @param z the z location in the chunk from 0-15 inclusive + * @return the block id or 0 if x, y or z are outside the chunk's bounds + * @deprecated Uses magic values + */ + @Deprecated + public int getTypeId(int x, int y, int z); + + /** + * Get the block data at x,y,z in the chunk data. + * + * Getting blocks outside the chunk's bounds returns 0. + * + * @param x the x location in the chunk from 0-15 inclusive + * @param y the y location in the chunk from 0 (inclusive) - maxHeight (exclusive) + * @param z the z location in the chunk from 0-15 inclusive + * @return the block data value or air if x, y or z are outside the chunk's bounds + * @deprecated Uses magic values + */ + @Deprecated + public byte getData(int x, int y, int z); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/GenericCommandHelpTopic.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/GenericCommandHelpTopic.java new file mode 100644 index 0000000..3e85e77 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/GenericCommandHelpTopic.java @@ -0,0 +1,80 @@ +package org.bukkit.help; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.apache.commons.lang.StringUtils; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.command.defaults.VanillaCommand; +import org.bukkit.help.HelpTopic; + +/** + * Lacking an alternative, the help system will create instances of + * GenericCommandHelpTopic for each command in the server's CommandMap. You + * can use this class as a base class for custom help topics, or as an example + * for how to write your own. + */ +public class GenericCommandHelpTopic extends HelpTopic { + + protected Command command; + + public GenericCommandHelpTopic(Command command) { + this.command = command; + + if (command.getLabel().startsWith("/")) { + name = command.getLabel(); + } else { + name = "/" + command.getLabel(); + } + + // The short text is the first line of the description + int i = command.getDescription().indexOf("\n"); + if (i > 1) { + shortText = command.getDescription().substring(0, i - 1); + } else { + shortText = command.getDescription(); + } + + // Build full text + StringBuffer sb = new StringBuffer(); + + sb.append(ChatColor.GOLD); + sb.append("Description: "); + sb.append(ChatColor.WHITE); + sb.append(command.getDescription()); + + sb.append("\n"); + + sb.append(ChatColor.GOLD); + sb.append("Usage: "); + sb.append(ChatColor.WHITE); + sb.append(command.getUsage().replace("", name.substring(1))); + + if (command.getAliases().size() > 0) { + sb.append("\n"); + sb.append(ChatColor.GOLD); + sb.append("Aliases: "); + sb.append(ChatColor.WHITE); + sb.append(ChatColor.WHITE + StringUtils.join(command.getAliases(), ", ")); + } + fullText = sb.toString(); + } + + public boolean canSee(CommandSender sender) { + if (!command.isRegistered() && !(command instanceof VanillaCommand)) { + // Unregistered commands should not show up in the help (ignore VanillaCommands) + return false; + } + + if (sender instanceof ConsoleCommandSender) { + return true; + } + + if (amendedPermission != null) { + return sender.hasPermission(amendedPermission); + } else { + return command.testPermissionSilent(sender); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpMap.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpMap.java new file mode 100644 index 0000000..43017c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpMap.java @@ -0,0 +1,79 @@ +package org.bukkit.help; + +import java.util.Collection; +import java.util.List; + +/** + * The HelpMap tracks all help topics registered in a Bukkit server. When the + * server starts up or is reloaded, help is processed and topics are added in + * the following order: + * + *

    + *
  1. General topics are loaded from the help.yml + *
  2. Plugins load and optionally call {@code addTopic()} + *
  3. Registered plugin commands are processed by {@link HelpTopicFactory} + * objects to create topics + *
  4. Topic contents are amended as directed in help.yml + *
+ */ +public interface HelpMap { + /** + * Returns a help topic for a given topic name. + * + * @param topicName The help topic name to look up. + * @return A {@link HelpTopic} object matching the topic name or null if + * none can be found. + */ + public HelpTopic getHelpTopic(String topicName); + + /** + * Returns a collection of all the registered help topics. + * + * @return All the registered help topics. + */ + public Collection getHelpTopics(); + + /** + * Adds a topic to the server's help index. + * + * @param topic The new help topic to add. + */ + public void addTopic(HelpTopic topic); + + /** + * Clears out the contents of the help index. Normally called during + * server reload. + */ + public void clear(); + + /** + * Associates a {@link HelpTopicFactory} object with given command base + * class. Plugins typically call this method during {@code onLoad()}. Once + * registered, the custom HelpTopicFactory will be used to create a custom + * {@link HelpTopic} for all commands deriving from the {@code + * commandClass} base class, or all commands deriving from {@link + * org.bukkit.command.PluginCommand} who's executor derives from {@code + * commandClass} base class. + * + * @param commandClass The class for which the custom HelpTopicFactory + * applies. Must derive from either {@link org.bukkit.command.Command} + * or {@link org.bukkit.command.CommandExecutor}. + * @param factory The {@link HelpTopicFactory} implementation to associate + * with the {@code commandClass}. + * @throws IllegalArgumentException Thrown if {@code commandClass} does + * not derive from a legal base class. + */ + public void registerHelpTopicFactory(Class commandClass, HelpTopicFactory factory); + + /** + * Gets the list of plugins the server administrator has chosen to exclude + * from the help index. Plugin authors who choose to directly extend + * {@link org.bukkit.command.Command} instead of {@link + * org.bukkit.command.PluginCommand} will need to check this collection in + * their {@link HelpTopicFactory} implementations to ensure they meet the + * server administrator's expectations. + * + * @return A list of plugins that should be excluded from the help index. + */ + public List getIgnoredPlugins(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopic.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopic.java new file mode 100644 index 0000000..a2ba5f5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopic.java @@ -0,0 +1,121 @@ +package org.bukkit.help; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * HelpTopic implementations are displayed to the user when the user uses the + * /help command. + *

+ * Custom implementations of this class can work at two levels. A simple + * implementation only needs to set the value of {@code name}, {@code + * shortText}, and {@code fullText} in the constructor. This base class will + * take care of the rest. + *

+ * Complex implementations can be created by overriding the behavior of all + * the methods in this class. + */ +public abstract class HelpTopic { + protected String name; + protected String shortText; + protected String fullText; + protected String amendedPermission; + + /** + * Determines if a {@link Player} is allowed to see this help topic. + *

+ * HelpTopic implementations should take server administrator wishes into + * account as set by the {@link HelpTopic#amendCanSee(String)} function. + * + * @param player The Player in question. + * @return True of the Player can see this help topic, false otherwise. + */ + public abstract boolean canSee(CommandSender player); + + /** + * Allows the server administrator to override the permission required to + * see a help topic. + *

+ * HelpTopic implementations should take this into account when + * determining topic visibility on the {@link + * HelpTopic#canSee(org.bukkit.command.CommandSender)} function. + * + * @param amendedPermission The permission node the server administrator + * wishes to apply to this topic. + */ + public void amendCanSee(String amendedPermission) { + this.amendedPermission = amendedPermission; + } + + /** + * Returns the name of this help topic. + * + * @return The topic name. + */ + public String getName() { + return name; + } + + /** + * Returns a brief description that will be displayed in the topic index. + * + * @return A brief topic description. + */ + public String getShortText() { + return shortText; + } + + /** + * Returns the full description of this help topic that is displayed when + * the user requests this topic's details. + *

+ * The result will be paginated to properly fit the user's client. + * + * @param forWho The player or console requesting the full text. Useful + * for further security trimming the command's full text based on + * sub-permissions in custom implementations. + * + * @return A full topic description. + */ + public String getFullText(CommandSender forWho) { + return fullText; + } + + /** + * Allows the server admin (or another plugin) to add or replace the + * contents of a help topic. + *

+ * A null in either parameter will leave that part of the topic unchanged. + * In either amending parameter, the string {@literal } is replaced + * with the existing contents in the help topic. Use this to append or + * prepend additional content into an automatically generated help topic. + * + * @param amendedShortText The new topic short text to use, or null to + * leave alone. + * @param amendedFullText The new topic full text to use, or null to leave + * alone. + */ + public void amendTopic(String amendedShortText, String amendedFullText) { + shortText = applyAmendment(shortText, amendedShortText); + fullText = applyAmendment(fullText, amendedFullText); + } + + /** + * Developers implementing their own custom HelpTopic implementations can + * use this utility method to ensure their implementations comply with the + * expected behavior of the {@link HelpTopic#amendTopic(String, String)} + * method. + * + * @param baseText The existing text of the help topic. + * @param amendment The amending text from the amendTopic() method. + * @return The application of the amending text to the existing text, + * according to the expected rules of amendTopic(). + */ + protected String applyAmendment(String baseText, String amendment) { + if (amendment == null) { + return baseText; + } else { + return amendment.replaceAll("", baseText); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopicComparator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopicComparator.java new file mode 100644 index 0000000..3e43eb3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopicComparator.java @@ -0,0 +1,48 @@ +package org.bukkit.help; + +import org.bukkit.help.HelpTopic; + +import java.util.Comparator; + +/** + * Used to impose a custom total ordering on help topics. + *

+ * All topics are listed in alphabetic order, but topics that start with a + * slash come after topics that don't. + */ +public class HelpTopicComparator implements Comparator { + + // Singleton implementations + private static final TopicNameComparator tnc = new TopicNameComparator(); + public static TopicNameComparator topicNameComparatorInstance() { + return tnc; + } + + private static final HelpTopicComparator htc = new HelpTopicComparator(); + public static HelpTopicComparator helpTopicComparatorInstance() { + return htc; + } + + private HelpTopicComparator() {} + + public int compare(HelpTopic lhs, HelpTopic rhs) { + return tnc.compare(lhs.getName(), rhs.getName()); + } + + public static class TopicNameComparator implements Comparator { + private TopicNameComparator(){} + + public int compare(String lhs, String rhs) { + boolean lhsStartSlash = lhs.startsWith("/"); + boolean rhsStartSlash = rhs.startsWith("/"); + + if (lhsStartSlash && !rhsStartSlash) { + return 1; + } else if (!lhsStartSlash && rhsStartSlash) { + return -1; + } else { + return lhs.compareToIgnoreCase(rhs); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopicFactory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopicFactory.java new file mode 100644 index 0000000..87d3697 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/HelpTopicFactory.java @@ -0,0 +1,42 @@ +package org.bukkit.help; + +import org.bukkit.command.Command; + +/** + * A HelpTopicFactory is used to create custom {@link HelpTopic} objects from + * commands that inherit from a common base class or have executors that + * inherit from a common base class. You can use a custom HelpTopic to change + * the way all the commands in your plugin display in the help. If your plugin + * implements a complex permissions system, a custom help topic may also be + * appropriate. + *

+ * To automatically bind your plugin's commands to your custom HelpTopic + * implementation, first make sure all your commands or executors derive from + * a custom base class (it doesn't have to do anything). Next implement a + * custom HelpTopicFactory that accepts your custom command base class and + * instantiates an instance of your custom HelpTopic from it. Finally, + * register your HelpTopicFactory against your command base class using the + * {@link HelpMap#registerHelpTopicFactory(Class, HelpTopicFactory)} method. + *

+ * As the help system iterates over all registered commands to make help + * topics, it first checks to see if there is a HelpTopicFactory registered + * for the command's base class. If so, the factory is used to make a help + * topic rather than a generic help topic. If no factory is found for the + * command's base class and the command derives from {@link + * org.bukkit.command.PluginCommand}, then the type of the command's executor + * is inspected looking for a registered HelpTopicFactory. Finally, if no + * factory is found, a generic help topic is created for the command. + * + * @param The base class for your custom commands. + */ +public interface HelpTopicFactory { + /** + * This method accepts a command deriving from a custom command base class + * and constructs a custom HelpTopic for it. + * + * @param command The custom command to build a help topic for. + * @return A new custom help topic or {@code null} to intentionally NOT + * create a topic. + */ + public HelpTopic createTopic(TCommand command); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/IndexHelpTopic.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/IndexHelpTopic.java new file mode 100644 index 0000000..c474031 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/help/IndexHelpTopic.java @@ -0,0 +1,112 @@ +package org.bukkit.help; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.bukkit.util.ChatPaginator; + +import java.util.Collection; + +/** + * This help topic generates a list of other help topics. This class is useful + * for adding your own index help topics. To enforce a particular order, use a + * sorted collection. + *

+ * If a preamble is provided to the constructor, that text will be displayed + * before the first item in the index. + */ +public class IndexHelpTopic extends HelpTopic { + + protected String permission; + protected String preamble; + protected Collection allTopics; + + public IndexHelpTopic(String name, String shortText, String permission, Collection topics) { + this(name, shortText, permission, topics, null); + } + + public IndexHelpTopic(String name, String shortText, String permission, Collection topics, String preamble) { + this.name = name; + this.shortText = shortText; + this.permission = permission; + this.preamble = preamble; + setTopicsCollection(topics); + } + + /** + * Sets the contents of the internal allTopics collection. + * + * @param topics The topics to set. + */ + protected void setTopicsCollection(Collection topics) { + this.allTopics = topics; + } + + public boolean canSee(CommandSender sender) { + if (sender instanceof ConsoleCommandSender) { + return true; + } + if (permission == null) { + return true; + } + return sender.hasPermission(permission); + } + + @Override + public void amendCanSee(String amendedPermission) { + permission = amendedPermission; + } + + public String getFullText(CommandSender sender) { + StringBuilder sb = new StringBuilder(); + + if (preamble != null) { + sb.append(buildPreamble(sender)); + sb.append("\n"); + } + + for (HelpTopic topic : allTopics) { + if (topic.canSee(sender)) { + String lineStr = buildIndexLine(sender, topic).replace("\n", ". "); + if (sender instanceof Player && lineStr.length() > ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH) { + sb.append(lineStr.substring(0, ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH - 3)); + sb.append("..."); + } else { + sb.append(lineStr); + } + sb.append("\n"); + } + } + return sb.toString(); + } + + /** + * Builds the topic preamble. Override this method to change how the index + * preamble looks. + * + * @param sender The command sender requesting the preamble. + * @return The topic preamble. + */ + protected String buildPreamble(CommandSender sender) { + return ChatColor.GRAY + preamble; + } + + /** + * Builds individual lines in the index topic. Override this method to + * change how index lines are rendered. + * + * @param sender The command sender requesting the index line. + * @param topic The topic to render into an index line. + * @return The rendered index line. + */ + protected String buildIndexLine(CommandSender sender, HelpTopic topic) { + StringBuilder line = new StringBuilder(); + line.append(ChatColor.GOLD); + line.append(topic.getName()); + line.append(": "); + line.append(ChatColor.WHITE); + line.append(topic.getShortText()); + return line.toString(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/AnvilInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/AnvilInventory.java new file mode 100644 index 0000000..70fae71 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/AnvilInventory.java @@ -0,0 +1,7 @@ +package org.bukkit.inventory; + +/** + * Interface to the inventory of an Anvil. + */ +public interface AnvilInventory extends Inventory { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/BeaconInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/BeaconInventory.java new file mode 100644 index 0000000..2f8769e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/BeaconInventory.java @@ -0,0 +1,21 @@ +package org.bukkit.inventory; + +/** + * Interface to the inventory of a Beacon. + */ +public interface BeaconInventory extends Inventory { + + /** + * Set the item powering the beacon. + * + * @param item The new item + */ + void setItem(ItemStack item); + + /** + * Get the item powering the beacon. + * + * @return The current item. + */ + ItemStack getItem(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/BrewerInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/BrewerInventory.java new file mode 100644 index 0000000..9cc31c9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/BrewerInventory.java @@ -0,0 +1,25 @@ +package org.bukkit.inventory; + +import org.bukkit.block.BrewingStand; + +/** + * Interface to the inventory of a Brewing Stand. + */ +public interface BrewerInventory extends Inventory { + + /** + * Get the current ingredient for brewing. + * + * @return The ingredient. + */ + ItemStack getIngredient(); + + /** + * Set the current ingredient for brewing. + * + * @param ingredient The ingredient + */ + void setIngredient(ItemStack ingredient); + + BrewingStand getHolder(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/CraftingInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/CraftingInventory.java new file mode 100644 index 0000000..f71533c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/CraftingInventory.java @@ -0,0 +1,45 @@ +package org.bukkit.inventory; + +/** + * Interface to the crafting inventories + */ +public interface CraftingInventory extends Inventory { + + /** + * Check what item is in the result slot of this crafting inventory. + * + * @return The result item. + */ + ItemStack getResult(); + + /** + * Get the contents of the crafting matrix. + * + * @return The contents. + */ + ItemStack[] getMatrix(); + + /** + * Set the item in the result slot of the crafting inventory. + * + * @param newResult The new result item. + */ + void setResult(ItemStack newResult); + + /** + * Replace the contents of the crafting matrix + * + * @param contents The new contents. + * @throws IllegalArgumentException if the length of contents is greater + * than the size of the crafting matrix. + */ + void setMatrix(ItemStack[] contents); + + /** + * Get the current recipe formed on the crafting inventory, if any. + * + * @return The recipe, or null if the current contents don't match any + * recipe. + */ + Recipe getRecipe(); +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/DoubleChestInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/DoubleChestInventory.java new file mode 100644 index 0000000..c03ad53 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/DoubleChestInventory.java @@ -0,0 +1,25 @@ +package org.bukkit.inventory; + +import org.bukkit.block.DoubleChest; + +/** + * Interface to the inventory of a Double Chest. + */ +public interface DoubleChestInventory extends Inventory { + + /** + * Get the left half of this double chest. + * + * @return The left side inventory + */ + Inventory getLeftSide(); + + /** + * Get the right side of this double chest. + * + * @return The right side inventory + */ + Inventory getRightSide(); + + DoubleChest getHolder(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EnchantingInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EnchantingInventory.java new file mode 100644 index 0000000..6551a16 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EnchantingInventory.java @@ -0,0 +1,35 @@ +package org.bukkit.inventory; + +/** + * Interface to the inventory of an Enchantment Table. + */ +public interface EnchantingInventory extends Inventory { + + /** + * Set the item being enchanted. + * + * @param item The new item + */ + void setItem(ItemStack item); + + /** + * Get the item being enchanted. + * + * @return The current item. + */ + ItemStack getItem(); + + /** + * Set the secondary item being used for the enchant. + * + * @param item The new item + */ + void setSecondary(ItemStack item); + + /** + * Get the secondary item being used for the enchant. + * + * @return The second item + */ + ItemStack getSecondary(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EntityEquipment.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EntityEquipment.java new file mode 100644 index 0000000..24dfd20 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EntityEquipment.java @@ -0,0 +1,236 @@ +package org.bukkit.inventory; + +import org.bukkit.entity.Entity; + +/** + * An interface to a creatures inventory + */ +public interface EntityEquipment { + + /** + * Gets a copy of the item the entity is currently holding + * + * @return the currently held item + */ + ItemStack getItemInHand(); + + /** + * Sets the item the entity is holding + * + * @param stack The item to put into the entities hand + */ + void setItemInHand(ItemStack stack); + + /** + * Gets a copy of the helmet currently being worn by the entity + * + * @return The helmet being worn + */ + ItemStack getHelmet(); + + /** + * Sets the helmet worn by the entity + * + * @param helmet The helmet to put on the entity + */ + void setHelmet(ItemStack helmet); + + /** + * Gets a copy of the chest plate currently being worn by the entity + * + * @return The chest plate being worn + */ + ItemStack getChestplate(); + + /** + * Sets the chest plate worn by the entity + * + * @param chestplate The chest plate to put on the entity + */ + void setChestplate(ItemStack chestplate); + + /** + * Gets a copy of the leggings currently being worn by the entity + * + * @return The leggings being worn + */ + ItemStack getLeggings(); + + /** + * Sets the leggings worn by the entity + * + * @param leggings The leggings to put on the entity + */ + void setLeggings(ItemStack leggings); + + /** + * Gets a copy of the boots currently being worn by the entity + * + * @return The boots being worn + */ + ItemStack getBoots(); + + /** + * Sets the boots worn by the entity + * + * @param boots The boots to put on the entity + */ + void setBoots(ItemStack boots); + + /** + * Gets a copy of all worn armor + * + * @return The array of worn armor + */ + ItemStack[] getArmorContents(); + + /** + * Sets the entities armor to the provided array of ItemStacks + * + * @param items The items to set the armor as + */ + void setArmorContents(ItemStack[] items); + + /** + * Clears the entity of all armor and held items + */ + void clear(); + + /** + * Gets the chance of the currently held item being dropped upon this + * creature's death. + * + *

    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @return chance of the currently held item being dropped (1 for players) + */ + float getItemInHandDropChance(); + + /** + * Sets the chance of the item this creature is currently holding being + * dropped upon this creature's death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @param chance the chance of the currently held item being dropped + * @throws UnsupportedOperationException when called on players + */ + void setItemInHandDropChance(float chance); + + /** + * Gets the chance of the helmet being dropped upon this creature's death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @return the chance of the helmet being dropped (1 for players) + */ + float getHelmetDropChance(); + + /** + * Sets the chance of the helmet being dropped upon this creature's death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @param chance of the helmet being dropped + * @throws UnsupportedOperationException when called on players + */ + void setHelmetDropChance(float chance); + + /** + * Gets the chance of the chest plate being dropped upon this creature's + * death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @return the chance of the chest plate being dropped (1 for players) + */ + float getChestplateDropChance(); + + /** + * Sets the chance of the chest plate being dropped upon this creature's + * death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @param chance of the chest plate being dropped + * @throws UnsupportedOperationException when called on players + */ + void setChestplateDropChance(float chance); + + /** + * Gets the chance of the leggings being dropped upon this creature's + * death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @return the chance of the leggings being dropped (1 for players) + */ + float getLeggingsDropChance(); + + /** + * Sets the chance of the leggings being dropped upon this creature's + * death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @param chance chance of the leggings being dropped + * @throws UnsupportedOperationException when called on players + */ + void setLeggingsDropChance(float chance); + + /** + * Gets the chance of the boots being dropped upon this creature's death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @return the chance of the boots being dropped (1 for players) + */ + float getBootsDropChance(); + + /** + * Sets the chance of the boots being dropped upon this creature's death. + * + *
    + *
  • A drop chance of 0F will never drop + *
  • A drop chance of 1F will always drop + *
+ * + * @param chance of the boots being dropped + * @throws UnsupportedOperationException when called on players + */ + void setBootsDropChance(float chance); + + /** + * Get the entity this EntityEquipment belongs to + * + * @return the entity this EntityEquipment belongs to + */ + Entity getHolder(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EquipmentSlot.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EquipmentSlot.java new file mode 100644 index 0000000..0b2eb98 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/EquipmentSlot.java @@ -0,0 +1,10 @@ +package org.bukkit.inventory; + +public enum EquipmentSlot { + + HAND, + FEET, + LEGS, + CHEST, + HEAD +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/FurnaceInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/FurnaceInventory.java new file mode 100644 index 0000000..93b41d3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/FurnaceInventory.java @@ -0,0 +1,53 @@ +package org.bukkit.inventory; + +import org.bukkit.block.Furnace; + +/** + * Interface to the inventory of a Furnace. + */ +public interface FurnaceInventory extends Inventory { + + /** + * Get the current item in the result slot. + * + * @return The item + */ + ItemStack getResult(); + + /** + * Get the current fuel. + * + * @return The item + */ + ItemStack getFuel(); + + /** + * Get the item currently smelting. + * + * @return The item + */ + ItemStack getSmelting(); + + /** + * Set the current fuel. + * + * @param stack The item + */ + void setFuel(ItemStack stack); + + /** + * Set the current item in the result slot. + * + * @param stack The item + */ + void setResult(ItemStack stack); + + /** + * Set the item currently smelting. + * + * @param stack The item + */ + void setSmelting(ItemStack stack); + + Furnace getHolder(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/FurnaceRecipe.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/FurnaceRecipe.java new file mode 100644 index 0000000..8075323 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/FurnaceRecipe.java @@ -0,0 +1,100 @@ +package org.bukkit.inventory; + +import org.bukkit.Material; +import org.bukkit.material.MaterialData; + +/** + * Represents a smelting recipe. + */ +public class FurnaceRecipe implements Recipe { + private ItemStack output; + private ItemStack ingredient; + + /** + * Create a furnace recipe to craft the specified ItemStack. + * + * @param result The item you want the recipe to create. + * @param source The input material. + */ + public FurnaceRecipe(ItemStack result, Material source) { + this(result, source, 0); + } + + /** + * Create a furnace recipe to craft the specified ItemStack. + * + * @param result The item you want the recipe to create. + * @param source The input material. + */ + public FurnaceRecipe(ItemStack result, MaterialData source) { + this(result, source.getItemType(), source.getData()); + } + + /** + * Create a furnace recipe to craft the specified ItemStack. + * + * @param result The item you want the recipe to create. + * @param source The input material. + * @param data The data value. (Note: This is currently ignored by the + * CraftBukkit server.) + * @deprecated Magic value + */ + @Deprecated + public FurnaceRecipe(ItemStack result, Material source, int data) { + this.output = new ItemStack(result); + this.ingredient = new ItemStack(source, 1, (short) data); + } + + /** + * Sets the input of this furnace recipe. + * + * @param input The input material. + * @return The changed recipe, so you can chain calls. + */ + public FurnaceRecipe setInput(MaterialData input) { + return setInput(input.getItemType(), input.getData()); + } + + /** + * Sets the input of this furnace recipe. + * + * @param input The input material. + * @return The changed recipe, so you can chain calls. + */ + public FurnaceRecipe setInput(Material input) { + return setInput(input, 0); + } + + /** + * Sets the input of this furnace recipe. + * + * @param input The input material. + * @param data The data value. (Note: This is currently ignored by the + * CraftBukkit server.) + * @return The changed recipe, so you can chain calls. + * @deprecated Magic value + */ + @Deprecated + public FurnaceRecipe setInput(Material input, int data) { + this.ingredient = new ItemStack(input, 1, (short) data); + return this; + } + + /** + * Get the input material. + * + * @return The input material. + */ + public ItemStack getInput() { + return this.ingredient.clone(); + } + + /** + * Get the result of this recipe. + * + * @return The resulting stack. + */ + public ItemStack getResult() { + return output.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/HorseInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/HorseInventory.java new file mode 100644 index 0000000..a71efb8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/HorseInventory.java @@ -0,0 +1,35 @@ +package org.bukkit.inventory; + +/** + * An interface to the inventory of a Horse. + */ +public interface HorseInventory extends Inventory { + + /** + * Gets the item in the horse's saddle slot. + * + * @return the saddle item + */ + ItemStack getSaddle(); + + /** + * Gets the item in the horse's armor slot. + * + * @return the armor item + */ + ItemStack getArmor(); + + /** + * Sets the item in the horse's saddle slot. + * + * @param stack the new item + */ + void setSaddle(ItemStack stack); + + /** + * Sets the item in the horse's armor slot. + * + * @param stack the new item + */ + void setArmor(ItemStack stack); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/Inventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/Inventory.java new file mode 100644 index 0000000..da5d83e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/Inventory.java @@ -0,0 +1,381 @@ +package org.bukkit.inventory; + +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; + +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; + +/** + * Interface to the various inventories. Behavior relating to {@link + * Material#AIR} is unspecified. + */ +public interface Inventory extends Iterable { + + /** + * Returns the size of the inventory + * + * @return The size of the inventory + */ + public int getSize(); + + /** + * Returns the maximum stack size for an ItemStack in this inventory. + * + * @return The maximum size for an ItemStack in this inventory. + */ + public int getMaxStackSize(); + + /** + * This method allows you to change the maximum stack size for an + * inventory. + *

+ * Caveats: + *

    + *
  • Not all inventories respect this value. + *
  • Stacks larger than 127 may be clipped when the world is saved. + *
  • This value is not guaranteed to be preserved; be sure to set it + * before every time you want to set a slot over the max stack size. + *
  • Stacks larger than the default max size for this type of inventory + * may not display correctly in the client. + *
+ * + * @param size The new maximum stack size for items in this inventory. + */ + public void setMaxStackSize(int size); + + /** + * Returns the name of the inventory + * + * @return The String with the name of the inventory + */ + public String getName(); + + /** + * Returns the ItemStack found in the slot at the given index + * + * @param index The index of the Slot's ItemStack to return + * @return The ItemStack in the slot + */ + public ItemStack getItem(int index); + + /** + * Stores the ItemStack at the given index of the inventory. + * + * @param index The index where to put the ItemStack + * @param item The ItemStack to set + */ + public void setItem(int index, ItemStack item); + + /** + * Stores the given ItemStacks in the inventory. This will try to fill + * existing stacks and empty slots as well as it can. + *

+ * The returned HashMap contains what it couldn't store, where the key is + * the index of the parameter, and the value is the ItemStack at that + * index of the varargs parameter. If all items are stored, it will return + * an empty HashMap. + *

+ * If you pass in ItemStacks which exceed the maximum stack size for the + * Material, first they will be added to partial stacks where + * Material.getMaxStackSize() is not exceeded, up to + * Material.getMaxStackSize(). When there are no partial stacks left + * stacks will be split on Inventory.getMaxStackSize() allowing you to + * exceed the maximum stack size for that material. + * + * @param items The ItemStacks to add + * @return A HashMap containing items that didn't fit. + * @throws IllegalArgumentException if items or any element in it is null + */ + public HashMap addItem(ItemStack... items) throws IllegalArgumentException; + + /** + * Removes the given ItemStacks from the inventory. + *

+ * It will try to remove 'as much as possible' from the types and amounts + * you give as arguments. + *

+ * The returned HashMap contains what it couldn't remove, where the key is + * the index of the parameter, and the value is the ItemStack at that + * index of the varargs parameter. If all the given ItemStacks are + * removed, it will return an empty HashMap. + * + * @param items The ItemStacks to remove + * @return A HashMap containing items that couldn't be removed. + * @throws IllegalArgumentException if items is null + */ + public HashMap removeItem(ItemStack... items) throws IllegalArgumentException; + + /** + * Returns all ItemStacks from the inventory + * + * @return An array of ItemStacks from the inventory. + */ + public ItemStack[] getContents(); + + /** + * Completely replaces the inventory's contents. Removes all existing + * contents and replaces it with the ItemStacks given in the array. + * + * @param items A complete replacement for the contents; the length must + * be less than or equal to {@link #getSize()}. + * @throws IllegalArgumentException If the array has more items than the + * inventory. + */ + public void setContents(ItemStack[] items) throws IllegalArgumentException; + + /** + * Checks if the inventory contains any ItemStacks with the given + * materialId + * + * @param materialId The materialId to check for + * @return true if an ItemStack in this inventory contains the materialId + * @deprecated Magic value + */ + @Deprecated + public boolean contains(int materialId); + + /** + * Checks if the inventory contains any ItemStacks with the given + * material. + * + * @param material The material to check for + * @return true if an ItemStack is found with the given Material + * @throws IllegalArgumentException if material is null + */ + public boolean contains(Material material) throws IllegalArgumentException; + + /** + * Checks if the inventory contains any ItemStacks matching the given + * ItemStack. + *

+ * This will only return true if both the type and the amount of the stack + * match. + * + * @param item The ItemStack to match against + * @return false if item is null, true if any exactly matching ItemStacks + * were found + */ + public boolean contains(ItemStack item); + + /** + * Checks if the inventory contains any ItemStacks with the given + * materialId, adding to at least the minimum amount specified. + * + * @param materialId The materialId to check for + * @param amount The minimum amount to look for + * @return true if this contains any matching ItemStack with the given + * materialId and amount + * @deprecated Magic value + */ + @Deprecated + public boolean contains(int materialId, int amount); + + /** + * Checks if the inventory contains any ItemStacks with the given + * material, adding to at least the minimum amount specified. + * + * @param material The material to check for + * @param amount The minimum amount + * @return true if amount is less than 1, true if enough ItemStacks were + * found to add to the given amount + * @throws IllegalArgumentException if material is null + */ + public boolean contains(Material material, int amount) throws IllegalArgumentException; + + /** + * Checks if the inventory contains at least the minimum amount specified + * of exactly matching ItemStacks. + *

+ * An ItemStack only counts if both the type and the amount of the stack + * match. + * + * @param item the ItemStack to match against + * @param amount how many identical stacks to check for + * @return false if item is null, true if amount less than 1, true if + * amount of exactly matching ItemStacks were found + * @see #containsAtLeast(ItemStack, int) + */ + public boolean contains(ItemStack item, int amount); + + /** + * Checks if the inventory contains ItemStacks matching the given + * ItemStack whose amounts sum to at least the minimum amount specified. + * + * @param item the ItemStack to match against + * @param amount the minimum amount + * @return false if item is null, true if amount less than 1, true if + * enough ItemStacks were found to add to the given amount + */ + public boolean containsAtLeast(ItemStack item, int amount); + + /** + * Returns a HashMap with all slots and ItemStacks in the inventory with + * given materialId. + *

+ * The HashMap contains entries where, the key is the slot index, and the + * value is the ItemStack in that slot. If no matching ItemStack with the + * given materialId is found, an empty map is returned. + * + * @param materialId The materialId to look for + * @return A HashMap containing the slot index, ItemStack pairs + * @deprecated Magic value + */ + @Deprecated + public HashMap all(int materialId); + + /** + * Returns a HashMap with all slots and ItemStacks in the inventory with + * the given Material. + *

+ * The HashMap contains entries where, the key is the slot index, and the + * value is the ItemStack in that slot. If no matching ItemStack with the + * given Material is found, an empty map is returned. + * + * @param material The material to look for + * @return A HashMap containing the slot index, ItemStack pairs + * @throws IllegalArgumentException if material is null + */ + public HashMap all(Material material) throws IllegalArgumentException; + + /** + * Finds all slots in the inventory containing any ItemStacks with the + * given ItemStack. This will only match slots if both the type and the + * amount of the stack match + *

+ * The HashMap contains entries where, the key is the slot index, and the + * value is the ItemStack in that slot. If no matching ItemStack with the + * given Material is found, an empty map is returned. + * + * @param item The ItemStack to match against + * @return A map from slot indexes to item at index + */ + public HashMap all(ItemStack item); + + /** + * Finds the first slot in the inventory containing an ItemStack with the + * given materialId. + * + * @param materialId The materialId to look for + * @return The slot index of the given materialId or -1 if not found + * @deprecated Magic value + */ + @Deprecated + public int first(int materialId); + + /** + * Finds the first slot in the inventory containing an ItemStack with the + * given material + * + * @param material The material to look for + * @return The slot index of the given Material or -1 if not found + * @throws IllegalArgumentException if material is null + */ + public int first(Material material) throws IllegalArgumentException; + + /** + * Returns the first slot in the inventory containing an ItemStack with + * the given stack. This will only match a slot if both the type and the + * amount of the stack match + * + * @param item The ItemStack to match against + * @return The slot index of the given ItemStack or -1 if not found + */ + public int first(ItemStack item); + + /** + * Returns the first empty Slot. + * + * @return The first empty Slot found, or -1 if no empty slots. + */ + public int firstEmpty(); + + /** + * Removes all stacks in the inventory matching the given materialId. + * + * @param materialId The material to remove + * @deprecated Magic value + */ + @Deprecated + public void remove(int materialId); + + /** + * Removes all stacks in the inventory matching the given material. + * + * @param material The material to remove + * @throws IllegalArgumentException if material is null + */ + public void remove(Material material) throws IllegalArgumentException; + + /** + * Removes all stacks in the inventory matching the given stack. + *

+ * This will only match a slot if both the type and the amount of the + * stack match + * + * @param item The ItemStack to match against + */ + public void remove(ItemStack item); + + /** + * Clears out a particular slot in the index. + * + * @param index The index to empty. + */ + public void clear(int index); + + /** + * Clears out the whole Inventory. + */ + public void clear(); + + /** + * Gets a list of players viewing the inventory. Note that a player is + * considered to be viewing their own inventory and internal crafting + * screen even when said inventory is not open. They will normally be + * considered to be viewing their inventory even when they have a + * different inventory screen open, but it's possible for customized + * inventory screens to exclude the viewer's inventory, so this should + * never be assumed to be non-empty. + * + * @return A list of HumanEntities who are viewing this Inventory. + */ + public List getViewers(); + + /** + * Returns the title of this inventory. + * + * @return A String with the title. + */ + public String getTitle(); + + /** + * Returns what type of inventory this is. + * + * @return The InventoryType representing the type of inventory. + */ + public InventoryType getType(); + + /** + * Gets the block or entity belonging to the open inventory + * + * @return The holder of the inventory; null if it has no holder. + */ + public InventoryHolder getHolder(); + + @Override + public ListIterator iterator(); + + /** + * Returns an iterator starting at the given index. If the index is + * positive, then the first call to next() will return the item at that + * index; if it is negative, the first call to previous will return the + * item at index (getSize() + index). + * + * @param index The index. + * @return An iterator. + */ + public ListIterator iterator(int index); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/InventoryHolder.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/InventoryHolder.java new file mode 100644 index 0000000..9c06a3d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/InventoryHolder.java @@ -0,0 +1,11 @@ +package org.bukkit.inventory; + +public interface InventoryHolder { + + /** + * Get the object's inventory. + * + * @return The inventory. + */ + public Inventory getInventory(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/InventoryView.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/InventoryView.java new file mode 100644 index 0000000..46242f8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/InventoryView.java @@ -0,0 +1,232 @@ +package org.bukkit.inventory; + +import org.bukkit.GameMode; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; + +/** + * Represents a view linking two inventories and a single player (whose + * inventory may or may not be one of the two). + *

+ * Note: If you implement this interface but fail to satisfy the expected + * contracts of certain methods, there's no guarantee that the game will work + * as it should. + */ +public abstract class InventoryView { + public final static int OUTSIDE = -999; + /** + * Represents various extra properties of certain inventory windows. + */ + public enum Property { + /** + * The progress of the down-pointing arrow in a brewing inventory. + */ + BREW_TIME(0, InventoryType.BREWING), + /** + * The progress of the right-pointing arrow in a furnace inventory. + */ + COOK_TIME(0, InventoryType.FURNACE), + /** + * The progress of the flame in a furnace inventory. + */ + BURN_TIME(1, InventoryType.FURNACE), + /** + * How many total ticks the current fuel should last. + */ + TICKS_FOR_CURRENT_FUEL(2, InventoryType.FURNACE), + /** + * In an enchanting inventory, the top button's experience level + * value. + */ + ENCHANT_BUTTON1(0, InventoryType.ENCHANTING), + /** + * In an enchanting inventory, the middle button's experience level + * value. + */ + ENCHANT_BUTTON2(1, InventoryType.ENCHANTING), + /** + * In an enchanting inventory, the bottom button's experience level + * value. + */ + ENCHANT_BUTTON3(2, InventoryType.ENCHANTING); + int id; + InventoryType style; + private Property(int id, InventoryType appliesTo) { + this.id = id; + style = appliesTo; + } + + public InventoryType getType() { + return style; + } + + /** + * + * @return the id of this view + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + } + /** + * Get the upper inventory involved in this transaction. + * + * @return the inventory + */ + public abstract Inventory getTopInventory(); + + /** + * Get the lower inventory involved in this transaction. + * + * @return the inventory + */ + public abstract Inventory getBottomInventory(); + + /** + * Get the player viewing. + * + * @return the player + */ + public abstract HumanEntity getPlayer(); + + /** + * Determine the type of inventory involved in the transaction. This + * indicates the window style being shown. It will never return PLAYER, + * since that is common to all windows. + * + * @return the inventory type + */ + public abstract InventoryType getType(); + + /** + * Sets one item in this inventory view by its raw slot ID. + *

+ * Note: If slot ID -999 is chosen, it may be expected that the item is + * dropped on the ground. This is not required behaviour, however. + * + * @param slot The ID as returned by InventoryClickEvent.getRawSlot() + * @param item The new item to put in the slot, or null to clear it. + */ + public void setItem(int slot, ItemStack item) { + if (slot != OUTSIDE) { + if (slot < getTopInventory().getSize()) { + getTopInventory().setItem(convertSlot(slot),item); + } else { + getBottomInventory().setItem(convertSlot(slot),item); + } + } else { + getPlayer().getWorld().dropItemNaturally(getPlayer().getLocation(), item); + } + } + + /** + * Gets one item in this inventory view by its raw slot ID. + * + * @param slot The ID as returned by InventoryClickEvent.getRawSlot() + * @return The item currently in the slot. + */ + public ItemStack getItem(int slot) { + if (slot == OUTSIDE) { + return null; + } + if (slot < getTopInventory().getSize()) { + return getTopInventory().getItem(convertSlot(slot)); + } else { + return getBottomInventory().getItem(convertSlot(slot)); + } + } + + /** + * Sets the item on the cursor of one of the viewing players. + * + * @param item The item to put on the cursor, or null to remove the item + * on their cursor. + */ + public final void setCursor(ItemStack item) { + getPlayer().setItemOnCursor(item); + } + + /** + * Get the item on the cursor of one of the viewing players. + * + * @return The item on the player's cursor, or null if they aren't holding + * one. + */ + public final ItemStack getCursor() { + return getPlayer().getItemOnCursor(); + } + + /** + * Converts a raw slot ID into its local slot ID into whichever of the two + * inventories the slot points to. + *

+ * If the raw slot refers to the upper inventory, it will be returned + * unchanged and thus be suitable for getTopInventory().getItem(); if it + * refers to the lower inventory, the output will differ from the input + * and be suitable for getBottomInventory().getItem(). + * + * @param rawSlot The raw slot ID. + * @return The converted slot ID. + */ + public final int convertSlot(int rawSlot) { + int numInTop = getTopInventory().getSize(); + if (rawSlot < numInTop) { + return rawSlot; + } + int slot = rawSlot - numInTop; + if (getPlayer().getGameMode() == GameMode.CREATIVE && getType() == InventoryType.PLAYER) { + return slot; + } + if (getType() == InventoryType.CRAFTING) { + if(slot < 4) return 39 - slot; + else slot -= 4; + } + if (slot >= 27) slot -= 27; + else slot += 9; + return slot; + } + + /** + * Closes the inventory view. + */ + public final void close() { + getPlayer().closeInventory(); + } + + /** + * Check the total number of slots in this view, combining the upper and + * lower inventories. + *

+ * Note though that it's possible for this to be greater than the sum of + * the two inventories if for example some slots are not being used. + * + * @return The total size + */ + public final int countSlots() { + return getTopInventory().getSize() + getBottomInventory().getSize(); + } + + /** + * Sets an extra property of this inventory if supported by that + * inventory, for example the state of a progress bar. + * + * @param prop the window property to update + * @param value the new value for the window property + * @return true if the property was updated successfully, false if the + * property is not supported by that inventory + */ + public final boolean setProperty(Property prop, int value) { + return getPlayer().setWindowProperty(prop, value); + } + + /** + * Get the title of this inventory window. + * + * @return The title. + */ + public final String getTitle() { + return getTopInventory().getTitle(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemFactory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemFactory.java new file mode 100644 index 0000000..52a8d4d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemFactory.java @@ -0,0 +1,124 @@ +package org.bukkit.inventory; + +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +/** + * An instance of the ItemFactory can be obtained with {@link + * Server#getItemFactory()}. + *

+ * The ItemFactory is solely responsible for creating item meta containers to + * apply on item stacks. + */ +public interface ItemFactory { + + /** + * This creates a new item meta for the material. + * + * @param material The material to consider as base for the meta + * @return a new ItemMeta that could be applied to an item stack of the + * specified material + */ + ItemMeta getItemMeta(final Material material); + + /** + * This method checks the item meta to confirm that it is applicable (no + * data lost if applied) to the specified ItemStack. + *

+ * A {@link SkullMeta} would not be valid for a sword, but a normal {@link + * ItemMeta} from an enchanted dirt block would. + * + * @param meta Meta to check + * @param stack Item that meta will be applied to + * @return true if the meta can be applied without losing data, false + * otherwise + * @throws IllegalArgumentException if the meta was not created by this + * factory + */ + boolean isApplicable(final ItemMeta meta, final ItemStack stack) throws IllegalArgumentException; + + /** + * This method checks the item meta to confirm that it is applicable (no + * data lost if applied) to the specified Material. + *

+ * A {@link SkullMeta} would not be valid for a sword, but a normal {@link + * ItemMeta} from an enchanted dirt block would. + * + * @param meta Meta to check + * @param material Material that meta will be applied to + * @return true if the meta can be applied without losing data, false + * otherwise + * @throws IllegalArgumentException if the meta was not created by this + * factory + */ + boolean isApplicable(final ItemMeta meta, final Material material) throws IllegalArgumentException; + + /** + * This method is used to compare two item meta data objects. + * + * @param meta1 First meta to compare, and may be null to indicate no data + * @param meta2 Second meta to compare, and may be null to indicate no + * data + * @return false if one of the meta has data the other does not, otherwise + * true + * @throws IllegalArgumentException if either meta was not created by this + * factory + */ + boolean equals(final ItemMeta meta1, final ItemMeta meta2) throws IllegalArgumentException; + + /** + * Returns an appropriate item meta for the specified stack. + *

+ * The item meta returned will always be a valid meta for a given + * ItemStack of the specified material. It may be a more or less specific + * meta, and could also be the same meta or meta type as the parameter. + * The item meta returned will also always be the most appropriate meta. + *

+ * Example, if a {@link SkullMeta} is being applied to a book, this method + * would return a {@link BookMeta} containing all information in the + * specified meta that is applicable to an {@link ItemMeta}, the highest + * common interface. + * + * @param meta the meta to convert + * @param stack the stack to convert the meta for + * @return An appropriate item meta for the specified item stack. No + * guarantees are made as to if a copy is returned. This will be null + * for a stack of air. + * @throws IllegalArgumentException if the specified meta was not created + * by this factory + */ + ItemMeta asMetaFor(final ItemMeta meta, final ItemStack stack) throws IllegalArgumentException; + + /** + * Returns an appropriate item meta for the specified material. + *

+ * The item meta returned will always be a valid meta for a given + * ItemStack of the specified material. It may be a more or less specific + * meta, and could also be the same meta or meta type as the parameter. + * The item meta returned will also always be the most appropriate meta. + *

+ * Example, if a {@link SkullMeta} is being applied to a book, this method + * would return a {@link BookMeta} containing all information in the + * specified meta that is applicable to an {@link ItemMeta}, the highest + * common interface. + * + * @param meta the meta to convert + * @param material the material to convert the meta for + * @return An appropriate item meta for the specified item material. No + * guarantees are made as to if a copy is returned. This will be null for air. + * @throws IllegalArgumentException if the specified meta was not created + * by this factory + */ + ItemMeta asMetaFor(final ItemMeta meta, final Material material) throws IllegalArgumentException; + + /** + * Returns the default color for all leather armor. + * + * @return the default color for leather armor + */ + Color getDefaultLeatherColor(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemFlag.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemFlag.java new file mode 100644 index 0000000..2a8af7b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemFlag.java @@ -0,0 +1,32 @@ +package org.bukkit.inventory; + +/** + * A ItemFlag can hide some Attributes from ItemStacks + */ +public enum ItemFlag { + + /** + * Setting to show/hide enchants + */ + HIDE_ENCHANTS, + /** + * Setting to show/hide Attributes like Damage + */ + HIDE_ATTRIBUTES, + /** + * Setting to show/hide the unbreakable State + */ + HIDE_UNBREAKABLE, + /** + * Setting to show/hide what the ItemStack can break/destroy + */ + HIDE_DESTROYS, + /** + * Setting to show/hide where this ItemStack can be build/placed on + */ + HIDE_PLACED_ON, + /** + * Setting to show/hide potion effects on this ItemStack + */ + HIDE_POTION_EFFECTS; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemStack.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemStack.java new file mode 100644 index 0000000..d9cff5b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ItemStack.java @@ -0,0 +1,611 @@ +package org.bukkit.inventory; + +import com.google.common.collect.ImmutableMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Utility; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.material.MaterialData; + +/** + * Represents a stack of items + */ +public class ItemStack implements Cloneable, ConfigurationSerializable { + private int type = 0; + private int amount = 0; + private MaterialData data = null; + private short durability = 0; + private ItemMeta meta; + + @Utility + protected ItemStack() {} + + /** + * Defaults stack size to 1, with no extra data + * + * @param type item material id + * @deprecated Magic value + */ + @Deprecated + public ItemStack(final int type) { + this(type, 1); + } + + /** + * Defaults stack size to 1, with no extra data + * + * @param type item material + */ + public ItemStack(final Material type) { + this(type, 1); + } + + /** + * An item stack with no extra data + * + * @param type item material id + * @param amount stack size + * @deprecated Magic value + */ + @Deprecated + public ItemStack(final int type, final int amount) { + this(type, amount, (short) 0); + } + + /** + * An item stack with no extra data + * + * @param type item material + * @param amount stack size + */ + public ItemStack(final Material type, final int amount) { + this(type.getId(), amount); + } + + /** + * An item stack with the specified damage / durability + * + * @param type item material id + * @param amount stack size + * @param damage durability / damage + * @deprecated Magic value + */ + @Deprecated + public ItemStack(final int type, final int amount, final short damage) { + this.type = type; + this.amount = amount; + this.durability = damage; + } + + /** + * An item stack with the specified damage / durabiltiy + * + * @param type item material + * @param amount stack size + * @param damage durability / damage + */ + public ItemStack(final Material type, final int amount, final short damage) { + this(type.getId(), amount, damage); + } + + /** + * @param type the raw type id + * @param amount the amount in the stack + * @param damage the damage value of the item + * @param data the data value or null + * @deprecated this method uses an ambiguous data byte object + */ + @Deprecated + public ItemStack(final int type, final int amount, final short damage, final Byte data) { + this.type = type; + this.amount = amount; + this.durability = damage; + if (data != null) { + createData(data); + this.durability = data; + } + } + + /** + * @param type the type + * @param amount the amount in the stack + * @param damage the damage value of the item + * @param data the data value or null + * @deprecated this method uses an ambiguous data byte object + */ + @Deprecated + public ItemStack(final Material type, final int amount, final short damage, final Byte data) { + this(type.getId(), amount, damage, data); + } + + /** + * Creates a new item stack derived from the specified stack + * + * @param stack the stack to copy + * @throws IllegalArgumentException if the specified stack is null or + * returns an item meta not created by the item factory + */ + public ItemStack(final ItemStack stack) throws IllegalArgumentException { + Validate.notNull(stack, "Cannot copy null stack"); + this.type = stack.getTypeId(); + this.amount = stack.getAmount(); + this.durability = stack.getDurability(); + this.data = stack.getData(); + if (stack.hasItemMeta()) { + setItemMeta0(stack.getItemMeta(), getType0()); + } + } + + /** + * Gets the type of this item + * + * @return Type of the items in this stack + */ + @Utility + public Material getType() { + return getType0(getTypeId()); + } + + private Material getType0() { + return getType0(this.type); + } + + private static Material getType0(int id) { + Material material = Material.getMaterial(id); + return material == null ? Material.AIR : material; + } + + /** + * Sets the type of this item + *

+ * Note that in doing so you will reset the MaterialData for this stack + * + * @param type New type to set the items in this stack to + */ + @Utility + public void setType(Material type) { + Validate.notNull(type, "Material cannot be null"); + setTypeId(type.getId()); + } + + /** + * Gets the type id of this item + * + * @return Type Id of the items in this stack + * @deprecated Magic value + */ + @Deprecated + public int getTypeId() { + return type; + } + + /** + * Sets the type id of this item + *

+ * Note that in doing so you will reset the MaterialData for this stack + * + * @param type New type id to set the items in this stack to + * @deprecated Magic value + */ + @Deprecated + public void setTypeId(int type) { + this.type = type; + if (this.meta != null) { + this.meta = Bukkit.getItemFactory().asMetaFor(meta, getType0()); + } + createData((byte) 0); + } + + /** + * Gets the amount of items in this stack + * + * @return Amount of items in this stick + */ + public int getAmount() { + return amount; + } + + /** + * Sets the amount of items in this stack + * + * @param amount New amount of items in this stack + */ + public void setAmount(int amount) { + this.amount = amount; + } + + /** + * Gets the MaterialData for this stack of items + * + * @return MaterialData for this item + */ + public MaterialData getData() { + Material mat = getType(); + if (data == null && mat != null && mat.getData() != null) { + data = mat.getNewData((byte) this.getDurability()); + } + + return data; + } + + /** + * Sets the MaterialData for this stack of items + * + * @param data New MaterialData for this item + */ + public void setData(MaterialData data) { + Material mat = getType(); + + if (data == null || mat == null || mat.getData() == null) { + this.data = data; + } else { + if ((data.getClass() == mat.getData()) || (data.getClass() == MaterialData.class)) { + this.data = data; + } else { + throw new IllegalArgumentException("Provided data is not of type " + mat.getData().getName() + ", found " + data.getClass().getName()); + } + } + } + + /** + * Sets the durability of this item + * + * @param durability Durability of this item + */ + public void setDurability(final short durability) { + this.durability = durability; + } + + /** + * Gets the durability of this item + * + * @return Durability of this item + */ + public short getDurability() { + return durability; + } + + /** + * Get the maximum stacksize for the material hold in this ItemStack. + * (Returns -1 if it has no idea) + * + * @return The maximum you can stack this material to. + */ + @Utility + public int getMaxStackSize() { + Material material = getType(); + if (material != null) { + return material.getMaxStackSize(); + } + return -1; + } + + private void createData(final byte data) { + Material mat = Material.getMaterial(type); + + if (mat == null) { + this.data = new MaterialData(type, data); + } else { + this.data = mat.getNewData(data); + } + } + + @Override + @Utility + public String toString() { + StringBuilder toString = new StringBuilder("ItemStack{").append(getType().name()).append(" x ").append(getAmount()); + if (hasItemMeta()) { + toString.append(", ").append(getItemMeta()); + } + return toString.append('}').toString(); + } + + @Override + @Utility + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ItemStack)) { + return false; + } + + ItemStack stack = (ItemStack) obj; + return getAmount() == stack.getAmount() && isSimilar(stack); + } + + /** + * This method is the same as equals, but does not consider stack size + * (amount). + * + * @param stack the item stack to compare to + * @return true if the two stacks are equal, ignoring the amount + */ + @Utility + public boolean isSimilar(ItemStack stack) { + if (stack == null) { + return false; + } + if (stack == this) { + return true; + } + return getTypeId() == stack.getTypeId() && getDurability() == stack.getDurability() && hasItemMeta() == stack.hasItemMeta() && (hasItemMeta() ? Bukkit.getItemFactory().equals(getItemMeta(), stack.getItemMeta()) : true); + } + + @Override + public ItemStack clone() { + try { + ItemStack itemStack = (ItemStack) super.clone(); + + if (this.meta != null) { + itemStack.meta = this.meta.clone(); + } + + if (this.data != null) { + itemStack.data = this.data.clone(); + } + + return itemStack; + } catch (CloneNotSupportedException e) { + throw new Error(e); + } + } + + @Override + @Utility + public final int hashCode() { + int hash = 1; + + hash = hash * 31 + getTypeId(); + hash = hash * 31 + getAmount(); + hash = hash * 31 + (getDurability() & 0xffff); + hash = hash * 31 + (hasItemMeta() ? (meta == null ? getItemMeta().hashCode() : meta.hashCode()) : 0); + + return hash; + } + + /** + * Checks if this ItemStack contains the given {@link Enchantment} + * + * @param ench Enchantment to test + * @return True if this has the given enchantment + */ + public boolean containsEnchantment(Enchantment ench) { + return meta == null ? false : meta.hasEnchant(ench); + } + + /** + * Gets the level of the specified enchantment on this item stack + * + * @param ench Enchantment to check + * @return Level of the enchantment, or 0 + */ + public int getEnchantmentLevel(Enchantment ench) { + return meta == null ? 0 : meta.getEnchantLevel(ench); + } + + /** + * Gets a map containing all enchantments and their levels on this item. + * + * @return Map of enchantments. + */ + public Map getEnchantments() { + return meta == null ? ImmutableMap.of() : meta.getEnchants(); + } + + /** + * Adds the specified enchantments to this item stack. + *

+ * This method is the same as calling {@link + * #addEnchantment(org.bukkit.enchantments.Enchantment, int)} for each + * element of the map. + * + * @param enchantments Enchantments to add + * @throws IllegalArgumentException if the specified enchantments is null + * @throws IllegalArgumentException if any specific enchantment or level + * is null. Warning: Some enchantments may be added before this + * exception is thrown. + */ + @Utility + public void addEnchantments(Map enchantments) { + Validate.notNull(enchantments, "Enchantments cannot be null"); + for (Map.Entry entry : enchantments.entrySet()) { + addEnchantment(entry.getKey(), entry.getValue()); + } + } + + /** + * Adds the specified {@link Enchantment} to this item stack. + *

+ * If this item stack already contained the given enchantment (at any + * level), it will be replaced. + * + * @param ench Enchantment to add + * @param level Level of the enchantment + * @throws IllegalArgumentException if enchantment null, or enchantment is + * not applicable + */ + @Utility + public void addEnchantment(Enchantment ench, int level) { + Validate.notNull(ench, "Enchantment cannot be null"); + if ((level < ench.getStartLevel()) || (level > ench.getMaxLevel())) { + throw new IllegalArgumentException("Enchantment level is either too low or too high (given " + level + ", bounds are " + ench.getStartLevel() + " to " + ench.getMaxLevel() + ")"); + } else if (!ench.canEnchantItem(this)) { + throw new IllegalArgumentException("Specified enchantment cannot be applied to this itemstack"); + } + + addUnsafeEnchantment(ench, level); + } + + /** + * Adds the specified enchantments to this item stack in an unsafe manner. + *

+ * This method is the same as calling {@link + * #addUnsafeEnchantment(org.bukkit.enchantments.Enchantment, int)} for + * each element of the map. + * + * @param enchantments Enchantments to add + */ + @Utility + public void addUnsafeEnchantments(Map enchantments) { + for (Map.Entry entry : enchantments.entrySet()) { + addUnsafeEnchantment(entry.getKey(), entry.getValue()); + } + } + + /** + * Adds the specified {@link Enchantment} to this item stack. + *

+ * If this item stack already contained the given enchantment (at any + * level), it will be replaced. + *

+ * This method is unsafe and will ignore level restrictions or item type. + * Use at your own discretion. + * + * @param ench Enchantment to add + * @param level Level of the enchantment + */ + public void addUnsafeEnchantment(Enchantment ench, int level) { + (meta == null ? meta = Bukkit.getItemFactory().getItemMeta(getType0()) : meta).addEnchant(ench, level, true); + } + + /** + * Removes the specified {@link Enchantment} if it exists on this + * ItemStack + * + * @param ench Enchantment to remove + * @return Previous level, or 0 + */ + public int removeEnchantment(Enchantment ench) { + int level = getEnchantmentLevel(ench); + if (level == 0 || meta == null) { + return level; + } + meta.removeEnchant(ench); + return level; + } + + @Utility + public Map serialize() { + Map result = new LinkedHashMap(); + + result.put("type", getType().name()); + + if (getDurability() != 0) { + result.put("damage", getDurability()); + } + + if (getAmount() != 1) { + result.put("amount", getAmount()); + } + + ItemMeta meta = getItemMeta(); + if (!Bukkit.getItemFactory().equals(meta, null)) { + result.put("meta", meta); + } + + return result; + } + + /** + * Required method for configuration serialization + * + * @param args map to deserialize + * @return deserialized item stack + * @see ConfigurationSerializable + */ + public static ItemStack deserialize(Map args) { + Material type = Material.getMaterial((String) args.get("type")); + short damage = 0; + int amount = 1; + + if (args.containsKey("damage")) { + damage = ((Number) args.get("damage")).shortValue(); + } + + if (args.containsKey("amount")) { + amount = ((Number) args.get("amount")).intValue(); + } + + ItemStack result = new ItemStack(type, amount, damage); + + if (args.containsKey("enchantments")) { // Backward compatiblity, @deprecated + Object raw = args.get("enchantments"); + + if (raw instanceof Map) { + Map map = (Map) raw; + + for (Map.Entry entry : map.entrySet()) { + Enchantment enchantment = Enchantment.getByName(entry.getKey().toString()); + + if ((enchantment != null) && (entry.getValue() instanceof Integer)) { + result.addUnsafeEnchantment(enchantment, (Integer) entry.getValue()); + } + } + } + } else if (args.containsKey("meta")) { // We cannot and will not have meta when enchantments (pre-ItemMeta) exist + Object raw = args.get("meta"); + if (raw instanceof ItemMeta) { + result.setItemMeta((ItemMeta) raw); + } + } + + return result; + } + + /** + * Get a copy of this ItemStack's {@link ItemMeta}. + * + * @return a copy of the current ItemStack's ItemData + */ + public ItemMeta getItemMeta() { + return this.meta == null ? Bukkit.getItemFactory().getItemMeta(getType0()) : this.meta.clone(); + } + + /** + * Checks to see if any meta data has been defined. + * + * @return Returns true if some meta data has been set for this item + */ + public boolean hasItemMeta() { + return !Bukkit.getItemFactory().equals(meta, null); + } + + /** + * Set the ItemMeta of this ItemStack. + * + * @param itemMeta new ItemMeta, or null to indicate meta data be cleared. + * @return True if successfully applied ItemMeta, see {@link + * ItemFactory#isApplicable(ItemMeta, ItemStack)} + * @throws IllegalArgumentException if the item meta was not created by + * the {@link ItemFactory} + */ + public boolean setItemMeta(ItemMeta itemMeta) { + return setItemMeta0(itemMeta, getType0()); + } + + /* + * Cannot be overridden, so it's safe for constructor call + */ + private boolean setItemMeta0(ItemMeta itemMeta, Material material) { + if (itemMeta == null) { + this.meta = null; + return true; + } + if (!Bukkit.getItemFactory().isApplicable(itemMeta, material)) { + return false; + } + this.meta = Bukkit.getItemFactory().asMetaFor(itemMeta, material); + if (this.meta == itemMeta) { + this.meta = itemMeta.clone(); + } + + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/MerchantInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/MerchantInventory.java new file mode 100644 index 0000000..163f459 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/MerchantInventory.java @@ -0,0 +1,4 @@ +package org.bukkit.inventory; + +public interface MerchantInventory extends Inventory { +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/PlayerInventory.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/PlayerInventory.java new file mode 100644 index 0000000..b79a4f0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/PlayerInventory.java @@ -0,0 +1,154 @@ +package org.bukkit.inventory; + +import org.bukkit.entity.HumanEntity; + +/** + * Interface to the inventory of a Player, including the four armor slots. + */ +public interface PlayerInventory extends Inventory { + + /** + * Get all ItemStacks from the armor slots + * + * @return All the ItemStacks from the armor slots + */ + public ItemStack[] getArmorContents(); + + /** + * Return the ItemStack from the helmet slot + * + * @return The ItemStack in the helmet slot + */ + public ItemStack getHelmet(); + + /** + * Return the ItemStack from the chestplate slot + * + * @return The ItemStack in the chestplate slot + */ + public ItemStack getChestplate(); + + /** + * Return the ItemStack from the leg slot + * + * @return The ItemStack in the leg slot + */ + public ItemStack getLeggings(); + + /** + * Return the ItemStack from the boots slot + * + * @return The ItemStack in the boots slot + */ + public ItemStack getBoots(); + + /** + * Stores the ItemStack at the given index of the inventory. + *

+ * Indexes 0 through 8 refer to the hotbar. 9 through 35 refer to the main inventory, counting up from 9 at the top + * left corner of the inventory, moving to the right, and moving to the row below it back on the left side when it + * reaches the end of the row. It follows the same path in the inventory like you would read a book. + *

+ * Indexes 36 through 39 refer to the armor slots. Though you can set armor with this method using these indexes, + * you are encouraged to use the provided methods for those slots. + *

+ * If you attempt to use this method with an index less than 0 or greater than 39, an ArrayIndexOutOfBounds + * exception will be thrown. + * + * @param index The index where to put the ItemStack + * @param item The ItemStack to set + * @throws ArrayIndexOutOfBoundsException when index < 0 || index > 39 + * @see #setBoots(ItemStack) + * @see #setChestplate(ItemStack) + * @see #setHelmet(ItemStack) + * @see #setLeggings(ItemStack) + */ + @Override + public void setItem(int index, ItemStack item); + + /** + * Put the given ItemStacks into the armor slots + * + * @param items The ItemStacks to use as armour + */ + public void setArmorContents(ItemStack[] items); + + /** + * Put the given ItemStack into the helmet slot. This does not check if + * the ItemStack is a helmet + * + * @param helmet The ItemStack to use as helmet + */ + public void setHelmet(ItemStack helmet); + + /** + * Put the given ItemStack into the chestplate slot. This does not check + * if the ItemStack is a chestplate + * + * @param chestplate The ItemStack to use as chestplate + */ + public void setChestplate(ItemStack chestplate); + + /** + * Put the given ItemStack into the leg slot. This does not check if the + * ItemStack is a pair of leggings + * + * @param leggings The ItemStack to use as leggings + */ + public void setLeggings(ItemStack leggings); + + /** + * Put the given ItemStack into the boots slot. This does not check if the + * ItemStack is a boots + * + * @param boots The ItemStack to use as boots + */ + public void setBoots(ItemStack boots); + + /** + * Returns the ItemStack currently hold + * + * @return The currently held ItemStack + */ + public ItemStack getItemInHand(); + + /** + * Sets the item in hand + * + * @param stack Stack to set + */ + public void setItemInHand(ItemStack stack); + + /** + * Get the slot number of the currently held item + * + * @return Held item slot number + */ + public int getHeldItemSlot(); + + /** + * Set the slot number of the currently held item. + *

+ * This validates whether the slot is between 0 and 8 inclusive. + * + * @param slot The new slot number + * @throws IllegalArgumentException Thrown if slot is not between 0 and 8 + * inclusive + */ + public void setHeldItemSlot(int slot); + + /** + * Clears all matching items from the inventory. Setting either value to + * -1 will skip it's check, while setting both to -1 will clear all items + * in your inventory unconditionally. + * + * @param id the id of the item you want to clear from the inventory + * @param data the data of the item you want to clear from the inventory + * @return The number of items cleared + * @deprecated Magic value + */ + @Deprecated + public int clear(int id, int data); + + public HumanEntity getHolder(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/Recipe.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/Recipe.java new file mode 100644 index 0000000..7977ce2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/Recipe.java @@ -0,0 +1,14 @@ +package org.bukkit.inventory; + +/** + * Represents some type of crafting recipe. + */ +public interface Recipe { + + /** + * Get the result of this recipe. + * + * @return The result stack + */ + ItemStack getResult(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ShapedRecipe.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ShapedRecipe.java new file mode 100644 index 0000000..2796473 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ShapedRecipe.java @@ -0,0 +1,148 @@ +package org.bukkit.inventory; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.Validate; + +import org.bukkit.Material; +import org.bukkit.material.MaterialData; + +/** + * Represents a shaped (ie normal) crafting recipe. + */ +public class ShapedRecipe implements Recipe { + private ItemStack output; + private String[] rows; + private Map ingredients = new HashMap(); + + /** + * Create a shaped recipe to craft the specified ItemStack. The + * constructor merely determines the result and type; to set the actual + * recipe, you'll need to call the appropriate methods. + * + * @param result The item you want the recipe to create. + * @see ShapedRecipe#shape(String...) + * @see ShapedRecipe#setIngredient(char, Material) + * @see ShapedRecipe#setIngredient(char, Material, int) + * @see ShapedRecipe#setIngredient(char, MaterialData) + */ + public ShapedRecipe(ItemStack result) { + this.output = new ItemStack(result); + } + + /** + * Set the shape of this recipe to the specified rows. Each character + * represents a different ingredient; exactly what each character + * represents is set separately. The first row supplied corresponds with + * the upper most part of the recipe on the workbench e.g. if all three + * rows are supplies the first string represents the top row on the + * workbench. + * + * @param shape The rows of the recipe (up to 3 rows). + * @return The changed recipe, so you can chain calls. + */ + public ShapedRecipe shape(final String... shape) { + Validate.notNull(shape, "Must provide a shape"); + Validate.isTrue(shape.length > 0 && shape.length < 4, "Crafting recipes should be 1, 2, 3 rows, not ", shape.length); + + for (String row : shape) { + Validate.notNull(row, "Shape cannot have null rows"); + Validate.isTrue(row.length() > 0 && row.length() < 4, "Crafting rows should be 1, 2, or 3 characters, not ", row.length()); + } + this.rows = new String[shape.length]; + for (int i = 0; i < shape.length; i++) { + this.rows[i] = shape[i]; + } + + // Remove character mappings for characters that no longer exist in the shape + HashMap newIngredients = new HashMap(); + for (String row : shape) { + for (Character c : row.toCharArray()) { + newIngredients.put(c, ingredients.get(c)); + } + } + this.ingredients = newIngredients; + + return this; + } + + /** + * Sets the material that a character in the recipe shape refers to. + * + * @param key The character that represents the ingredient in the shape. + * @param ingredient The ingredient. + * @return The changed recipe, so you can chain calls. + */ + public ShapedRecipe setIngredient(char key, MaterialData ingredient) { + return setIngredient(key, ingredient.getItemType(), ingredient.getData()); + } + + /** + * Sets the material that a character in the recipe shape refers to. + * + * @param key The character that represents the ingredient in the shape. + * @param ingredient The ingredient. + * @return The changed recipe, so you can chain calls. + */ + public ShapedRecipe setIngredient(char key, Material ingredient) { + return setIngredient(key, ingredient, 0); + } + + /** + * Sets the material that a character in the recipe shape refers to. + * + * @param key The character that represents the ingredient in the shape. + * @param ingredient The ingredient. + * @param raw The raw material data as an integer. + * @return The changed recipe, so you can chain calls. + * @deprecated Magic value + */ + @Deprecated + public ShapedRecipe setIngredient(char key, Material ingredient, int raw) { + Validate.isTrue(ingredients.containsKey(key), "Symbol does not appear in the shape:", key); + + // -1 is the old wildcard, map to Short.MAX_VALUE as the new one + if (raw == -1) { + raw = Short.MAX_VALUE; + } + + ingredients.put(key, new ItemStack(ingredient, 1, (short) raw)); + return this; + } + + /** + * Get a copy of the ingredients map. + * + * @return The mapping of character to ingredients. + */ + public Map getIngredientMap() { + HashMap result = new HashMap(); + for (Map.Entry ingredient : ingredients.entrySet()) { + if (ingredient.getValue() == null) { + result.put(ingredient.getKey(), null); + } else { + result.put(ingredient.getKey(), ingredient.getValue().clone()); + } + } + return result; + } + + /** + * Get the shape. + * + * @return The recipe's shape. + */ + public String[] getShape() { + return rows.clone(); + } + + /** + * Get the result. + * + * @return The result stack. + */ + public ItemStack getResult() { + return output.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ShapelessRecipe.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ShapelessRecipe.java new file mode 100644 index 0000000..a718086 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/ShapelessRecipe.java @@ -0,0 +1,226 @@ +package org.bukkit.inventory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.lang.Validate; + +import org.bukkit.Material; +import org.bukkit.material.MaterialData; + +/** + * Represents a shapeless recipe, where the arrangement of the ingredients on + * the crafting grid does not matter. + */ +public class ShapelessRecipe implements Recipe { + private ItemStack output; + private List ingredients = new ArrayList(); + + /** + * Create a shapeless recipe to craft the specified ItemStack. The + * constructor merely determines the result and type; to set the actual + * recipe, you'll need to call the appropriate methods. + * + * @param result The item you want the recipe to create. + * @see ShapelessRecipe#addIngredient(Material) + * @see ShapelessRecipe#addIngredient(MaterialData) + * @see ShapelessRecipe#addIngredient(Material,int) + * @see ShapelessRecipe#addIngredient(int,Material) + * @see ShapelessRecipe#addIngredient(int,MaterialData) + * @see ShapelessRecipe#addIngredient(int,Material,int) + */ + public ShapelessRecipe(ItemStack result) { + this.output = new ItemStack(result); + } + + /** + * Adds the specified ingredient. + * + * @param ingredient The ingredient to add. + * @return The changed recipe, so you can chain calls. + */ + public ShapelessRecipe addIngredient(MaterialData ingredient) { + return addIngredient(1, ingredient); + } + + /** + * Adds the specified ingredient. + * + * @param ingredient The ingredient to add. + * @return The changed recipe, so you can chain calls. + */ + public ShapelessRecipe addIngredient(Material ingredient) { + return addIngredient(1, ingredient, 0); + } + + /** + * Adds the specified ingredient. + * + * @param ingredient The ingredient to add. + * @param rawdata The data value, or -1 to allow any data value. + * @return The changed recipe, so you can chain calls. + * @deprecated Magic value + */ + @Deprecated + public ShapelessRecipe addIngredient(Material ingredient, int rawdata) { + return addIngredient(1, ingredient, rawdata); + } + + /** + * Adds multiples of the specified ingredient. + * + * @param count How many to add (can't be more than 9!) + * @param ingredient The ingredient to add. + * @return The changed recipe, so you can chain calls. + */ + public ShapelessRecipe addIngredient(int count, MaterialData ingredient) { + return addIngredient(count, ingredient.getItemType(), ingredient.getData()); + } + + /** + * Adds multiples of the specified ingredient. + * + * @param count How many to add (can't be more than 9!) + * @param ingredient The ingredient to add. + * @return The changed recipe, so you can chain calls. + */ + public ShapelessRecipe addIngredient(int count, Material ingredient) { + return addIngredient(count, ingredient, 0); + } + + /** + * Adds multiples of the specified ingredient. + * + * @param count How many to add (can't be more than 9!) + * @param ingredient The ingredient to add. + * @param rawdata The data value, or -1 to allow any data value. + * @return The changed recipe, so you can chain calls. + * @deprecated Magic value + */ + @Deprecated + public ShapelessRecipe addIngredient(int count, Material ingredient, int rawdata) { + Validate.isTrue(ingredients.size() + count <= 9, "Shapeless recipes cannot have more than 9 ingredients"); + + // -1 is the old wildcard, map to Short.MAX_VALUE as the new one + if (rawdata == -1) { + rawdata = Short.MAX_VALUE; + } + + while (count-- > 0) { + ingredients.add(new ItemStack(ingredient, 1, (short) rawdata)); + } + return this; + } + + /** + * Removes an ingredient from the list. If the ingredient occurs multiple + * times, only one instance of it is removed. Only removes exact matches, + * with a data value of 0. + * + * @param ingredient The ingredient to remove + * @return The changed recipe. + */ + public ShapelessRecipe removeIngredient(Material ingredient) { + return removeIngredient(ingredient, 0); + } + + /** + * Removes an ingredient from the list. If the ingredient occurs multiple + * times, only one instance of it is removed. If the data value is -1, + * only ingredients with a -1 data value will be removed. + * + * @param ingredient The ingredient to remove + * @return The changed recipe. + */ + public ShapelessRecipe removeIngredient(MaterialData ingredient) { + return removeIngredient(ingredient.getItemType(), ingredient.getData()); + } + + /** + * Removes multiple instances of an ingredient from the list. If there are + * less instances then specified, all will be removed. Only removes exact + * matches, with a data value of 0. + * + * @param count The number of copies to remove. + * @param ingredient The ingredient to remove + * @return The changed recipe. + */ + public ShapelessRecipe removeIngredient(int count, Material ingredient) { + return removeIngredient(count, ingredient, 0); + } + + /** + * Removes multiple instances of an ingredient from the list. If there are + * less instances then specified, all will be removed. If the data value + * is -1, only ingredients with a -1 data value will be removed. + * + * @param count The number of copies to remove. + * @param ingredient The ingredient to remove. + * @return The changed recipe. + */ + public ShapelessRecipe removeIngredient(int count, MaterialData ingredient) { + return removeIngredient(count, ingredient.getItemType(), ingredient.getData()); + } + + /** + * Removes an ingredient from the list. If the ingredient occurs multiple + * times, only one instance of it is removed. If the data value is -1, + * only ingredients with a -1 data value will be removed. + * + * @param ingredient The ingredient to remove + * @param rawdata The data value; + * @return The changed recipe. + * @deprecated Magic value + */ + @Deprecated + public ShapelessRecipe removeIngredient(Material ingredient, int rawdata) { + return removeIngredient(1, ingredient, rawdata); + } + + /** + * Removes multiple instances of an ingredient from the list. If there are + * less instances then specified, all will be removed. If the data value + * is -1, only ingredients with a -1 data value will be removed. + * + * @param count The number of copies to remove. + * @param ingredient The ingredient to remove. + * @param rawdata The data value. + * @return The changed recipe. + * @deprecated Magic value + */ + @Deprecated + public ShapelessRecipe removeIngredient(int count, Material ingredient, int rawdata) { + Iterator iterator = ingredients.iterator(); + while (count > 0 && iterator.hasNext()) { + ItemStack stack = iterator.next(); + if (stack.getType() == ingredient && stack.getDurability() == rawdata) { + iterator.remove(); + count--; + } + } + return this; + } + + /** + * Get the result of this recipe. + * + * @return The result stack. + */ + public ItemStack getResult() { + return output.clone(); + } + + /** + * Get the list of ingredients used for this recipe. + * + * @return The input list + */ + public List getIngredientList() { + ArrayList result = new ArrayList(ingredients.size()); + for (ItemStack ingredient : ingredients) { + result.add(ingredient.clone()); + } + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BannerMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BannerMeta.java new file mode 100644 index 0000000..6bf33c5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BannerMeta.java @@ -0,0 +1,76 @@ +package org.bukkit.inventory.meta; + +import java.util.List; +import org.bukkit.DyeColor; +import org.bukkit.block.banner.Pattern; + +public interface BannerMeta extends ItemMeta { + + /** + * Returns the base color for this banner + * + * @return the base color + */ + DyeColor getBaseColor(); + + /** + * Sets the base color for this banner + * + * @param color the base color + */ + void setBaseColor(DyeColor color); + + /** + * Returns a list of patterns on this banner + * + * @return the patterns + */ + List getPatterns(); + + /** + * Sets the patterns used on this banner + * + * @param patterns the new list of patterns + */ + void setPatterns(List patterns); + + /** + * Adds a new pattern on top of the existing + * patterns + * + * @param pattern the new pattern to add + */ + void addPattern(Pattern pattern); + + /** + * Returns the pattern at the specified index + * + * @param i the index + * @return the pattern + */ + Pattern getPattern(int i); + + /** + * Removes the pattern at the specified index + * + * @param i the index + * @return the removed pattern + */ + Pattern removePattern(int i); + + /** + * Sets the pattern at the specified index + * + * @param i the index + * @param pattern the new pattern + */ + void setPattern(int i, Pattern pattern); + + /** + * Returns the number of patterns on this + * banner + * + * @return the number of patterns + */ + int numberOfPatterns(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java new file mode 100644 index 0000000..4c2a746 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java @@ -0,0 +1,35 @@ + +package org.bukkit.inventory.meta; + +import org.bukkit.block.BlockState; + +public interface BlockStateMeta extends ItemMeta { + + /** + * Returns whether the item has a block state currently + * attached to it. + * + * @return whether a block state is already attached + */ + boolean hasBlockState(); + + /** + * Returns the currently attached block state for this + * item or creates a new one if one doesn't exist. + * + * The state is a copy, it must be set back (or to another + * item) with {@link #setBlockState(org.bukkit.block.BlockState)} + * + * @return the attached state or a new state + */ + BlockState getBlockState(); + + /** + * Attaches a copy of the passed block state to the item. + * + * @param blockState the block state to attach to the block. + * @throws IllegalArgumentException if the blockState is null + * or invalid for this item. + */ + void setBlockState(BlockState blockState); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BookMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BookMeta.java new file mode 100644 index 0000000..0017596 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/BookMeta.java @@ -0,0 +1,130 @@ +package org.bukkit.inventory.meta; + +import java.util.List; + +import org.bukkit.Material; + +/** + * Represents a book ({@link Material#BOOK_AND_QUILL} or {@link + * Material#WRITTEN_BOOK}) that can have a title, an author, and pages. + */ +public interface BookMeta extends ItemMeta { + + /** + * Checks for the existence of a title in the book. + * + * @return true if the book has a title + */ + boolean hasTitle(); + + /** + * Gets the title of the book. + *

+ * Plugins should check that hasTitle() returns true before calling this + * method. + * + * @return the title of the book + */ + String getTitle(); + + /** + * Sets the title of the book. + *

+ * Limited to 16 characters. Removes title when given null. + * + * @param title the title to set + * @return true if the title was successfully set + */ + boolean setTitle(String title); + + /** + * Checks for the existence of an author in the book. + * + * @return the author of the book + */ + boolean hasAuthor(); + + /** + * Gets the author of the book. + *

+ * Plugins should check that hasAuthor() returns true before calling this + * method. + * + * @return the author of the book + */ + String getAuthor(); + + /** + * Sets the author of the book. Removes author when given null. + * + * @param author the author of the book + */ + void setAuthor(String author); + + /** + * Checks for the existence of pages in the book. + * + * @return true if the book has pages + */ + boolean hasPages(); + + /** + * Gets the specified page in the book. The given page must exist. + * + * @param page the page number to get + * @return the page from the book + */ + String getPage(int page); + + /** + * Sets the specified page in the book. Pages of the book must be + * contiguous. + *

+ * The data can be up to 256 characters in length, additional characters + * are truncated. + * + * @param page the page number to set + * @param data the data to set for that page + */ + void setPage(int page, String data); + + /** + * Gets all the pages in the book. + * + * @return list of all the pages in the book + */ + List getPages(); + + /** + * Clears the existing book pages, and sets the book to use the provided + * pages. Maximum 50 pages with 256 characters per page. + * + * @param pages A list of pages to set the book to use + */ + void setPages(List pages); + + /** + * Clears the existing book pages, and sets the book to use the provided + * pages. Maximum 50 pages with 256 characters per page. + * + * @param pages A list of strings, each being a page + */ + void setPages(String... pages); + + /** + * Adds new pages to the end of the book. Up to a maximum of 50 pages with + * 256 characters per page. + * + * @param pages A list of strings, each being a page + */ + void addPage(String... pages); + + /** + * Gets the number of pages in the book. + * + * @return the number of pages in the book + */ + int getPageCount(); + + BookMeta clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/EnchantmentStorageMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/EnchantmentStorageMeta.java new file mode 100644 index 0000000..fb93d03 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/EnchantmentStorageMeta.java @@ -0,0 +1,79 @@ +package org.bukkit.inventory.meta; + +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; + +/** + * EnchantmentMeta is specific to items that can store enchantments, as + * opposed to being enchanted. {@link Material#ENCHANTED_BOOK} is an example + * of an item with enchantment storage. + */ +public interface EnchantmentStorageMeta extends ItemMeta { + + /** + * Checks for the existence of any stored enchantments. + * + * @return true if an enchantment exists on this meta + */ + boolean hasStoredEnchants(); + + /** + * Checks for storage of the specified enchantment. + * + * @param ench enchantment to check + * @return true if this enchantment is stored in this meta + */ + boolean hasStoredEnchant(Enchantment ench); + + /** + * Checks for the level of the stored enchantment. + * + * @param ench enchantment to check + * @return The level that the specified stored enchantment has, or 0 if + * none + */ + int getStoredEnchantLevel(Enchantment ench); + + /** + * Gets a copy the stored enchantments in this ItemMeta. + * + * @return An immutable copy of the stored enchantments + */ + Map getStoredEnchants(); + + /** + * Stores the specified enchantment in this item meta. + * + * @param ench Enchantment to store + * @param level Level for the enchantment + * @param ignoreLevelRestriction this indicates the enchantment should be + * applied, ignoring the level limit + * @return true if the item meta changed as a result of this call, false + * otherwise + * @throws IllegalArgumentException if enchantment is null + */ + boolean addStoredEnchant(Enchantment ench, int level, boolean ignoreLevelRestriction); + + /** + * Remove the specified stored enchantment from this item meta. + * + * @param ench Enchantment to remove + * @return true if the item meta changed as a result of this call, false + * otherwise + * @throws IllegalArgumentException if enchantment is null + */ + boolean removeStoredEnchant(Enchantment ench) throws IllegalArgumentException; + + /** + * Checks if the specified enchantment conflicts with any enchantments in + * this ItemMeta. + * + * @param ench enchantment to test + * @return true if the enchantment conflicts, false otherwise + */ + boolean hasConflictingStoredEnchant(Enchantment ench); + + EnchantmentStorageMeta clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/FireworkEffectMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/FireworkEffectMeta.java new file mode 100644 index 0000000..47046f1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/FireworkEffectMeta.java @@ -0,0 +1,34 @@ +package org.bukkit.inventory.meta; + +import org.bukkit.FireworkEffect; +import org.bukkit.Material; + +/** + * Represents a meta that can store a single FireworkEffect. An example + * includes {@link Material#FIREWORK_CHARGE}. + */ +public interface FireworkEffectMeta extends ItemMeta { + + /** + * Sets the firework effect for this meta. + * + * @param effect the effect to set, or null to indicate none. + */ + void setEffect(FireworkEffect effect); + + /** + * Checks if this meta has an effect. + * + * @return true if this meta has an effect, false otherwise + */ + boolean hasEffect(); + + /** + * Gets the firework effect for this meta. + * + * @return the current effect, or null if none + */ + FireworkEffect getEffect(); + + FireworkEffectMeta clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/FireworkMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/FireworkMeta.java new file mode 100644 index 0000000..1e3ee59 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/FireworkMeta.java @@ -0,0 +1,94 @@ +package org.bukkit.inventory.meta; + +import java.util.List; + +import org.bukkit.FireworkEffect; +import org.bukkit.Material; + +/** + * Represents a {@link Material#FIREWORK} and its effects. + */ +public interface FireworkMeta extends ItemMeta { + + /** + * Add another effect to this firework. + * + * @param effect The firework effect to add + * @throws IllegalArgumentException If effect is null + */ + void addEffect(FireworkEffect effect) throws IllegalArgumentException; + + /** + * Add several effects to this firework. + * + * @param effects The firework effects to add + * @throws IllegalArgumentException If effects is null + * @throws IllegalArgumentException If any effect is null (may be thrown + * after changes have occurred) + */ + void addEffects(FireworkEffect...effects) throws IllegalArgumentException; + + /** + * Add several firework effects to this firework. + * + * @param effects An iterable object whose iterator yields the desired + * firework effects + * @throws IllegalArgumentException If effects is null + * @throws IllegalArgumentException If any effect is null (may be thrown + * after changes have occurred) + */ + void addEffects(Iterable effects) throws IllegalArgumentException; + + /** + * Get the effects in this firework. + * + * @return An immutable list of the firework effects + */ + List getEffects(); + + /** + * Get the number of effects in this firework. + * + * @return The number of effects + */ + int getEffectsSize(); + + /** + * Remove an effect from this firework. + * + * @param index The index of the effect to remove + * @throws IndexOutOfBoundsException If index {@literal < 0 or index >} {@link + * #getEffectsSize()} + */ + void removeEffect(int index) throws IndexOutOfBoundsException; + + /** + * Remove all effects from this firework. + */ + void clearEffects(); + + /** + * Get whether this firework has any effects. + * + * @return true if it has effects, false if there are no effects + */ + boolean hasEffects(); + + /** + * Gets the approximate height the firework will fly. + * + * @return approximate flight height of the firework. + */ + int getPower(); + + /** + * Sets the approximate power of the firework. Each level of power is half + * a second of flight time. + * + * @param power the power of the firework, from 0-128 + * @throws IllegalArgumentException if {@literal height<0 or height>128} + */ + void setPower(int power) throws IllegalArgumentException; + + FireworkMeta clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/ItemMeta.java new file mode 100644 index 0000000..d8cc821 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/ItemMeta.java @@ -0,0 +1,188 @@ +package org.bukkit.inventory.meta; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; + +/** + * This type represents the storage mechanism for auxiliary item data. + *

+ * An implementation will handle the creation and application for ItemMeta. + * This class should not be implemented by a plugin in a live environment. + */ +public interface ItemMeta extends Cloneable, ConfigurationSerializable { + + /** + * Checks for existence of a display name. + * + * @return true if this has a display name + */ + boolean hasDisplayName(); + + /** + * Gets the display name that is set. + *

+ * Plugins should check that hasDisplayName() returns true + * before calling this method. + * + * @return the display name that is set + */ + String getDisplayName(); + + /** + * Sets the display name. + * + * @param name the name to set + */ + void setDisplayName(String name); + + /** + * Checks for existence of lore. + * + * @return true if this has lore + */ + boolean hasLore(); + + /** + * Gets the lore that is set. + *

+ * Plugins should check if hasLore() returns true before + * calling this method. + * + * @return a list of lore that is set + */ + List getLore(); + + /** + * Sets the lore for this item. + * Removes lore when given null. + * + * @param lore the lore that will be set + */ + void setLore(List lore); + + /** + * Checks for the existence of any enchantments. + * + * @return true if an enchantment exists on this meta + */ + boolean hasEnchants(); + + /** + * Checks for existence of the specified enchantment. + * + * @param ench enchantment to check + * @return true if this enchantment exists for this meta + */ + boolean hasEnchant(Enchantment ench); + + /** + * Checks for the level of the specified enchantment. + * + * @param ench enchantment to check + * @return The level that the specified enchantment has, or 0 if none + */ + int getEnchantLevel(Enchantment ench); + + /** + * Returns a copy the enchantments in this ItemMeta.
+ * Returns an empty map if none. + * + * @return An immutable copy of the enchantments + */ + Map getEnchants(); + + /** + * Adds the specified enchantment to this item meta. + * + * @param ench Enchantment to add + * @param level Level for the enchantment + * @param ignoreLevelRestriction this indicates the enchantment should be + * applied, ignoring the level limit + * @return true if the item meta changed as a result of this call, false + * otherwise + */ + boolean addEnchant(Enchantment ench, int level, boolean ignoreLevelRestriction); + + /** + * Removes the specified enchantment from this item meta. + * + * @param ench Enchantment to remove + * @return true if the item meta changed as a result of this call, false + * otherwise + */ + boolean removeEnchant(Enchantment ench); + + /** + * Checks if the specified enchantment conflicts with any enchantments in + * this ItemMeta. + * + * @param ench enchantment to test + * @return true if the enchantment conflicts, false otherwise + */ + boolean hasConflictingEnchant(Enchantment ench); + + /** + * Set itemflags which should be ignored when rendering a ItemStack in the Client. This Method does silently ignore double set itemFlags. + * + * @param itemFlags The hideflags which shouldn't be rendered + */ + void addItemFlags(ItemFlag... itemFlags); + + /** + * Remove specific set of itemFlags. This tells the Client it should render it again. This Method does silently ignore double removed itemFlags. + * + * @param itemFlags Hideflags which should be removed + */ + void removeItemFlags(ItemFlag... itemFlags); + + /** + * Get current set itemFlags. The collection returned is unmodifiable. + * + * @return A set of all itemFlags set + */ + Set getItemFlags(); + + /** + * Check if the specified flag is present on this item. + * + * @param flag the flag to check + * @return if it is present + */ + boolean hasItemFlag(ItemFlag flag); + + @SuppressWarnings("javadoc") + ItemMeta clone(); + + // Spigot start + public class Spigot + { + + /** + * Sets the unbreakable tag + * + * @param unbreakable true if set unbreakable + */ + public void setUnbreakable(boolean unbreakable) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Return if the unbreakable tag is true + * + * @return true if the unbreakable tag is true + */ + public boolean isUnbreakable() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java new file mode 100644 index 0000000..2dc2420 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java @@ -0,0 +1,31 @@ +package org.bukkit.inventory.meta; + +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.inventory.ItemFactory; + +/** + * Represents leather armor ({@link Material#LEATHER_BOOTS}, {@link + * Material#LEATHER_CHESTPLATE}, {@link Material#LEATHER_HELMET}, or {@link + * Material#LEATHER_LEGGINGS}) that can be colored. + */ +public interface LeatherArmorMeta extends ItemMeta { + + /** + * Gets the color of the armor. If it has not been set otherwise, it will + * be {@link ItemFactory#getDefaultLeatherColor()}. + * + * @return the color of the armor, never null + */ + Color getColor(); + + /** + * Sets the color of the armor. + * + * @param color the color to set. Setting it to null is equivalent to + * setting it to {@link ItemFactory#getDefaultLeatherColor()}. + */ + void setColor(Color color); + + LeatherArmorMeta clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/MapMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/MapMeta.java new file mode 100644 index 0000000..fb5c297 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/MapMeta.java @@ -0,0 +1,23 @@ +package org.bukkit.inventory.meta; + +/** + * Represents a map that can be scalable. + */ +public interface MapMeta extends ItemMeta { + + /** + * Checks to see if this map is scaling. + * + * @return true if this map is scaling + */ + boolean isScaling(); + + /** + * Sets if this map is scaling or not. + * + * @param value true to scale + */ + void setScaling(boolean value); + + MapMeta clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/PotionMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/PotionMeta.java new file mode 100644 index 0000000..8dca983 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/PotionMeta.java @@ -0,0 +1,77 @@ +package org.bukkit.inventory.meta; + +import org.bukkit.Material; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.List; + +/** + * Represents a potion ({@link Material#POTION}) that can have custom effects. + */ +public interface PotionMeta extends ItemMeta { + + /** + * Checks for the presence of custom potion effects. + * + * @return true if custom potion effects are applied + */ + boolean hasCustomEffects(); + + /** + * Gets an immutable list containing all custom potion effects applied to + * this potion. + *

+ * Plugins should check that hasCustomEffects() returns true before + * calling this method. + * + * @return the immutable list of custom potion effects + */ + List getCustomEffects(); + + /** + * Adds a custom potion effect to this potion. + * + * @param effect the potion effect to add + * @param overwrite true if any existing effect of the same type should be + * overwritten + * @return true if the potion meta changed as a result of this call + */ + boolean addCustomEffect(PotionEffect effect, boolean overwrite); + + /** + * Removes a custom potion effect from this potion. + * + * @param type the potion effect type to remove + * @return true if the potion meta changed as a result of this call + */ + boolean removeCustomEffect(PotionEffectType type); + + /** + * Checks for a specific custom potion effect type on this potion. + * + * @param type the potion effect type to check for + * @return true if the potion has this effect + */ + boolean hasCustomEffect(PotionEffectType type); + + /** + * Moves a potion effect to the top of the potion effect list. + *

+ * This causes the client to display the potion effect in the potion's + * name. + * + * @param type the potion effect type to move + * @return true if the potion meta changed as a result of this call + */ + boolean setMainEffect(PotionEffectType type); + + /** + * Removes all custom potion effects from this potion. + * + * @return true if the potion meta changed as a result of this call + */ + boolean clearCustomEffects(); + + PotionMeta clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/Repairable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/Repairable.java new file mode 100644 index 0000000..c49844e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/Repairable.java @@ -0,0 +1,31 @@ +package org.bukkit.inventory.meta; + +/** + * Represents an item that can be repaired at an anvil. + */ +public interface Repairable { + + /** + * Checks to see if this has a repair penalty + * + * @return true if this has a repair penalty + */ + boolean hasRepairCost(); + + /** + * Gets the repair penalty + * + * @return the repair penalty + */ + int getRepairCost(); + + /** + * Sets the repair penalty + * + * @param cost repair penalty + */ + void setRepairCost(int cost); + + @SuppressWarnings("javadoc") + Repairable clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/SkullMeta.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/SkullMeta.java new file mode 100644 index 0000000..fab3119 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/inventory/meta/SkullMeta.java @@ -0,0 +1,36 @@ +package org.bukkit.inventory.meta; + +import org.bukkit.Material; + +/** + * Represents a skull ({@link Material#SKULL_ITEM}) that can have an owner. + */ +public interface SkullMeta extends ItemMeta { + + /** + * Gets the owner of the skull. + * + * @return the owner if the skull + */ + String getOwner(); + + /** + * Checks to see if the skull has an owner. + * + * @return true if the skull has an owner + */ + boolean hasOwner(); + + /** + * Sets the owner of the skull. + *

+ * Plugins should check that hasOwner() returns true before calling this + * plugin. + * + * @param owner the new owner of the skull + * @return true if the owner was successfully set + */ + boolean setOwner(String owner); + + SkullMeta clone(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCanvas.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCanvas.java new file mode 100644 index 0000000..d68bb17 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCanvas.java @@ -0,0 +1,84 @@ +package org.bukkit.map; + +import java.awt.Image; + +/** + * Represents a canvas for drawing to a map. Each canvas is associated with a + * specific {@link MapRenderer} and represents that renderer's layer on the + * map. + */ +public interface MapCanvas { + + /** + * Get the map this canvas is attached to. + * + * @return The MapView this canvas is attached to. + */ + public MapView getMapView(); + + /** + * Get the cursor collection associated with this canvas. + * + * @return The MapCursorCollection associated with this canvas. + */ + public MapCursorCollection getCursors(); + + /** + * Set the cursor collection associated with this canvas. This does not + * usually need to be called since a MapCursorCollection is already + * provided. + * + * @param cursors The MapCursorCollection to associate with this canvas. + */ + public void setCursors(MapCursorCollection cursors); + + /** + * Draw a pixel to the canvas. + * + * @param x The x coordinate, from 0 to 127. + * @param y The y coordinate, from 0 to 127. + * @param color The color. See {@link MapPalette}. + */ + public void setPixel(int x, int y, byte color); + + /** + * Get a pixel from the canvas. + * + * @param x The x coordinate, from 0 to 127. + * @param y The y coordinate, from 0 to 127. + * @return The color. See {@link MapPalette}. + */ + public byte getPixel(int x, int y); + + /** + * Get a pixel from the layers below this canvas. + * + * @param x The x coordinate, from 0 to 127. + * @param y The y coordinate, from 0 to 127. + * @return The color. See {@link MapPalette}. + */ + public byte getBasePixel(int x, int y); + + /** + * Draw an image to the map. The image will be clipped if necessary. + * + * @param x The x coordinate of the image. + * @param y The y coordinate of the image. + * @param image The Image to draw. + */ + public void drawImage(int x, int y, Image image); + + /** + * Render text to the map using fancy formatting. Newline (\n) characters + * will move down one line and return to the original column, and the text + * color can be changed using sequences such as "§12;", replacing 12 with + * the palette index of the color (see {@link MapPalette}). + * + * @param x The column to start rendering on. + * @param y The row to start rendering on. + * @param font The font to use. + * @param text The formatted text to render. + */ + public void drawText(int x, int y, MapFont font, String text); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCursor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCursor.java new file mode 100644 index 0000000..5231749 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCursor.java @@ -0,0 +1,192 @@ +package org.bukkit.map; + +/** + * Represents a cursor on a map. + */ +public final class MapCursor { + private byte x, y; + private byte direction, type; + private boolean visible; + + /** + * Initialize the map cursor. + * + * @param x The x coordinate, from -128 to 127. + * @param y The y coordinate, from -128 to 127. + * @param direction The facing of the cursor, from 0 to 15. + * @param type The type (color/style) of the map cursor. + * @param visible Whether the cursor is visible by default. + * @deprecated Magic value + */ + @Deprecated + public MapCursor(byte x, byte y, byte direction, byte type, boolean visible) { + this.x = x; + this.y = y; + setDirection(direction); + setRawType(type); + this.visible = visible; + } + + /** + * Get the X position of this cursor. + * + * @return The X coordinate. + */ + public byte getX() { + return x; + } + + /** + * Get the Y position of this cursor. + * + * @return The Y coordinate. + */ + public byte getY() { + return y; + } + + /** + * Get the direction of this cursor. + * + * @return The facing of the cursor, from 0 to 15. + */ + public byte getDirection() { + return direction; + } + + /** + * Get the type of this cursor. + * + * @return The type (color/style) of the map cursor. + */ + public Type getType() { + return Type.byValue(type); + } + + /** + * Get the type of this cursor. + * + * @return The type (color/style) of the map cursor. + * @deprecated Magic value + */ + @Deprecated + public byte getRawType() { + return type; + } + + /** + * Get the visibility status of this cursor. + * + * @return True if visible, false otherwise. + */ + public boolean isVisible() { + return visible; + } + + /** + * Set the X position of this cursor. + * + * @param x The X coordinate. + */ + public void setX(byte x) { + this.x = x; + } + + /** + * Set the Y position of this cursor. + * + * @param y The Y coordinate. + */ + public void setY(byte y) { + this.y = y; + } + + /** + * Set the direction of this cursor. + * + * @param direction The facing of the cursor, from 0 to 15. + */ + public void setDirection(byte direction) { + if (direction < 0 || direction > 15) { + throw new IllegalArgumentException("Direction must be in the range 0-15"); + } + this.direction = direction; + } + + /** + * Set the type of this cursor. + * + * @param type The type (color/style) of the map cursor. + */ + public void setType(Type type) { + setRawType(type.value); + } + + /** + * Set the type of this cursor. + * + * @param type The type (color/style) of the map cursor. + * @deprecated Magic value + */ + @Deprecated + public void setRawType(byte type) { + if (type < 0 || type > 15) { + throw new IllegalArgumentException("Type must be in the range 0-15"); + } + this.type = type; + } + + /** + * Set the visibility status of this cursor. + * + * @param visible True if visible. + */ + public void setVisible(boolean visible) { + this.visible = visible; + } + + /** + * Represents the standard types of map cursors. More may be made + * available by texture packs - the value is used by the client as an + * index in the file './misc/mapicons.png' from minecraft.jar or from a + * texture pack. + */ + public enum Type { + WHITE_POINTER(0), + GREEN_POINTER(1), + RED_POINTER(2), + BLUE_POINTER(3), + WHITE_CROSS(4); + + private byte value; + + private Type(int value) { + this.value = (byte) value; + } + + /** + * + * @return the value + * @deprecated Magic value + */ + @Deprecated + public byte getValue() { + return value; + } + + /** + * + * @param value the value + * @return the matching type + * @deprecated Magic value + */ + @Deprecated + public static Type byValue(byte value) { + for (Type t : values()) { + if (t.value == value) return t; + } + return null; + } + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCursorCollection.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCursorCollection.java new file mode 100644 index 0000000..1dc9025 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapCursorCollection.java @@ -0,0 +1,96 @@ +package org.bukkit.map; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents all the map cursors on a {@link MapCanvas}. Like MapCanvas, a + * MapCursorCollection is linked to a specific {@link MapRenderer}. + */ +public final class MapCursorCollection { + private List cursors = new ArrayList(); + + /** + * Get the amount of cursors in this collection. + * + * @return The size of this collection. + */ + public int size() { + return cursors.size(); + } + + /** + * Get a cursor from this collection. + * + * @param index The index of the cursor. + * @return The MapCursor. + */ + public MapCursor getCursor(int index) { + return cursors.get(index); + } + + /** + * Remove a cursor from the collection. + * + * @param cursor The MapCursor to remove. + * @return Whether the cursor was removed successfully. + */ + public boolean removeCursor(MapCursor cursor) { + return cursors.remove(cursor); + } + + /** + * Add a cursor to the collection. + * + * @param cursor The MapCursor to add. + * @return The MapCursor that was passed. + */ + public MapCursor addCursor(MapCursor cursor) { + cursors.add(cursor); + return cursor; + } + + /** + * Add a cursor to the collection. + * + * @param x The x coordinate, from -128 to 127. + * @param y The y coordinate, from -128 to 127. + * @param direction The facing of the cursor, from 0 to 15. + * @return The newly added MapCursor. + */ + public MapCursor addCursor(int x, int y, byte direction) { + return addCursor(x, y, direction, (byte) 0, true); + } + + /** + * Add a cursor to the collection. + * + * @param x The x coordinate, from -128 to 127. + * @param y The y coordinate, from -128 to 127. + * @param direction The facing of the cursor, from 0 to 15. + * @param type The type (color/style) of the map cursor. + * @return The newly added MapCursor. + * @deprecated Magic value + */ + @Deprecated + public MapCursor addCursor(int x, int y, byte direction, byte type) { + return addCursor(x, y, direction, type, true); + } + + /** + * Add a cursor to the collection. + * + * @param x The x coordinate, from -128 to 127. + * @param y The y coordinate, from -128 to 127. + * @param direction The facing of the cursor, from 0 to 15. + * @param type The type (color/style) of the map cursor. + * @param visible Whether the cursor is visible. + * @return The newly added MapCursor. + * @deprecated Magic value + */ + @Deprecated + public MapCursor addCursor(int x, int y, byte direction, byte type, boolean visible) { + return addCursor(new MapCursor((byte) x, (byte) y, direction, type, visible)); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapFont.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapFont.java new file mode 100644 index 0000000..ea8f0ea --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapFont.java @@ -0,0 +1,144 @@ +package org.bukkit.map; + +import java.util.HashMap; + +/** + * Represents a bitmap font drawable to a map. + */ +public class MapFont { + + private final HashMap chars = new HashMap(); + private int height = 0; + protected boolean malleable = true; + + /** + * Set the sprite for a given character. + * + * @param ch The character to set the sprite for. + * @param sprite The CharacterSprite to set. + * @throws IllegalStateException if this font is static. + */ + public void setChar(char ch, CharacterSprite sprite) { + if (!malleable) { + throw new IllegalStateException("this font is not malleable"); + } + + chars.put(ch, sprite); + if (sprite.getHeight() > height) { + height = sprite.getHeight(); + } + } + + /** + * Get the sprite for a given character. + * + * @param ch The character to get the sprite for. + * @return The CharacterSprite associated with the character, or null if + * there is none. + */ + public CharacterSprite getChar(char ch) { + return chars.get(ch); + } + + /** + * Get the width of the given text as it would be rendered using this + * font. + * + * @param text The text. + * @return The width in pixels. + */ + public int getWidth(String text) { + if (!isValid(text)) { + throw new IllegalArgumentException("text contains invalid characters"); + } + + if (text.length() == 0){ + return 0; + } + + int result = 0; + for (int i = 0; i < text.length(); ++i) { + result += chars.get(text.charAt(i)).getWidth(); + } + result += text.length() - 1; // Account for 1px spacing between characters + + return result; + } + + /** + * Get the height of this font. + * + * @return The height of the font. + */ + public int getHeight() { + return height; + } + + /** + * Check whether the given text is valid. + * + * @param text The text. + * @return True if the string contains only defined characters, false + * otherwise. + */ + public boolean isValid(String text) { + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch == '\u00A7' || ch == '\n') continue; + if (chars.get(ch) == null) return false; + } + return true; + } + + /** + * Represents the graphics for a single character in a MapFont. + */ + public static class CharacterSprite { + + private final int width; + private final int height; + private final boolean[] data; + + public CharacterSprite(int width, int height, boolean[] data) { + this.width = width; + this.height = height; + this.data = data; + + if (data.length != width * height) { + throw new IllegalArgumentException("size of data does not match dimensions"); + } + } + + /** + * Get the value of a pixel of the character. + * + * @param row The row, in the range [0,8). + * @param col The column, in the range [0,8). + * @return True if the pixel is solid, false if transparent. + */ + public boolean get(int row, int col) { + if (row < 0 || col < 0 || row >= height || col >= width) return false; + return data[row * width + col]; + } + + /** + * Get the width of the character sprite. + * + * @return The width of the character. + */ + public int getWidth() { + return width; + } + + /** + * Get the height of the character sprite. + * + * @return The height of the character. + */ + public int getHeight() { + return height; + } + + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapPalette.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapPalette.java new file mode 100644 index 0000000..3aca081 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapPalette.java @@ -0,0 +1,240 @@ +package org.bukkit.map; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; + +/** + * Represents the palette that map items use. + *

+ * These fields are hee base color ranges. Each entry corresponds to four + * colors of varying shades with values entry to entry + 3. + */ +public final class MapPalette { + // Internal mechanisms + private MapPalette() {} + + private static Color c(int r, int g, int b) { + return new Color(r, g, b); + } + + private static double getDistance(Color c1, Color c2) { + double rmean = (c1.getRed() + c2.getRed()) / 2.0; + double r = c1.getRed() - c2.getRed(); + double g = c1.getGreen() - c2.getGreen(); + int b = c1.getBlue() - c2.getBlue(); + double weightR = 2 + rmean / 256.0; + double weightG = 4.0; + double weightB = 2 + (255 - rmean) / 256.0; + return weightR * r * r + weightG * g * g + weightB * b * b; + } + + static final Color[] colors = { + c(0, 0, 0), c(0, 0, 0), c(0, 0, 0), c(0, 0, 0), + c(89, 125, 39), c(109, 153, 48), c(127, 178, 56), c(67, 94, 29), + c(174, 164, 115), c(213, 201, 140), c(247, 233, 163), c(130, 123, 86), + c(140, 140, 140), c(171, 171, 171), c(199, 199, 199), c(105, 105, 105), + c(180, 0, 0), c(220, 0, 0), c(255, 0, 0), c(135, 0, 0), + c(112, 112, 180), c(138, 138, 220), c(160, 160, 255), c(84, 84, 135), + c(117, 117, 117), c(144, 144, 144), c(167, 167, 167), c(88, 88, 88), + c(0, 87, 0), c(0, 106, 0), c(0, 124, 0), c(0, 65, 0), + c(180, 180, 180), c(220, 220, 220), c(255, 255, 255), c(135, 135, 135), + c(115, 118, 129), c(141, 144, 158), c(164, 168, 184), c(86, 88, 97), + c(106, 76, 54), c(130, 94, 66), c(151, 109, 77), c(79, 57, 40), + c(79, 79, 79), c(96, 96, 96), c(112, 112, 112), c(59, 59, 59), + c(45, 45, 180), c(55, 55, 220), c(64, 64, 255), c(33, 33, 135), + c(100, 84, 50), c(123, 102, 62), c(143, 119, 72), c(75, 63, 38), + c(180, 177, 172), c(220, 217, 211), c(255, 252, 245), c(135, 133, 129), + c(152, 89, 36), c(186, 109, 44), c(216, 127, 51), c(114, 67, 27), + c(125, 53, 152), c(153, 65, 186), c(178, 76, 216), c(94, 40, 114), + c(72, 108, 152), c(88, 132, 186), c(102, 153, 216), c(54, 81, 114), + c(161, 161, 36), c(197, 197, 44), c(229, 229, 51), c(121, 121, 27), + c(89, 144, 17), c(109, 176, 21), c(127, 204, 25), c(67, 108, 13), + c(170, 89, 116), c(208, 109, 142), c(242, 127, 165), c(128, 67, 87), + c(53, 53, 53), c(65, 65, 65), c(76, 76, 76), c(40, 40, 40), + c(108, 108, 108), c(132, 132, 132), c(153, 153, 153), c(81, 81, 81), + c(53, 89, 108), c(65, 109, 132), c(76, 127, 153), c(40, 67, 81), + c(89, 44, 125), c(109, 54, 153), c(127, 63, 178), c(67, 33, 94), + c(36, 53, 125), c(44, 65, 153), c(51, 76, 178), c(27, 40, 94), + c(72, 53, 36), c(88, 65, 44), c(102, 76, 51), c(54, 40, 27), + c(72, 89, 36), c(88, 109, 44), c(102, 127, 51), c(54, 67, 27), + c(108, 36, 36), c(132, 44, 44), c(153, 51, 51), c(81, 27, 27), + c(17, 17, 17), c(21, 21, 21), c(25, 25, 25), c(13, 13, 13), + c(176, 168, 54), c(215, 205, 66), c(250, 238, 77), c(132, 126, 40), + c(64, 154, 150), c(79, 188, 183), c(92, 219, 213), c(48, 115, 112), + c(52, 90, 180), c(63, 110, 220), c(74, 128, 255), c(39, 67, 135), + c(0, 153, 40), c(0, 187, 50), c(0, 217, 58), c(0, 114, 30), + c(91, 60, 34), c(111, 74, 42), c(129, 86, 49), c(68, 45, 25), + c(79, 1, 0), c(96, 1, 0), c(112, 2, 0), c(59, 1, 0), + }; + + // Interface + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte TRANSPARENT = 0; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte LIGHT_GREEN = 4; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte LIGHT_BROWN = 8; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte GRAY_1 = 12; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte RED = 16; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte PALE_BLUE = 20; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte GRAY_2 = 24; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte DARK_GREEN = 28; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte WHITE = 32; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte LIGHT_GRAY = 36; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte BROWN = 40; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte DARK_GRAY = 44; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte BLUE = 48; + /** + * @deprecated Magic value + */ + @Deprecated + public static final byte DARK_BROWN = 52; + + /** + * Resize an image to 128x128. + * + * @param image The image to resize. + * @return The resized image. + */ + public static BufferedImage resizeImage(Image image) { + BufferedImage result = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = result.createGraphics(); + graphics.drawImage(image, 0, 0, 128, 128, null); + graphics.dispose(); + return result; + } + + /** + * Convert an Image to a byte[] using the palette. + * + * @param image The image to convert. + * @return A byte[] containing the pixels of the image. + * @deprecated Magic value + */ + @Deprecated + public static byte[] imageToBytes(Image image) { + BufferedImage temp = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB); + Graphics2D graphics = temp.createGraphics(); + graphics.drawImage(image, 0, 0, null); + graphics.dispose(); + + int[] pixels = new int[temp.getWidth() * temp.getHeight()]; + temp.getRGB(0, 0, temp.getWidth(), temp.getHeight(), pixels, 0, temp.getWidth()); + + byte[] result = new byte[temp.getWidth() * temp.getHeight()]; + for (int i = 0; i < pixels.length; i++) { + result[i] = matchColor(new Color(pixels[i], true)); + } + return result; + } + + /** + * Get the index of the closest matching color in the palette to the given + * color. + * + * @param r The red component of the color. + * @param b The blue component of the color. + * @param g The green component of the color. + * @return The index in the palette. + * @deprecated Magic value + */ + @Deprecated + public static byte matchColor(int r, int g, int b) { + return matchColor(new Color(r, g, b)); + } + + /** + * Get the index of the closest matching color in the palette to the given + * color. + * + * @param color The Color to match. + * @return The index in the palette. + * @deprecated Magic value + */ + @Deprecated + public static byte matchColor(Color color) { + if (color.getAlpha() < 128) return 0; + + int index = 0; + double best = -1; + + for (int i = 4; i < colors.length; i++) { + double distance = getDistance(color, colors[i]); + if (distance < best || best == -1) { + best = distance; + index = i; + } + } + + // Minecraft has 143 colors, some of which have negative byte representations + return (byte) (index < 128 ? index : -129 + (index - 127)); + } + + /** + * Get the value of the given color in the palette. + * + * @param index The index in the palette. + * @return The Color of the palette entry. + * @deprecated Magic value + */ + @Deprecated + public static Color getColor(byte index) { + if ((index > -113 && index < 0) || index > 127) { + throw new IndexOutOfBoundsException(); + } else { + // Minecraft has 143 colors, some of which have negative byte representations + return colors[index >= 0 ? index : index + 256]; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapRenderer.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapRenderer.java new file mode 100644 index 0000000..322d0ce --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapRenderer.java @@ -0,0 +1,56 @@ +package org.bukkit.map; + +import org.bukkit.entity.Player; + +/** + * Represents a renderer for a map. + */ +public abstract class MapRenderer { + + private boolean contextual; + + /** + * Initialize the map renderer base to be non-contextual. See {@link + * #isContextual()}. + */ + public MapRenderer() { + this(false); + } + + /** + * Initialize the map renderer base with the given contextual status. + * + * @param contextual Whether the renderer is contextual. See {@link + * #isContextual()}. + */ + public MapRenderer(boolean contextual) { + this.contextual = contextual; + } + + /** + * Get whether the renderer is contextual, i.e. has different canvases for + * different players. + * + * @return True if contextual, false otherwise. + */ + final public boolean isContextual() { + return contextual; + } + + /** + * Initialize this MapRenderer for the given map. + * + * @param map The MapView being initialized. + */ + public void initialize(MapView map) {} + + /** + * Render to the given map. + * + * @param map The MapView being rendered to. + * @param canvas The canvas to use for rendering. + * @param player The player who triggered the rendering. + */ + abstract public void render(MapView map, MapCanvas canvas, Player player); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapView.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapView.java new file mode 100644 index 0000000..65c4159 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MapView.java @@ -0,0 +1,157 @@ +package org.bukkit.map; + +import java.util.List; +import org.bukkit.World; + +/** + * Represents a map item. + */ +public interface MapView { + + /** + * An enum representing all possible scales a map can be set to. + */ + public static enum Scale { + CLOSEST(0), + CLOSE(1), + NORMAL(2), + FAR(3), + FARTHEST(4); + + private byte value; + + private Scale(int value) { + this.value = (byte) value; + } + + /** + * Get the scale given the raw value. + * + * @param value The raw scale + * @return The enum scale, or null for an invalid input + * @deprecated Magic value + */ + @Deprecated + public static Scale valueOf(byte value) { + switch (value) { + case 0: return CLOSEST; + case 1: return CLOSE; + case 2: return NORMAL; + case 3: return FAR; + case 4: return FARTHEST; + default: return null; + } + } + + /** + * Get the raw value of this scale level. + * + * @return The scale value + * @deprecated Magic value + */ + @Deprecated + public byte getValue() { + return value; + } + } + + /** + * Get the ID of this map item. Corresponds to the damage value of a map + * in an inventory. + * + * @return The ID of the map. + * @deprecated Magic value + */ + @Deprecated + public short getId(); + + /** + * Check whether this map is virtual. A map is virtual if its lowermost + * MapRenderer is plugin-provided. + * + * @return Whether the map is virtual. + */ + public boolean isVirtual(); + + /** + * Get the scale of this map. + * + * @return The scale of the map. + */ + public Scale getScale(); + + /** + * Set the scale of this map. + * + * @param scale The scale to set. + */ + public void setScale(Scale scale); + + /** + * Get the center X position of this map. + * + * @return The center X position. + */ + public int getCenterX(); + + /** + * Get the center Z position of this map. + * + * @return The center Z position. + */ + public int getCenterZ(); + + /** + * Set the center X position of this map. + * + * @param x The center X position. + */ + public void setCenterX(int x); + + /** + * Set the center Z position of this map. + * + * @param z The center Z position. + */ + public void setCenterZ(int z); + + /** + * Get the world that this map is associated with. Primarily used by the + * internal renderer, but may be used by external renderers. May return + * null if the world the map is associated with is not loaded. + * + * @return The World this map is associated with. + */ + public World getWorld(); + + /** + * Set the world that this map is associated with. The world is used by + * the internal renderer, and may also be used by external renderers. + * + * @param world The World to associate this map with. + */ + public void setWorld(World world); + + /** + * Get a list of MapRenderers currently in effect. + * + * @return A {@code List} containing each map renderer. + */ + public List getRenderers(); + + /** + * Add a renderer to this map. + * + * @param renderer The MapRenderer to add. + */ + public void addRenderer(MapRenderer renderer); + + /** + * Remove a renderer from this map. + * + * @param renderer The MapRenderer to remove. + * @return True if the renderer was successfully removed. + */ + public boolean removeRenderer(MapRenderer renderer); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MinecraftFont.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MinecraftFont.java new file mode 100644 index 0000000..9ec8d10 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/map/MinecraftFont.java @@ -0,0 +1,328 @@ +package org.bukkit.map; + +/** + * Represents the built-in Minecraft font. + */ +public class MinecraftFont extends MapFont { + + private static final int spaceSize = 2; + + private static final String fontChars = + " !\"#$%&'()*+,-./0123456789:;<=>?" + + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" + + "'abcdefghijklmnopqrstuvwxyz{|}~\u007F" + + "\u00C7\u00FC\u00E9\u00E2\u00E4\u00E0\u00E5\u00E7" + // Çüéâäàåç + "\u00EA\u00EB\u00E8\u00EF\u00EE\u00EC\u00C4\u00C5" + // êëèïîìÄÅ + "\u00C9\u00E6\u00C6\u00F4\u00F6\u00F2\u00FB\u00F9" + // ÉæÆôöòûù + "\u00FF\u00D6\u00DC\u00F8\u00A3\u00D8\u00D7\u0191" + // ÿÖÜø£Ø׃ + "\u00E1\u00ED\u00F3\u00FA\u00F1\u00D1\u00AA\u00BA" + // áíóúñѪº + "\u00BF\u00AE\u00AC\u00BD\u00BC\u00A1\u00AB\u00BB"; // ¿®¬½¼¡«» + + private static final int[][] fontData = new int[][] { + /* null */ {0,0,0,0,0,0,0,0}, + /* 1 */ {126,129,165,129,189,153,129,126}, + /* 2 */ {126,255,219,255,195,231,255,126}, + /* 3 */ {54,127,127,127,62,28,8,0}, + /* 4 */ {8,28,62,127,62,28,8,0}, + /* 5 */ {28,62,28,127,127,62,28,62}, + /* 6 */ {8,8,28,62,127,62,28,62}, + /* 7 */ {0,0,24,60,60,24,0,0}, + /* 8 */ {255,255,231,195,195,231,255,255}, + /* 9 */ {0,60,102,66,66,102,60,0}, + /* 10 */ {255,195,153,189,189,153,195,255}, + /* 11 */ {240,224,240,190,51,51,51,30}, + /* 12 */ {60,102,102,102,60,24,126,24}, + /* 13 */ {252,204,252,12,12,14,15,7}, + /* 14 */ {254,198,254,198,198,230,103,3}, + /* 15 */ {153,90,60,231,231,60,90,153}, + /* 16 */ {1,7,31,127,31,7,1,0}, + /* 17 */ {64,112,124,127,124,112,64,0}, + /* 18 */ {24,60,126,24,24,126,60,24}, + /* 19 */ {102,102,102,102,102,0,102,0}, + /* 20 */ {254,219,219,222,216,216,216,0}, + /* 21 */ {124,198,28,54,54,28,51,30}, + /* 22 */ {0,0,0,0,126,126,126,0}, + /* 23 */ {24,60,126,24,126,60,24,255}, + /* 24 */ {24,60,126,24,24,24,24,0}, + /* 25 */ {24,24,24,24,126,60,24,0}, + /* 26 */ {0,24,48,127,48,24,0,0}, + /* 27 */ {0,12,6,127,6,12,0,0}, + /* 28 */ {0,0,3,3,3,127,0,0}, + /* 29 */ {0,36,102,255,102,36,0,0}, + /* 30 */ {0,24,60,126,255,255,0,0}, + /* 31 */ {0,255,255,126,60,24,0,0}, + /* */ {0,0,0,0,0,0,0,0}, + /* ! */ {1,1,1,1,1,0,1,0}, + /* " */ {10,10,5,0,0,0,0,0}, + /* # */ {10,10,31,10,31,10,10,0}, + /* $ */ {4,30,1,14,16,15,4,0}, + /* % */ {17,9,8,4,2,18,17,0}, + /* & */ {4,10,4,22,13,9,22,0}, + /* ' */ {2,2,1,0,0,0,0,0}, + /* ( */ {12,2,1,1,1,2,12,0}, + /* ) */ {3,4,8,8,8,4,3,0}, + /* * */ {0,0,9,6,9,0,0,0}, + /* + */ {0,4,4,31,4,4,0,0}, + /* , */ {0,0,0,0,0,1,1,1}, + /* - */ {0,0,0,31,0,0,0,0}, + /* . */ {0,0,0,0,0,1,1,0}, + /* / */ {16,8,8,4,2,2,1,0}, + /* 0 */ {14,17,25,21,19,17,14,0}, + /* 1 */ {4,6,4,4,4,4,31,0}, + /* 2 */ {14,17,16,12,2,17,31,0}, + /* 3 */ {14,17,16,12,16,17,14,0}, + /* 4 */ {24,20,18,17,31,16,16,0}, + /* 5 */ {31,1,15,16,16,17,14,0}, + /* 6 */ {12,2,1,15,17,17,14,0}, + /* 7 */ {31,17,16,8,4,4,4,0}, + /* 8 */ {14,17,17,14,17,17,14,0}, + /* 9 */ {14,17,17,30,16,8,6,0}, + /* : */ {0,1,1,0,0,1,1,0}, + /* ; */ {0,1,1,0,0,1,1,1}, + /* < */ {8,4,2,1,2,4,8,0}, + /* = */ {0,0,31,0,0,31,0,0}, + /* > */ {1,2,4,8,4,2,1,0}, + /* ? */ {14,17,16,8,4,0,4,0}, + /* @ */ {30,33,45,45,61,1,30,0}, + /* A */ {14,17,31,17,17,17,17,0}, + /* B */ {15,17,15,17,17,17,15,0}, + /* C */ {14,17,1,1,1,17,14,0}, + /* D */ {15,17,17,17,17,17,15,0}, + /* E */ {31,1,7,1,1,1,31,0}, + /* F */ {31,1,7,1,1,1,1,0}, + /* G */ {30,1,25,17,17,17,14,0}, + /* H */ {17,17,31,17,17,17,17,0}, + /* I */ {7,2,2,2,2,2,7,0}, + /* J */ {16,16,16,16,16,17,14,0}, + /* K */ {17,9,7,9,17,17,17,0}, + /* L */ {1,1,1,1,1,1,31,0}, + /* M */ {17,27,21,17,17,17,17,0}, + /* N */ {17,19,21,25,17,17,17,0}, + /* O */ {14,17,17,17,17,17,14,0}, + /* P */ {15,17,15,1,1,1,1,0}, + /* Q */ {14,17,17,17,17,9,22,0}, + /* R */ {15,17,15,17,17,17,17,0}, + /* S */ {30,1,14,16,16,17,14,0}, + /* T */ {31,4,4,4,4,4,4,0}, + /* U */ {17,17,17,17,17,17,14,0}, + /* V */ {17,17,17,17,10,10,4,0}, + /* W */ {17,17,17,17,21,27,17,0}, + /* X */ {17,10,4,10,17,17,17,0}, + /* Y */ {17,10,4,4,4,4,4,0}, + /* Z */ {31,16,8,4,2,1,31,0}, + /* [ */ {7,1,1,1,1,1,7,0}, + /* \ */ {1,2,2,4,8,8,16,0}, + /* ] */ {7,4,4,4,4,4,7,0}, + /* ^ */ {4,10,17,0,0,0,0,0}, + /* _ */ {0,0,0,0,0,0,0,31}, + /* ` */ {1,1,2,0,0,0,0,0}, + /* a */ {0,0,14,16,30,17,30,0}, + /* b */ {1,1,13,19,17,17,15,0}, + /* c */ {0,0,14,17,1,17,14,0}, + /* d */ {16,16,22,25,17,17,30,0}, + /* e */ {0,0,14,17,31,1,30,0}, + /* f */ {12,2,15,2,2,2,2,0}, + /* g */ {0,0,30,17,17,30,16,15}, + /* h */ {1,1,13,19,17,17,17,0}, + /* i */ {1,0,1,1,1,1,1,0}, + /* j */ {16,0,16,16,16,17,17,14}, + /* k */ {1,1,9,5,3,5,9,0}, + /* l */ {1,1,1,1,1,1,2,0}, + /* m */ {0,0,11,21,21,17,17,0}, + /* n */ {0,0,15,17,17,17,17,0}, + /* o */ {0,0,14,17,17,17,14,0}, + /* p */ {0,0,13,19,17,15,1,1}, + /* q */ {0,0,22,25,17,30,16,16}, + /* r */ {0,0,13,19,1,1,1,0}, + /* s */ {0,0,30,1,14,16,15,0}, + /* t */ {2,2,7,2,2,2,4,0}, + /* u */ {0,0,17,17,17,17,30,0}, + /* v */ {0,0,17,17,17,10,4,0}, + /* w */ {0,0,17,17,21,21,30,0}, + /* x */ {0,0,17,10,4,10,17,0}, + /* y */ {0,0,17,17,17,30,16,15}, + /* z */ {0,0,31,8,4,2,31,0}, + /* { */ {12,2,2,1,2,2,12,0}, + /* | */ {1,1,1,0,1,1,1,0}, + /* } */ {3,4,4,8,4,4,3,0}, + /* ~ */ {38,25,0,0,0,0,0,0}, + /* ⌂ */ {0,0,4,10,17,17,31,0}, + /* Ç */ {14,17,1,1,17,14,16,12}, + /* ü */ {10,0,17,17,17,17,30,0}, + /* é */ {24,0,14,17,31,1,30,0}, + /* â */ {14,17,14,16,30,17,30,0}, + /* ä */ {10,0,14,16,30,17,30,0}, + /* à */ {3,0,14,16,30,17,30,0}, + /* å */ {4,0,14,16,30,17,30,0}, + /* ç */ {0,14,17,1,17,14,16,12}, + /* ê */ {14,17,14,17,31,1,30,0}, + /* ë */ {10,0,14,17,31,1,30,0}, + /* è */ {3,0,14,17,31,1,30,0}, + /* ï */ {5,0,2,2,2,2,2,0}, + /* î */ {14,17,4,4,4,4,4,0}, + /* ì */ {3,0,2,2,2,2,2,0}, + /* Ä */ {17,14,17,31,17,17,17,0}, + /* Å */ {4,0,14,17,31,17,17,0}, + /* É */ {24,0,31,1,7,1,31,0}, + /* æ */ {0,0,10,20,30,5,30,0}, + /* Æ */ {30,5,15,5,5,5,29,0}, + /* ô */ {14,17,14,17,17,17,14,0}, + /* ö */ {10,0,14,17,17,17,14,0}, + /* ò */ {3,0,14,17,17,17,14,0}, + /* û */ {14,17,0,17,17,17,30,0}, + /* ù */ {3,0,17,17,17,17,30,0}, + /* ÿ */ {10,0,17,17,17,30,16,15}, + /* Ö */ {17,14,17,17,17,17,14,0}, + /* Ü */ {17,0,17,17,17,17,14,0}, + /* ø */ {0,0,14,25,21,19,14,4}, + /* £ */ {12,18,2,15,2,2,31,0}, + /* Ø */ {14,17,25,21,19,17,14,0}, + /* × */ {0,0,5,2,5,0,0,0}, + /* ƒ */ {8,20,4,14,4,4,5,2}, + /* á */ {24,0,14,16,30,17,30,0}, + /* í */ {3,0,1,1,1,1,1,0}, + /* ó */ {24,0,14,17,17,17,14,0}, + /* ú */ {24,0,17,17,17,17,30,0}, + /* ñ */ {31,0,15,17,17,17,17,0}, + /* Ñ */ {31,0,17,19,21,25,17,0}, + /* ª */ {14,16,31,30,0,31,0,0}, + /* º */ {14,17,17,14,0,31,0,0}, + /* ¿ */ {4,0,4,2,1,17,14,0}, + /* ® */ {0,30,45,37,43,30,0,0}, + /* ¬ */ {0,0,0,31,16,16,0,0}, + /* ½ */ {17,9,8,4,18,10,25,0}, + /* ¼ */ {17,9,8,4,26,26,17,0}, + /* ¡ */ {0,1,0,1,1,1,1,0}, + /* « */ {0,20,10,5,10,20,0,0}, + /* » */ {0,5,10,20,10,5,0,0}, + /* 176 */ {68,17,68,17,68,17,68,17}, + /* 177 */ {170,85,170,85,170,85,170,85}, + /* 178 */ {219,238,219,119,219,238,219,119}, + /* 179 */ {24,24,24,24,24,24,24,24}, + /* 180 */ {24,24,24,24,31,24,24,24}, + /* 181 */ {24,24,31,24,31,24,24,24}, + /* 182 */ {108,108,108,108,111,108,108,108}, + /* 183 */ {0,0,0,0,127,108,108,108}, + /* 184 */ {0,0,31,24,31,24,24,24}, + /* 185 */ {108,108,111,96,111,108,108,108}, + /* 186 */ {108,108,108,108,108,108,108,108}, + /* 187 */ {0,0,127,96,111,108,108,108}, + /* 188 */ {108,108,111,96,127,0,0,0}, + /* 189 */ {108,108,108,108,127,0,0,0}, + /* 190 */ {24,24,31,24,31,0,0,0}, + /* 191 */ {0,0,0,0,31,24,24,24}, + /* 192 */ {24,24,24,24,248,0,0,0}, + /* 193 */ {24,24,24,24,255,0,0,0}, + /* 194 */ {0,0,0,0,255,24,24,24}, + /* 195 */ {24,24,24,24,248,24,24,24}, + /* 196 */ {0,0,0,0,255,0,0,0}, + /* 197 */ {24,24,24,24,255,24,24,24}, + /* 198 */ {24,24,248,24,248,24,24,24}, + /* 199 */ {108,108,108,108,236,108,108,108}, + /* 200 */ {108,108,236,12,252,0,0,0}, + /* 201 */ {0,0,252,12,236,108,108,108}, + /* 202 */ {108,108,239,0,255,0,0,0}, + /* 203 */ {0,0,255,0,239,108,108,108}, + /* 204 */ {108,108,236,12,236,108,108,108}, + /* 205 */ {0,0,255,0,255,0,0,0}, + /* 206 */ {108,108,239,0,239,108,108,108}, + /* 207 */ {24,24,255,0,255,0,0,0}, + /* 208 */ {108,108,108,108,255,0,0,0}, + /* 209 */ {0,0,255,0,255,24,24,24}, + /* 210 */ {0,0,0,0,255,108,108,108}, + /* 211 */ {108,108,108,108,252,0,0,0}, + /* 212 */ {24,24,248,24,248,0,0,0}, + /* 213 */ {0,0,248,24,248,24,24,24}, + /* 214 */ {0,0,0,0,252,108,108,108}, + /* 215 */ {108,108,108,108,255,108,108,108}, + /* 216 */ {24,24,255,24,255,24,24,24}, + /* 217 */ {24,24,24,24,31,0,0,0}, + /* 218 */ {0,0,0,0,248,24,24,24}, + /* 219 */ {255,255,255,255,255,255,255,255}, + /* 220 */ {0,0,0,0,255,255,255,255}, + /* 221 */ {15,15,15,15,15,15,15,15}, + /* 222 */ {240,240,240,240,240,240,240,240}, + /* 223 */ {255,255,255,255,0,0,0,0}, + /* 224 */ {0,0,110,59,19,59,110,0}, + /* 225 */ {0,30,51,31,51,31,3,3}, + /* 226 */ {0,63,51,3,3,3,3,0}, + /* 227 */ {0,127,54,54,54,54,54,0}, + /* 228 */ {63,51,6,12,6,51,63,0}, + /* 229 */ {0,0,126,27,27,27,14,0}, + /* 230 */ {0,102,102,102,102,62,6,3}, + /* 231 */ {0,110,59,24,24,24,24,0}, + /* 232 */ {63,12,30,51,51,30,12,63}, + /* 233 */ {28,54,99,127,99,54,28,0}, + /* 234 */ {28,54,99,99,54,54,119,0}, + /* 235 */ {56,12,24,62,51,51,30,0}, + /* 236 */ {0,0,126,219,219,126,0,0}, + /* 237 */ {96,48,126,219,219,126,6,3}, + /* 238 */ {28,6,3,31,3,6,28,0}, + /* 239 */ {30,51,51,51,51,51,51,0}, + /* 240 */ {0,63,0,63,0,63,0,0}, + /* 241 */ {12,12,63,12,12,0,63,0}, + /* 242 */ {6,12,24,12,6,0,63,0}, + /* 243 */ {24,12,6,12,24,0,63,0}, + /* 244 */ {112,216,216,24,24,24,24,24}, + /* 245 */ {24,24,24,24,24,27,27,14}, + /* 246 */ {12,12,0,63,0,12,12,0}, + /* 247 */ {0,110,59,0,110,59,0,0}, + /* 248 */ {28,54,54,28,0,0,0,0}, + /* 249 */ {0,0,0,24,24,0,0,0}, + /* 250 */ {0,0,0,0,24,0,0,0}, + /* 251 */ {240,48,48,48,55,54,60,56}, + /* 252 */ {30,54,54,54,54,0,0,0}, + /* 253 */ {14,24,12,6,30,0,0,0}, + /* 254 */ {0,0,60,60,60,60,0,0}, + /* 255 */ {0,0,0,0,0,0,0,0}, + }; + + /** + * A static non-malleable MinecraftFont. + */ + public static final MinecraftFont Font = new MinecraftFont(false); + + /** + * Initialize a new MinecraftFont. + */ + public MinecraftFont() { + this(true); + } + + private MinecraftFont(boolean malleable) { + for (int i = 1; i < fontData.length; ++i) { + char ch = (char) i; + if (i >= 32 && i < 32 + fontChars.length()) { + ch = fontChars.charAt(i - 32); + } + + if (ch == ' ') { + setChar(ch, new CharacterSprite(spaceSize, 8, new boolean[spaceSize * 8])); + continue; + } + + int[] rows = fontData[i]; + int width = 0; + for (int r = 0; r < 8; ++r) { + for (int c = 0; c < 8; ++c) { + if ((rows[r] & (1 << c)) != 0 && c > width) { + width = c; + } + } + } + ++width; + + boolean[] data = new boolean[width * 8]; + for (int r = 0; r < 8; ++r) { + for (int c = 0; c < width; ++c) { + data[r * width + c] = (rows[r] & (1 << c)) != 0; + } + } + + setChar(ch, new CharacterSprite(width, 8, data)); + } + + this.malleable = malleable; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Attachable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Attachable.java new file mode 100644 index 0000000..1d3f107 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Attachable.java @@ -0,0 +1,16 @@ +package org.bukkit.material; + +import org.bukkit.block.BlockFace; + +/** + * Indicates that a block can be attached to another block + */ +public interface Attachable extends Directional { + + /** + * Gets the face that this block is attached on + * + * @return BlockFace attached to + */ + public BlockFace getAttachedFace(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Banner.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Banner.java new file mode 100644 index 0000000..80a7616 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Banner.java @@ -0,0 +1,235 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +public class Banner extends MaterialData implements Attachable { + + public Banner() { + super(Material.BANNER); + } + + public Banner(Material type) { + super(type); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Banner(int type) { + super(type); + } + + /** + * + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Banner(Material type, byte data) { + super(type, data); + } + + /** * + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Banner(int type, byte data) { + super(type, data); + } + + public boolean isWallBanner() { + return getItemType() == Material.WALL_BANNER; + } + + public BlockFace getAttachedFace() { + if (isWallBanner()) { + byte data = getData(); + + switch (data) { + case 0x2: + return BlockFace.SOUTH; + + case 0x3: + return BlockFace.NORTH; + + case 0x4: + return BlockFace.EAST; + + case 0x5: + return BlockFace.WEST; + } + + return null; + } else { + return BlockFace.DOWN; + } + } + + public BlockFace getFacing() { + byte data = getData(); + + if (!isWallBanner()) { + switch (data) { + case 0x0: + return BlockFace.SOUTH; + + case 0x1: + return BlockFace.SOUTH_SOUTH_WEST; + + case 0x2: + return BlockFace.SOUTH_WEST; + + case 0x3: + return BlockFace.WEST_SOUTH_WEST; + + case 0x4: + return BlockFace.WEST; + + case 0x5: + return BlockFace.WEST_NORTH_WEST; + + case 0x6: + return BlockFace.NORTH_WEST; + + case 0x7: + return BlockFace.NORTH_NORTH_WEST; + + case 0x8: + return BlockFace.NORTH; + + case 0x9: + return BlockFace.NORTH_NORTH_EAST; + + case 0xA: + return BlockFace.NORTH_EAST; + + case 0xB: + return BlockFace.EAST_NORTH_EAST; + + case 0xC: + return BlockFace.EAST; + + case 0xD: + return BlockFace.EAST_SOUTH_EAST; + + case 0xE: + return BlockFace.SOUTH_EAST; + + case 0xF: + return BlockFace.SOUTH_SOUTH_EAST; + } + + return null; + } else { + return getAttachedFace().getOppositeFace(); + } + } + + public void setFacingDirection(BlockFace face) { + byte data; + + if (isWallBanner()) { + switch (face) { + case NORTH: + data = 0x2; + break; + + case SOUTH: + data = 0x3; + break; + + case WEST: + data = 0x4; + break; + + case EAST: + default: + data = 0x5; + } + } else { + switch (face) { + case SOUTH: + data = 0x0; + break; + + case SOUTH_SOUTH_WEST: + data = 0x1; + break; + + case SOUTH_WEST: + data = 0x2; + break; + + case WEST_SOUTH_WEST: + data = 0x3; + break; + + case WEST: + data = 0x4; + break; + + case WEST_NORTH_WEST: + data = 0x5; + break; + + case NORTH_WEST: + data = 0x6; + break; + + case NORTH_NORTH_WEST: + data = 0x7; + break; + + case NORTH: + data = 0x8; + break; + + case NORTH_NORTH_EAST: + data = 0x9; + break; + + case NORTH_EAST: + data = 0xA; + break; + + case EAST_NORTH_EAST: + data = 0xB; + break; + + case EAST: + data = 0xC; + break; + + case EAST_SOUTH_EAST: + data = 0xD; + break; + + case SOUTH_SOUTH_EAST: + data = 0xF; + break; + + case SOUTH_EAST: + default: + data = 0xE; + } + } + + setData(data); + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing(); + } + + @Override + public Banner clone() { + return (Banner) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Bed.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Bed.java new file mode 100644 index 0000000..ce94daf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Bed.java @@ -0,0 +1,145 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a bed. + */ +public class Bed extends MaterialData implements Directional { + + /** + * Default constructor for a bed. + */ + public Bed() { + super(Material.BED_BLOCK); + } + + /** + * Instantiate a bed facing in a particular direction. + * + * @param direction the direction the bed's head is facing + */ + public Bed(BlockFace direction) { + this(); + setFacingDirection(direction); + } + + /** + * + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Bed(final int type) { + super(type); + } + + public Bed(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Bed(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Bed(final Material type, final byte data) { + super(type, data); + } + + /** + * Determine if this block represents the head of the bed + * + * @return true if this is the head of the bed, false if it is the foot + */ + public boolean isHeadOfBed() { + return (getData() & 0x8) == 0x8; + } + + /** + * Configure this to be either the head or the foot of the bed + * + * @param isHeadOfBed True to make it the head. + */ + public void setHeadOfBed(boolean isHeadOfBed) { + setData((byte) (isHeadOfBed ? (getData() | 0x8) : (getData() & ~0x8))); + } + + /** + * Set which direction the head of the bed is facing. Note that this will + * only affect one of the two blocks the bed is made of. + */ + public void setFacingDirection(BlockFace face) { + byte data; + + switch (face) { + case SOUTH: + data = 0x0; + break; + + case WEST: + data = 0x1; + break; + + case NORTH: + data = 0x2; + break; + + case EAST: + default: + data = 0x3; + } + + if (isHeadOfBed()) { + data |= 0x8; + } + + setData(data); + } + + /** + * Get the direction that this bed's head is facing toward + * + * @return the direction the head of the bed is facing + */ + public BlockFace getFacing() { + byte data = (byte) (getData() & 0x7); + + switch (data) { + case 0x0: + return BlockFace.SOUTH; + + case 0x1: + return BlockFace.WEST; + + case 0x2: + return BlockFace.NORTH; + + case 0x3: + default: + return BlockFace.EAST; + } + } + + @Override + public String toString() { + return (isHeadOfBed() ? "HEAD" : "FOOT") + " of " + super.toString() + " facing " + getFacing(); + } + + @Override + public Bed clone() { + return (Bed) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Button.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Button.java new file mode 100644 index 0000000..fd6a7db --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Button.java @@ -0,0 +1,142 @@ +package org.bukkit.material; + +import org.bukkit.block.BlockFace; +import org.bukkit.Material; + +/** + * Represents a button + */ +public class Button extends SimpleAttachableMaterialData implements Redstone { + public Button() { + super(Material.STONE_BUTTON); + } + + /** + * @param type the type + * @deprecated Magic value + */ + @Deprecated + public Button(final int type) { + super(type); + } + + public Button(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Button(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Button(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current state of this Material, indicating if it's powered or + * unpowered + * + * @return true if powered, otherwise false + */ + public boolean isPowered() { + return (getData() & 0x8) == 0x8; + } + + /** + * Sets the current state of this button + * + * @param bool + * whether or not the button is powered + */ + public void setPowered(boolean bool) { + setData((byte) (bool ? (getData() | 0x8) : (getData() & ~0x8))); + } + + /** + * Gets the face that this block is attached on + * + * @return BlockFace attached to + */ + public BlockFace getAttachedFace() { + byte data = (byte) (getData() & 0x7); + + switch (data) { + case 0x0: + return BlockFace.UP; + + case 0x1: + return BlockFace.WEST; + + case 0x2: + return BlockFace.EAST; + + case 0x3: + return BlockFace.NORTH; + + case 0x4: + return BlockFace.SOUTH; + + case 0x5: + return BlockFace.DOWN; + } + + return null; + } + + /** + * Sets the direction this button is pointing toward + */ + public void setFacingDirection(BlockFace face) { + byte data = (byte) (getData() & 0x8); + + switch (face) { + case DOWN: + data |= 0x0; + break; + + case EAST: + data |= 0x1; + break; + + case WEST: + data |= 0x2; + break; + + case SOUTH: + data |= 0x3; + break; + + case NORTH: + data |= 0x4; + break; + + case UP: + data |= 0x5; + break; + } + + setData(data); + } + + @Override + public String toString() { + return super.toString() + " " + (isPowered() ? "" : "NOT ") + "POWERED"; + } + + @Override + public Button clone() { + return (Button) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Cake.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Cake.java new file mode 100644 index 0000000..e72cb91 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Cake.java @@ -0,0 +1,93 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +public class Cake extends MaterialData { + public Cake() { + super(Material.CAKE_BLOCK); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Cake(int type) { + super(type); + } + + public Cake(Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Cake(int type, byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Cake(Material type, byte data) { + super(type, data); + } + + /** + * Gets the number of slices eaten from this cake + * + * @return The number of slices eaten + */ + public int getSlicesEaten() { + return getData(); + } + + /** + * Gets the number of slices remaining on this cake + * + * @return The number of slices remaining + */ + public int getSlicesRemaining() { + return 6 - getData(); + } + + /** + * Sets the number of slices eaten from this cake + * + * @param n The number of slices eaten + */ + public void setSlicesEaten(int n) { + if (n < 6) { + setData((byte) n); + } // TODO: else destroy the block? Probably not possible though + } + + /** + * Sets the number of slices remaining on this cake + * + * @param n The number of slices remaining + */ + public void setSlicesRemaining(int n) { + if (n > 6) { + n = 6; + } + setData((byte) (6 - n)); + } + + @Override + public String toString() { + return super.toString() + " " + getSlicesEaten() + "/" + getSlicesRemaining() + " slices eaten/remaining"; + } + + @Override + public Cake clone() { + return (Cake) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Cauldron.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Cauldron.java new file mode 100644 index 0000000..0ead402 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Cauldron.java @@ -0,0 +1,64 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents a cauldron + */ +public class Cauldron extends MaterialData { + private static final int CAULDRON_FULL = 3; + private static final int CAULDRON_EMPTY = 0; + + public Cauldron() { + super(Material.CAULDRON); + } + + /** + * + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Cauldron(int type, byte data){ + super(type, data); + } + + /** + * + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Cauldron(byte data) { + super(Material.CAULDRON, data); + } + + /** + * Check if the cauldron is full. + * + * @return True if it is full. + */ + public boolean isFull() { + return getData() >= CAULDRON_FULL; + } + + /** + * Check if the cauldron is empty. + * + * @return True if it is empty. + */ + public boolean isEmpty() { + return getData() <= CAULDRON_EMPTY; + } + + @Override + public String toString() { + return (isEmpty() ? "EMPTY" : (isFull() ? "FULL" : getData() + "/3 FULL")) + " CAULDRON"; + } + + @Override + public Cauldron clone() { + return (Cauldron) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Chest.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Chest.java new file mode 100644 index 0000000..0db8aa5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Chest.java @@ -0,0 +1,62 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a chest + */ +public class Chest extends DirectionalContainer { + + public Chest() { + super(Material.CHEST); + } + + /** + * Instantiate a chest facing in a particular direction. + * + * @param direction the direction the chest's lit opens towards + */ + public Chest(BlockFace direction) { + this(); + setFacingDirection(direction); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Chest(final int type) { + super(type); + } + + public Chest(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Chest(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Chest(final Material type, final byte data) { + super(type, data); + } + + @Override + public Chest clone() { + return (Chest) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Coal.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Coal.java new file mode 100644 index 0000000..dd940b6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Coal.java @@ -0,0 +1,79 @@ +package org.bukkit.material; + +import org.bukkit.CoalType; +import org.bukkit.Material; + +/** + * Represents the different types of coals. + */ +public class Coal extends MaterialData { + public Coal() { + super(Material.COAL); + } + + public Coal(CoalType type) { + this(); + setType(type); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Coal(final int type) { + super(type); + } + + public Coal(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Coal(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Coal(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current type of this coal + * + * @return CoalType of this coal + */ + public CoalType getType() { + return CoalType.getByData(getData()); + } + + /** + * Sets the type of this coal + * + * @param type New type of this coal + */ + public void setType(CoalType type) { + setData(type.getData()); + } + + @Override + public String toString() { + return getType() + " " + super.toString(); + } + + @Override + public Coal clone() { + return (Coal) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/CocoaPlant.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/CocoaPlant.java new file mode 100644 index 0000000..6dede93 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/CocoaPlant.java @@ -0,0 +1,133 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents the cocoa plant + */ +public class CocoaPlant extends MaterialData implements Directional, Attachable { + + public enum CocoaPlantSize { + SMALL, + MEDIUM, + LARGE + } + + public CocoaPlant() { + super(Material.COCOA); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public CocoaPlant(final int type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public CocoaPlant(final int type, final byte data) { + super(type, data); + } + + public CocoaPlant(CocoaPlantSize sz) { + this(); + setSize(sz); + } + + public CocoaPlant(CocoaPlantSize sz, BlockFace dir) { + this(); + setSize(sz); + setFacingDirection(dir); + } + + /** + * Get size of plant + * + * @return size + */ + public CocoaPlantSize getSize() { + switch (getData() & 0xC) { + case 0: + return CocoaPlantSize.SMALL; + case 4: + return CocoaPlantSize.MEDIUM; + default: + return CocoaPlantSize.LARGE; + } + } + + /** + * Set size of plant + * + * @param sz - size of plant + */ + public void setSize(CocoaPlantSize sz) { + int dat = getData() & 0x3; + switch (sz) { + case SMALL: + break; + case MEDIUM: + dat |= 0x4; + break; + case LARGE: + dat |= 0x8; + break; + } + setData((byte) dat); + } + + public BlockFace getAttachedFace() { + return getFacing().getOppositeFace(); + } + + public void setFacingDirection(BlockFace face) { + int dat = getData() & 0xC; + switch (face) { + default: + case SOUTH: + break; + case WEST: + dat |= 0x1; + break; + case NORTH: + dat |= 0x2; + break; + case EAST: + dat |= 0x3; + break; + } + setData((byte) dat); + } + + public BlockFace getFacing() { + switch (getData() & 0x3) { + case 0: + return BlockFace.SOUTH; + case 1: + return BlockFace.WEST; + case 2: + return BlockFace.NORTH; + case 3: + return BlockFace.EAST; + } + return null; + } + + @Override + public CocoaPlant clone() { + return (CocoaPlant) super.clone(); + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing() + " " + getSize(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Colorable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Colorable.java new file mode 100644 index 0000000..3b91b24 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Colorable.java @@ -0,0 +1,24 @@ +package org.bukkit.material; + +import org.bukkit.DyeColor; + +/** + * An object that can be colored. + */ +public interface Colorable { + + /** + * Gets the color of this object. + * + * @return The DyeColor of this object. + */ + public DyeColor getColor(); + + /** + * Sets the color of this object to the specified DyeColor. + * + * @param color The color of the object, as a DyeColor. + */ + public void setColor(DyeColor color); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Command.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Command.java new file mode 100644 index 0000000..b484229 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Command.java @@ -0,0 +1,75 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents a command block + */ +public class Command extends MaterialData implements Redstone { + public Command() { + super(Material.COMMAND); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Command(final int type) { + super(type); + } + + public Command(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Command(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Command(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current state of this Material, indicating if it's powered or + * unpowered + * + * @return true if powered, otherwise false + */ + public boolean isPowered() { + return (getData() & 1) != 0; + } + + /** + * Sets the current state of this Material + * + * @param bool + * whether or not the command block is powered + */ + public void setPowered(boolean bool) { + setData((byte) (bool ? (getData() | 1) : (getData() & -2))); + } + + @Override + public String toString() { + return super.toString() + " " + (isPowered() ? "" : "NOT ") + "POWERED"; + } + + @Override + public Command clone() { + return (Command) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Crops.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Crops.java new file mode 100644 index 0000000..0a4f8f1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Crops.java @@ -0,0 +1,79 @@ +package org.bukkit.material; + +import org.bukkit.CropState; +import org.bukkit.Material; + +/** + * Represents the different types of crops. + */ +public class Crops extends MaterialData { + public Crops() { + super(Material.CROPS); + } + + public Crops(CropState state) { + this(); + setState(state); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Crops(final int type) { + super(type); + } + + public Crops(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Crops(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Crops(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current growth state of this crop + * + * @return CropState of this crop + */ + public CropState getState() { + return CropState.getByData(getData()); + } + + /** + * Sets the growth state of this crop + * + * @param state New growth state of this crop + */ + public void setState(CropState state) { + setData(state.getData()); + } + + @Override + public String toString() { + return getState() + " " + super.toString(); + } + + @Override + public Crops clone() { + return (Crops) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/DetectorRail.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/DetectorRail.java new file mode 100644 index 0000000..652a4b5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/DetectorRail.java @@ -0,0 +1,58 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents a detector rail + */ +public class DetectorRail extends ExtendedRails implements PressureSensor { + public DetectorRail() { + super(Material.DETECTOR_RAIL); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public DetectorRail(final int type) { + super(type); + } + + public DetectorRail(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public DetectorRail(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public DetectorRail(final Material type, final byte data) { + super(type, data); + } + + public boolean isPressed() { + return (getData() & 0x8) == 0x8; + } + + public void setPressed(boolean isPressed) { + setData((byte) (isPressed ? (getData() | 0x8) : (getData() & ~0x8))); + } + + @Override + public DetectorRail clone() { + return (DetectorRail) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Diode.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Diode.java new file mode 100644 index 0000000..fbfacc0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Diode.java @@ -0,0 +1,125 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +public class Diode extends MaterialData implements Directional { + public Diode() { + super(Material.DIODE_BLOCK_ON); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Diode(int type) { + super(type); + } + + public Diode(Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Diode(int type, byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Diode(Material type, byte data) { + super(type, data); + } + + /** + * Sets the delay of the repeater + * + * @param delay + * The new delay (1-4) + */ + public void setDelay(int delay) { + if (delay > 4) { + delay = 4; + } + if (delay < 1) { + delay = 1; + } + byte newData = (byte) (getData() & 0x3); + + setData((byte) (newData | ((delay - 1) << 2))); + } + + /** + * Gets the delay of the repeater in ticks + * + * @return The delay (1-4) + */ + public int getDelay() { + return (getData() >> 2) + 1; + } + + public void setFacingDirection(BlockFace face) { + int delay = getDelay(); + byte data; + + switch (face) { + case EAST: + data = 0x1; + break; + + case SOUTH: + data = 0x2; + break; + + case WEST: + data = 0x3; + break; + + case NORTH: + default: + data = 0x0; + } + + setData(data); + setDelay(delay); + } + + public BlockFace getFacing() { + byte data = (byte) (getData() & 0x3); + + switch (data) { + case 0x0: + default: + return BlockFace.NORTH; + + case 0x1: + return BlockFace.EAST; + + case 0x2: + return BlockFace.SOUTH; + + case 0x3: + return BlockFace.WEST; + } + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing() + " with " + getDelay() + " ticks delay"; + } + + @Override + public Diode clone() { + return (Diode) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Directional.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Directional.java new file mode 100644 index 0000000..25624d2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Directional.java @@ -0,0 +1,20 @@ +package org.bukkit.material; + +import org.bukkit.block.BlockFace; + +public interface Directional { + + /** + * Sets the direction that this block is facing in + * + * @param face The facing direction + */ + public void setFacingDirection(BlockFace face); + + /** + * Gets the direction this block is facing + * + * @return the direction this block is facing + */ + public BlockFace getFacing(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/DirectionalContainer.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/DirectionalContainer.java new file mode 100644 index 0000000..b56f098 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/DirectionalContainer.java @@ -0,0 +1,95 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a furnace or a dispenser. + */ +public class DirectionalContainer extends MaterialData implements Directional { + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public DirectionalContainer(final int type) { + super(type); + } + + public DirectionalContainer(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public DirectionalContainer(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public DirectionalContainer(final Material type, final byte data) { + super(type, data); + } + + public void setFacingDirection(BlockFace face) { + byte data; + + switch (face) { + case NORTH: + data = 0x2; + break; + + case SOUTH: + data = 0x3; + break; + + case WEST: + data = 0x4; + break; + + case EAST: + default: + data = 0x5; + } + + setData(data); + } + + public BlockFace getFacing() { + byte data = getData(); + + switch (data) { + case 0x2: + return BlockFace.NORTH; + + case 0x3: + return BlockFace.SOUTH; + + case 0x4: + return BlockFace.WEST; + + case 0x5: + default: + return BlockFace.EAST; + } + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing(); + } + + @Override + public DirectionalContainer clone() { + return (DirectionalContainer) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Dispenser.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Dispenser.java new file mode 100644 index 0000000..988407c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Dispenser.java @@ -0,0 +1,114 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a dispenser. + */ +public class Dispenser extends FurnaceAndDispenser { + + public Dispenser() { + super(Material.DISPENSER); + } + + public Dispenser(BlockFace direction) { + this(); + setFacingDirection(direction); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Dispenser(final int type) { + super(type); + } + + public Dispenser(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Dispenser(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Dispenser(final Material type, final byte data) { + super(type, data); + } + + public void setFacingDirection(BlockFace face) { + byte data; + + switch (face) { + case DOWN: + data = 0x0; + break; + + case UP: + data = 0x1; + break; + + case NORTH: + data = 0x2; + break; + + case SOUTH: + data = 0x3; + break; + + case WEST: + data = 0x4; + break; + + case EAST: + default: + data = 0x5; + } + + setData(data); + } + + public BlockFace getFacing() { + int data = getData() & 0x7; + + switch (data) { + case 0x0: + return BlockFace.DOWN; + + case 0x1: + return BlockFace.UP; + + case 0x2: + return BlockFace.NORTH; + + case 0x3: + return BlockFace.SOUTH; + + case 0x4: + return BlockFace.WEST; + + case 0x5: + default: + return BlockFace.EAST; + } + } + + @Override + public Dispenser clone() { + return (Dispenser) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Door.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Door.java new file mode 100644 index 0000000..e02d8e6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Door.java @@ -0,0 +1,338 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.TreeSpecies; +import org.bukkit.block.BlockFace; + +/** + * Represents a door. + * + * This class was previously deprecated, but has been retrofitted to + * work with modern doors. Some methods are undefined dependant on isTopHalf() + * due to Minecraft's internal representation of doors. + * + * @see Material.WOODEN_DOOR + * @see Material.IRON_DOOR_BLOCK + * @see Material.SPRUCE_DOOR + * @see Material.BIRCH_DOOR + * @see Material.JUNGLE_DOOR + * @see Material.ACACIA_DOOR + * @see Material.DARK_OAK_DOOR + */ +public class Door extends MaterialData implements Directional, Openable { + + // This class breaks API contracts on Directional and Openable because + // of the way doors are currently implemented. Beware! + + /** + * @deprecated Artifact of old API, equivalent to new Door(Material.WOODEN_DOOR); + */ + @Deprecated + public Door() { + super(Material.WOODEN_DOOR); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Door(final int type) { + super(type); + } + + public Door(final Material type) { + super(type); + } + + /** + * Constructs the bottom half of a door of the given material type, facing the specified direction and set to closed + * + * @param type The type of material this door is made of. This must match the type of the block above. + * @param face The direction the door is facing. + * + * @see Material.WOODEN_DOOR + * @see Material.IRON_DOOR_BLOCK + * @see Material.SPRUCE_DOOR + * @see Material.BIRCH_DOOR + * @see Material.JUNGLE_DOOR + * @see Material.ACACIA_DOOR + * @see Material.DARK_OAK_DOOR + * + * @see BlockFace.WEST + * @see BlockFace.NORTH + * @see BlockFace.EAST + * @see BlockFace.SOUTH + */ + public Door(final Material type, BlockFace face) { + this(type, face, false); + } + + /** + * Constructs the bottom half of a door of the given material type, facing the specified direction and set to open + * or closed + * + * @param type The type of material this door is made of. This must match the type of the block above. + * @param face The direction the door is facing. + * @param isOpen Whether the door is currently opened. + * + * @see Material.WOODEN_DOOR + * @see Material.IRON_DOOR_BLOCK + * @see Material.SPRUCE_DOOR + * @see Material.BIRCH_DOOR + * @see Material.JUNGLE_DOOR + * @see Material.ACACIA_DOOR + * @see Material.DARK_OAK_DOOR + * + * @see BlockFace.WEST + * @see BlockFace.NORTH + * @see BlockFace.EAST + * @see BlockFace.SOUTH + */ + public Door(final Material type, BlockFace face, boolean isOpen) { + super(type); + setTopHalf(false); + setFacingDirection(face); + setOpen(isOpen); + } + + /** + * Constructs the top half of door of the given material type and with the hinge on the left or right + * + * @param type The type of material this door is made of. This must match the type of the block below. + * @param isHingeRight True if the hinge is on the right hand side, false if the hinge is on the left hand side. + * + * @see Material.WOODEN_DOOR + * @see Material.IRON_DOOR_BLOCK + * @see Material.SPRUCE_DOOR + * @see Material.BIRCH_DOOR + * @see Material.JUNGLE_DOOR + * @see Material.ACACIA_DOOR + * @see Material.DARK_OAK_DOOR + */ + public Door(final Material type, boolean isHingeRight) { + super(type); + setTopHalf(true); + setHinge(isHingeRight); + } + + /** + * Constructs the bottom half of a wooden door of the given species, facing the specified direction and set to + * closed + * + * @param species The species this wooden door is made of. This must match the species of the block above. + * @param face The direction the door is facing. + * + * @see TreeSpecies + * + * @see BlockFace.WEST + * @see BlockFace.NORTH + * @see BlockFace.EAST + * @see BlockFace.SOUTH + */ + public Door(final TreeSpecies species, BlockFace face) { + this(getWoodDoorOfSpecies(species), face, false); + } + + /** + * Constructs the bottom half of a wooden door of the given species, facing the specified direction and set to open + * or closed + * + * @param species The species this wooden door is made of. This must match the species of the block above. + * @param face The direction the door is facing. + * @param isOpen Whether the door is currently opened. + * + * @see TreeSpecies + * + * @see BlockFace.WEST + * @see BlockFace.NORTH + * @see BlockFace.EAST + * @see BlockFace.SOUTH + */ + public Door(final TreeSpecies species, BlockFace face, boolean isOpen) { + this(getWoodDoorOfSpecies(species), face, isOpen); + } + + /** + * Constructs the top half of a wooden door of the given species and with the hinge on the left or right + * + * @param species The species this wooden door is made of. This must match the species of the block below. + * @param isHingeRight True if the hinge is on the right hand side, false if the hinge is on the left hand side. + * + * @see TreeSpecies + */ + public Door(final TreeSpecies species, boolean isHingeRight) { + this(getWoodDoorOfSpecies(species), isHingeRight); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Door(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Door(final Material type, final byte data) { + super(type, data); + } + + /** + * Returns the item type of a wooden door for the given tree species. + * + * @param species The species of wood door required. + * @return The item type for the given species. + * + * @see Material.WOODEN_DOOR + * @see Material.SPRUCE_DOOR + * @see Material.BIRCH_DOOR + * @see Material.JUNGLE_DOOR + * @see Material.ACACIA_DOOR + * @see Material.DARK_OAK_DOOR + */ + public static Material getWoodDoorOfSpecies(TreeSpecies species) { + switch (species) { + default: + case GENERIC: + return Material.WOODEN_DOOR; + case BIRCH: + return Material.BIRCH_DOOR; + case REDWOOD: + return Material.SPRUCE_DOOR; + case JUNGLE: + return Material.JUNGLE_DOOR; + case ACACIA: + return Material.ACACIA_DOOR; + case DARK_OAK: + return Material.DARK_OAK_DOOR; + } + } + + /** + * Result is undefined if isTopHalf() is true. + */ + public boolean isOpen() { + return ((getData() & 0x4) == 0x4); + } + + /** + * Set whether the door is open. Undefined if isTopHalf() is true. + */ + public void setOpen(boolean isOpen) { + setData((byte) (isOpen ? (getData() | 0x4) : (getData() & ~0x4))); + } + + /** + * @return whether this is the top half of the door + */ + public boolean isTopHalf() { + return ((getData() & 0x8) == 0x8); + } + + /** + * Configure this part of the door to be either the top or the bottom half + * + * @param isTopHalf True to make it the top half. + */ + public void setTopHalf(boolean isTopHalf) { + setData((byte) (isTopHalf ? (getData() | 0x8) : (getData() & ~0x8))); + } + + /** + * @return BlockFace.SELF + * @deprecated This method should not be used; use hinge and facing accessors instead. + */ + @Deprecated + public BlockFace getHingeCorner() { + return BlockFace.SELF; + } + + @Override + public String toString() { + return (isTopHalf() ? "TOP" : "BOTTOM") + " half of " + super.toString(); + } + + /** + * Set the direction that this door should is facing. + * + * Undefined if isTopHalf() is true. + * + * @param face the direction + */ + public void setFacingDirection(BlockFace face) { + byte data = (byte) (getData() & 0xC); + switch (face) { + case WEST: + data |= 0x0; + break; + case NORTH: + data |= 0x1; + break; + case EAST: + data |= 0x2; + break; + case SOUTH: + data |= 0x3; + break; + } + setData(data); + } + + /** + * Get the direction that this door is facing. + * + * Undefined if isTopHalf() is true. + * + * @return the direction + */ + public BlockFace getFacing() { + byte data = (byte) (getData() & 0x3); + switch (data) { + case 0: + return BlockFace.WEST; + case 1: + return BlockFace.NORTH; + case 2: + return BlockFace.EAST; + case 3: + return BlockFace.SOUTH; + default: + throw new IllegalStateException("Unknown door facing (data: " + data + ")"); + } + } + + /** + * Returns the side of the door the hinge is on. + * + * Undefined if isTopHalf() is false. + * + * @return false for left hinge, true for right hinge + */ + public boolean getHinge() { + return (getData() & 0x1) == 1; + } + + /** + * Set whether the hinge is on the left or right side. Left is false, right is true. + * + * Undefined if isTopHalf() is false. + * + * @param isHingeRight True if the hinge is on the right hand side, false if the hinge is on the left hand side. + */ + public void setHinge(boolean isHingeRight) { + setData((byte) (isHingeRight ? (getData() | 0x1) : (getData() & ~0x1))); + } + + @Override + public Door clone() { + return (Door) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Dye.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Dye.java new file mode 100644 index 0000000..7174fdb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Dye.java @@ -0,0 +1,81 @@ +package org.bukkit.material; + +import org.bukkit.DyeColor; +import org.bukkit.Material; + +/** + * Represents dye + */ +public class Dye extends MaterialData implements Colorable { + public Dye() { + super(Material.INK_SACK); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Dye(final int type) { + super(type); + } + + public Dye(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Dye(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Dye(final Material type, final byte data) { + super(type, data); + } + + /** + * @param color color of the dye + */ + public Dye(final DyeColor color) { + super(Material.INK_SACK, color.getDyeData()); + } + + /** + * Gets the current color of this dye + * + * @return DyeColor of this dye + */ + public DyeColor getColor() { + return DyeColor.getByDyeData(getData()); + } + + /** + * Sets the color of this dye + * + * @param color New color of this dye + */ + public void setColor(DyeColor color) { + setData(color.getDyeData()); + } + + @Override + public String toString() { + return getColor() + " DYE(" + getData() + ")"; + } + + @Override + public Dye clone() { + return (Dye) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/EnderChest.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/EnderChest.java new file mode 100644 index 0000000..d3a6019 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/EnderChest.java @@ -0,0 +1,62 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents an ender chest + */ +public class EnderChest extends DirectionalContainer { + + public EnderChest() { + super(Material.ENDER_CHEST); + } + + /** + * Instantiate an ender chest facing in a particular direction. + * + * @param direction the direction the ender chest's lid opens towards + */ + public EnderChest(BlockFace direction) { + this(); + setFacingDirection(direction); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public EnderChest(final int type) { + super(type); + } + + public EnderChest(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public EnderChest(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public EnderChest(final Material type, final byte data) { + super(type, data); + } + + @Override + public EnderChest clone() { + return (EnderChest) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/ExtendedRails.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/ExtendedRails.java new file mode 100644 index 0000000..34fb55e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/ExtendedRails.java @@ -0,0 +1,75 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * This is the superclass for the {@link DetectorRail} and {@link PoweredRail} + * classes + */ +public class ExtendedRails extends Rails { + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public ExtendedRails(final int type) { + super(type); + } + + public ExtendedRails(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public ExtendedRails(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public ExtendedRails(final Material type, final byte data) { + super(type, data); + } + + @Override + public boolean isCurve() { + return false; + } + + /** + * + * @deprecated Magic value + */ + @Deprecated + @Override + protected byte getConvertedData() { + return (byte) (getData() & 0x7); + } + + @Override + public void setDirection(BlockFace face, boolean isOnSlope) { + boolean extraBitSet = (getData() & 0x8) == 0x8; + + if (face != BlockFace.WEST && face != BlockFace.EAST && face != BlockFace.NORTH && face != BlockFace.SOUTH) { + throw new IllegalArgumentException("Detector rails and powered rails cannot be set on a curve!"); + } + + super.setDirection(face, isOnSlope); + setData((byte) (extraBitSet ? (getData() | 0x8) : (getData() & ~0x8))); + } + + @Override + public ExtendedRails clone() { + return (ExtendedRails) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/FlowerPot.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/FlowerPot.java new file mode 100644 index 0000000..7f3574e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/FlowerPot.java @@ -0,0 +1,137 @@ +package org.bukkit.material; + +import org.bukkit.GrassSpecies; +import org.bukkit.Material; +import org.bukkit.TreeSpecies; + +/** + * Represents a flower pot. + */ +public class FlowerPot extends MaterialData { + + /** + * Default constructor for a flower pot. + */ + public FlowerPot() { + super(Material.FLOWER_POT); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public FlowerPot(final int type) { + super(type); + } + + public FlowerPot(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public FlowerPot(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public FlowerPot(final Material type, final byte data) { + super(type, data); + } + + /** + * Get the material in the flower pot + * + * @return material MaterialData for the block currently in the flower pot + * or null if empty + */ + public MaterialData getContents() { + switch (getData()) { + case 1: + return new MaterialData(Material.RED_ROSE); + case 2: + return new MaterialData(Material.YELLOW_FLOWER); + case 3: + return new Tree(TreeSpecies.GENERIC); + case 4: + return new Tree(TreeSpecies.REDWOOD); + case 5: + return new Tree(TreeSpecies.BIRCH); + case 6: + return new Tree(TreeSpecies.JUNGLE); + case 7: + return new MaterialData(Material.RED_MUSHROOM); + case 8: + return new MaterialData(Material.BROWN_MUSHROOM); + case 9: + return new MaterialData(Material.CACTUS); + case 10: + return new MaterialData(Material.DEAD_BUSH); + case 11: + return new LongGrass(GrassSpecies.FERN_LIKE); + default: + return null; + } + } + + /** + * Set the contents of the flower pot + * + * @param materialData MaterialData of the block to put in the flower pot. + */ + public void setContents(MaterialData materialData) { + Material mat = materialData.getItemType(); + + if (mat == Material.RED_ROSE) { + setData((byte) 1); + } else if (mat == Material.YELLOW_FLOWER) { + setData((byte) 2); + } else if (mat == Material.RED_MUSHROOM) { + setData((byte) 7); + } else if (mat == Material.BROWN_MUSHROOM) { + setData((byte) 8); + } else if (mat == Material.CACTUS) { + setData((byte) 9); + } else if (mat == Material.DEAD_BUSH) { + setData((byte) 10); + } else if (mat == Material.SAPLING) { + TreeSpecies species = ((Tree) materialData).getSpecies(); + + if (species == TreeSpecies.GENERIC) { + setData((byte) 3); + } else if (species == TreeSpecies.REDWOOD) { + setData((byte) 4); + } else if (species == TreeSpecies.BIRCH) { + setData((byte) 5); + } else { + setData((byte) 6); + } + } else if (mat == Material.LONG_GRASS) { + GrassSpecies species = ((LongGrass) materialData).getSpecies(); + + if (species == GrassSpecies.FERN_LIKE) { + setData((byte) 11); + } + } + } + + @Override + public String toString() { + return super.toString() + " containing " + getContents(); + } + + @Override + public FlowerPot clone() { + return (FlowerPot) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Furnace.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Furnace.java new file mode 100644 index 0000000..c607226 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Furnace.java @@ -0,0 +1,62 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a furnace. + */ +public class Furnace extends FurnaceAndDispenser { + + public Furnace() { + super(Material.FURNACE); + } + + /** + * Instantiate a furnace facing in a particular direction. + * + * @param direction the direction the furnace's "opening" is facing + */ + public Furnace(BlockFace direction) { + this(); + setFacingDirection(direction); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Furnace(final int type) { + super(type); + } + + public Furnace(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Furnace(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Furnace(final Material type, final byte data) { + super(type, data); + } + + @Override + public Furnace clone() { + return (Furnace) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/FurnaceAndDispenser.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/FurnaceAndDispenser.java new file mode 100644 index 0000000..184fda2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/FurnaceAndDispenser.java @@ -0,0 +1,47 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents a furnace or dispenser, two types of directional containers + */ +public class FurnaceAndDispenser extends DirectionalContainer { + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public FurnaceAndDispenser(final int type) { + super(type); + } + + public FurnaceAndDispenser(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public FurnaceAndDispenser(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public FurnaceAndDispenser(final Material type, final byte data) { + super(type, data); + } + + @Override + public FurnaceAndDispenser clone() { + return (FurnaceAndDispenser) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Gate.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Gate.java new file mode 100644 index 0000000..8adc1cf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Gate.java @@ -0,0 +1,91 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a fence gate + */ +public class Gate extends MaterialData implements Directional, Openable { + private static final byte OPEN_BIT = 0x4; + private static final byte DIR_BIT = 0x3; + private static final byte GATE_SOUTH = 0x0; + private static final byte GATE_WEST = 0x1; + private static final byte GATE_NORTH = 0x2; + private static final byte GATE_EAST = 0x3; + + public Gate() { + super(Material.FENCE_GATE); + } + + public Gate(int type, byte data){ + super(type, data); + } + + public Gate(byte data) { + super(Material.FENCE_GATE, data); + } + + public void setFacingDirection(BlockFace face) { + byte data = (byte) (getData() &~ DIR_BIT); + + switch (face) { + default: + case EAST: + data |= GATE_SOUTH; + break; + case SOUTH: + data |= GATE_WEST; + break; + case WEST: + data |= GATE_NORTH; + break; + case NORTH: + data |= GATE_EAST; + break; + } + + setData(data); + } + + public BlockFace getFacing() { + switch (getData() & DIR_BIT) { + case GATE_SOUTH: + return BlockFace.EAST; + case GATE_WEST: + return BlockFace.SOUTH; + case GATE_NORTH: + return BlockFace.WEST; + case GATE_EAST: + return BlockFace.NORTH; + } + + return BlockFace.EAST; + } + + public boolean isOpen() { + return (getData() & OPEN_BIT) > 0; + } + + public void setOpen(boolean isOpen) { + byte data = getData(); + + if (isOpen) { + data |= OPEN_BIT; + } else { + data &= ~OPEN_BIT; + } + + setData(data); + } + + @Override + public String toString() { + return (isOpen() ? "OPEN " : "CLOSED ") + " facing and opening " + getFacing(); + } + + @Override + public Gate clone() { + return (Gate) super.clone(); + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Ladder.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Ladder.java new file mode 100644 index 0000000..cd4d691 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Ladder.java @@ -0,0 +1,104 @@ +package org.bukkit.material; + +import org.bukkit.block.BlockFace; +import org.bukkit.Material; + +/** + * Represents Ladder data + */ +public class Ladder extends SimpleAttachableMaterialData { + public Ladder() { + super(Material.LADDER); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Ladder(final int type) { + super(type); + } + + public Ladder(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Ladder(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Ladder(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the face that this block is attached on + * + * @return BlockFace attached to + */ + public BlockFace getAttachedFace() { + byte data = getData(); + + switch (data) { + case 0x2: + return BlockFace.SOUTH; + + case 0x3: + return BlockFace.NORTH; + + case 0x4: + return BlockFace.EAST; + + case 0x5: + return BlockFace.WEST; + } + + return null; + } + + /** + * Sets the direction this ladder is facing + */ + public void setFacingDirection(BlockFace face) { + byte data = (byte) 0x0; + + switch (face) { + case SOUTH: + data = 0x2; + break; + + case NORTH: + data = 0x3; + break; + + case EAST: + data = 0x4; + break; + + case WEST: + data = 0x5; + break; + } + + setData(data); + + } + + @Override + public Ladder clone() { + return (Ladder) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Leaves.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Leaves.java new file mode 100644 index 0000000..9f40a23 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Leaves.java @@ -0,0 +1,79 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.TreeSpecies; + +/** + * Represents the different types of leaves. + */ +public class Leaves extends MaterialData { + public Leaves() { + super(Material.LEAVES); + } + + public Leaves(TreeSpecies species) { + this(); + setSpecies(species); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Leaves(final int type) { + super(type); + } + + public Leaves(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Leaves(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Leaves(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current species of this leave + * + * @return TreeSpecies of this leave + */ + public TreeSpecies getSpecies() { + return TreeSpecies.getByData((byte) (getData() & 3)); + } + + /** + * Sets the species of this leave + * + * @param species New species of this leave + */ + public void setSpecies(TreeSpecies species) { + setData(species.getData()); + } + + @Override + public String toString() { + return getSpecies() + " " + super.toString(); + } + + @Override + public Leaves clone() { + return (Leaves) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Lever.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Lever.java new file mode 100644 index 0000000..c6d3882 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Lever.java @@ -0,0 +1,162 @@ +package org.bukkit.material; + +import org.bukkit.block.BlockFace; +import org.bukkit.Material; + +/** + * Represents a lever + */ +public class Lever extends SimpleAttachableMaterialData implements Redstone { + public Lever() { + super(Material.LEVER); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Lever(final int type) { + super(type); + } + + public Lever(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Lever(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Lever(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current state of this Material, indicating if it's powered or + * unpowered + * + * @return true if powered, otherwise false + */ + public boolean isPowered() { + return (getData() & 0x8) == 0x8; + } + + /** + * Set this lever to be powered or not. + * + * @param isPowered whether the lever should be powered or not + */ + public void setPowered(boolean isPowered) { + setData((byte) (isPowered ? (getData() | 0x8) : (getData() & ~0x8))); + } + + /** + * Gets the face that this block is attached on + * + * @return BlockFace attached to + */ + public BlockFace getAttachedFace() { + byte data = (byte) (getData() & 0x7); + + switch (data) { + case 0x1: + return BlockFace.WEST; + + case 0x2: + return BlockFace.EAST; + + case 0x3: + return BlockFace.NORTH; + + case 0x4: + return BlockFace.SOUTH; + + case 0x5: + case 0x6: + return BlockFace.DOWN; + + case 0x0: + case 0x7: + return BlockFace.UP; + + } + + return null; + } + + /** + * Sets the direction this lever is pointing in + */ + public void setFacingDirection(BlockFace face) { + byte data = (byte) (getData() & 0x8); + BlockFace attach = getAttachedFace(); + + if (attach == BlockFace.DOWN) { + switch (face) { + case SOUTH: + case NORTH: + data |= 0x5; + break; + + case EAST: + case WEST: + data |= 0x6; + break; + } + } else if (attach == BlockFace.UP) { + switch (face) { + case SOUTH: + case NORTH: + data |= 0x7; + break; + + case EAST: + case WEST: + data |= 0x0; + break; + } + } else { + switch (face) { + case EAST: + data |= 0x1; + break; + + case WEST: + data |= 0x2; + break; + + case SOUTH: + data |= 0x3; + break; + + case NORTH: + data |= 0x4; + break; + } + } + setData(data); + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing() + " " + (isPowered() ? "" : "NOT ") + "POWERED"; + } + + @Override + public Lever clone() { + return (Lever) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/LongGrass.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/LongGrass.java new file mode 100644 index 0000000..5cd8d20 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/LongGrass.java @@ -0,0 +1,79 @@ +package org.bukkit.material; + +import org.bukkit.GrassSpecies; +import org.bukkit.Material; + +/** + * Represents the different types of long grasses. + */ +public class LongGrass extends MaterialData { + public LongGrass() { + super(Material.LONG_GRASS); + } + + public LongGrass(GrassSpecies species) { + this(); + setSpecies(species); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public LongGrass(final int type) { + super(type); + } + + public LongGrass(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public LongGrass(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public LongGrass(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current species of this grass + * + * @return GrassSpecies of this grass + */ + public GrassSpecies getSpecies() { + return GrassSpecies.getByData(getData()); + } + + /** + * Sets the species of this grass + * + * @param species New species of this grass + */ + public void setSpecies(GrassSpecies species) { + setData(species.getData()); + } + + @Override + public String toString() { + return getSpecies() + " " + super.toString(); + } + + @Override + public LongGrass clone() { + return (LongGrass) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/MaterialData.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/MaterialData.java new file mode 100644 index 0000000..9caf085 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/MaterialData.java @@ -0,0 +1,137 @@ +package org.bukkit.material; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.Material; + +/** + * Handles specific metadata for certain items or blocks + */ +public class MaterialData implements Cloneable { + private final int type; + private byte data = 0; + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public MaterialData(final int type) { + this(type, (byte) 0); + } + + public MaterialData(final Material type) { + this(type, (byte) 0); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public MaterialData(final int type, final byte data) { + this.type = type; + this.data = data; + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public MaterialData(final Material type, final byte data) { + this(type.getId(), data); + } + + /** + * Gets the raw data in this material + * + * @return Raw data + * @deprecated Magic value + */ + @Deprecated + public byte getData() { + return data; + } + + /** + * Sets the raw data of this material + * + * @param data New raw data + * @deprecated Magic value + */ + @Deprecated + public void setData(byte data) { + this.data = data; + } + + /** + * Gets the Material that this MaterialData represents + * + * @return Material represented by this MaterialData + */ + public Material getItemType() { + return Material.getMaterial(type); + } + + /** + * Gets the Material Id that this MaterialData represents + * + * @return Material Id represented by this MaterialData + * @deprecated Magic value + */ + @Deprecated + public int getItemTypeId() { + return type; + } + + /** + * Creates a new ItemStack based on this MaterialData + * + * @return New ItemStack containing a copy of this MaterialData + */ + public ItemStack toItemStack() { + return new ItemStack(type, 0, data); + } + + /** + * Creates a new ItemStack based on this MaterialData + * + * @param amount The stack size of the new stack + * @return New ItemStack containing a copy of this MaterialData + */ + public ItemStack toItemStack(int amount) { + return new ItemStack(type, amount, data); + } + + @Override + public String toString() { + return getItemType() + "(" + getData() + ")"; + } + + @Override + public int hashCode() { + return ((getItemTypeId() << 8) ^ getData()); + } + + @Override + public boolean equals(Object obj) { + if (obj != null && obj instanceof MaterialData) { + MaterialData md = (MaterialData) obj; + + return (md.getItemTypeId() == getItemTypeId() && md.getData() == getData()); + } else { + return false; + } + } + + @Override + public MaterialData clone() { + try { + return (MaterialData) super.clone(); + } catch (CloneNotSupportedException e) { + throw new Error(e); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/MonsterEggs.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/MonsterEggs.java new file mode 100644 index 0000000..a6897b7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/MonsterEggs.java @@ -0,0 +1,69 @@ +package org.bukkit.material; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Material; + +/** + * Represents the different types of monster eggs + */ +public class MonsterEggs extends TexturedMaterial { + + private static final List textures = new ArrayList(); + static { + textures.add(Material.STONE); + textures.add(Material.COBBLESTONE); + textures.add(Material.SMOOTH_BRICK); + } + + public MonsterEggs() { + super(Material.MONSTER_EGGS); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public MonsterEggs(final int type) { + super(type); + } + + public MonsterEggs(final Material type) { + super((textures.contains(type)) ? Material.MONSTER_EGGS : type); + if (textures.contains(type)) { + setMaterial(type); + } + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public MonsterEggs(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public MonsterEggs(final Material type, final byte data) { + super(type, data); + } + + @Override + public List getTextures() { + return textures; + } + + @Override + public MonsterEggs clone() { + return (MonsterEggs) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Mushroom.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Mushroom.java new file mode 100644 index 0000000..40077a6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Mushroom.java @@ -0,0 +1,199 @@ +package org.bukkit.material; + +import java.util.EnumSet; +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a huge mushroom block + */ +public class Mushroom extends MaterialData { + private static final byte SHROOM_NONE = 0; + private static final byte SHROOM_STEM = 10; + private static final byte NORTH_LIMIT = 4; + private static final byte SOUTH_LIMIT = 6; + private static final byte EAST_WEST_LIMIT = 3; + private static final byte EAST_REMAINDER = 0; + private static final byte WEST_REMAINDER = 1; + private static final byte NORTH_SOUTH_MOD = 3; + private static final byte EAST_WEST_MOD = 1; + + public Mushroom(Material shroom) { + super(shroom); + Validate.isTrue(shroom == Material.HUGE_MUSHROOM_1 || shroom == Material.HUGE_MUSHROOM_2, "Not a mushroom!"); + } + + /** + * @param shroom the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Mushroom(Material shroom, byte data) { + super(shroom, data); + Validate.isTrue(shroom == Material.HUGE_MUSHROOM_1 || shroom == Material.HUGE_MUSHROOM_2, "Not a mushroom!"); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Mushroom(int type, byte data){ + super(type, data); + Validate.isTrue(type == Material.HUGE_MUSHROOM_1.getId() || type == Material.HUGE_MUSHROOM_2.getId(), "Not a mushroom!"); + } + + /** + * @return Whether this is a mushroom stem. + */ + public boolean isStem() { + return getData() == SHROOM_STEM; + } + + /** + * Sets this to be a mushroom stem. + */ + public void setStem() { + setData((byte) 10); + } + + /** + * Checks whether a face of the block is painted. + * + * @param face The face to check. + * @return True if it is painted. + */ + public boolean isFacePainted(BlockFace face) { + byte data = getData(); + + if (data == SHROOM_NONE || data == SHROOM_STEM) { + return false; + } + + switch (face) { + case WEST: + return data < NORTH_LIMIT; + case EAST: + return data > SOUTH_LIMIT; + case NORTH: + return data % EAST_WEST_LIMIT == EAST_REMAINDER; + case SOUTH: + return data % EAST_WEST_LIMIT == WEST_REMAINDER; + case UP: + return true; + default: + return false; + } + } + + /** + * Set a face of the block to be painted or not. Note that due to the + * nature of how the data is stored, setting a face painted or not is not + * guaranteed to leave the other faces unchanged. + * + * @param face The face to paint or unpaint. + * @param painted True if you want to paint it, false if you want the + * pores to show. + */ + public void setFacePainted(BlockFace face, boolean painted) { + if (painted == isFacePainted(face)) { + return; + } + + byte data = getData(); + + if (data == SHROOM_STEM) { + data = 5; + } + + switch (face) { + case WEST: + if (painted) { + data -= NORTH_SOUTH_MOD; + } else { + data += NORTH_SOUTH_MOD; + } + + break; + case EAST: + if (painted) { + data += NORTH_SOUTH_MOD; + } else { + data -= NORTH_SOUTH_MOD; + } + + break; + case NORTH: + if (painted) { + data += EAST_WEST_MOD; + } else { + data -= EAST_WEST_MOD; + } + + break; + case SOUTH: + if (painted) { + data -= EAST_WEST_MOD; + } else { + data += EAST_WEST_MOD; + } + + break; + case UP: + if (!painted) { + data = 0; + } + + break; + default: + throw new IllegalArgumentException("Can't paint that face of a mushroom!"); + } + + setData(data); + } + + /** + * @return A set of all faces that are currently painted (an empty set if + * it is a stem) + */ + public Set getPaintedFaces() { + EnumSet faces = EnumSet.noneOf(BlockFace.class); + + if (isFacePainted(BlockFace.WEST)) { + faces.add(BlockFace.WEST); + } + + if (isFacePainted(BlockFace.NORTH)) { + faces.add(BlockFace.NORTH); + } + + if (isFacePainted(BlockFace.SOUTH)) { + faces.add(BlockFace.SOUTH); + } + + if (isFacePainted(BlockFace.EAST)) { + faces.add(BlockFace.EAST); + } + + if (isFacePainted(BlockFace.UP)) { + faces.add(BlockFace.UP); + } + + return faces; + } + + @Override + public String toString() { + return Material.getMaterial(getItemTypeId()).toString() + (isStem() ? "{STEM}" : getPaintedFaces()); + } + + @Override + public Mushroom clone() { + return (Mushroom) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/NetherWarts.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/NetherWarts.java new file mode 100644 index 0000000..55eb864 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/NetherWarts.java @@ -0,0 +1,101 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.NetherWartsState; + +/** + * Represents nether wart + */ +public class NetherWarts extends MaterialData { + public NetherWarts() { + super(Material.NETHER_WARTS); + } + + public NetherWarts(NetherWartsState state) { + this(); + setState(state); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public NetherWarts(final int type) { + super(type); + } + + public NetherWarts(final Material type) { + super (type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public NetherWarts(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public NetherWarts(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current growth state of this nether wart + * + * @return NetherWartsState of this nether wart + */ + public NetherWartsState getState() { + switch (getData()) { + case 0: + return NetherWartsState.SEEDED; + case 1: + return NetherWartsState.STAGE_ONE; + case 2: + return NetherWartsState.STAGE_TWO; + default: + return NetherWartsState.RIPE; + } + } + + /** + * Sets the growth state of this nether wart + * + * @param state New growth state of this nether wart + */ + public void setState(NetherWartsState state) { + switch (state) { + case SEEDED: + setData((byte) 0x0); + return; + case STAGE_ONE: + setData((byte) 0x1); + return; + case STAGE_TWO: + setData((byte) 0x2); + return; + case RIPE: + setData((byte) 0x3); + return; + } + } + + @Override + public String toString() { + return getState() + " " + super.toString(); + } + + @Override + public NetherWarts clone() { + return (NetherWarts) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Openable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Openable.java new file mode 100644 index 0000000..0ae54f9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Openable.java @@ -0,0 +1,18 @@ +package org.bukkit.material; + +public interface Openable { + + /** + * Check to see if the door is open. + * + * @return true if the door has swung counterclockwise around its hinge. + */ + boolean isOpen(); + + /** + * Configure this door to be either open or closed; + * + * @param isOpen True to open the door. + */ + void setOpen(boolean isOpen); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PistonBaseMaterial.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PistonBaseMaterial.java new file mode 100644 index 0000000..bbf1565 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PistonBaseMaterial.java @@ -0,0 +1,123 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Material data for the piston base block + */ +public class PistonBaseMaterial extends MaterialData implements Directional, Redstone { + + /** + * Constructs a PistonBaseMaterial + * + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public PistonBaseMaterial(final int type) { + super(type); + } + + public PistonBaseMaterial(final Material type) { + super(type); + } + + /** + * Constructs a PistonBaseMaterial. + * + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public PistonBaseMaterial(final int type, final byte data) { + super(type, data); + } + + /** + * Constructs a PistonBaseMaterial. + * + * @param type the material type to use + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public PistonBaseMaterial(final Material type, final byte data) { + super(type, data); + } + + @Override + public void setFacingDirection(BlockFace face) { + byte data = (byte) (getData() & 0x8); + + switch (face) { + case UP: + data |= 1; + break; + case NORTH: + data |= 2; + break; + case SOUTH: + data |= 3; + break; + case WEST: + data |= 4; + break; + case EAST: + data |= 5; + break; + } + setData(data); + } + + @Override + public BlockFace getFacing() { + byte dir = (byte) (getData() & 7); + + switch (dir) { + case 0: + return BlockFace.DOWN; + case 1: + return BlockFace.UP; + case 2: + return BlockFace.NORTH; + case 3: + return BlockFace.SOUTH; + case 4: + return BlockFace.WEST; + case 5: + return BlockFace.EAST; + default: + return BlockFace.SELF; + } + } + + @Override + public boolean isPowered() { + return (getData() & 0x8) == 0x8; + } + + /** + * Sets the current state of this piston + * + * @param powered true if the piston is extended {@literal &} powered, or false + */ + public void setPowered(boolean powered) { + setData((byte) (powered ? (getData() | 0x8) : (getData() & ~0x8))); + } + + /** + * Checks if this piston base is sticky, and returns true if so + * + * @return true if this piston is "sticky", or false + */ + public boolean isSticky() { + return this.getItemType() == Material.PISTON_STICKY_BASE; + } + + @Override + public PistonBaseMaterial clone() { + return (PistonBaseMaterial) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PistonExtensionMaterial.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PistonExtensionMaterial.java new file mode 100644 index 0000000..8076ec9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PistonExtensionMaterial.java @@ -0,0 +1,113 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Material data for the piston extension block + */ +public class PistonExtensionMaterial extends MaterialData implements Attachable { + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public PistonExtensionMaterial(final int type) { + super(type); + } + + public PistonExtensionMaterial(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public PistonExtensionMaterial(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public PistonExtensionMaterial(final Material type, final byte data) { + super(type, data); + } + + public void setFacingDirection(BlockFace face) { + byte data = (byte) (getData() & 0x8); + + switch (face) { + case UP: + data |= 1; + break; + case NORTH: + data |= 2; + break; + case SOUTH: + data |= 3; + break; + case WEST: + data |= 4; + break; + case EAST: + data |= 5; + break; + } + setData(data); + } + + public BlockFace getFacing() { + byte dir = (byte) (getData() & 7); + + switch (dir) { + case 0: + return BlockFace.DOWN; + case 1: + return BlockFace.UP; + case 2: + return BlockFace.NORTH; + case 3: + return BlockFace.SOUTH; + case 4: + return BlockFace.WEST; + case 5: + return BlockFace.EAST; + default: + return BlockFace.SELF; + } + } + + /** + * Checks if this piston extension is sticky, and returns true if so + * + * @return true if this piston is "sticky", or false + */ + public boolean isSticky() { + return (getData() & 8) == 8; + } + + /** + * Sets whether or not this extension is sticky + * + * @param sticky true if sticky, otherwise false + */ + public void setSticky(boolean sticky) { + setData((byte) (sticky ? (getData() | 0x8) : (getData() & ~0x8))); + } + + public BlockFace getAttachedFace() { + return getFacing().getOppositeFace(); + } + + @Override + public PistonExtensionMaterial clone() { + return (PistonExtensionMaterial) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PoweredRail.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PoweredRail.java new file mode 100644 index 0000000..4a9d6a9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PoweredRail.java @@ -0,0 +1,63 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents a powered rail + */ +public class PoweredRail extends ExtendedRails implements Redstone { + public PoweredRail() { + super(Material.POWERED_RAIL); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public PoweredRail(final int type) { + super(type); + } + + public PoweredRail(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public PoweredRail(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public PoweredRail(final Material type, final byte data) { + super(type, data); + } + + public boolean isPowered() { + return (getData() & 0x8) == 0x8; + } + + /** + * Set whether this PoweredRail should be powered or not. + * + * @param isPowered whether or not the rail is powered + */ + public void setPowered(boolean isPowered) { + setData((byte) (isPowered ? (getData() | 0x8) : (getData() & ~0x8))); + } + + @Override + public PoweredRail clone() { + return (PoweredRail) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PressurePlate.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PressurePlate.java new file mode 100644 index 0000000..d7747b5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PressurePlate.java @@ -0,0 +1,59 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents a pressure plate + */ +public class PressurePlate extends MaterialData implements PressureSensor { + public PressurePlate() { + super(Material.WOOD_PLATE); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public PressurePlate(int type) { + super(type); + } + + public PressurePlate(Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public PressurePlate(int type, byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public PressurePlate(Material type, byte data) { + super(type, data); + } + + public boolean isPressed() { + return getData() == 0x1; + } + + @Override + public String toString() { + return super.toString() + (isPressed() ? " PRESSED" : ""); + } + + @Override + public PressurePlate clone() { + return (PressurePlate) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PressureSensor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PressureSensor.java new file mode 100644 index 0000000..de20bd3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/PressureSensor.java @@ -0,0 +1,5 @@ +package org.bukkit.material; + +public interface PressureSensor { + public boolean isPressed(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Pumpkin.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Pumpkin.java new file mode 100644 index 0000000..afd200a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Pumpkin.java @@ -0,0 +1,114 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a pumpkin. + */ +public class Pumpkin extends MaterialData implements Directional { + + public Pumpkin() { + super(Material.PUMPKIN); + } + + /** + * Instantiate a pumpkin facing in a particular direction. + * + * @param direction the direction the pumkin's face is facing + */ + public Pumpkin(BlockFace direction) { + this(); + setFacingDirection(direction); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Pumpkin(final int type) { + super(type); + } + + public Pumpkin(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Pumpkin(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Pumpkin(final Material type, final byte data) { + super(type, data); + } + + public boolean isLit() { + return getItemType() == Material.JACK_O_LANTERN; + } + + public void setFacingDirection(BlockFace face) { + byte data; + + switch (face) { + case NORTH: + data = 0x0; + break; + + case EAST: + data = 0x1; + break; + + case SOUTH: + data = 0x2; + break; + + case WEST: + default: + data = 0x3; + } + + setData(data); + } + + public BlockFace getFacing() { + byte data = getData(); + + switch (data) { + case 0x0: + return BlockFace.NORTH; + + case 0x1: + return BlockFace.EAST; + + case 0x2: + return BlockFace.SOUTH; + + case 0x3: + default: + return BlockFace.EAST; + } + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing() + " " + (isLit() ? "" : "NOT ") + "LIT"; + } + + @Override + public Pumpkin clone() { + return (Pumpkin) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Rails.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Rails.java new file mode 100644 index 0000000..10044ee --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Rails.java @@ -0,0 +1,178 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents minecart rails. + */ +public class Rails extends MaterialData { + + public Rails() { + super(Material.RAILS); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Rails(final int type) { + super(type); + } + + public Rails(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Rails(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Rails(final Material type, final byte data) { + super(type, data); + } + + /** + * @return the whether this track is set on a slope + */ + public boolean isOnSlope() { + byte d = getConvertedData(); + + return (d == 0x2 || d == 0x3 || d == 0x4 || d == 0x5); + } + + /** + * @return the whether this track is set as a curve + */ + public boolean isCurve() { + byte d = getConvertedData(); + + return (d == 0x6 || d == 0x7 || d == 0x8 || d == 0x9); + } + + /** + * @return the direction these tracks are set + *

+ * Note that tracks are bidirectional and that the direction returned + * is the ascending direction if the track is set on a slope. If it is + * set as a curve, the corner of the track is returned. + */ + public BlockFace getDirection() { + byte d = getConvertedData(); + + switch (d) { + case 0x0: + default: + return BlockFace.SOUTH; + + case 0x1: + return BlockFace.EAST; + + case 0x2: + return BlockFace.EAST; + + case 0x3: + return BlockFace.WEST; + + case 0x4: + return BlockFace.NORTH; + + case 0x5: + return BlockFace.SOUTH; + + case 0x6: + return BlockFace.NORTH_WEST; + + case 0x7: + return BlockFace.NORTH_EAST; + + case 0x8: + return BlockFace.SOUTH_EAST; + + case 0x9: + return BlockFace.SOUTH_WEST; + } + } + + @Override + public String toString() { + return super.toString() + " facing " + getDirection() + (isCurve() ? " on a curve" : (isOnSlope() ? " on a slope" : "")); + } + + /** + * Return the data without the extended properties used by {@link + * PoweredRail} and {@link DetectorRail}. Overridden in {@link + * ExtendedRails} + * + * @return the data without the extended part + * @deprecated Magic value + */ + @Deprecated + protected byte getConvertedData() { + return getData(); + } + + /** + * Set the direction of these tracks + *

+ * Note that tracks are bidirectional and that the direction returned is + * the ascending direction if the track is set on a slope. If it is set as + * a curve, the corner of the track should be supplied. + * + * @param face the direction the track should be facing + * @param isOnSlope whether or not the track should be on a slope + */ + public void setDirection(BlockFace face, boolean isOnSlope) { + switch (face) { + case EAST: + setData((byte) (isOnSlope ? 0x2 : 0x1)); + break; + + case WEST: + setData((byte) (isOnSlope ? 0x3 : 0x1)); + break; + + case NORTH: + setData((byte) (isOnSlope ? 0x4 : 0x0)); + break; + + case SOUTH: + setData((byte) (isOnSlope ? 0x5 : 0x0)); + break; + + case NORTH_WEST: + setData((byte) 0x6); + break; + + case NORTH_EAST: + setData((byte) 0x7); + break; + + case SOUTH_EAST: + setData((byte) 0x8); + break; + + case SOUTH_WEST: + setData((byte) 0x9); + break; + } + } + + @Override + public Rails clone() { + return (Rails) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Redstone.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Redstone.java new file mode 100644 index 0000000..3e46603 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Redstone.java @@ -0,0 +1,15 @@ +package org.bukkit.material; + +/** + * Indicated a Material that may carry or create a Redstone current + */ +public interface Redstone { + + /** + * Gets the current state of this Material, indicating if it's powered or + * unpowered + * + * @return true if powered, otherwise false + */ + public boolean isPowered(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/RedstoneTorch.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/RedstoneTorch.java new file mode 100644 index 0000000..45c3e47 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/RedstoneTorch.java @@ -0,0 +1,65 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents a redstone torch + */ +public class RedstoneTorch extends Torch implements Redstone { + public RedstoneTorch() { + super(Material.REDSTONE_TORCH_ON); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public RedstoneTorch(final int type) { + super(type); + } + + public RedstoneTorch(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public RedstoneTorch(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public RedstoneTorch(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current state of this Material, indicating if it's powered or + * unpowered + * + * @return true if powered, otherwise false + */ + public boolean isPowered() { + return getItemType() == Material.REDSTONE_TORCH_ON; + } + + @Override + public String toString() { + return super.toString() + " " + (isPowered() ? "" : "NOT ") + "POWERED"; + } + + @Override + public RedstoneTorch clone() { + return (RedstoneTorch) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/RedstoneWire.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/RedstoneWire.java new file mode 100644 index 0000000..d13ae4b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/RedstoneWire.java @@ -0,0 +1,65 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents redstone wire + */ +public class RedstoneWire extends MaterialData implements Redstone { + public RedstoneWire() { + super(Material.REDSTONE_WIRE); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public RedstoneWire(final int type) { + super(type); + } + + public RedstoneWire(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public RedstoneWire(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public RedstoneWire(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current state of this Material, indicating if it's powered or + * unpowered + * + * @return true if powered, otherwise false + */ + public boolean isPowered() { + return getData() > 0; + } + + @Override + public String toString() { + return super.toString() + " " + (isPowered() ? "" : "NOT ") + "POWERED"; + } + + @Override + public RedstoneWire clone() { + return (RedstoneWire) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Sandstone.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Sandstone.java new file mode 100644 index 0000000..be88d43 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Sandstone.java @@ -0,0 +1,79 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.SandstoneType; + +/** + * Represents the different types of sandstone. + */ +public class Sandstone extends MaterialData { + public Sandstone() { + super(Material.SANDSTONE); + } + + public Sandstone(SandstoneType type) { + this(); + setType(type); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Sandstone(final int type) { + super(type); + } + + public Sandstone(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Sandstone(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Sandstone(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current type of this sandstone + * + * @return SandstoneType of this sandstone + */ + public SandstoneType getType() { + return SandstoneType.getByData(getData()); + } + + /** + * Sets the type of this sandstone + * + * @param type New type of this sandstone + */ + public void setType(SandstoneType type) { + setData(type.getData()); + } + + @Override + public String toString() { + return getType() + " " + super.toString(); + } + + @Override + public Sandstone clone() { + return (Sandstone) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Sign.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Sign.java new file mode 100644 index 0000000..0accdbc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Sign.java @@ -0,0 +1,252 @@ +package org.bukkit.material; + +import org.bukkit.block.BlockFace; +import org.bukkit.Material; + +/** + * MaterialData for signs + */ +public class Sign extends MaterialData implements Attachable { + public Sign() { + super(Material.SIGN_POST); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Sign(final int type) { + super(type); + } + + public Sign(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Sign(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Sign(final Material type, final byte data) { + super(type, data); + } + + /** + * Check if this sign is attached to a wall + * + * @return true if this sign is attached to a wall, false if set on top of + * a block + */ + public boolean isWallSign() { + return getItemType() == Material.WALL_SIGN; + } + + /** + * Gets the face that this block is attached on + * + * @return BlockFace attached to + */ + public BlockFace getAttachedFace() { + if (isWallSign()) { + byte data = getData(); + + switch (data) { + case 0x2: + return BlockFace.SOUTH; + + case 0x3: + return BlockFace.NORTH; + + case 0x4: + return BlockFace.EAST; + + case 0x5: + return BlockFace.WEST; + } + + return null; + } else { + return BlockFace.DOWN; + } + } + + /** + * Gets the direction that this sign is currently facing + * + * @return BlockFace indicating where this sign is facing + */ + public BlockFace getFacing() { + byte data = getData(); + + if (!isWallSign()) { + switch (data) { + case 0x0: + return BlockFace.SOUTH; + + case 0x1: + return BlockFace.SOUTH_SOUTH_WEST; + + case 0x2: + return BlockFace.SOUTH_WEST; + + case 0x3: + return BlockFace.WEST_SOUTH_WEST; + + case 0x4: + return BlockFace.WEST; + + case 0x5: + return BlockFace.WEST_NORTH_WEST; + + case 0x6: + return BlockFace.NORTH_WEST; + + case 0x7: + return BlockFace.NORTH_NORTH_WEST; + + case 0x8: + return BlockFace.NORTH; + + case 0x9: + return BlockFace.NORTH_NORTH_EAST; + + case 0xA: + return BlockFace.NORTH_EAST; + + case 0xB: + return BlockFace.EAST_NORTH_EAST; + + case 0xC: + return BlockFace.EAST; + + case 0xD: + return BlockFace.EAST_SOUTH_EAST; + + case 0xE: + return BlockFace.SOUTH_EAST; + + case 0xF: + return BlockFace.SOUTH_SOUTH_EAST; + } + + return null; + } else { + return getAttachedFace().getOppositeFace(); + } + } + + public void setFacingDirection(BlockFace face) { + byte data; + + if (isWallSign()) { + switch (face) { + case NORTH: + data = 0x2; + break; + + case SOUTH: + data = 0x3; + break; + + case WEST: + data = 0x4; + break; + + case EAST: + default: + data = 0x5; + } + } else { + switch (face) { + case SOUTH: + data = 0x0; + break; + + case SOUTH_SOUTH_WEST: + data = 0x1; + break; + + case SOUTH_WEST: + data = 0x2; + break; + + case WEST_SOUTH_WEST: + data = 0x3; + break; + + case WEST: + data = 0x4; + break; + + case WEST_NORTH_WEST: + data = 0x5; + break; + + case NORTH_WEST: + data = 0x6; + break; + + case NORTH_NORTH_WEST: + data = 0x7; + break; + + case NORTH: + data = 0x8; + break; + + case NORTH_NORTH_EAST: + data = 0x9; + break; + + case NORTH_EAST: + data = 0xA; + break; + + case EAST_NORTH_EAST: + data = 0xB; + break; + + case EAST: + data = 0xC; + break; + + case EAST_SOUTH_EAST: + data = 0xD; + break; + + case SOUTH_SOUTH_EAST: + data = 0xF; + break; + + case SOUTH_EAST: + default: + data = 0xE; + } + } + + setData(data); + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing(); + } + + @Override + public Sign clone() { + return (Sign) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SimpleAttachableMaterialData.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SimpleAttachableMaterialData.java new file mode 100644 index 0000000..b1897b7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SimpleAttachableMaterialData.java @@ -0,0 +1,68 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Simple utility class for attachable MaterialData subclasses + */ +public abstract class SimpleAttachableMaterialData extends MaterialData implements Attachable { + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public SimpleAttachableMaterialData(int type) { + super(type); + } + + public SimpleAttachableMaterialData(int type, BlockFace direction) { + this(type); + setFacingDirection(direction); + } + + public SimpleAttachableMaterialData(Material type, BlockFace direction) { + this(type); + setFacingDirection(direction); + } + + public SimpleAttachableMaterialData(Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public SimpleAttachableMaterialData(int type, byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public SimpleAttachableMaterialData(Material type, byte data) { + super(type, data); + } + + public BlockFace getFacing() { + BlockFace attachedFace = getAttachedFace(); + return attachedFace == null ? null : attachedFace.getOppositeFace(); + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing(); + } + + @Override + public SimpleAttachableMaterialData clone() { + return (SimpleAttachableMaterialData) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Skull.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Skull.java new file mode 100644 index 0000000..659d9e9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Skull.java @@ -0,0 +1,116 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a skull. + */ +public class Skull extends MaterialData implements Directional { + public Skull() { + super(Material.SKULL); + } + + /** + * Instantiate a skull facing in a particular direction. + * + * @param direction the direction the skull's face is facing + */ + public Skull(BlockFace direction) { + this(); + setFacingDirection(direction); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Skull(final int type) { + super(type); + } + + public Skull(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Skull(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Skull(final Material type, final byte data) { + super(type, data); + } + + public void setFacingDirection(BlockFace face) { + int data; + + switch (face) { + case SELF: + default: + data = 0x1; + break; + + case NORTH: + data = 0x2; + break; + + case EAST: + data = 0x4; + break; + + case SOUTH: + data = 0x3; + break; + + case WEST: + data = 0x5; + } + + setData((byte) data); + } + + public BlockFace getFacing() { + int data = getData(); + + switch (data) { + case 0x1: + default: + return BlockFace.SELF; + + case 0x2: + return BlockFace.NORTH; + + case 0x3: + return BlockFace.SOUTH; + + case 0x4: + return BlockFace.EAST; + + case 0x5: + return BlockFace.WEST; + } + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing(); + } + + @Override + public Skull clone() { + return (Skull) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SmoothBrick.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SmoothBrick.java new file mode 100644 index 0000000..a6d8931 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SmoothBrick.java @@ -0,0 +1,70 @@ +package org.bukkit.material; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Material; + +/** + * Represents the different types of smooth bricks. + */ +public class SmoothBrick extends TexturedMaterial { + + private static final List textures = new ArrayList(); + static { + textures.add(Material.STONE); + textures.add(Material.MOSSY_COBBLESTONE); + textures.add(Material.COBBLESTONE); + textures.add(Material.SMOOTH_BRICK); + } + + public SmoothBrick() { + super(Material.SMOOTH_BRICK); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public SmoothBrick(final int type) { + super(type); + } + + public SmoothBrick(final Material type) { + super((textures.contains(type)) ? Material.SMOOTH_BRICK : type); + if (textures.contains(type)) { + setMaterial(type); + } + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public SmoothBrick(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public SmoothBrick(final Material type, final byte data) { + super(type, data); + } + + @Override + public List getTextures() { + return textures; + } + + @Override + public SmoothBrick clone() { + return (SmoothBrick) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SpawnEgg.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SpawnEgg.java new file mode 100644 index 0000000..4260627 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/SpawnEgg.java @@ -0,0 +1,66 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.entity.EntityType; + +/** + * Represents a spawn egg that can be used to spawn mobs + */ +public class SpawnEgg extends MaterialData { + + public SpawnEgg() { + super(Material.MONSTER_EGG); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public SpawnEgg(int type, byte data){ + super(type, data); + } + + /** + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public SpawnEgg(byte data) { + super(Material.MONSTER_EGG, data); + } + + public SpawnEgg(EntityType type) { + this(); + setSpawnedType(type); + } + + /** + * Get the type of entity this egg will spawn. + * + * @return The entity type. + */ + public EntityType getSpawnedType() { + return EntityType.fromId(getData()); + } + + /** + * Set the type of entity this egg will spawn. + * + * @param type The entity type. + */ + public void setSpawnedType(EntityType type) { + setData((byte) type.getTypeId()); + } + + @Override + public String toString() { + return "SPAWN EGG{" + getSpawnedType() + "}"; + } + + @Override + public SpawnEgg clone() { + return (SpawnEgg) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Stairs.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Stairs.java new file mode 100644 index 0000000..7dde021 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Stairs.java @@ -0,0 +1,140 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents stairs. + */ +public class Stairs extends MaterialData implements Directional { + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Stairs(final int type) { + super(type); + } + + public Stairs(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Stairs(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Stairs(final Material type, final byte data) { + super(type, data); + } + + /** + * @return the direction the stairs ascend towards + */ + public BlockFace getAscendingDirection() { + byte data = getData(); + + switch (data & 0x3) { + case 0x0: + default: + return BlockFace.EAST; + + case 0x1: + return BlockFace.WEST; + + case 0x2: + return BlockFace.SOUTH; + + case 0x3: + return BlockFace.NORTH; + } + } + + /** + * @return the direction the stairs descend towards + */ + public BlockFace getDescendingDirection() { + return getAscendingDirection().getOppositeFace(); + } + + /** + * Set the direction the stair part of the block is facing + */ + public void setFacingDirection(BlockFace face) { + byte data; + + switch (face) { + case NORTH: + data = 0x3; + break; + + case SOUTH: + data = 0x2; + break; + + case EAST: + default: + data = 0x0; + break; + + case WEST: + data = 0x1; + break; + } + + setData((byte) ((getData() & 0xC) | data)); + } + + /** + * @return the direction the stair part of the block is facing + */ + public BlockFace getFacing() { + return getDescendingDirection(); + } + + /** + * Test if step is inverted + * + * @return true if inverted (top half), false if normal (bottom half) + */ + public boolean isInverted() { + return ((getData() & 0x4) != 0); + } + + /** + * Set step inverted state + * + * @param inv - true if step is inverted (top half), false if step is + * normal (bottom half) + */ + public void setInverted(boolean inv) { + int dat = getData() & 0x3; + if (inv) { + dat |= 0x4; + } + setData((byte) dat); + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing() + (isInverted()?" inverted":""); + } + + @Override + public Stairs clone() { + return (Stairs) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Step.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Step.java new file mode 100644 index 0000000..c2ccfce --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Step.java @@ -0,0 +1,121 @@ +package org.bukkit.material; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Material; + +/** + * Represents the different types of steps. + */ +public class Step extends TexturedMaterial { + private static final List textures = new ArrayList(); + static { + textures.add(Material.STONE); + textures.add(Material.SANDSTONE); + textures.add(Material.WOOD); + textures.add(Material.COBBLESTONE); + textures.add(Material.BRICK); + textures.add(Material.SMOOTH_BRICK); + textures.add(Material.NETHER_BRICK); + textures.add(Material.QUARTZ_BLOCK); + } + + public Step() { + super(Material.STEP); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Step(final int type) { + super(type); + } + + public Step(final Material type) { + super((textures.contains(type)) ? Material.STEP : type); + if (textures.contains(type)) { + setMaterial(type); + } + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Step(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Step(final Material type, final byte data) { + super(type, data); + } + + @Override + public List getTextures() { + return textures; + } + + /** + * Test if step is inverted + * + * @return true if inverted (top half), false if normal (bottom half) + */ + public boolean isInverted() { + return ((getData() & 0x8) != 0); + } + + /** + * Set step inverted state + * + * @param inv - true if step is inverted (top half), false if step is + * normal (bottom half) + */ + public void setInverted(boolean inv) { + int dat = getData() & 0x7; + if (inv) { + dat |= 0x8; + } + setData((byte) dat); + } + + /** + * + * @deprecated Magic value + */ + @Deprecated + @Override + protected int getTextureIndex() { + return getData() & 0x7; + } + + /** + * + * @deprecated Magic value + */ + @Deprecated + @Override + protected void setTextureIndex(int idx) { + setData((byte) ((getData() & 0x8) | idx)); + } + + @Override + public Step clone() { + return (Step) super.clone(); + } + + @Override + public String toString() { + return super.toString() + (isInverted()?"inverted":""); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TexturedMaterial.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TexturedMaterial.java new file mode 100644 index 0000000..d1b85e2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TexturedMaterial.java @@ -0,0 +1,112 @@ +package org.bukkit.material; + +import java.util.List; + +import org.bukkit.Material; + +/** + * Represents textured materials like steps and smooth bricks + */ +public abstract class TexturedMaterial extends MaterialData { + + public TexturedMaterial(Material m) { + super(m); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public TexturedMaterial(int type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public TexturedMaterial(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public TexturedMaterial(final Material type, final byte data) { + super(type, data); + } + + /** + * Retrieve a list of possible textures. The first element of the list + * will be used as a default. + * + * @return a list of possible textures for this block + */ + public abstract List getTextures(); + + /** + * Gets the current Material this block is made of + * + * @return Material of this block + */ + public Material getMaterial() { + int n = getTextureIndex(); + if (n > getTextures().size() - 1) { + n = 0; + } + + return getTextures().get(n); + } + + /** + * Sets the material this block is made of + * + * @param material + * New material of this block + */ + public void setMaterial(Material material) { + if (getTextures().contains(material)) { + setTextureIndex(getTextures().indexOf(material)); + } else { + setTextureIndex(0x0); + } + } + + /** + * Get material index from data + * + * @return index of data in textures list + * @deprecated Magic value + */ + @Deprecated + protected int getTextureIndex() { + return getData(); // Default to using all bits - override for other mappings + } + + /** + * Set material index + * + * @param idx - index of data in textures list + * @deprecated Magic value + */ + @Deprecated + protected void setTextureIndex(int idx) { + setData((byte) idx); // Defult to using all bits - override for other mappings + } + + @Override + public String toString() { + return getMaterial() + " " + super.toString(); + } + + @Override + public TexturedMaterial clone() { + return (TexturedMaterial) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Torch.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Torch.java new file mode 100644 index 0000000..60be6bd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Torch.java @@ -0,0 +1,106 @@ +package org.bukkit.material; + +import org.bukkit.block.BlockFace; +import org.bukkit.Material; + +/** + * MaterialData for torches + */ +public class Torch extends SimpleAttachableMaterialData { + public Torch() { + super(Material.TORCH); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Torch(final int type) { + super(type); + } + + public Torch(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Torch(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Torch(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the face that this block is attached on + * + * @return BlockFace attached to + */ + public BlockFace getAttachedFace() { + byte data = getData(); + + switch (data) { + case 0x1: + return BlockFace.WEST; + + case 0x2: + return BlockFace.EAST; + + case 0x3: + return BlockFace.NORTH; + + case 0x4: + return BlockFace.SOUTH; + + case 0x5: + default: + return BlockFace.DOWN; + } + } + + public void setFacingDirection(BlockFace face) { + byte data; + + switch (face) { + case EAST: + data = 0x1; + break; + + case WEST: + data = 0x2; + break; + + case SOUTH: + data = 0x3; + break; + + case NORTH: + data = 0x4; + break; + + case UP: + default: + data = 0x5; + } + + setData(data); + } + + @Override + public Torch clone() { + return (Torch) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TrapDoor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TrapDoor.java new file mode 100644 index 0000000..2ae3362 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TrapDoor.java @@ -0,0 +1,133 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a trap door + */ +public class TrapDoor extends SimpleAttachableMaterialData implements Openable { + public TrapDoor() { + super(Material.TRAP_DOOR); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public TrapDoor(final int type) { + super(type); + } + + public TrapDoor(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public TrapDoor(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public TrapDoor(final Material type, final byte data) { + super(type, data); + } + + public boolean isOpen() { + return ((getData() & 0x4) == 0x4); + } + + public void setOpen(boolean isOpen) { + byte data = getData(); + + if (isOpen) { + data |= 0x4; + } else { + data &= ~0x4; + } + + setData(data); + } + + /** + * Test if trapdoor is inverted + * + * @return true if inverted (top half), false if normal (bottom half) + */ + public boolean isInverted() { + return ((getData() & 0x8) != 0); + } + + /** + * Set trapdoor inverted state + * + * @param inv - true if inverted (top half), false if normal (bottom half) + */ + public void setInverted(boolean inv) { + int dat = getData() & 0x7; + if (inv) { + dat |= 0x8; + } + setData((byte) dat); + } + + public BlockFace getAttachedFace() { + byte data = (byte) (getData() & 0x3); + + switch (data) { + case 0x0: + return BlockFace.SOUTH; + + case 0x1: + return BlockFace.NORTH; + + case 0x2: + return BlockFace.EAST; + + case 0x3: + return BlockFace.WEST; + } + + return null; + + } + + public void setFacingDirection(BlockFace face) { + byte data = (byte) (getData() & 0xC); + + switch (face) { + case SOUTH: + data |= 0x1; + break; + case WEST: + data |= 0x2; + break; + case EAST: + data |= 0x3; + break; + } + + setData(data); + } + + @Override + public String toString() { + return (isOpen() ? "OPEN " : "CLOSED ") + super.toString() + " with hinges set " + getAttachedFace() + (isInverted() ? " inverted" : ""); + } + + @Override + public TrapDoor clone() { + return (TrapDoor) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Tree.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Tree.java new file mode 100644 index 0000000..d90126c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Tree.java @@ -0,0 +1,138 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.TreeSpecies; +import org.bukkit.block.BlockFace; + +/** + * Represents the different types of Trees. + */ +public class Tree extends MaterialData { + public Tree() { + super(Material.LOG); + } + + public Tree(TreeSpecies species) { + this(); + setSpecies(species); + } + + public Tree(TreeSpecies species, BlockFace dir) { + this(); + setSpecies(species); + setDirection(dir); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Tree(final int type) { + super(type); + } + + public Tree(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Tree(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Tree(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current species of this tree + * + * @return TreeSpecies of this tree + */ + public TreeSpecies getSpecies() { + return TreeSpecies.getByData((byte) (getData() & 0x3)); + } + + /** + * Sets the species of this tree + * + * @param species New species of this tree + */ + public void setSpecies(TreeSpecies species) { + setData((byte) ((getData() & 0xC) | species.getData())); + } + + /** + * Get direction of the log + * + * @return one of: + *

    + *
  • BlockFace.TOP for upright (default) + *
  • BlockFace.NORTH (east-west) + *
  • BlockFace.WEST (north-south) + *
  • BlockFace.SELF (directionless) + *
+ */ + public BlockFace getDirection() { + switch ((getData() >> 2) & 0x3) { + case 0: // Up-down + default: + return BlockFace.UP; + case 1: // North-south + return BlockFace.WEST; + case 2: // East-west + return BlockFace.NORTH; + case 3: // Directionless (bark on all sides) + return BlockFace.SELF; + } + } + /** + * Set direction of the log + * + * @param dir - direction of end of log (BlockFace.SELF for no direction) + */ + public void setDirection(BlockFace dir) { + int dat; + switch (dir) { + case UP: + case DOWN: + default: + dat = 0; + break; + case WEST: + case EAST: + dat = 1; + break; + case NORTH: + case SOUTH: + dat = 2; + break; + case SELF: + dat = 3; + break; + } + setData((byte) ((getData() & 0x3) | (dat << 2))); + } + + @Override + public String toString() { + return getSpecies() + " " + getDirection() + " " + super.toString(); + } + + @Override + public Tree clone() { + return (Tree) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Tripwire.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Tripwire.java new file mode 100644 index 0000000..570635d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Tripwire.java @@ -0,0 +1,86 @@ +package org.bukkit.material; + +import org.bukkit.Material; + +/** + * Represents the tripwire + */ +public class Tripwire extends MaterialData { + + public Tripwire() { + super(Material.TRIPWIRE); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Tripwire(final int type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Tripwire(final int type, final byte data) { + super(type, data); + } + + /** + * Test if tripwire is currently activated + * + * @return true if activated, false if not + */ + public boolean isActivated() { + return (getData() & 0x4) != 0; + } + + /** + * Set tripwire activated state + * + * @param act - true if activated, false if not + */ + public void setActivated(boolean act) { + int dat = getData() & (0x8 | 0x3); + if (act) { + dat |= 0x4; + } + setData((byte) dat); + } + + /** + * Test if object triggering this tripwire directly + * + * @return true if object activating tripwire, false if not + */ + public boolean isObjectTriggering() { + return (getData() & 0x1) != 0; + } + + /** + * Set object triggering state for this tripwire + * + * @param trig - true if object activating tripwire, false if not + */ + public void setObjectTriggering(boolean trig) { + int dat = getData() & 0xE; + if (trig) { + dat |= 0x1; + } + setData((byte) dat); + } + + @Override + public Tripwire clone() { + return (Tripwire) super.clone(); + } + + @Override + public String toString() { + return super.toString() + (isActivated()?" Activated":"") + (isObjectTriggering()?" Triggered":""); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TripwireHook.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TripwireHook.java new file mode 100644 index 0000000..8ff23e9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/TripwireHook.java @@ -0,0 +1,129 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents the tripwire hook + */ +public class TripwireHook extends SimpleAttachableMaterialData implements Redstone { + + public TripwireHook() { + super(Material.TRIPWIRE_HOOK); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public TripwireHook(final int type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public TripwireHook(final int type, final byte data) { + super(type, data); + } + + public TripwireHook(BlockFace dir) { + this(); + setFacingDirection(dir); + } + + /** + * Test if tripwire is connected + * + * @return true if connected, false if not + */ + public boolean isConnected() { + return (getData() & 0x4) != 0; + } + + /** + * Set tripwire connection state + * + * @param connected - true if connected, false if not + */ + public void setConnected(boolean connected) { + int dat = getData() & (0x8 | 0x3); + if (connected) { + dat |= 0x4; + } + setData((byte) dat); + } + + /** + * Test if hook is currently activated + * + * @return true if activated, false if not + */ + public boolean isActivated() { + return (getData() & 0x8) != 0; + } + + /** + * Set hook activated state + * + * @param act - true if activated, false if not + */ + public void setActivated(boolean act) { + int dat = getData() & (0x4 | 0x3); + if (act) { + dat |= 0x8; + } + setData((byte) dat); + } + + public void setFacingDirection(BlockFace face) { + int dat = getData() & 0xC; + switch (face) { + case WEST: + dat |= 0x1; + break; + case NORTH: + dat |= 0x2; + break; + case EAST: + dat |= 0x3; + break; + case SOUTH: + default: + break; + } + setData((byte) dat); + } + + public BlockFace getAttachedFace() { + switch (getData() & 0x3) { + case 0: + return BlockFace.NORTH; + case 1: + return BlockFace.EAST; + case 2: + return BlockFace.SOUTH; + case 3: + return BlockFace.WEST; + } + return null; + } + + public boolean isPowered() { + return isActivated(); + } + + @Override + public TripwireHook clone() { + return (TripwireHook) super.clone(); + } + + @Override + public String toString() { + return super.toString() + " facing " + getFacing() + (isActivated()?" Activated":"") + (isConnected()?" Connected":""); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Vine.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Vine.java new file mode 100644 index 0000000..5a09667 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Vine.java @@ -0,0 +1,197 @@ +package org.bukkit.material; + +import java.util.Arrays; +import java.util.EnumSet; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; + +/** + * Represents a vine + */ +public class Vine extends MaterialData { + private static final int VINE_NORTH = 0x4; + private static final int VINE_EAST = 0x8; + private static final int VINE_WEST = 0x2; + private static final int VINE_SOUTH = 0x1; + EnumSet possibleFaces = EnumSet.of(BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST); + + public Vine() { + super(Material.VINE); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Vine(int type, byte data){ + super(type, data); + } + + /** + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Vine(byte data) { + super(Material.VINE, data); + } + + public Vine(BlockFace... faces) { + this(EnumSet.copyOf(Arrays.asList(faces))); + } + + public Vine(EnumSet faces) { + this((byte) 0); + faces.retainAll(possibleFaces); + + byte data = 0; + + if (faces.contains(BlockFace.WEST)) { + data |= VINE_WEST; + } + + if (faces.contains(BlockFace.NORTH)) { + data |= VINE_NORTH; + } + + if (faces.contains(BlockFace.SOUTH)) { + data |= VINE_SOUTH; + } + + if (faces.contains(BlockFace.EAST)) { + data |= VINE_EAST; + } + + setData(data); + } + + /** + * Check if the vine is attached to the specified face of an adjacent + * block. You can check two faces at once by passing e.g. {@link + * BlockFace#NORTH_EAST}. + * + * @param face The face to check. + * @return Whether it is attached to that face. + */ + public boolean isOnFace(BlockFace face) { + switch (face) { + case WEST: + return (getData() & VINE_WEST) == VINE_WEST; + case NORTH: + return (getData() & VINE_NORTH) == VINE_NORTH; + case SOUTH: + return (getData() & VINE_SOUTH) == VINE_SOUTH; + case EAST: + return (getData() & VINE_EAST) == VINE_EAST; + case NORTH_EAST: + return isOnFace(BlockFace.EAST) && isOnFace(BlockFace.NORTH); + case NORTH_WEST: + return isOnFace(BlockFace.WEST) && isOnFace(BlockFace.NORTH); + case SOUTH_EAST: + return isOnFace(BlockFace.EAST) && isOnFace(BlockFace.SOUTH); + case SOUTH_WEST: + return isOnFace(BlockFace.WEST) && isOnFace(BlockFace.SOUTH); + case UP: // It's impossible to be accurate with this since it's contextual + return true; + default: + return false; + } + } + + /** + * Attach the vine to the specified face of an adjacent block. + * + * @param face The face to attach. + */ + public void putOnFace(BlockFace face) { + switch(face) { + case WEST: + setData((byte) (getData() | VINE_WEST)); + break; + case NORTH: + setData((byte) (getData() | VINE_NORTH)); + break; + case SOUTH: + setData((byte) (getData() | VINE_SOUTH)); + break; + case EAST: + setData((byte) (getData() | VINE_EAST)); + break; + case NORTH_WEST: + putOnFace(BlockFace.WEST); + putOnFace(BlockFace.NORTH); + break; + case SOUTH_WEST: + putOnFace(BlockFace.WEST); + putOnFace(BlockFace.SOUTH); + break; + case NORTH_EAST: + putOnFace(BlockFace.EAST); + putOnFace(BlockFace.NORTH); + break; + case SOUTH_EAST: + putOnFace(BlockFace.EAST); + putOnFace(BlockFace.SOUTH); + break; + case UP: + break; + default: + throw new IllegalArgumentException("Vines can't go on face " + face.toString()); + } + } + + /** + * Detach the vine from the specified face of an adjacent block. + * + * @param face The face to detach. + */ + public void removeFromFace(BlockFace face) { + switch(face) { + case WEST: + setData((byte) (getData() & ~VINE_WEST)); + break; + case NORTH: + setData((byte) (getData() & ~VINE_NORTH)); + break; + case SOUTH: + setData((byte) (getData() & ~VINE_SOUTH)); + break; + case EAST: + setData((byte) (getData() & ~VINE_EAST)); + break; + case NORTH_WEST: + removeFromFace(BlockFace.WEST); + removeFromFace(BlockFace.NORTH); + break; + case SOUTH_WEST: + removeFromFace(BlockFace.WEST); + removeFromFace(BlockFace.SOUTH); + break; + case NORTH_EAST: + removeFromFace(BlockFace.EAST); + removeFromFace(BlockFace.NORTH); + break; + case SOUTH_EAST: + removeFromFace(BlockFace.EAST); + removeFromFace(BlockFace.SOUTH); + break; + case UP: + break; + default: + throw new IllegalArgumentException("Vines can't go on face " + face.toString()); + } + } + + @Override + public String toString() { + return "VINE"; + } + + @Override + public Vine clone() { + return (Vine) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/WoodenStep.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/WoodenStep.java new file mode 100644 index 0000000..b07ee89 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/WoodenStep.java @@ -0,0 +1,105 @@ +package org.bukkit.material; + +import org.bukkit.Material; +import org.bukkit.TreeSpecies; + +/** + * Represents the different types of wooden steps. + */ +public class WoodenStep extends MaterialData { + + public WoodenStep() { + super(Material.WOOD_STEP); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public WoodenStep(final int type) { + super(type); + } + + public WoodenStep(TreeSpecies species) { + this(); + setSpecies(species); + } + + public WoodenStep(TreeSpecies species, boolean inv) { + this(); + setSpecies(species); + setInverted(inv); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public WoodenStep(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public WoodenStep(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current species of this tree + * + * @return TreeSpecies of this tree + */ + public TreeSpecies getSpecies() { + return TreeSpecies.getByData((byte) (getData() & 0x3)); + } + + /** + * Sets the species of this tree + * + * @param species New species of this tree + */ + public void setSpecies(TreeSpecies species) { + setData((byte) ((getData() & 0xC) | species.getData())); + } + + /** + * Test if step is inverted + * + * @return true if inverted (top half), false if normal (bottom half) + */ + public boolean isInverted() { + return ((getData() & 0x8) != 0); + } + + /** + * Set step inverted state + * + * @param inv - true if step is inverted (top half), false if step is + * normal (bottom half) + */ + public void setInverted(boolean inv) { + int dat = getData() & 0x7; + if (inv) { + dat |= 0x8; + } + setData((byte) dat); + } + + @Override + public WoodenStep clone() { + return (WoodenStep) super.clone(); + } + + @Override + public String toString() { + return super.toString() + " " + getSpecies() + (isInverted()?" inverted":""); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Wool.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Wool.java new file mode 100644 index 0000000..c4e4bfa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/material/Wool.java @@ -0,0 +1,79 @@ +package org.bukkit.material; + +import org.bukkit.DyeColor; +import org.bukkit.Material; + +/** + * Represents a Wool/Cloth block + */ +public class Wool extends MaterialData implements Colorable { + public Wool() { + super(Material.WOOL); + } + + public Wool(DyeColor color) { + this(); + setColor(color); + } + + /** + * @param type the raw type id + * @deprecated Magic value + */ + @Deprecated + public Wool(final int type) { + super(type); + } + + public Wool(final Material type) { + super(type); + } + + /** + * @param type the raw type id + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Wool(final int type, final byte data) { + super(type, data); + } + + /** + * @param type the type + * @param data the raw data value + * @deprecated Magic value + */ + @Deprecated + public Wool(final Material type, final byte data) { + super(type, data); + } + + /** + * Gets the current color of this dye + * + * @return DyeColor of this dye + */ + public DyeColor getColor() { + return DyeColor.getByWoolData(getData()); + } + + /** + * Sets the color of this dye + * + * @param color New color of this dye + */ + public void setColor(DyeColor color) { + setData(color.getWoolData()); + } + + @Override + public String toString() { + return getColor() + " " + super.toString(); + } + + @Override + public Wool clone() { + return (Wool) super.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/FixedMetadataValue.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/FixedMetadataValue.java new file mode 100644 index 0000000..bce6f00 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/FixedMetadataValue.java @@ -0,0 +1,43 @@ +package org.bukkit.metadata; + +import org.bukkit.plugin.Plugin; + +import java.util.concurrent.Callable; + +/** + * A FixedMetadataValue is a special case metadata item that contains the same + * value forever after initialization. Invalidating a FixedMetadataValue has + * no effect. + *

+ * This class extends LazyMetadataValue for historical reasons, even though it + * overrides all the implementation methods. it is possible that in the future + * that the inheritance hierarchy may change. + */ +public class FixedMetadataValue extends LazyMetadataValue { + + /** + * Store the internal value that is represented by this fixed value. + */ + private final Object internalValue; + + /** + * Initializes a FixedMetadataValue with an Object + * + * @param owningPlugin the {@link Plugin} that created this metadata value + * @param value the value assigned to this metadata value + */ + public FixedMetadataValue(Plugin owningPlugin, final Object value) { + super(owningPlugin); + this.internalValue = value; + } + + @Override + public void invalidate() { + + } + + @Override + public Object value() { + return internalValue; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/LazyMetadataValue.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/LazyMetadataValue.java new file mode 100644 index 0000000..564d0fa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/LazyMetadataValue.java @@ -0,0 +1,122 @@ +package org.bukkit.metadata; + +import java.lang.ref.SoftReference; +import java.util.concurrent.Callable; + +import org.apache.commons.lang.Validate; +import org.bukkit.plugin.Plugin; + +/** + * The LazyMetadataValue class implements a type of metadata that is not + * computed until another plugin asks for it. + *

+ * By making metadata values lazy, no computation is done by the providing + * plugin until absolutely necessary (if ever). Additionally, + * LazyMetadataValue objects cache their values internally unless overridden + * by a {@link CacheStrategy} or invalidated at the individual or plugin + * level. Once invalidated, the LazyMetadataValue will recompute its value + * when asked. + */ +public class LazyMetadataValue extends MetadataValueAdapter implements MetadataValue { + private Callable lazyValue; + private CacheStrategy cacheStrategy; + private SoftReference internalValue; + private static final Object ACTUALLY_NULL = new Object(); + + /** + * Initialized a LazyMetadataValue object with the default + * CACHE_AFTER_FIRST_EVAL cache strategy. + * + * @param owningPlugin the {@link Plugin} that created this metadata + * value. + * @param lazyValue the lazy value assigned to this metadata value. + */ + public LazyMetadataValue(Plugin owningPlugin, Callable lazyValue) { + this(owningPlugin, CacheStrategy.CACHE_AFTER_FIRST_EVAL, lazyValue); + } + + /** + * Initializes a LazyMetadataValue object with a specific cache strategy. + * + * @param owningPlugin the {@link Plugin} that created this metadata + * value. + * @param cacheStrategy determines the rules for caching this metadata + * value. + * @param lazyValue the lazy value assigned to this metadata value. + */ + public LazyMetadataValue(Plugin owningPlugin, CacheStrategy cacheStrategy, Callable lazyValue) { + super(owningPlugin); + Validate.notNull(cacheStrategy, "cacheStrategy cannot be null"); + Validate.notNull(lazyValue, "lazyValue cannot be null"); + this.internalValue = new SoftReference(null); + this.lazyValue = lazyValue; + this.cacheStrategy = cacheStrategy; + } + + /** + * Protected special constructor used by FixedMetadataValue to bypass + * standard setup. + * + * @param owningPlugin the owning plugin + */ + protected LazyMetadataValue(Plugin owningPlugin) { + super(owningPlugin); + } + + public Object value() { + eval(); + Object value = internalValue.get(); + if (value == ACTUALLY_NULL) { + return null; + } + return value; + } + + /** + * Lazily evaluates the value of this metadata item. + * + * @throws MetadataEvaluationException if computing the metadata value + * fails. + */ + private synchronized void eval() throws MetadataEvaluationException { + if (cacheStrategy == CacheStrategy.NEVER_CACHE || internalValue.get() == null) { + try { + Object value = lazyValue.call(); + if (value == null) { + value = ACTUALLY_NULL; + } + internalValue = new SoftReference(value); + } catch (Exception e) { + throw new MetadataEvaluationException(e); + } + } + } + + public synchronized void invalidate() { + if (cacheStrategy != CacheStrategy.CACHE_ETERNALLY) { + internalValue.clear(); + } + } + + /** + * Describes possible caching strategies for metadata. + */ + public enum CacheStrategy { + /** + * Once the metadata value has been evaluated, do not re-evaluate the + * value until it is manually invalidated. + */ + CACHE_AFTER_FIRST_EVAL, + + /** + * Re-evaluate the metadata item every time it is requested + */ + NEVER_CACHE, + + /** + * Once the metadata value has been evaluated, do not re-evaluate the + * value in spite of manual invalidation. + */ + CACHE_ETERNALLY + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataConversionException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataConversionException.java new file mode 100644 index 0000000..a3def46 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataConversionException.java @@ -0,0 +1,13 @@ +package org.bukkit.metadata; + +/** + * A MetadataConversionException is thrown any time a {@link + * LazyMetadataValue} attempts to convert a metadata value to an inappropriate + * data type. + */ +@SuppressWarnings("serial") +public class MetadataConversionException extends RuntimeException { + MetadataConversionException(String message) { + super(message); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataEvaluationException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataEvaluationException.java new file mode 100644 index 0000000..918e7c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataEvaluationException.java @@ -0,0 +1,13 @@ +package org.bukkit.metadata; + +/** + * A MetadataEvaluationException is thrown any time a {@link + * LazyMetadataValue} fails to evaluate its value due to an exception. The + * originating exception will be included as this exception's cause. + */ +@SuppressWarnings("serial") +public class MetadataEvaluationException extends RuntimeException { + MetadataEvaluationException(Throwable cause) { + super(cause); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataStore.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataStore.java new file mode 100644 index 0000000..700d0bf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataStore.java @@ -0,0 +1,60 @@ +package org.bukkit.metadata; + +import org.bukkit.plugin.Plugin; + +import java.util.List; + +public interface MetadataStore { + /** + * Adds a metadata value to an object. + * + * @param subject The object receiving the metadata. + * @param metadataKey A unique key to identify this metadata. + * @param newMetadataValue The metadata value to apply. + * @throws IllegalArgumentException If value is null, or the owning plugin + * is null + */ + public void setMetadata(T subject, String metadataKey, MetadataValue newMetadataValue); + + /** + * Returns all metadata values attached to an object. If multiple plugins + * have attached metadata, each will value will be included. + * + * @param subject the object being interrogated. + * @param metadataKey the unique metadata key being sought. + * @return A list of values, one for each plugin that has set the + * requested value. + */ + public List getMetadata(T subject, String metadataKey); + + /** + * Tests to see if a metadata attribute has been set on an object. + * + * @param subject the object upon which the has-metadata test is + * performed. + * @param metadataKey the unique metadata key being queried. + * @return the existence of the metadataKey within subject. + */ + public boolean hasMetadata(T subject, String metadataKey); + + /** + * Removes a metadata item owned by a plugin from a subject. + * + * @param subject the object to remove the metadata from. + * @param metadataKey the unique metadata key identifying the metadata to + * remove. + * @param owningPlugin the plugin attempting to remove a metadata item. + * @throws IllegalArgumentException If plugin is null + */ + public void removeMetadata(T subject, String metadataKey, Plugin owningPlugin); + + /** + * Invalidates all metadata in the metadata store that originates from the + * given plugin. Doing this will force each invalidated metadata item to + * be recalculated the next time it is accessed. + * + * @param owningPlugin the plugin requesting the invalidation. + * @throws IllegalArgumentException If plugin is null + */ + public void invalidateAll(Plugin owningPlugin); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataStoreBase.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataStoreBase.java new file mode 100644 index 0000000..093c144 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataStoreBase.java @@ -0,0 +1,136 @@ +package org.bukkit.metadata; + +import org.apache.commons.lang.Validate; +import org.bukkit.plugin.Plugin; + +import java.util.*; + +public abstract class MetadataStoreBase { + private Map> metadataMap = new HashMap>(); + + /** + * Adds a metadata value to an object. Each metadata value is owned by a + * specific {@link Plugin}. If a plugin has already added a metadata value + * to an object, that value will be replaced with the value of {@code + * newMetadataValue}. Multiple plugins can set independent values for the + * same {@code metadataKey} without conflict. + *

+ * Implementation note: I considered using a {@link + * java.util.concurrent.locks.ReadWriteLock} for controlling access to + * {@code metadataMap}, but decided that the added overhead wasn't worth + * the finer grained access control. + *

+ * Bukkit is almost entirely single threaded so locking overhead shouldn't + * pose a problem. + * + * @param subject The object receiving the metadata. + * @param metadataKey A unique key to identify this metadata. + * @param newMetadataValue The metadata value to apply. + * @see MetadataStore#setMetadata(Object, String, MetadataValue) + * @throws IllegalArgumentException If value is null, or the owning plugin + * is null + */ + public synchronized void setMetadata(T subject, String metadataKey, MetadataValue newMetadataValue) { + Validate.notNull(newMetadataValue, "Value cannot be null"); + Plugin owningPlugin = newMetadataValue.getOwningPlugin(); + Validate.notNull(owningPlugin, "Plugin cannot be null"); + String key = disambiguate(subject, metadataKey); + Map entry = metadataMap.get(key); + if (entry == null) { + entry = new WeakHashMap(1); + metadataMap.put(key, entry); + } + entry.put(owningPlugin, newMetadataValue); + } + + /** + * Returns all metadata values attached to an object. If multiple + * have attached metadata, each will value will be included. + * + * @param subject the object being interrogated. + * @param metadataKey the unique metadata key being sought. + * @return A list of values, one for each plugin that has set the + * requested value. + * @see MetadataStore#getMetadata(Object, String) + */ + public synchronized List getMetadata(T subject, String metadataKey) { + String key = disambiguate(subject, metadataKey); + if (metadataMap.containsKey(key)) { + Collection values = metadataMap.get(key).values(); + return Collections.unmodifiableList(new ArrayList(values)); + } else { + return Collections.emptyList(); + } + } + + /** + * Tests to see if a metadata attribute has been set on an object. + * + * @param subject the object upon which the has-metadata test is + * performed. + * @param metadataKey the unique metadata key being queried. + * @return the existence of the metadataKey within subject. + */ + public synchronized boolean hasMetadata(T subject, String metadataKey) { + String key = disambiguate(subject, metadataKey); + return metadataMap.containsKey(key); + } + + /** + * Removes a metadata item owned by a plugin from a subject. + * + * @param subject the object to remove the metadata from. + * @param metadataKey the unique metadata key identifying the metadata to + * remove. + * @param owningPlugin the plugin attempting to remove a metadata item. + * @see MetadataStore#removeMetadata(Object, String, + * org.bukkit.plugin.Plugin) + * @throws IllegalArgumentException If plugin is null + */ + public synchronized void removeMetadata(T subject, String metadataKey, Plugin owningPlugin) { + Validate.notNull(owningPlugin, "Plugin cannot be null"); + String key = disambiguate(subject, metadataKey); + Map entry = metadataMap.get(key); + if (entry == null) { + return; + } + + entry.remove(owningPlugin); + if (entry.isEmpty()) { + metadataMap.remove(key); + } + } + + /** + * Invalidates all metadata in the metadata store that originates from the + * given plugin. Doing this will force each invalidated metadata item to + * be recalculated the next time it is accessed. + * + * @param owningPlugin the plugin requesting the invalidation. + * @see MetadataStore#invalidateAll(org.bukkit.plugin.Plugin) + * @throws IllegalArgumentException If plugin is null + */ + public synchronized void invalidateAll(Plugin owningPlugin) { + Validate.notNull(owningPlugin, "Plugin cannot be null"); + for (Map values : metadataMap.values()) { + if (values.containsKey(owningPlugin)) { + values.get(owningPlugin).invalidate(); + } + } + } + + /** + * Creates a unique name for the object receiving metadata by combining + * unique data from the subject with a metadataKey. + *

+ * The name created must be globally unique for the given object and any + * two equivalent objects must generate the same unique name. For example, + * two Player objects must generate the same string if they represent the + * same player, even if the objects would fail a reference equality test. + * + * @param subject The object for which this key is being generated. + * @param metadataKey The name identifying the metadata value. + * @return a unique metadata key for the given subject. + */ + protected abstract String disambiguate(T subject, String metadataKey); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataValue.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataValue.java new file mode 100644 index 0000000..eded8c0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataValue.java @@ -0,0 +1,83 @@ +package org.bukkit.metadata; + +import org.bukkit.plugin.Plugin; + +public interface MetadataValue { + + /** + * Fetches the value of this metadata item. + * + * @return the metadata value. + */ + public Object value(); + + /** + * Attempts to convert the value of this metadata item into an int. + * + * @return the value as an int. + */ + public int asInt(); + + /** + * Attempts to convert the value of this metadata item into a float. + * + * @return the value as a float. + */ + public float asFloat(); + + /** + * Attempts to convert the value of this metadata item into a double. + * + * @return the value as a double. + */ + public double asDouble(); + + /** + * Attempts to convert the value of this metadata item into a long. + * + * @return the value as a long. + */ + public long asLong(); + + /** + * Attempts to convert the value of this metadata item into a short. + * + * @return the value as a short. + */ + public short asShort(); + + /** + * Attempts to convert the value of this metadata item into a byte. + * + * @return the value as a byte. + */ + public byte asByte(); + + /** + * Attempts to convert the value of this metadata item into a boolean. + * + * @return the value as a boolean. + */ + public boolean asBoolean(); + + /** + * Attempts to convert the value of this metadata item into a string. + * + * @return the value as a string. + */ + public String asString(); + + /** + * Returns the {@link Plugin} that created this metadata item. + * + * @return the plugin that owns this metadata value. This should never be + * null. + */ + public Plugin getOwningPlugin(); + + /** + * Invalidates this metadata item, forcing it to recompute when next + * accessed. + */ + public void invalidate(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataValueAdapter.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataValueAdapter.java new file mode 100644 index 0000000..bbc3da8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/MetadataValueAdapter.java @@ -0,0 +1,78 @@ +package org.bukkit.metadata; + +import java.lang.ref.WeakReference; + +import org.apache.commons.lang.Validate; +import org.bukkit.plugin.Plugin; +import org.bukkit.util.NumberConversions; + +/** + * Optional base class for facilitating MetadataValue implementations. + *

+ * This provides all the conversion functions for MetadataValue so that + * writing an implementation of MetadataValue is as simple as implementing + * value() and invalidate(). + */ +public abstract class MetadataValueAdapter implements MetadataValue { + protected final WeakReference owningPlugin; + + protected MetadataValueAdapter(Plugin owningPlugin) { + Validate.notNull(owningPlugin, "owningPlugin cannot be null"); + this.owningPlugin = new WeakReference(owningPlugin); + } + + public Plugin getOwningPlugin() { + return owningPlugin.get(); + } + + public int asInt() { + return NumberConversions.toInt(value()); + } + + public float asFloat() { + return NumberConversions.toFloat(value()); + } + + public double asDouble() { + return NumberConversions.toDouble(value()); + } + + public long asLong() { + return NumberConversions.toLong(value()); + } + + public short asShort() { + return NumberConversions.toShort(value()); + } + + public byte asByte() { + return NumberConversions.toByte(value()); + } + + public boolean asBoolean() { + Object value = value(); + if (value instanceof Boolean) { + return (Boolean) value; + } + + if (value instanceof Number) { + return ((Number) value).intValue() != 0; + } + + if (value instanceof String) { + return Boolean.parseBoolean((String) value); + } + + return value != null; + } + + public String asString() { + Object value = value(); + + if (value == null) { + return ""; + } + return value.toString(); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/Metadatable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/Metadatable.java new file mode 100644 index 0000000..b47cf2b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/metadata/Metadatable.java @@ -0,0 +1,52 @@ +package org.bukkit.metadata; + +import org.bukkit.plugin.Plugin; + +import java.util.List; + +/** + * This interface is implemented by all objects that can provide metadata + * about themselves. + */ +public interface Metadatable { + /** + * Sets a metadata value in the implementing object's metadata store. + * + * @param metadataKey A unique key to identify this metadata. + * @param newMetadataValue The metadata value to apply. + * @throws IllegalArgumentException If value is null, or the owning plugin + * is null + */ + public void setMetadata(String metadataKey, MetadataValue newMetadataValue); + + /** + * Returns a list of previously set metadata values from the implementing + * object's metadata store. + * + * @param metadataKey the unique metadata key being sought. + * @return A list of values, one for each plugin that has set the + * requested value. + */ + public List getMetadata(String metadataKey); + + /** + * Tests to see whether the implementing object contains the given + * metadata value in its metadata store. + * + * @param metadataKey the unique metadata key being queried. + * @return the existence of the metadataKey within subject. + */ + public boolean hasMetadata(String metadataKey); + + /** + * Removes the given metadata value from the implementing object's + * metadata store. + * + * @param metadataKey the unique metadata key identifying the metadata to + * remove. + * @param owningPlugin This plugin's metadata value will be removed. All + * other values will be left untouched. + * @throws IllegalArgumentException If plugin is null + */ + public void removeMetadata(String metadataKey, Plugin owningPlugin); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/Permissible.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/Permissible.java new file mode 100644 index 0000000..5cd3cff --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/Permissible.java @@ -0,0 +1,122 @@ +package org.bukkit.permissions; + +import java.util.Set; +import org.bukkit.plugin.Plugin; + +/** + * Represents an object that may be assigned permissions + */ +public interface Permissible extends ServerOperator { + + /** + * Checks if this object contains an override for the specified + * permission, by fully qualified name + * + * @param name Name of the permission + * @return true if the permission is set, otherwise false + */ + public boolean isPermissionSet(String name); + + /** + * Checks if this object contains an override for the specified {@link + * Permission} + * + * @param perm Permission to check + * @return true if the permission is set, otherwise false + */ + public boolean isPermissionSet(Permission perm); + + /** + * Gets the value of the specified permission, if set. + *

+ * If a permission override is not set on this object, the default value + * of the permission will be returned. + * + * @param name Name of the permission + * @return Value of the permission + */ + public boolean hasPermission(String name); + + /** + * Gets the value of the specified permission, if set. + *

+ * If a permission override is not set on this object, the default value + * of the permission will be returned + * + * @param perm Permission to get + * @return Value of the permission + */ + public boolean hasPermission(Permission perm); + + /** + * Adds a new {@link PermissionAttachment} with a single permission by + * name and value + * + * @param plugin Plugin responsible for this attachment, may not be null + * or disabled + * @param name Name of the permission to attach + * @param value Value of the permission + * @return The PermissionAttachment that was just created + */ + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value); + + /** + * Adds a new empty {@link PermissionAttachment} to this object + * + * @param plugin Plugin responsible for this attachment, may not be null + * or disabled + * @return The PermissionAttachment that was just created + */ + public PermissionAttachment addAttachment(Plugin plugin); + + /** + * Temporarily adds a new {@link PermissionAttachment} with a single + * permission by name and value + * + * @param plugin Plugin responsible for this attachment, may not be null + * or disabled + * @param name Name of the permission to attach + * @param value Value of the permission + * @param ticks Amount of ticks to automatically remove this attachment + * after + * @return The PermissionAttachment that was just created + */ + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks); + + /** + * Temporarily adds a new empty {@link PermissionAttachment} to this + * object + * + * @param plugin Plugin responsible for this attachment, may not be null + * or disabled + * @param ticks Amount of ticks to automatically remove this attachment + * after + * @return The PermissionAttachment that was just created + */ + public PermissionAttachment addAttachment(Plugin plugin, int ticks); + + /** + * Removes the given {@link PermissionAttachment} from this object + * + * @param attachment Attachment to remove + * @throws IllegalArgumentException Thrown when the specified attachment + * isn't part of this object + */ + public void removeAttachment(PermissionAttachment attachment); + + /** + * Recalculates the permissions for this object, if the attachments have + * changed values. + *

+ * This should very rarely need to be called from a plugin. + */ + public void recalculatePermissions(); + + /** + * Gets a set containing all of the permissions currently in effect by + * this object + * + * @return Set of currently effective permissions + */ + public Set getEffectivePermissions(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissibleBase.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissibleBase.java new file mode 100644 index 0000000..3b95061 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissibleBase.java @@ -0,0 +1,246 @@ +package org.bukkit.permissions; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +/** + * Base Permissible for use in any Permissible object via proxy or extension + */ +public class PermissibleBase implements Permissible { + private ServerOperator opable = null; + private Permissible parent = this; + private final List attachments = new LinkedList(); + private final Map permissions = new HashMap(); + + public PermissibleBase(ServerOperator opable) { + this.opable = opable; + + if (opable instanceof Permissible) { + this.parent = (Permissible) opable; + } + + recalculatePermissions(); + } + + public boolean isOp() { + if (opable == null) { + return false; + } else { + return opable.isOp(); + } + } + + public void setOp(boolean value) { + if (opable == null) { + throw new UnsupportedOperationException("Cannot change op value as no ServerOperator is set"); + } else { + opable.setOp(value); + } + } + + public boolean isPermissionSet(String name) { + if (name == null) { + throw new IllegalArgumentException("Permission name cannot be null"); + } + + return permissions.containsKey(name.toLowerCase()); + } + + public boolean isPermissionSet(Permission perm) { + if (perm == null) { + throw new IllegalArgumentException("Permission cannot be null"); + } + + return isPermissionSet(perm.getName()); + } + + public boolean hasPermission(String inName) { + if (inName == null) { + throw new IllegalArgumentException("Permission name cannot be null"); + } + + String name = inName.toLowerCase(); + + if (isPermissionSet(name)) { + return permissions.get(name).getValue(); + } else { + Permission perm = Bukkit.getServer().getPluginManager().getPermission(name); + + if (perm != null) { + return perm.getDefault().getValue(isOp()); + } else { + return Permission.DEFAULT_PERMISSION.getValue(isOp()); + } + } + } + + public boolean hasPermission(Permission perm) { + if (perm == null) { + throw new IllegalArgumentException("Permission cannot be null"); + } + + String name = perm.getName().toLowerCase(); + + if (isPermissionSet(name)) { + return permissions.get(name).getValue(); + } + return perm.getDefault().getValue(isOp()); + } + + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + if (name == null) { + throw new IllegalArgumentException("Permission name cannot be null"); + } else if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } else if (!plugin.isEnabled()) { + throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); + } + + PermissionAttachment result = addAttachment(plugin); + result.setPermission(name, value); + + recalculatePermissions(); + + return result; + } + + public PermissionAttachment addAttachment(Plugin plugin) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } else if (!plugin.isEnabled()) { + throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); + } + + PermissionAttachment result = new PermissionAttachment(plugin, parent); + + attachments.add(result); + recalculatePermissions(); + + return result; + } + + public void removeAttachment(PermissionAttachment attachment) { + if (attachment == null) { + throw new IllegalArgumentException("Attachment cannot be null"); + } + + if (attachments.contains(attachment)) { + attachments.remove(attachment); + PermissionRemovedExecutor ex = attachment.getRemovalCallback(); + + if (ex != null) { + ex.attachmentRemoved(attachment); + } + + recalculatePermissions(); + } else { + throw new IllegalArgumentException("Given attachment is not part of Permissible object " + parent); + } + } + + public void recalculatePermissions() { + clearPermissions(); + Set defaults = Bukkit.getServer().getPluginManager().getDefaultPermissions(isOp()); + Bukkit.getServer().getPluginManager().subscribeToDefaultPerms(isOp(), parent); + + for (Permission perm : defaults) { + String name = perm.getName().toLowerCase(); + permissions.put(name, new PermissionAttachmentInfo(parent, name, null, true)); + Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent); + calculateChildPermissions(perm.getChildren(), false, null); + } + + for (PermissionAttachment attachment : attachments) { + calculateChildPermissions(attachment.getPermissions(), false, attachment); + } + } + + public synchronized void clearPermissions() { + Set perms = permissions.keySet(); + + for (String name : perms) { + Bukkit.getServer().getPluginManager().unsubscribeFromPermission(name, parent); + } + + Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(false, parent); + Bukkit.getServer().getPluginManager().unsubscribeFromDefaultPerms(true, parent); + + permissions.clear(); + } + + private void calculateChildPermissions(Map children, boolean invert, PermissionAttachment attachment) { + Set keys = children.keySet(); + + for (String name : keys) { + Permission perm = Bukkit.getServer().getPluginManager().getPermission(name); + boolean value = children.get(name) ^ invert; + String lname = name.toLowerCase(); + + permissions.put(lname, new PermissionAttachmentInfo(parent, lname, attachment, value)); + Bukkit.getServer().getPluginManager().subscribeToPermission(name, parent); + + if (perm != null) { + calculateChildPermissions(perm.getChildren(), !value, attachment); + } + } + } + + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + if (name == null) { + throw new IllegalArgumentException("Permission name cannot be null"); + } else if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } else if (!plugin.isEnabled()) { + throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); + } + + PermissionAttachment result = addAttachment(plugin, ticks); + + if (result != null) { + result.setPermission(name, value); + } + + return result; + } + + public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } else if (!plugin.isEnabled()) { + throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); + } + + PermissionAttachment result = addAttachment(plugin); + + if (Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new RemoveAttachmentRunnable(result), ticks) == -1) { + Bukkit.getServer().getLogger().log(Level.WARNING, "Could not add PermissionAttachment to " + parent + " for plugin " + plugin.getDescription().getFullName() + ": Scheduler returned -1"); + result.remove(); + return null; + } else { + return result; + } + } + + public Set getEffectivePermissions() { + return new HashSet(permissions.values()); + } + + private class RemoveAttachmentRunnable implements Runnable { + private PermissionAttachment attachment; + + public RemoveAttachmentRunnable(PermissionAttachment attachment) { + this.attachment = attachment; + } + + public void run() { + attachment.remove(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/Permission.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/Permission.java new file mode 100644 index 0000000..0184f47 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/Permission.java @@ -0,0 +1,345 @@ +package org.bukkit.permissions; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.plugin.PluginManager; + +/** + * Represents a unique permission that may be attached to a {@link + * Permissible} + */ +public class Permission { + public static final PermissionDefault DEFAULT_PERMISSION = PermissionDefault.OP; + + private final String name; + private final Map children = new LinkedHashMap(); + private PermissionDefault defaultValue = DEFAULT_PERMISSION; + private String description; + + public Permission(String name) { + this(name, null, null, null); + } + + public Permission(String name, String description) { + this(name, description, null, null); + } + + public Permission(String name, PermissionDefault defaultValue) { + this(name, null, defaultValue, null); + } + + public Permission(String name, String description, PermissionDefault defaultValue) { + this(name, description, defaultValue, null); + } + + public Permission(String name, Map children) { + this(name, null, null, children); + } + + public Permission(String name, String description, Map children) { + this(name, description, null, children); + } + + public Permission(String name, PermissionDefault defaultValue, Map children) { + this(name, null, defaultValue, children); + } + + public Permission(String name, String description, PermissionDefault defaultValue, Map children) { + Validate.notNull(name, "Name cannot be null"); + this.name = name; + this.description = (description == null) ? "" : description; + + if (defaultValue != null) { + this.defaultValue = defaultValue; + } + + if (children != null) { + this.children.putAll(children); + } + + recalculatePermissibles(); + } + + /** + * Returns the unique fully qualified name of this Permission + * + * @return Fully qualified name + */ + public String getName() { + return name; + } + + /** + * Gets the children of this permission. + *

+ * If you change this map in any form, you must call {@link + * #recalculatePermissibles()} to recalculate all {@link Permissible}s + * + * @return Permission children + */ + public Map getChildren() { + return children; + } + + /** + * Gets the default value of this permission. + * + * @return Default value of this permission. + */ + public PermissionDefault getDefault() { + return defaultValue; + } + + /** + * Sets the default value of this permission. + *

+ * This will not be saved to disk, and is a temporary operation until the + * server reloads permissions. Changing this default will cause all {@link + * Permissible}s that contain this permission to recalculate their + * permissions + * + * @param value The new default to set + */ + public void setDefault(PermissionDefault value) { + if (defaultValue == null) { + throw new IllegalArgumentException("Default value cannot be null"); + } + + defaultValue = value; + recalculatePermissibles(); + } + + /** + * Gets a brief description of this permission, if set + * + * @return Brief description of this permission + */ + public String getDescription() { + return description; + } + + /** + * Sets the description of this permission. + *

+ * This will not be saved to disk, and is a temporary operation until the + * server reloads permissions. + * + * @param value The new description to set + */ + public void setDescription(String value) { + if (value == null) { + description = ""; + } else { + description = value; + } + } + + /** + * Gets a set containing every {@link Permissible} that has this + * permission. + *

+ * This set cannot be modified. + * + * @return Set containing permissibles with this permission + */ + public Set getPermissibles() { + return Bukkit.getServer().getPluginManager().getPermissionSubscriptions(name); + } + + /** + * Recalculates all {@link Permissible}s that contain this permission. + *

+ * This should be called after modifying the children, and is + * automatically called after modifying the default value + */ + public void recalculatePermissibles() { + Set perms = getPermissibles(); + + Bukkit.getServer().getPluginManager().recalculatePermissionDefaults(this); + + for (Permissible p : perms) { + p.recalculatePermissions(); + } + } + + /** + * Adds this permission to the specified parent permission. + *

+ * If the parent permission does not exist, it will be created and + * registered. + * + * @param name Name of the parent permission + * @param value The value to set this permission to + * @return Parent permission it created or loaded + */ + public Permission addParent(String name, boolean value) { + PluginManager pm = Bukkit.getServer().getPluginManager(); + String lname = name.toLowerCase(); + + Permission perm = pm.getPermission(lname); + + if (perm == null) { + perm = new Permission(lname); + pm.addPermission(perm); + } + + addParent(perm, value); + + return perm; + } + + /** + * Adds this permission to the specified parent permission. + * + * @param perm Parent permission to register with + * @param value The value to set this permission to + */ + public void addParent(Permission perm, boolean value) { + perm.getChildren().put(getName(), value); + perm.recalculatePermissibles(); + } + + /** + * Loads a list of Permissions from a map of data, usually used from + * retrieval from a yaml file. + *

+ * The data may contain a list of name:data, where the data contains the + * following keys: + *

    + *
  • default: Boolean true or false. If not specified, false. + *
  • children: {@code Map} of child permissions. If not + * specified, empty list. + *
  • description: Short string containing a very small description of + * this description. If not specified, empty string. + *
+ * + * @param data Map of permissions + * @param error An error message to show if a permission is invalid. + * @param def Default permission value to use if missing + * @return Permission object + */ + public static List loadPermissions(Map data, String error, PermissionDefault def) { + List result = new ArrayList(); + + for (Map.Entry entry : data.entrySet()) { + try { + result.add(Permission.loadPermission(entry.getKey().toString(), (Map) entry.getValue(), def, result)); + } catch (Throwable ex) { + Bukkit.getServer().getLogger().log(Level.SEVERE, String.format(error, entry.getKey()), ex); + } + } + + return result; + } + + /** + * Loads a Permission from a map of data, usually used from retrieval from + * a yaml file. + *

+ * The data may contain the following keys: + *

    + *
  • default: Boolean true or false. If not specified, false. + *
  • children: {@code Map} of child permissions. If not + * specified, empty list. + *
  • description: Short string containing a very small description of + * this description. If not specified, empty string. + *
+ * + * @param name Name of the permission + * @param data Map of keys + * @return Permission object + */ + public static Permission loadPermission(String name, Map data) { + return loadPermission(name, data, DEFAULT_PERMISSION, null); + } + + /** + * Loads a Permission from a map of data, usually used from retrieval from + * a yaml file. + *

+ * The data may contain the following keys: + *

    + *
  • default: Boolean true or false. If not specified, false. + *
  • children: {@code Map} of child permissions. If not + * specified, empty list. + *
  • description: Short string containing a very small description of + * this description. If not specified, empty string. + *
+ * + * @param name Name of the permission + * @param data Map of keys + * @param def Default permission value to use if not set + * @param output A list to append any created child-Permissions to, may be null + * @return Permission object + */ + public static Permission loadPermission(String name, Map data, PermissionDefault def, List output) { + Validate.notNull(name, "Name cannot be null"); + Validate.notNull(data, "Data cannot be null"); + + String desc = null; + Map children = null; + + if (data.get("default") != null) { + PermissionDefault value = PermissionDefault.getByName(data.get("default").toString()); + if (value != null) { + def = value; + } else { + throw new IllegalArgumentException("'default' key contained unknown value"); + } + } + + if (data.get("children") != null) { + Object childrenNode = data.get("children"); + if (childrenNode instanceof Iterable) { + children = new LinkedHashMap(); + for (Object child : (Iterable) childrenNode) { + if (child != null) { + children.put(child.toString(), Boolean.TRUE); + } + } + } else if (childrenNode instanceof Map) { + children = extractChildren((Map) childrenNode, name, def, output); + } else { + throw new IllegalArgumentException("'children' key is of wrong type"); + } + } + + if (data.get("description") != null) { + desc = data.get("description").toString(); + } + + return new Permission(name, desc, def, children); + } + + private static Map extractChildren(Map input, String name, PermissionDefault def, List output) { + Map children = new LinkedHashMap(); + + for (Map.Entry entry : input.entrySet()) { + if ((entry.getValue() instanceof Boolean)) { + children.put(entry.getKey().toString(), (Boolean) entry.getValue()); + } else if ((entry.getValue() instanceof Map)) { + try { + Permission perm = loadPermission(entry.getKey().toString(), (Map) entry.getValue(), def, output); + children.put(perm.getName(), Boolean.TRUE); + + if (output != null) { + output.add(perm); + } + } catch (Throwable ex) { + throw new IllegalArgumentException("Permission node '" + entry.getKey().toString() + "' in child of " + name + " is invalid", ex); + } + } else { + throw new IllegalArgumentException("Child '" + entry.getKey().toString() + "' contains invalid value"); + } + } + + return children; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionAttachment.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionAttachment.java new file mode 100644 index 0000000..b2a44d5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionAttachment.java @@ -0,0 +1,139 @@ +package org.bukkit.permissions; + +import java.util.LinkedHashMap; +import java.util.Map; +import org.bukkit.plugin.Plugin; + +/** + * Holds information about a permission attachment on a {@link Permissible} + * object + */ +public class PermissionAttachment { + private PermissionRemovedExecutor removed; + private final Map permissions = new LinkedHashMap(); + private final Permissible permissible; + private final Plugin plugin; + + public PermissionAttachment(Plugin plugin, Permissible Permissible) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } else if (!plugin.isEnabled()) { + throw new IllegalArgumentException("Plugin " + plugin.getDescription().getFullName() + " is disabled"); + } + + this.permissible = Permissible; + this.plugin = plugin; + } + + /** + * Gets the plugin responsible for this attachment + * + * @return Plugin responsible for this permission attachment + */ + public Plugin getPlugin() { + return plugin; + } + + /** + * Sets an object to be called for when this attachment is removed from a + * {@link Permissible}. May be null. + * + * @param ex Object to be called when this is removed + */ + public void setRemovalCallback(PermissionRemovedExecutor ex) { + removed = ex; + } + + /** + * Gets the class that was previously set to be called when this + * attachment was removed from a {@link Permissible}. May be null. + * + * @return Object to be called when this is removed + */ + public PermissionRemovedExecutor getRemovalCallback() { + return removed; + } + + /** + * Gets the Permissible that this is attached to + * + * @return Permissible containing this attachment + */ + public Permissible getPermissible() { + return permissible; + } + + /** + * Gets a copy of all set permissions and values contained within this + * attachment. + *

+ * This map may be modified but will not affect the attachment, as it is a + * copy. + * + * @return Copy of all permissions and values expressed by this attachment + */ + public Map getPermissions() { + return new LinkedHashMap(permissions); + } + + /** + * Sets a permission to the given value, by its fully qualified name + * + * @param name Name of the permission + * @param value New value of the permission + */ + public void setPermission(String name, boolean value) { + permissions.put(name.toLowerCase(), value); + permissible.recalculatePermissions(); + } + + /** + * Sets a permission to the given value + * + * @param perm Permission to set + * @param value New value of the permission + */ + public void setPermission(Permission perm, boolean value) { + setPermission(perm.getName(), value); + } + + /** + * Removes the specified permission from this attachment. + *

+ * If the permission does not exist in this attachment, nothing will + * happen. + * + * @param name Name of the permission to remove + */ + public void unsetPermission(String name) { + permissions.remove(name.toLowerCase()); + permissible.recalculatePermissions(); + } + + /** + * Removes the specified permission from this attachment. + *

+ * If the permission does not exist in this attachment, nothing will + * happen. + * + * @param perm Permission to remove + */ + public void unsetPermission(Permission perm) { + unsetPermission(perm.getName()); + } + + /** + * Removes this attachment from its registered {@link Permissible} + * + * @return true if the permissible was removed successfully, false if it + * did not exist + */ + public boolean remove() { + try { + permissible.removeAttachment(this); + return true; + } catch (IllegalArgumentException ex) { + return false; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionAttachmentInfo.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionAttachmentInfo.java new file mode 100644 index 0000000..8e8e335 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionAttachmentInfo.java @@ -0,0 +1,62 @@ +package org.bukkit.permissions; + +/** + * Holds information on a permission and which {@link PermissionAttachment} + * provides it + */ +public class PermissionAttachmentInfo { + private final Permissible permissible; + private final String permission; + private final PermissionAttachment attachment; + private final boolean value; + + public PermissionAttachmentInfo(Permissible permissible, String permission, PermissionAttachment attachment, boolean value) { + if (permissible == null) { + throw new IllegalArgumentException("Permissible may not be null"); + } else if (permission == null) { + throw new IllegalArgumentException("Permissions may not be null"); + } + + this.permissible = permissible; + this.permission = permission; + this.attachment = attachment; + this.value = value; + } + + /** + * Gets the permissible this is attached to + * + * @return Permissible this permission is for + */ + public Permissible getPermissible() { + return permissible; + } + + /** + * Gets the permission being set + * + * @return Name of the permission + */ + public String getPermission() { + return permission; + } + + /** + * Gets the attachment providing this permission. This may be null for + * default permissions (usually parent permissions). + * + * @return Attachment + */ + public PermissionAttachment getAttachment() { + return attachment; + } + + /** + * Gets the value of this permission + * + * @return Value of the permission + */ + public boolean getValue() { + return value; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionDefault.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionDefault.java new file mode 100644 index 0000000..045e733 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionDefault.java @@ -0,0 +1,66 @@ +package org.bukkit.permissions; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents the possible default values for permissions + */ +public enum PermissionDefault { + TRUE("true"), + FALSE("false"), + OP("op", "isop", "operator", "isoperator", "admin", "isadmin"), + NOT_OP("!op", "notop", "!operator", "notoperator", "!admin", "notadmin"); + + private final String[] names; + private final static Map lookup = new HashMap(); + + private PermissionDefault(String... names) { + this.names = names; + } + + /** + * Calculates the value of this PermissionDefault for the given operator + * value + * + * @param op If the target is op + * @return True if the default should be true, or false + */ + public boolean getValue(boolean op) { + switch (this) { + case TRUE: + return true; + case FALSE: + return false; + case OP: + return op; + case NOT_OP: + return !op; + default: + return false; + } + } + + /** + * Looks up a PermissionDefault by name + * + * @param name Name of the default + * @return Specified value, or null if not found + */ + public static PermissionDefault getByName(String name) { + return lookup.get(name.toLowerCase().replaceAll("[^a-z!]", "")); + } + + @Override + public String toString() { + return names[0]; + } + + static { + for (PermissionDefault value : values()) { + for (String name : value.names) { + lookup.put(name, value); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionRemovedExecutor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionRemovedExecutor.java new file mode 100644 index 0000000..b13d008 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/PermissionRemovedExecutor.java @@ -0,0 +1,16 @@ +package org.bukkit.permissions; + +/** + * Represents a class which is to be notified when a {@link + * PermissionAttachment} is removed from a {@link Permissible} + */ +public interface PermissionRemovedExecutor { + + /** + * Called when a {@link PermissionAttachment} is removed from a {@link + * Permissible} + * + * @param attachment Attachment which was removed + */ + public void attachmentRemoved(PermissionAttachment attachment); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/ServerOperator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/ServerOperator.java new file mode 100644 index 0000000..26ed243 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/permissions/ServerOperator.java @@ -0,0 +1,24 @@ +package org.bukkit.permissions; + +import org.bukkit.entity.Player; + +/** + * Represents an object that may become a server operator, such as a {@link + * Player} + */ +public interface ServerOperator { + + /** + * Checks if this object is a server operator + * + * @return true if this is an operator, otherwise false + */ + public boolean isOp(); + + /** + * Sets the operator status of this object + * + * @param value New operator value + */ + public void setOp(boolean value); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/AuthorNagException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/AuthorNagException.java new file mode 100644 index 0000000..6565a44 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/AuthorNagException.java @@ -0,0 +1,20 @@ +package org.bukkit.plugin; + +@SuppressWarnings("serial") +public class AuthorNagException extends RuntimeException { + private final String message; + + /** + * Constructs a new AuthorNagException based on the given Exception + * + * @param message Brief message explaining the cause of the exception + */ + public AuthorNagException(final String message) { + this.message = message; + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/EventExecutor.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/EventExecutor.java new file mode 100644 index 0000000..3b2c99e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/EventExecutor.java @@ -0,0 +1,12 @@ +package org.bukkit.plugin; + +import org.bukkit.event.Event; +import org.bukkit.event.EventException; +import org.bukkit.event.Listener; + +/** + * Interface which defines the class for event call backs to plugins + */ +public interface EventExecutor { + public void execute(Listener listener, Event event) throws EventException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/IllegalPluginAccessException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/IllegalPluginAccessException.java new file mode 100644 index 0000000..b25447d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/IllegalPluginAccessException.java @@ -0,0 +1,25 @@ +package org.bukkit.plugin; + +/** + * Thrown when a plugin attempts to interact with the server when it is not + * enabled + */ +@SuppressWarnings("serial") +public class IllegalPluginAccessException extends RuntimeException { + + /** + * Creates a new instance of IllegalPluginAccessException + * without detail message. + */ + public IllegalPluginAccessException() {} + + /** + * Constructs an instance of IllegalPluginAccessException + * with the specified detail message. + * + * @param msg the detail message. + */ + public IllegalPluginAccessException(String msg) { + super(msg); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java new file mode 100644 index 0000000..0a77c2e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/InvalidDescriptionException.java @@ -0,0 +1,45 @@ +package org.bukkit.plugin; + +/** + * Thrown when attempting to load an invalid PluginDescriptionFile + */ +public class InvalidDescriptionException extends Exception { + private static final long serialVersionUID = 5721389122281775896L; + + /** + * Constructs a new InvalidDescriptionException based on the given + * Exception + * + * @param message Brief message explaining the cause of the exception + * @param cause Exception that triggered this Exception + */ + public InvalidDescriptionException(final Throwable cause, final String message) { + super(message, cause); + } + + /** + * Constructs a new InvalidDescriptionException based on the given + * Exception + * + * @param cause Exception that triggered this Exception + */ + public InvalidDescriptionException(final Throwable cause) { + super("Invalid plugin.yml", cause); + } + + /** + * Constructs a new InvalidDescriptionException with the given message + * + * @param message Brief message explaining the cause of the exception + */ + public InvalidDescriptionException(final String message) { + super(message); + } + + /** + * Constructs a new InvalidDescriptionException + */ + public InvalidDescriptionException() { + super("Invalid plugin.yml"); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/InvalidPluginException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/InvalidPluginException.java new file mode 100644 index 0000000..7ddf7b6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/InvalidPluginException.java @@ -0,0 +1,49 @@ +package org.bukkit.plugin; + +/** + * Thrown when attempting to load an invalid Plugin file + */ +public class InvalidPluginException extends Exception { + private static final long serialVersionUID = -8242141640709409544L; + + /** + * Constructs a new InvalidPluginException based on the given Exception + * + * @param cause Exception that triggered this Exception + */ + public InvalidPluginException(final Throwable cause) { + super(cause); + } + + /** + * Constructs a new InvalidPluginException + */ + public InvalidPluginException() { + + } + + /** + * Constructs a new InvalidPluginException with the specified detail + * message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the getMessage() method). + * @param cause the cause (which is saved for later retrieval by the + * getCause() method). (A null value is permitted, and indicates that + * the cause is nonexistent or unknown.) + */ + public InvalidPluginException(final String message, final Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new InvalidPluginException with the specified detail + * message + * + * @param message TThe detail message is saved for later retrieval by the + * getMessage() method. + */ + public InvalidPluginException(final String message) { + super(message); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/Plugin.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/Plugin.java new file mode 100644 index 0000000..7bdc809 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/Plugin.java @@ -0,0 +1,189 @@ +package org.bukkit.plugin; + +import java.io.File; +import java.io.InputStream; +import java.util.logging.Logger; + +import org.bukkit.Server; +import org.bukkit.command.TabExecutor; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.generator.ChunkGenerator; + +import com.avaje.ebean.EbeanServer; + +/** + * Represents a Plugin + *

+ * The use of {@link PluginBase} is recommended for actual Implementation + */ +public interface Plugin extends TabExecutor { + /** + * Returns the folder that the plugin data's files are located in. The + * folder may not yet exist. + * + * @return The folder + */ + public File getDataFolder(); + + /** + * Returns the plugin.yaml file containing the details for this plugin + * + * @return Contents of the plugin.yaml file + */ + public PluginDescriptionFile getDescription(); + + /** + * Gets a {@link FileConfiguration} for this plugin, read through + * "config.yml" + *

+ * If there is a default config.yml embedded in this plugin, it will be + * provided as a default for this Configuration. + * + * @return Plugin configuration + */ + public FileConfiguration getConfig(); + + /** + * Gets an embedded resource in this plugin + * + * @param filename Filename of the resource + * @return File if found, otherwise null + */ + public InputStream getResource(String filename); + + /** + * Saves the {@link FileConfiguration} retrievable by {@link #getConfig()}. + */ + public void saveConfig(); + + /** + * Saves the raw contents of the default config.yml file to the location + * retrievable by {@link #getConfig()}. If there is no default config.yml + * embedded in the plugin, an empty config.yml file is saved. This should + * fail silently if the config.yml already exists. + */ + public void saveDefaultConfig(); + + /** + * Saves the raw contents of any resource embedded with a plugin's .jar + * file assuming it can be found using {@link #getResource(String)}. + *

+ * The resource is saved into the plugin's data folder using the same + * hierarchy as the .jar file (subdirectories are preserved). + * + * @param resourcePath the embedded resource path to look for within the + * plugin's .jar file. (No preceding slash). + * @param replace if true, the embedded resource will overwrite the + * contents of an existing file. + * @throws IllegalArgumentException if the resource path is null, empty, + * or points to a nonexistent resource. + */ + public void saveResource(String resourcePath, boolean replace); + + /** + * Discards any data in {@link #getConfig()} and reloads from disk. + */ + public void reloadConfig(); + + /** + * Gets the associated PluginLoader responsible for this plugin + * + * @return PluginLoader that controls this plugin + */ + public PluginLoader getPluginLoader(); + + /** + * Returns the Server instance currently running this plugin + * + * @return Server running this plugin + */ + public Server getServer(); + + /** + * Returns a value indicating whether or not this plugin is currently + * enabled + * + * @return true if this plugin is enabled, otherwise false + */ + public boolean isEnabled(); + + /** + * Called when this plugin is disabled + */ + public void onDisable(); + + /** + * Called after a plugin is loaded but before it has been enabled. + *

+ * When mulitple plugins are loaded, the onLoad() for all plugins is + * called before any onEnable() is called. + */ + public void onLoad(); + + /** + * Called when this plugin is enabled + */ + public void onEnable(); + + /** + * Simple boolean if we can still nag to the logs about things + * + * @return boolean whether we can nag + */ + public boolean isNaggable(); + + /** + * Set naggable state + * + * @param canNag is this plugin still naggable? + */ + public void setNaggable(boolean canNag); + + /** + * Gets the {@link EbeanServer} tied to this plugin. This will only be + * available if enabled in the {@link + * PluginDescriptionFile#isDatabaseEnabled()} + *

+ * For more information on the use of + * Avaje Ebeans ORM, see Avaje Ebeans + * Documentation + *

+ * For an example using Ebeans ORM, see Bukkit's Homebukkit Plugin + * + * + * @return ebean server instance or null if not enabled + */ + public EbeanServer getDatabase(); + + /** + * Gets a {@link ChunkGenerator} for use in a default world, as specified + * in the server configuration + * + * @param worldName Name of the world that this will be applied to + * @param id Unique ID, if any, that was specified to indicate which + * generator was requested + * @return ChunkGenerator for use in the default world generation + */ + public ChunkGenerator getDefaultWorldGenerator(String worldName, String id); + + /** + * Returns the plugin logger associated with this server's logger. The + * returned logger automatically tags all log messages with the plugin's + * name. + * + * @return Logger associated with this plugin + */ + public Logger getLogger(); + + /** + * Returns the name of the plugin. + *

+ * This should return the bare name of the plugin and should be used for + * comparison. + * + * @return name of the plugin + */ + public String getName(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginAwareness.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginAwareness.java new file mode 100644 index 0000000..ddb47b7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginAwareness.java @@ -0,0 +1,29 @@ +package org.bukkit.plugin; + +import java.util.Set; + +import org.bukkit.plugin.java.JavaPlugin; + +/** + * Represents a concept that a plugin is aware of. + *

+ * The internal representation may be singleton, or be a parameterized + * instance, but must be immutable. + */ +public interface PluginAwareness { + /** + * Each entry here represents a particular plugin's awareness. These can + * be checked by using {@link PluginDescriptionFile#getAwareness()}.{@link + * Set#contains(Object) contains(flag)}. + */ + public enum Flags implements PluginAwareness { + /** + * This specifies that all (text) resources stored in a plugin's jar + * use UTF-8 encoding. + * + * @see JavaPlugin#getTextResource(String) + */ + UTF8, + ; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginBase.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginBase.java new file mode 100644 index 0000000..6031af1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginBase.java @@ -0,0 +1,32 @@ +package org.bukkit.plugin; + +/** + * Represents a base {@link Plugin} + *

+ * Extend this class if your plugin is not a {@link + * org.bukkit.plugin.java.JavaPlugin} + */ +public abstract class PluginBase implements Plugin { + @Override + public final int hashCode() { + return getName().hashCode(); + } + + @Override + public final boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof Plugin)) { + return false; + } + return getName().equals(((Plugin) obj).getName()); + } + + public final String getName() { + return getDescription().getName(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java new file mode 100644 index 0000000..c82928e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java @@ -0,0 +1,1116 @@ +package org.bukkit.plugin; + +import java.io.InputStream; +import java.io.Reader; +import java.io.Writer; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.PluginCommand; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.AbstractConstruct; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import org.yaml.snakeyaml.nodes.Node; +import org.yaml.snakeyaml.nodes.Tag; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +/** + * This type is the runtime-container for the information in the plugin.yml. + * All plugins must have a respective plugin.yml. For plugins written in java + * using the standard plugin loader, this file must be in the root of the jar + * file. + *

+ * When Bukkit loads a plugin, it needs to know some basic information about + * it. It reads this information from a YAML file, 'plugin.yml'. This file + * consists of a set of attributes, each defined on a new line and with no + * indentation. + *

+ * Every (almost* every) method corresponds with a specific entry in the + * plugin.yml. These are the required entries for every plugin.yml: + *

    + *
  • {@link #getName()} - name + *
  • {@link #getVersion()} - version + *
  • {@link #getMain()} - main + *
+ *

+ * Failing to include any of these items will throw an exception and cause the + * server to ignore your plugin. + *

+ * This is a list of the possible yaml keys, with specific details included in + * the respective method documentations: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
The description of the plugin.yml layout
NodeMethodSummary
name{@link #getName()}The unique name of plugin
version{@link #getVersion()}A plugin revision identifier
main{@link #getMain()}The plugin's initial class file
author
authors
{@link #getAuthors()}The plugin contributors
description{@link #getDescription()}Human readable plugin summary
website{@link #getWebsite()}The URL to the plugin's site
prefix{@link #getPrefix()}The token to prefix plugin log entries
database{@link #isDatabaseEnabled()}Indicator to enable database support
load{@link #getLoad()}The phase of server-startup this plugin will load during
depend{@link #getDepend()}Other required plugins
softdepend{@link #getSoftDepend()}Other plugins that add functionality
loadbefore{@link #getLoadBefore()}The inverse softdepend
commands{@link #getCommands()}The commands the plugin will register
permissions{@link #getPermissions()}The permissions the plugin will register
default-permission{@link #getPermissionDefault()}The default {@link Permission#getDefault() default} permission + * state for defined {@link #getPermissions() permissions} the plugin + * will register
awareness{@link #getAwareness()}The concepts that the plugin acknowledges
+ *

+ * A plugin.yml example:

+ *name: Inferno
+ *version: 1.4.1
+ *description: This plugin is so 31337. You can set yourself on fire.
+ *# We could place every author in the authors list, but chose not to for illustrative purposes
+ *# Also, having an author distinguishes that person as the project lead, and ensures their
+ *# name is displayed first
+ *author: CaptainInflamo
+ *authors: [Cogito, verrier, EvilSeph]
+ *website: http://www.curse.com/server-mods/minecraft/myplugin
+ *
+ *main: com.captaininflamo.bukkit.inferno.Inferno
+ *database: false
+ *depend: [NewFire, FlameWire]
+ *
+ *commands:
+ *  flagrate:
+ *    description: Set yourself on fire.
+ *    aliases: [combust_me, combustMe]
+ *    permission: inferno.flagrate
+ *    usage: Syntax error! Simply type /<command> to ignite yourself.
+ *  burningdeaths:
+ *    description: List how many times you have died by fire.
+ *    aliases: [burning_deaths, burningDeaths]
+ *    permission: inferno.burningdeaths
+ *    usage: |
+ *      /<command> [player]
+ *      Example: /<command> - see how many times you have burned to death
+ *      Example: /<command> CaptainIce - see how many times CaptainIce has burned to death
+ *
+ *permissions:
+ *  inferno.*:
+ *    description: Gives access to all Inferno commands
+ *    children:
+ *      inferno.flagrate: true
+ *      inferno.burningdeaths: true
+ *      inferno.burningdeaths.others: true
+ *  inferno.flagrate:
+ *    description: Allows you to ignite yourself
+ *    default: true
+ *  inferno.burningdeaths:
+ *    description: Allows you to see how many times you have burned to death
+ *    default: true
+ *  inferno.burningdeaths.others:
+ *    description: Allows you to see how many times others have burned to death
+ *    default: op
+ *    children:
+ *      inferno.burningdeaths: true
+ *
+ */ +public final class PluginDescriptionFile { + private static final ThreadLocal YAML = new ThreadLocal() { + @Override + protected Yaml initialValue() { + return new Yaml(new SafeConstructor() { + { + yamlConstructors.put(null, new AbstractConstruct() { + @Override + public Object construct(final Node node) { + if (!node.getTag().startsWith("!@")) { + // Unknown tag - will fail + return SafeConstructor.undefinedConstructor.construct(node); + } + // Unknown awareness - provide a graceful substitution + return new PluginAwareness() { + @Override + public String toString() { + return node.toString(); + } + }; + } + }); + for (final PluginAwareness.Flags flag : PluginAwareness.Flags.values()) { + yamlConstructors.put(new Tag("!@" + flag.name()), new AbstractConstruct() { + @Override + public PluginAwareness.Flags construct(final Node node) { + return flag; + } + }); + } + } + }); + } + }; + String rawName = null; + private String name = null; + private String main = null; + private String classLoaderOf = null; + private List depend = ImmutableList.of(); + private List softDepend = ImmutableList.of(); + private List loadBefore = ImmutableList.of(); + private String version = null; + private Map> commands = null; + private String description = null; + private List authors = null; + private String website = null; + private String prefix = null; + private boolean database = false; + private PluginLoadOrder order = PluginLoadOrder.POSTWORLD; + private List permissions = null; + private Map lazyPermissions = null; + private PermissionDefault defaultPerm = PermissionDefault.OP; + private Set awareness = ImmutableSet.of(); + + public PluginDescriptionFile(final InputStream stream) throws InvalidDescriptionException { + loadMap(asMap(YAML.get().load(stream))); + } + + /** + * Loads a PluginDescriptionFile from the specified reader + * + * @param reader The reader + * @throws InvalidDescriptionException If the PluginDescriptionFile is + * invalid + */ + public PluginDescriptionFile(final Reader reader) throws InvalidDescriptionException { + loadMap(asMap(YAML.get().load(reader))); + } + + /** + * Creates a new PluginDescriptionFile with the given detailed + * + * @param pluginName Name of this plugin + * @param pluginVersion Version of this plugin + * @param mainClass Full location of the main class of this plugin + */ + public PluginDescriptionFile(final String pluginName, final String pluginVersion, final String mainClass) { + name = pluginName.replace(' ', '_'); + version = pluginVersion; + main = mainClass; + } + + /** + * Gives the name of the plugin. This name is a unique identifier for + * plugins. + *
    + *
  • Must consist of all alphanumeric characters, underscores, hyphon, + * and period (a-z,A-Z,0-9, _.-). Any other character will cause the + * plugin.yml to fail loading. + *
  • Used to determine the name of the plugin's data folder. Data + * folders are placed in the ./plugins/ directory by default, but this + * behavior should not be relied on. {@link Plugin#getDataFolder()} + * should be used to reference the data folder. + *
  • It is good practice to name your jar the same as this, for example + * 'MyPlugin.jar'. + *
  • Case sensitive. + *
  • The is the token referenced in {@link #getDepend()}, {@link + * #getSoftDepend()}, and {@link #getLoadBefore()}. + *
  • Using spaces in the plugin's name is deprecated. + *
+ *

+ * In the plugin.yml, this entry is named name. + *

+ * Example:

name: MyPlugin
+ * + * @return the name of the plugin + */ + public String getName() { + return name; + } + + /** + * Gives the version of the plugin. + *
    + *
  • Version is an arbitrary string, however the most common format is + * MajorRelease.MinorRelease.Build (eg: 1.4.1). + *
  • Typically you will increment this every time you release a new + * feature or bug fix. + *
  • Displayed when a user types /version PluginName + *
+ *

+ * In the plugin.yml, this entry is named version. + *

+ * Example:

version: 1.4.1
+ * + * @return the version of the plugin + */ + public String getVersion() { + return version; + } + + /** + * Gives the fully qualified name of the main class for a plugin. The + * format should follow the {@link ClassLoader#loadClass(String)} syntax + * to successfully be resolved at runtime. For most plugins, this is the + * class that extends {@link JavaPlugin}. + *
    + *
  • This must contain the full namespace including the class file + * itself. + *
  • If your namespace is org.bukkit.plugin, and your class + * file is called MyPlugin then this must be + * org.bukkit.plugin.MyPlugin + *
  • No plugin can use org.bukkit. as a base package for + * any class, including the main class. + *
+ *

+ * In the plugin.yml, this entry is named main. + *

+ * Example: + *

main: org.bukkit.plugin.MyPlugin
+ * + * @return the fully qualified main class for the plugin + */ + public String getMain() { + return main; + } + + /** + * Gives a human-friendly description of the functionality the plugin + * provides. + *
    + *
  • The description can have multiple lines. + *
  • Displayed when a user types /version PluginName + *
+ *

+ * In the plugin.yml, this entry is named description. + *

+ * Example: + *

description: This plugin is so 31337. You can set yourself on fire.
+ * + * @return description of this plugin, or null if not specified + */ + public String getDescription() { + return description; + } + + /** + * Gives the phase of server startup that the plugin should be loaded. + *
    + *
  • Possible values are in {@link PluginLoadOrder}. + *
  • Defaults to {@link PluginLoadOrder#POSTWORLD}. + *
  • Certain caveats apply to each phase. + *
  • When different, {@link #getDepend()}, {@link #getSoftDepend()}, and + * {@link #getLoadBefore()} become relative in order loaded per-phase. + * If a plugin loads at STARTUP, but a dependency loads + * at POSTWORLD, the dependency will not be loaded before + * the plugin is loaded. + *
+ *

+ * In the plugin.yml, this entry is named load. + *

+ * Example:

load: STARTUP
+ * + * @return the phase when the plugin should be loaded + */ + public PluginLoadOrder getLoad() { + return order; + } + + /** + * Gives the list of authors for the plugin. + *
    + *
  • Gives credit to the developer. + *
  • Used in some server error messages to provide helpful feedback on + * who to contact when an error occurs. + *
  • A bukkit.org forum handle or email address is recommended. + *
  • Is displayed when a user types /version PluginName + *
  • authors must be in YAML list + * format. + *
+ *

+ * In the plugin.yml, this has two entries, author and + * authors. + *

+ * Single author example: + *

author: CaptainInflamo
+ * Multiple author example: + *
authors: [Cogito, verrier, EvilSeph]
+ * When both are specified, author will be the first entry in the list, so + * this example: + *
author: Grum
+     *authors:
+     *- feildmaster
+     *- amaranth
+ * Is equivilant to this example: + *
authors: [Grum, feildmaster, aramanth]
+ * + * @return an immutable list of the plugin's authors + */ + public List getAuthors() { + return authors; + } + + /** + * Gives the plugin's or plugin's author's website. + *
    + *
  • A link to the Curse page that includes documentation and downloads + * is highly recommended. + *
  • Displayed when a user types /version PluginName + *
+ *

+ * In the plugin.yml, this entry is named website. + *

+ * Example: + *

website: http://www.curse.com/server-mods/minecraft/myplugin
+ * + * @return description of this plugin, or null if not specified + */ + public String getWebsite() { + return website; + } + + /** + * Gives if the plugin uses a database. + *
    + *
  • Using a database is non-trivial. + *
  • Valid values include true and false + *
+ *

+ * In the plugin.yml, this entry is named database. + *

+ * Example: + *

database: false
+ * + * @return if this plugin requires a database + * @see Plugin#getDatabase() + */ + public boolean isDatabaseEnabled() { + return database; + } + + /** + * Gives a list of other plugins that the plugin requires. + *
    + *
  • Use the value in the {@link #getName()} of the target plugin to + * specify the dependency. + *
  • If any plugin listed here is not found, your plugin will fail to + * load at startup. + *
  • If multiple plugins list each other in depend, + * creating a network with no individual plugin does not list another + * plugin in the network, + * all plugins in that network will fail. + *
  • depend must be in must be in YAML list + * format. + *
+ *

+ * In the plugin.yml, this entry is named depend. + *

+ * Example: + *

depend:
+     *- OnePlugin
+     *- AnotherPlugin
+ * + * @return immutable list of the plugin's dependencies + */ + public List getDepend() { + return depend; + } + + /** + * Gives a list of other plugins that the plugin requires for full + * functionality. The {@link PluginManager} will make best effort to treat + * all entries here as if they were a {@link #getDepend() dependency}, but + * will never fail because of one of these entries. + *
    + *
  • Use the value in the {@link #getName()} of the target plugin to + * specify the dependency. + *
  • When an unresolvable plugin is listed, it will be ignored and does + * not affect load order. + *
  • When a circular dependency occurs (a network of plugins depending + * or soft-dependending each other), it will arbitrarily choose a + * plugin that can be resolved when ignoring soft-dependencies. + *
  • softdepend must be in YAML list + * format. + *
+ *

+ * In the plugin.yml, this entry is named softdepend. + *

+ * Example: + *

softdepend: [OnePlugin, AnotherPlugin]
+ * + * @return immutable list of the plugin's preferred dependencies + */ + public List getSoftDepend() { + return softDepend; + } + + /** + * Gets the list of plugins that should consider this plugin a + * soft-dependency. + *
    + *
  • Use the value in the {@link #getName()} of the target plugin to + * specify the dependency. + *
  • The plugin should load before any other plugins listed here. + *
  • Specifying another plugin here is strictly equivalent to having the + * specified plugin's {@link #getSoftDepend()} include {@link + * #getName() this plugin}. + *
  • loadbefore must be in YAML list + * format. + *
+ *

+ * In the plugin.yml, this entry is named loadbefore. + *

+ * Example: + *

loadbefore:
+     *- OnePlugin
+     *- AnotherPlugin
+ * + * @return immutable list of plugins that should consider this plugin a + * soft-dependency + */ + public List getLoadBefore() { + return loadBefore; + } + + /** + * Gives the token to prefix plugin-specific logging messages with. + *
    + *
  • This includes all messages using {@link Plugin#getLogger()}. + *
  • If not specified, the server uses the plugin's {@link #getName() + * name}. + *
  • This should clearly indicate what plugin is being logged. + *
+ *

+ * In the plugin.yml, this entry is named prefix. + *

+ * Example:

prefix: ex-why-zee
+ * + * @return the prefixed logging token, or null if not specified + */ + public String getPrefix() { + return prefix; + } + + /** + * Gives the map of command-name to command-properties. Each entry in this + * map corresponds to a single command and the respective values are the + * properties of the command. Each property, with the exception of + * aliases, can be defined at runtime using methods in {@link + * PluginCommand} and are defined here only as a convenience. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
The command section's description
NodeMethodTypeDescriptionExample
description{@link PluginCommand#setDescription(String)}StringA user-friendly description for a command. It is useful for + * documentation purposes as well as in-game help.
description: Set yourself on fire
aliases{@link PluginCommand#setAliases(List)}String or List of + * stringsAlternative command names, with special usefulness for commands + * that are already registered. Aliases are not effective when + * defined at runtime, so the plugin description file is the + * only way to have them properly defined. + *

+ * Note: Command aliases may not have a colon in them.

Single alias format: + *
aliases: combust_me
or + * multiple alias format: + *
aliases: [combust_me, combustMe]
permission{@link PluginCommand#setPermission(String)}StringThe name of the {@link Permission} required to use the command. + * A user without the permission will receive the specified + * message (see {@linkplain + * PluginCommand#setPermissionMessage(String) below}), or a + * standard one if no specific message is defined. Without the + * permission node, no {@link + * PluginCommand#setExecutor(CommandExecutor) CommandExecutor} or + * {@link PluginCommand#setTabCompleter(TabCompleter) + * TabCompleter} will be called.
permission: inferno.flagrate
permission-message{@link PluginCommand#setPermissionMessage(String)}String
    + *
  • Displayed to a player that attempts to use a command, but + * does not have the required permission. See {@link + * PluginCommand#getPermission() above}. + *
  • <permission> is a macro that is replaced with the + * permission node required to use the command. + *
  • Using empty quotes is a valid way to indicate nothing + * should be displayed to a player. + *
permission-message: You do not have /<permission>
usage{@link PluginCommand#setUsage(String)}StringThis message is displayed to a player when the {@link + * PluginCommand#setExecutor(CommandExecutor)} {@linkplain + * CommandExecutor#onCommand(CommandSender,Command,String,String[]) + * returns false}. <command> is a macro that is replaced + * the command issued.
usage: Syntax error! Perhaps you meant /<command> PlayerName?
+ * It is worth noting that to use a colon in a yaml, like + * `usage: Usage: /god [player]', you need to + * surround + * the message with double-quote: + *
usage: "Usage: /god [player]"
+ * The commands are structured as a hiearchy of nested mappings. + * The primary (top-level, no intendentation) node is + * `commands', while each individual command name is + * indented, indicating it maps to some value (in our case, the + * properties of the table above). + *

+ * Here is an example bringing together the piecemeal examples above, as + * well as few more definitions:

+     *commands:
+     *  flagrate:
+     *    description: Set yourself on fire.
+     *    aliases: [combust_me, combustMe]
+     *    permission: inferno.flagrate
+     *    permission-message: You do not have /<permission>
+     *    usage: Syntax error! Perhaps you meant /<command> PlayerName?
+     *  burningdeaths:
+     *    description: List how many times you have died by fire.
+     *    aliases:
+     *    - burning_deaths
+     *    - burningDeaths
+     *    permission: inferno.burningdeaths
+     *    usage: |
+     *      /<command> [player]
+     *      Example: /<command> - see how many times you have burned to death
+     *      Example: /<command> CaptainIce - see how many times CaptainIce has burned to death
+     *  # The next command has no description, aliases, etc. defined, but is still valid
+     *  # Having an empty declaration is useful for defining the description, permission, and messages from a configuration dynamically
+     *  apocalypse:
+     *
+ * Note: Command names may not have a colon in their name. + * + * @return the commands this plugin will register + */ + public Map> getCommands() { + return commands; + } + + /** + * Gives the list of permissions the plugin will register at runtime, + * immediately proceding enabling. The format for defining permissions is + * a map from permission name to properties. To represent a map without + * any specific property, empty curly-braces ( + * {} ) may be used (as a null value is not + * accepted, unlike the {@link #getCommands() commands} above). + *

+ * A list of optional properties for permissions: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
The permission section's description
NodeDescriptionExample
descriptionPlaintext (user-friendly) description of what the permission + * is for.
description: Allows you to set yourself on fire
defaultThe default state for the permission, as defined by {@link + * Permission#getDefault()}. If not defined, it will be set to + * the value of {@link PluginDescriptionFile#getPermissionDefault()}. + *

+ * For reference:

    + *
  • true - Represents a positive assignment to + * {@link Permissible permissibles}. + *
  • false - Represents no assignment to {@link + * Permissible permissibles}. + *
  • op - Represents a positive assignment to + * {@link Permissible#isOp() operator permissibles}. + *
  • notop - Represents a positive assignment to + * {@link Permissible#isOp() non-operator permissibiles}. + *
default: true
childrenAllows other permissions to be set as a {@linkplain + * Permission#getChildren() relation} to the parent permission. + * When a parent permissions is assigned, child permissions are + * respectively assigned as well. + *
    + *
  • When a parent permission is assigned negatively, child + * permissions are assigned based on an inversion of their + * association. + *
  • When a parent permission is assigned positively, child + * permissions are assigned based on their association. + *
+ *

+ * Child permissions may be defined in a number of ways:

    + *
  • Children may be defined as a list of + * names. Using a list will treat all children associated + * positively to their parent. + *
  • Children may be defined as a map. Each permission name maps + * to either a boolean (representing the association), or a + * nested permission definition (just as another permission). + * Using a nested definition treats the child as a positive + * association. + *
  • A nested permission definition must be a map of these same + * properties. To define a valid nested permission without + * defining any specific property, empty curly-braces ( + * {} ) must be used. + *
  • A nested permission may carry it's own nested permissions + * as children, as they may also have nested permissions, and + * so forth. There is no direct limit to how deep the + * permission tree is defined. + *
As a list: + *
children: [inferno.flagrate, inferno.burningdeaths]
+ * Or as a mapping: + *
children:
+     *  inferno.flagrate: true
+     *  inferno.burningdeaths: true
+ * An additional example showing basic nested values can be seen + * here. + *
+ * The permissions are structured as a hiearchy of nested mappings. + * The primary (top-level, no intendentation) node is + * `permissions', while each individual permission name is + * indented, indicating it maps to some value (in our case, the + * properties of the table above). + *

+ * Here is an example using some of the properties:

+     *permissions:
+     *  inferno.*:
+     *    description: Gives access to all Inferno commands
+     *    children:
+     *      inferno.flagrate: true
+     *      inferno.burningdeaths: true
+     *  inferno.flagate:
+     *    description: Allows you to ignite yourself
+     *    default: true
+     *  inferno.burningdeaths:
+     *    description: Allows you to see how many times you have burned to death
+     *    default: true
+     *
+ * Another example, with nested definitions, can be found here. + * + * @return the permissions this plugin will register + */ + public List getPermissions() { + if (permissions == null) { + if (lazyPermissions == null) { + permissions = ImmutableList.of(); + } else { + permissions = ImmutableList.copyOf(Permission.loadPermissions(lazyPermissions, "Permission node '%s' in plugin description file for " + getFullName() + " is invalid", defaultPerm)); + lazyPermissions = null; + } + } + return permissions; + } + + /** + * Gives the default {@link Permission#getDefault() default} state of + * {@link #getPermissions() permissions} registered for the plugin. + *
    + *
  • If not specified, it will be {@link PermissionDefault#OP}. + *
  • It is matched using {@link PermissionDefault#getByName(String)} + *
  • It only affects permissions that do not define the + * default node. + *
  • It may be any value in {@link PermissionDefault}. + *
+ *

+ * In the plugin.yml, this entry is named default-permission. + *

+ * Example:

default-permission: NOT_OP
+ * + * @return the default value for the plugin's permissions + */ + public PermissionDefault getPermissionDefault() { + return defaultPerm; + } + + /** + * Gives a set of every {@link PluginAwareness} for a plugin. An awareness + * dictates something that a plugin developer acknowledges when the plugin + * is compiled. Some implementions may define extra awarenesses that are + * not included in the API. Any unrecognized + * awareness (one unsupported or in a future version) will cause a dummy + * object to be created instead of failing. + * + *
    + *
  • Currently only supports the enumerated values in {@link + * PluginAwareness.Flags}. + *
  • Each awareness starts the identifier with bang-at + * (!@). + *
  • Unrecognized (future / unimplemented) entries are quietly replaced + * by a generic object that implements PluginAwareness. + *
  • A type of awareness must be defined by the runtime and acknowledged + * by the API, effectively discluding any derived type from any + * plugin's classpath. + *
  • awareness must be in YAML list + * format. + *
+ *

+ * In the plugin.yml, this entry is named awareness. + *

+ * Example:

awareness:
+     *- !@UTF8
+ *

+ * Note: Although unknown versions of some future awareness are + * gracefully substituted, previous versions of Bukkit (ones prior to the + * first implementation of awareness) will fail to load a plugin that + * defines any awareness. + * + * @return a set containing every awareness for the plugin + */ + public Set getAwareness() { + return awareness; + } + + /** + * Returns the name of a plugin, including the version. This method is + * provided for convenience; it uses the {@link #getName()} and {@link + * #getVersion()} entries. + * + * @return a descriptive name of the plugin and respective version + */ + public String getFullName() { + return name + " v" + version; + } + + /** + * @return unused + * @deprecated unused + */ + @Deprecated + public String getClassLoaderOf() { + return classLoaderOf; + } + + public void setDatabaseEnabled(boolean database) { + this.database = database; + } + + /** + * Saves this PluginDescriptionFile to the given writer + * + * @param writer Writer to output this file to + */ + public void save(Writer writer) { + YAML.get().dump(saveMap(), writer); + } + + private void loadMap(Map map) throws InvalidDescriptionException { + try { + name = rawName = map.get("name").toString(); + + if (!name.matches("^[A-Za-z0-9 _.-]+$")) { + throw new InvalidDescriptionException("name '" + name + "' contains invalid characters."); + } + name = name.replace(' ', '_'); + } catch (NullPointerException ex) { + throw new InvalidDescriptionException(ex, "name is not defined"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "name is of wrong type"); + } + + try { + version = map.get("version").toString(); + } catch (NullPointerException ex) { + throw new InvalidDescriptionException(ex, "version is not defined"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "version is of wrong type"); + } + + try { + main = map.get("main").toString(); + if (main.startsWith("org.bukkit.")) { + throw new InvalidDescriptionException("main may not be within the org.bukkit namespace"); + } + } catch (NullPointerException ex) { + throw new InvalidDescriptionException(ex, "main is not defined"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "main is of wrong type"); + } + + if (map.get("commands") != null) { + ImmutableMap.Builder> commandsBuilder = ImmutableMap.>builder(); + try { + for (Map.Entry command : ((Map) map.get("commands")).entrySet()) { + ImmutableMap.Builder commandBuilder = ImmutableMap.builder(); + if (command.getValue() != null) { + for (Map.Entry commandEntry : ((Map) command.getValue()).entrySet()) { + if (commandEntry.getValue() instanceof Iterable) { + // This prevents internal alias list changes + ImmutableList.Builder commandSubList = ImmutableList.builder(); + for (Object commandSubListItem : (Iterable) commandEntry.getValue()) { + if (commandSubListItem != null) { + commandSubList.add(commandSubListItem); + } + } + commandBuilder.put(commandEntry.getKey().toString(), commandSubList.build()); + } else if (commandEntry.getValue() != null) { + commandBuilder.put(commandEntry.getKey().toString(), commandEntry.getValue()); + } + } + } + commandsBuilder.put(command.getKey().toString(), commandBuilder.build()); + } + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "commands are of wrong type"); + } + commands = commandsBuilder.build(); + } + + if (map.get("class-loader-of") != null) { + classLoaderOf = map.get("class-loader-of").toString(); + } + + depend = makePluginNameList(map, "depend"); + softDepend = makePluginNameList(map, "softdepend"); + loadBefore = makePluginNameList(map, "loadbefore"); + + if (map.get("database") != null) { + try { + database = (Boolean) map.get("database"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "database is of wrong type"); + } + } + + if (map.get("website") != null) { + website = map.get("website").toString(); + } + + if (map.get("description") != null) { + description = map.get("description").toString(); + } + + if (map.get("load") != null) { + try { + order = PluginLoadOrder.valueOf(((String) map.get("load")).toUpperCase().replaceAll("\\W", "")); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "load is of wrong type"); + } catch (IllegalArgumentException ex) { + throw new InvalidDescriptionException(ex, "load is not a valid choice"); + } + } + + if (map.get("authors") != null) { + ImmutableList.Builder authorsBuilder = ImmutableList.builder(); + if (map.get("author") != null) { + authorsBuilder.add(map.get("author").toString()); + } + try { + for (Object o : (Iterable) map.get("authors")) { + authorsBuilder.add(o.toString()); + } + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "authors are of wrong type"); + } catch (NullPointerException ex) { + throw new InvalidDescriptionException(ex, "authors are improperly defined"); + } + authors = authorsBuilder.build(); + } else if (map.get("author") != null) { + authors = ImmutableList.of(map.get("author").toString()); + } else { + authors = ImmutableList.of(); + } + + if (map.get("default-permission") != null) { + try { + defaultPerm = PermissionDefault.getByName(map.get("default-permission").toString()); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "default-permission is of wrong type"); + } catch (IllegalArgumentException ex) { + throw new InvalidDescriptionException(ex, "default-permission is not a valid choice"); + } + } + + if (map.get("awareness") instanceof Iterable) { + Set awareness = new HashSet(); + try { + for (Object o : (Iterable) map.get("awareness")) { + awareness.add((PluginAwareness) o); + } + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "awareness has wrong type"); + } + this.awareness = ImmutableSet.copyOf(awareness); + } + + try { + lazyPermissions = (Map) map.get("permissions"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "permissions are of the wrong type"); + } + + if (map.get("prefix") != null) { + prefix = map.get("prefix").toString(); + } + } + + private static List makePluginNameList(final Map map, final String key) throws InvalidDescriptionException { + final Object value = map.get(key); + if (value == null) { + return ImmutableList.of(); + } + + final ImmutableList.Builder builder = ImmutableList.builder(); + try { + for (final Object entry : (Iterable) value) { + builder.add(entry.toString().replace(' ', '_')); + } + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, key + " is of wrong type"); + } catch (NullPointerException ex) { + throw new InvalidDescriptionException(ex, "invalid " + key + " format"); + } + return builder.build(); + } + + private Map saveMap() { + Map map = new HashMap(); + + map.put("name", name); + map.put("main", main); + map.put("version", version); + map.put("database", database); + map.put("order", order.toString()); + map.put("default-permission", defaultPerm.toString()); + + if (commands != null) { + map.put("command", commands); + } + if (depend != null) { + map.put("depend", depend); + } + if (softDepend != null) { + map.put("softdepend", softDepend); + } + if (website != null) { + map.put("website", website); + } + if (description != null) { + map.put("description", description); + } + + if (authors.size() == 1) { + map.put("author", authors.get(0)); + } else if (authors.size() > 1) { + map.put("authors", authors); + } + + if (classLoaderOf != null) { + map.put("class-loader-of", classLoaderOf); + } + + if (prefix != null) { + map.put("prefix", prefix); + } + + return map; + } + + private Map asMap(Object object) throws InvalidDescriptionException { + if (object instanceof Map) { + return (Map) object; + } + throw new InvalidDescriptionException(object + " is not properly structured."); + } + + /** + * @return internal use + * @deprecated Internal use + */ + @Deprecated + public String getRawName() { + return rawName; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLoadOrder.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLoadOrder.java new file mode 100644 index 0000000..b77436f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLoadOrder.java @@ -0,0 +1,17 @@ +package org.bukkit.plugin; + +/** + * Represents the order in which a plugin should be initialized and enabled + */ +public enum PluginLoadOrder { + + /** + * Indicates that the plugin will be loaded at startup + */ + STARTUP, + /** + * Indicates that the plugin will be loaded after the first/default world + * was created + */ + POSTWORLD +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLoader.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLoader.java new file mode 100644 index 0000000..e7981a1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLoader.java @@ -0,0 +1,76 @@ +package org.bukkit.plugin; + +import java.io.File; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import org.bukkit.event.Event; +import org.bukkit.event.Listener; + +/** + * Represents a plugin loader, which handles direct access to specific types + * of plugins + */ +public interface PluginLoader { + + /** + * Loads the plugin contained in the specified file + * + * @param file File to attempt to load + * @return Plugin that was contained in the specified file, or null if + * unsuccessful + * @throws InvalidPluginException Thrown when the specified file is not a + * plugin + * @throws UnknownDependencyException If a required dependency could not + * be found + */ + public Plugin loadPlugin(File file) throws InvalidPluginException, UnknownDependencyException; + + /** + * Loads a PluginDescriptionFile from the specified file + * + * @param file File to attempt to load from + * @return A new PluginDescriptionFile loaded from the plugin.yml in the + * specified file + * @throws InvalidDescriptionException If the plugin description file + * could not be created + */ + public PluginDescriptionFile getPluginDescription(File file) throws InvalidDescriptionException; + + /** + * Returns a list of all filename filters expected by this PluginLoader + * + * @return The filters + */ + public Pattern[] getPluginFileFilters(); + + /** + * Creates and returns registered listeners for the event classes used in + * this listener + * + * @param listener The object that will handle the eventual call back + * @param plugin The plugin to use when creating registered listeners + * @return The registered listeners. + */ + public Map, Set> createRegisteredListeners(Listener listener, Plugin plugin); + + /** + * Enables the specified plugin + *

+ * Attempting to enable a plugin that is already enabled will have no + * effect + * + * @param plugin Plugin to enable + */ + public void enablePlugin(Plugin plugin); + + /** + * Disables the specified plugin + *

+ * Attempting to disable a plugin that is not enabled will have no effect + * + * @param plugin Plugin to disable + */ + public void disablePlugin(Plugin plugin); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLogger.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLogger.java new file mode 100644 index 0000000..f43c10b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginLogger.java @@ -0,0 +1,36 @@ +package org.bukkit.plugin; + +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +/** + * The PluginLogger class is a modified {@link Logger} that prepends all + * logging calls with the name of the plugin doing the logging. The API for + * PluginLogger is exactly the same as {@link Logger}. + * + * @see Logger + */ +public class PluginLogger extends Logger { + private String pluginName; + + /** + * Creates a new PluginLogger that extracts the name from a plugin. + * + * @param context A reference to the plugin + */ + public PluginLogger(Plugin context) { + super(context.getClass().getCanonicalName(), null); + String prefix = context.getDescription().getPrefix(); + pluginName = prefix != null ? new StringBuilder().append("[").append(prefix).append("] ").toString() : "[" + context.getDescription().getName() + "] "; + setParent(context.getServer().getLogger()); + setLevel(Level.ALL); + } + + @Override + public void log(LogRecord logRecord) { + logRecord.setMessage(pluginName + logRecord.getMessage()); + super.log(logRecord); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginManager.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginManager.java new file mode 100644 index 0000000..e5638d5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/PluginManager.java @@ -0,0 +1,294 @@ +package org.bukkit.plugin; + +import java.io.File; +import java.util.Set; + +import org.bukkit.event.Event; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.Permission; + +/** + * Handles all plugin management from the Server + */ +public interface PluginManager { + + /** + * Registers the specified plugin loader + * + * @param loader Class name of the PluginLoader to register + * @throws IllegalArgumentException Thrown when the given Class is not a + * valid PluginLoader + */ + public void registerInterface(Class loader) throws IllegalArgumentException; + + /** + * Checks if the given plugin is loaded and returns it when applicable + *

+ * Please note that the name of the plugin is case-sensitive + * + * @param name Name of the plugin to check + * @return Plugin if it exists, otherwise null + */ + public Plugin getPlugin(String name); + + /** + * Gets a list of all currently loaded plugins + * + * @return Array of Plugins + */ + public Plugin[] getPlugins(); + + /** + * Checks if the given plugin is enabled or not + *

+ * Please note that the name of the plugin is case-sensitive. + * + * @param name Name of the plugin to check + * @return true if the plugin is enabled, otherwise false + */ + public boolean isPluginEnabled(String name); + + /** + * Checks if the given plugin is enabled or not + * + * @param plugin Plugin to check + * @return true if the plugin is enabled, otherwise false + */ + public boolean isPluginEnabled(Plugin plugin); + + /** + * Loads the plugin in the specified file + *

+ * File must be valid according to the current enabled Plugin interfaces + * + * @param file File containing the plugin to load + * @return The Plugin loaded, or null if it was invalid + * @throws InvalidPluginException Thrown when the specified file is not a + * valid plugin + * @throws InvalidDescriptionException Thrown when the specified file + * contains an invalid description + * @throws UnknownDependencyException If a required dependency could not + * be resolved + */ + public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException; + + /** + * Loads the plugins contained within the specified directory + * + * @param directory Directory to check for plugins + * @return A list of all plugins loaded + */ + public Plugin[] loadPlugins(File directory); + + /** + * Disables all the loaded plugins + */ + public void disablePlugins(); + + /** + * Disables and removes all plugins + */ + public void clearPlugins(); + + /** + * Calls an event with the given details + * + * @param event Event details + * @throws IllegalStateException Thrown when an asynchronous event is + * fired from synchronous code. + *

+ * Note: This is best-effort basis, and should not be used to test + * synchronized state. This is an indicator for flawed flow logic. + */ + public void callEvent(Event event) throws IllegalStateException; + + /** + * Registers all the events in the given listener class + * + * @param listener Listener to register + * @param plugin Plugin to register + */ + public void registerEvents(Listener listener, Plugin plugin); + + /** + * Registers the specified executor to the given event class + * + * @param event Event type to register + * @param listener Listener to register + * @param priority Priority to register this event at + * @param executor EventExecutor to register + * @param plugin Plugin to register + */ + public void registerEvent(Class event, Listener listener, EventPriority priority, EventExecutor executor, Plugin plugin); + + /** + * Registers the specified executor to the given event class + * + * @param event Event type to register + * @param listener Listener to register + * @param priority Priority to register this event at + * @param executor EventExecutor to register + * @param plugin Plugin to register + * @param ignoreCancelled Whether to pass cancelled events or not + */ + public void registerEvent(Class event, Listener listener, EventPriority priority, EventExecutor executor, Plugin plugin, boolean ignoreCancelled); + + /** + * Enables the specified plugin + *

+ * Attempting to enable a plugin that is already enabled will have no + * effect + * + * @param plugin Plugin to enable + */ + public void enablePlugin(Plugin plugin); + + /** + * Disables the specified plugin + *

+ * Attempting to disable a plugin that is not enabled will have no effect + * + * @param plugin Plugin to disable + */ + public void disablePlugin(Plugin plugin); + + /** + * Gets a {@link Permission} from its fully qualified name + * + * @param name Name of the permission + * @return Permission, or null if none + */ + public Permission getPermission(String name); + + /** + * Adds a {@link Permission} to this plugin manager. + *

+ * If a permission is already defined with the given name of the new + * permission, an exception will be thrown. + * + * @param perm Permission to add + * @throws IllegalArgumentException Thrown when a permission with the same + * name already exists + */ + public void addPermission(Permission perm); + + /** + * Removes a {@link Permission} registration from this plugin manager. + *

+ * If the specified permission does not exist in this plugin manager, + * nothing will happen. + *

+ * Removing a permission registration will not remove the + * permission from any {@link Permissible}s that have it. + * + * @param perm Permission to remove + */ + public void removePermission(Permission perm); + + /** + * Removes a {@link Permission} registration from this plugin manager. + *

+ * If the specified permission does not exist in this plugin manager, + * nothing will happen. + *

+ * Removing a permission registration will not remove the + * permission from any {@link Permissible}s that have it. + * + * @param name Permission to remove + */ + public void removePermission(String name); + + /** + * Gets the default permissions for the given op status + * + * @param op Which set of default permissions to get + * @return The default permissions + */ + public Set getDefaultPermissions(boolean op); + + /** + * Recalculates the defaults for the given {@link Permission}. + *

+ * This will have no effect if the specified permission is not registered + * here. + * + * @param perm Permission to recalculate + */ + public void recalculatePermissionDefaults(Permission perm); + + /** + * Subscribes the given Permissible for information about the requested + * Permission, by name. + *

+ * If the specified Permission changes in any form, the Permissible will + * be asked to recalculate. + * + * @param permission Permission to subscribe to + * @param permissible Permissible subscribing + */ + public void subscribeToPermission(String permission, Permissible permissible); + + /** + * Unsubscribes the given Permissible for information about the requested + * Permission, by name. + * + * @param permission Permission to unsubscribe from + * @param permissible Permissible subscribing + */ + public void unsubscribeFromPermission(String permission, Permissible permissible); + + /** + * Gets a set containing all subscribed {@link Permissible}s to the given + * permission, by name + * + * @param permission Permission to query for + * @return Set containing all subscribed permissions + */ + public Set getPermissionSubscriptions(String permission); + + /** + * Subscribes to the given Default permissions by operator status + *

+ * If the specified defaults change in any form, the Permissible will be + * asked to recalculate. + * + * @param op Default list to subscribe to + * @param permissible Permissible subscribing + */ + public void subscribeToDefaultPerms(boolean op, Permissible permissible); + + /** + * Unsubscribes from the given Default permissions by operator status + * + * @param op Default list to unsubscribe from + * @param permissible Permissible subscribing + */ + public void unsubscribeFromDefaultPerms(boolean op, Permissible permissible); + + /** + * Gets a set containing all subscribed {@link Permissible}s to the given + * default list, by op status + * + * @param op Default list to query for + * @return Set containing all subscribed permissions + */ + public Set getDefaultPermSubscriptions(boolean op); + + /** + * Gets a set of all registered permissions. + *

+ * This set is a copy and will not be modified live. + * + * @return Set containing all current registered permissions + */ + public Set getPermissions(); + + /** + * Returns whether or not timing code should be used for event calls + * + * @return True if event timings are to be used + */ + public boolean useTimings(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/RegisteredListener.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/RegisteredListener.java new file mode 100644 index 0000000..9dd0b7a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/RegisteredListener.java @@ -0,0 +1,73 @@ +package org.bukkit.plugin; + +import org.bukkit.event.*; + +/** + * Stores relevant information for plugin listeners + */ +public class RegisteredListener { + private final Listener listener; + private final EventPriority priority; + private final Plugin plugin; + private final EventExecutor executor; + private final boolean ignoreCancelled; + + public RegisteredListener(final Listener listener, final EventExecutor executor, final EventPriority priority, final Plugin plugin, final boolean ignoreCancelled) { + this.listener = listener; + this.priority = priority; + this.plugin = plugin; + this.executor = executor; + this.ignoreCancelled = ignoreCancelled; + } + + /** + * Gets the listener for this registration + * + * @return Registered Listener + */ + public Listener getListener() { + return listener; + } + + /** + * Gets the plugin for this registration + * + * @return Registered Plugin + */ + public Plugin getPlugin() { + return plugin; + } + + /** + * Gets the priority for this registration + * + * @return Registered Priority + */ + public EventPriority getPriority() { + return priority; + } + + /** + * Calls the event executor + * + * @param event The event + * @throws EventException If an event handler throws an exception. + */ + public void callEvent(final Event event) throws EventException { + if (event instanceof Cancellable){ + if (((Cancellable) event).isCancelled() && isIgnoringCancelled()){ + return; + } + } + executor.execute(listener, event); + } + + /** + * Whether this listener accepts cancelled events + * + * @return True when ignoring cancelled events + */ + public boolean isIgnoringCancelled() { + return ignoreCancelled; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/RegisteredServiceProvider.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/RegisteredServiceProvider.java new file mode 100644 index 0000000..ba3ff15 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/RegisteredServiceProvider.java @@ -0,0 +1,46 @@ +package org.bukkit.plugin; + +/** + * A registered service provider. + * + * @param Service + */ +public class RegisteredServiceProvider implements Comparable> { + + private Class service; + private Plugin plugin; + private T provider; + private ServicePriority priority; + + public RegisteredServiceProvider(Class service, T provider, ServicePriority priority, Plugin plugin) { + + this.service = service; + this.plugin = plugin; + this.provider = provider; + this.priority = priority; + } + + public Class getService() { + return service; + } + + public Plugin getPlugin() { + return plugin; + } + + public T getProvider() { + return provider; + } + + public ServicePriority getPriority() { + return priority; + } + + public int compareTo(RegisteredServiceProvider other) { + if (priority.ordinal() == other.getPriority().ordinal()) { + return 0; + } else { + return priority.ordinal() < other.getPriority().ordinal() ? 1 : -1; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/ServicePriority.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/ServicePriority.java new file mode 100644 index 0000000..4afe0fb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/ServicePriority.java @@ -0,0 +1,12 @@ +package org.bukkit.plugin; + +/** + * Represents various priorities of a provider. + */ +public enum ServicePriority { + Lowest, + Low, + Normal, + High, + Highest +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/ServicesManager.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/ServicesManager.java new file mode 100644 index 0000000..5d45ffb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/ServicesManager.java @@ -0,0 +1,106 @@ +package org.bukkit.plugin; + +import java.util.Collection; +import java.util.List; + +/** + * Manages services and service providers. Services are an interface + * specifying a list of methods that a provider must implement. Providers are + * implementations of these services. A provider can be queried from the + * services manager in order to use a service (if one is available). If + * multiple plugins register a service, then the service with the highest + * priority takes precedence. + */ +public interface ServicesManager { + + /** + * Register a provider of a service. + * + * @param Provider + * @param service service class + * @param provider provider to register + * @param plugin plugin with the provider + * @param priority priority of the provider + */ + public void register(Class service, T provider, Plugin plugin, ServicePriority priority); + + /** + * Unregister all the providers registered by a particular plugin. + * + * @param plugin The plugin + */ + public void unregisterAll(Plugin plugin); + + /** + * Unregister a particular provider for a particular service. + * + * @param service The service interface + * @param provider The service provider implementation + */ + public void unregister(Class service, Object provider); + + /** + * Unregister a particular provider. + * + * @param provider The service provider implementation + */ + public void unregister(Object provider); + + /** + * Queries for a provider. This may return if no provider has been + * registered for a service. The highest priority provider is returned. + * + * @param The service interface + * @param service The service interface + * @return provider or null + */ + public T load(Class service); + + /** + * Queries for a provider registration. This may return if no provider + * has been registered for a service. + * + * @param The service interface + * @param service The service interface + * @return provider registration or null + */ + public RegisteredServiceProvider getRegistration(Class service); + + /** + * Get registrations of providers for a plugin. + * + * @param plugin The plugin + * @return provider registration or null + */ + public List> getRegistrations(Plugin plugin); + + /** + * Get registrations of providers for a service. The returned list is + * unmodifiable. + * + * @param The service interface + * @param service The service interface + * @return list of registrations + */ + public Collection> getRegistrations(Class service); + + /** + * Get a list of known services. A service is known if it has registered + * providers for it. + * + * @return list of known services + */ + public Collection> getKnownServices(); + + /** + * Returns whether a provider has been registered for a service. Do not + * check this first only to call load(service) later, as that + * would be a non-thread safe situation. + * + * @param service + * @param service service to check + * @return whether there has been a registered provider + */ + public boolean isProvidedFor(Class service); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/SimplePluginManager.java new file mode 100644 index 0000000..1325b03 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -0,0 +1,731 @@ +package org.bukkit.plugin; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.Validate; +import org.bukkit.Server; +import org.bukkit.command.Command; +import org.bukkit.command.PluginCommandYamlParser; +import org.bukkit.command.SimpleCommandMap; +import org.bukkit.event.Event; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.util.FileUtil; + +import com.google.common.collect.ImmutableSet; + +/** + * Handles all plugin management from the Server + */ +public final class SimplePluginManager implements PluginManager { + private final Server server; + private final Map fileAssociations = new HashMap(); + private final List plugins = new ArrayList(); + private final Map lookupNames = new HashMap(); + private static File updateDirectory = null; + private final SimpleCommandMap commandMap; + private final Map permissions = new HashMap(); + private final Map> defaultPerms = new LinkedHashMap>(); + private final Map> permSubs = new HashMap>(); + private final Map> defSubs = new HashMap>(); + private boolean useTimings = false; + + public SimplePluginManager(Server instance, SimpleCommandMap commandMap) { + server = instance; + this.commandMap = commandMap; + + defaultPerms.put(true, new HashSet()); + defaultPerms.put(false, new HashSet()); + } + + /** + * Registers the specified plugin loader + * + * @param loader Class name of the PluginLoader to register + * @throws IllegalArgumentException Thrown when the given Class is not a + * valid PluginLoader + */ + public void registerInterface(Class loader) throws IllegalArgumentException { + PluginLoader instance; + + if (PluginLoader.class.isAssignableFrom(loader)) { + Constructor constructor; + + try { + constructor = loader.getConstructor(Server.class); + instance = constructor.newInstance(server); + } catch (NoSuchMethodException ex) { + String className = loader.getName(); + + throw new IllegalArgumentException(String.format("Class %s does not have a public %s(Server) constructor", className, className), ex); + } catch (Exception ex) { + throw new IllegalArgumentException(String.format("Unexpected exception %s while attempting to construct a new instance of %s", ex.getClass().getName(), loader.getName()), ex); + } + } else { + throw new IllegalArgumentException(String.format("Class %s does not implement interface PluginLoader", loader.getName())); + } + + Pattern[] patterns = instance.getPluginFileFilters(); + + synchronized (this) { + for (Pattern pattern : patterns) { + fileAssociations.put(pattern, instance); + } + } + } + + /** + * Loads the plugins contained within the specified directory + * + * @param directory Directory to check for plugins + * @return A list of all plugins loaded + */ + public Plugin[] loadPlugins(File directory) { + Validate.notNull(directory, "Directory cannot be null"); + Validate.isTrue(directory.isDirectory(), "Directory must be a directory"); + + List result = new ArrayList(); + Set filters = fileAssociations.keySet(); + + if (!(server.getUpdateFolder().equals(""))) { + updateDirectory = new File(directory, server.getUpdateFolder()); + } + + Map plugins = new HashMap(); + Set loadedPlugins = new HashSet(); + Map> dependencies = new HashMap>(); + Map> softDependencies = new HashMap>(); + + // This is where it figures out all possible plugins + for (File file : directory.listFiles()) { + PluginLoader loader = null; + for (Pattern filter : filters) { + Matcher match = filter.matcher(file.getName()); + if (match.find()) { + loader = fileAssociations.get(filter); + } + } + + if (loader == null) continue; + + PluginDescriptionFile description = null; + try { + description = loader.getPluginDescription(file); + String name = description.getName(); + if (name.equalsIgnoreCase("bukkit") || name.equalsIgnoreCase("minecraft") || name.equalsIgnoreCase("mojang")) { + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': Restricted Name"); + continue; + } else if (description.rawName.indexOf(' ') != -1) { + server.getLogger().warning(String.format( + "Plugin `%s' uses the space-character (0x20) in its name `%s' - this is discouraged", + description.getFullName(), + description.rawName + )); + } + } catch (InvalidDescriptionException ex) { + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'", ex); + continue; + } + + File replacedFile = plugins.put(description.getName(), file); + if (replacedFile != null) { + server.getLogger().severe(String.format( + "Ambiguous plugin name `%s' for files `%s' and `%s' in `%s'", + description.getName(), + file.getPath(), + replacedFile.getPath(), + directory.getPath() + )); + } + + Collection softDependencySet = description.getSoftDepend(); + if (softDependencySet != null && !softDependencySet.isEmpty()) { + if (softDependencies.containsKey(description.getName())) { + // Duplicates do not matter, they will be removed together if applicable + softDependencies.get(description.getName()).addAll(softDependencySet); + } else { + softDependencies.put(description.getName(), new LinkedList(softDependencySet)); + } + } + + Collection dependencySet = description.getDepend(); + if (dependencySet != null && !dependencySet.isEmpty()) { + dependencies.put(description.getName(), new LinkedList(dependencySet)); + } + + Collection loadBeforeSet = description.getLoadBefore(); + if (loadBeforeSet != null && !loadBeforeSet.isEmpty()) { + for (String loadBeforeTarget : loadBeforeSet) { + if (softDependencies.containsKey(loadBeforeTarget)) { + softDependencies.get(loadBeforeTarget).add(description.getName()); + } else { + // softDependencies is never iterated, so 'ghost' plugins aren't an issue + Collection shortSoftDependency = new LinkedList(); + shortSoftDependency.add(description.getName()); + softDependencies.put(loadBeforeTarget, shortSoftDependency); + } + } + } + } + + while (!plugins.isEmpty()) { + boolean missingDependency = true; + Iterator pluginIterator = plugins.keySet().iterator(); + + while (pluginIterator.hasNext()) { + String plugin = pluginIterator.next(); + + if (dependencies.containsKey(plugin)) { + Iterator dependencyIterator = dependencies.get(plugin).iterator(); + + while (dependencyIterator.hasNext()) { + String dependency = dependencyIterator.next(); + + // Dependency loaded + if (loadedPlugins.contains(dependency)) { + dependencyIterator.remove(); + + // We have a dependency not found + } else if (!plugins.containsKey(dependency)) { + missingDependency = false; + File file = plugins.get(plugin); + pluginIterator.remove(); + softDependencies.remove(plugin); + dependencies.remove(plugin); + + server.getLogger().log( + Level.SEVERE, + "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'", + new UnknownDependencyException(dependency)); + break; + } + } + + if (dependencies.containsKey(plugin) && dependencies.get(plugin).isEmpty()) { + dependencies.remove(plugin); + } + } + if (softDependencies.containsKey(plugin)) { + Iterator softDependencyIterator = softDependencies.get(plugin).iterator(); + + while (softDependencyIterator.hasNext()) { + String softDependency = softDependencyIterator.next(); + + // Soft depend is no longer around + if (!plugins.containsKey(softDependency)) { + softDependencyIterator.remove(); + } + } + + if (softDependencies.get(plugin).isEmpty()) { + softDependencies.remove(plugin); + } + } + if (!(dependencies.containsKey(plugin) || softDependencies.containsKey(plugin)) && plugins.containsKey(plugin)) { + // We're clear to load, no more soft or hard dependencies left + File file = plugins.get(plugin); + pluginIterator.remove(); + missingDependency = false; + + try { + result.add(loadPlugin(file)); + loadedPlugins.add(plugin); + continue; + } catch (InvalidPluginException ex) { + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'", ex); + } + } + } + + if (missingDependency) { + // We now iterate over plugins until something loads + // This loop will ignore soft dependencies + pluginIterator = plugins.keySet().iterator(); + + while (pluginIterator.hasNext()) { + String plugin = pluginIterator.next(); + + if (!dependencies.containsKey(plugin)) { + softDependencies.remove(plugin); + missingDependency = false; + File file = plugins.get(plugin); + pluginIterator.remove(); + + try { + result.add(loadPlugin(file)); + loadedPlugins.add(plugin); + break; + } catch (InvalidPluginException ex) { + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "'", ex); + } + } + } + // We have no plugins left without a depend + if (missingDependency) { + softDependencies.clear(); + dependencies.clear(); + Iterator failedPluginIterator = plugins.values().iterator(); + + while (failedPluginIterator.hasNext()) { + File file = failedPluginIterator.next(); + failedPluginIterator.remove(); + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': circular dependency detected"); + } + } + } + } + + return result.toArray(new Plugin[result.size()]); + } + + /** + * Loads the plugin in the specified file + *

+ * File must be valid according to the current enabled Plugin interfaces + * + * @param file File containing the plugin to load + * @return The Plugin loaded, or null if it was invalid + * @throws InvalidPluginException Thrown when the specified file is not a + * valid plugin + * @throws UnknownDependencyException If a required dependency could not + * be found + */ + public synchronized Plugin loadPlugin(File file) throws InvalidPluginException, UnknownDependencyException { + Validate.notNull(file, "File cannot be null"); + + checkUpdate(file); + + Set filters = fileAssociations.keySet(); + Plugin result = null; + + for (Pattern filter : filters) { + String name = file.getName(); + Matcher match = filter.matcher(name); + + if (match.find()) { + PluginLoader loader = fileAssociations.get(filter); + + result = loader.loadPlugin(file); + } + } + + if (result != null) { + plugins.add(result); + lookupNames.put(result.getDescription().getName().toLowerCase(), result); // Spigot + } + + return result; + } + + private void checkUpdate(File file) { + if (updateDirectory == null || !updateDirectory.isDirectory()) { + return; + } + + File updateFile = new File(updateDirectory, file.getName()); + if (updateFile.isFile() && FileUtil.copy(updateFile, file)) { + updateFile.delete(); + } + } + + /** + * Checks if the given plugin is loaded and returns it when applicable + *

+ * Please note that the name of the plugin is case-sensitive + * + * @param name Name of the plugin to check + * @return Plugin if it exists, otherwise null + */ + public synchronized Plugin getPlugin(String name) { + return lookupNames.get(name.replace(' ', '_').toLowerCase()); // Spigot + } + + public synchronized Plugin[] getPlugins() { + return plugins.toArray(new Plugin[0]); + } + + /** + * Checks if the given plugin is enabled or not + *

+ * Please note that the name of the plugin is case-sensitive. + * + * @param name Name of the plugin to check + * @return true if the plugin is enabled, otherwise false + */ + public boolean isPluginEnabled(String name) { + Plugin plugin = getPlugin(name); + + return isPluginEnabled(plugin); + } + + /** + * Checks if the given plugin is enabled or not + * + * @param plugin Plugin to check + * @return true if the plugin is enabled, otherwise false + */ + public boolean isPluginEnabled(Plugin plugin) { + if ((plugin != null) && (plugins.contains(plugin))) { + return plugin.isEnabled(); + } else { + return false; + } + } + + public void enablePlugin(final Plugin plugin) { + if (!plugin.isEnabled()) { + List pluginCommands = PluginCommandYamlParser.parse(plugin); + + if (!pluginCommands.isEmpty()) { + commandMap.registerAll(plugin.getDescription().getName(), pluginCommands); + } + + try { + plugin.getPluginLoader().enablePlugin(plugin); + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while enabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + + HandlerList.bakeAll(); + } + } + + public void disablePlugins() { + Plugin[] plugins = getPlugins(); + for (int i = plugins.length - 1; i >= 0; i--) { + disablePlugin(plugins[i]); + } + } + + public void disablePlugin(final Plugin plugin) { + if (plugin.isEnabled()) { + try { + plugin.getPluginLoader().disablePlugin(plugin); + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + + try { + server.getScheduler().cancelTasks(plugin); + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while cancelling tasks for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + + try { + server.getServicesManager().unregisterAll(plugin); + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering services for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + + try { + HandlerList.unregisterAll(plugin); + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering events for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + + try { + server.getMessenger().unregisterIncomingPluginChannel(plugin); + server.getMessenger().unregisterOutgoingPluginChannel(plugin); + } catch(Throwable ex) { + server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering plugin channels for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + } + } + + public void clearPlugins() { + synchronized (this) { + disablePlugins(); + plugins.clear(); + lookupNames.clear(); + HandlerList.unregisterAll(); + fileAssociations.clear(); + permissions.clear(); + defaultPerms.get(true).clear(); + defaultPerms.get(false).clear(); + } + } + + /** + * Calls an event with the given details. + *

+ * This method only synchronizes when the event is not asynchronous. + * + * @param event Event details + */ + public void callEvent(Event event) { + if (event.isAsynchronous()) { + if (Thread.holdsLock(this)) { + throw new IllegalStateException(event.getEventName() + " cannot be triggered asynchronously from inside synchronized code."); + } + if (server.isPrimaryThread()) { + throw new IllegalStateException(event.getEventName() + " cannot be triggered asynchronously from primary server thread."); + } + fireEvent(event); + } else { + synchronized (this) { + fireEvent(event); + } + } + } + + private void fireEvent(Event event) { + HandlerList handlers = event.getHandlers(); + RegisteredListener[] listeners = handlers.getRegisteredListeners(); + + for (RegisteredListener registration : listeners) { + if (!registration.getPlugin().isEnabled()) { + continue; + } + + try { + registration.callEvent(event); + } catch (AuthorNagException ex) { + Plugin plugin = registration.getPlugin(); + + if (plugin.isNaggable()) { + plugin.setNaggable(false); + + server.getLogger().log(Level.SEVERE, String.format( + "Nag author(s): '%s' of '%s' about the following: %s", + plugin.getDescription().getAuthors(), + plugin.getDescription().getFullName(), + ex.getMessage() + )); + } + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getFullName(), ex); + } + } + } + + public void registerEvents(Listener listener, Plugin plugin) { + if (!plugin.isEnabled()) { + throw new IllegalPluginAccessException("Plugin attempted to register " + listener + " while not enabled"); + } + + for (Map.Entry, Set> entry : plugin.getPluginLoader().createRegisteredListeners(listener, plugin).entrySet()) { + getEventListeners(getRegistrationClass(entry.getKey())).registerAll(entry.getValue()); + } + + } + + public void registerEvent(Class event, Listener listener, EventPriority priority, EventExecutor executor, Plugin plugin) { + registerEvent(event, listener, priority, executor, plugin, false); + } + + /** + * Registers the given event to the specified listener using a directly + * passed EventExecutor + * + * @param event Event class to register + * @param listener PlayerListener to register + * @param priority Priority of this event + * @param executor EventExecutor to register + * @param plugin Plugin to register + * @param ignoreCancelled Do not call executor if event was already + * cancelled + */ + public void registerEvent(Class event, Listener listener, EventPriority priority, EventExecutor executor, Plugin plugin, boolean ignoreCancelled) { + Validate.notNull(listener, "Listener cannot be null"); + Validate.notNull(priority, "Priority cannot be null"); + Validate.notNull(executor, "Executor cannot be null"); + Validate.notNull(plugin, "Plugin cannot be null"); + + if (!plugin.isEnabled()) { + throw new IllegalPluginAccessException("Plugin attempted to register " + event + " while not enabled"); + } + + executor = new co.aikar.timings.TimedEventExecutor(executor, plugin, null, event); // Spigot + if (false) { // Spigot - RL handles useTimings check now + getEventListeners(event).register(new TimedRegisteredListener(listener, executor, priority, plugin, ignoreCancelled)); + } else { + getEventListeners(event).register(new RegisteredListener(listener, executor, priority, plugin, ignoreCancelled)); + } + } + + private HandlerList getEventListeners(Class type) { + try { + Method method = getRegistrationClass(type).getDeclaredMethod("getHandlerList"); + method.setAccessible(true); + return (HandlerList) method.invoke(null); + } catch (Exception e) { + throw new IllegalPluginAccessException(e.toString()); + } + } + + private Class getRegistrationClass(Class clazz) { + try { + clazz.getDeclaredMethod("getHandlerList"); + return clazz; + } catch (NoSuchMethodException e) { + if (clazz.getSuperclass() != null + && !clazz.getSuperclass().equals(Event.class) + && Event.class.isAssignableFrom(clazz.getSuperclass())) { + return getRegistrationClass(clazz.getSuperclass().asSubclass(Event.class)); + } else { + throw new IllegalPluginAccessException("Unable to find handler list for event " + clazz.getName() + ". Static getHandlerList method required!"); + } + } + } + + public Permission getPermission(String name) { + return permissions.get(name.toLowerCase()); + } + + public void addPermission(Permission perm) { + String name = perm.getName().toLowerCase(); + + if (permissions.containsKey(name)) { + throw new IllegalArgumentException("The permission " + name + " is already defined!"); + } + + permissions.put(name, perm); + calculatePermissionDefault(perm); + } + + public Set getDefaultPermissions(boolean op) { + return ImmutableSet.copyOf(defaultPerms.get(op)); + } + + public void removePermission(Permission perm) { + removePermission(perm.getName()); + } + + public void removePermission(String name) { + permissions.remove(name.toLowerCase()); + } + + public void recalculatePermissionDefaults(Permission perm) { + if (perm != null && permissions.containsKey(perm.getName().toLowerCase())) { + defaultPerms.get(true).remove(perm); + defaultPerms.get(false).remove(perm); + + calculatePermissionDefault(perm); + } + } + + private void calculatePermissionDefault(Permission perm) { + if ((perm.getDefault() == PermissionDefault.OP) || (perm.getDefault() == PermissionDefault.TRUE)) { + defaultPerms.get(true).add(perm); + dirtyPermissibles(true); + } + if ((perm.getDefault() == PermissionDefault.NOT_OP) || (perm.getDefault() == PermissionDefault.TRUE)) { + defaultPerms.get(false).add(perm); + dirtyPermissibles(false); + } + } + + private void dirtyPermissibles(boolean op) { + Set permissibles = getDefaultPermSubscriptions(op); + + for (Permissible p : permissibles) { + p.recalculatePermissions(); + } + } + + public void subscribeToPermission(String permission, Permissible permissible) { + String name = permission.toLowerCase(); + Map map = permSubs.get(name); + + if (map == null) { + map = new WeakHashMap(); + permSubs.put(name, map); + } + + map.put(permissible, true); + } + + public void unsubscribeFromPermission(String permission, Permissible permissible) { + String name = permission.toLowerCase(); + Map map = permSubs.get(name); + + if (map != null) { + map.remove(permissible); + + if (map.isEmpty()) { + permSubs.remove(name); + } + } + } + + public Set getPermissionSubscriptions(String permission) { + String name = permission.toLowerCase(); + Map map = permSubs.get(name); + + if (map == null) { + return ImmutableSet.of(); + } else { + return ImmutableSet.copyOf(map.keySet()); + } + } + + public void subscribeToDefaultPerms(boolean op, Permissible permissible) { + Map map = defSubs.get(op); + + if (map == null) { + map = new WeakHashMap(); + defSubs.put(op, map); + } + + map.put(permissible, true); + } + + public void unsubscribeFromDefaultPerms(boolean op, Permissible permissible) { + Map map = defSubs.get(op); + + if (map != null) { + map.remove(permissible); + + if (map.isEmpty()) { + defSubs.remove(op); + } + } + } + + public Set getDefaultPermSubscriptions(boolean op) { + Map map = defSubs.get(op); + + if (map == null) { + return ImmutableSet.of(); + } else { + return ImmutableSet.copyOf(map.keySet()); + } + } + + public Set getPermissions() { + return new HashSet(permissions.values()); + } + + public boolean useTimings() { + return co.aikar.timings.Timings.isTimingsEnabled(); // Spigot + } + + /** + * Sets whether or not per event timing code should be used + * + * @param use True if per event timing code should be used + */ + public void useTimings(boolean use) { + co.aikar.timings.Timings.setTimingsEnabled(use); // Spigot + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/SimpleServicesManager.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/SimpleServicesManager.java new file mode 100644 index 0000000..4e17711 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/SimpleServicesManager.java @@ -0,0 +1,306 @@ +package org.bukkit.plugin; + +import org.bukkit.Bukkit; +import org.bukkit.event.server.ServiceRegisterEvent; +import org.bukkit.event.server.ServiceUnregisterEvent; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Set; + +/** + * A simple services manager. + */ +public class SimpleServicesManager implements ServicesManager { + + /** + * Map of providers. + */ + private final Map, List>> providers = new HashMap, List>>(); + + /** + * Register a provider of a service. + * + * @param Provider + * @param service service class + * @param provider provider to register + * @param plugin plugin with the provider + * @param priority priority of the provider + */ + public void register(Class service, T provider, Plugin plugin, ServicePriority priority) { + RegisteredServiceProvider registeredProvider = null; + synchronized (providers) { + List> registered = providers.get(service); + if (registered == null) { + registered = new ArrayList>(); + providers.put(service, registered); + } + + registeredProvider = new RegisteredServiceProvider(service, provider, priority, plugin); + + // Insert the provider into the collection, much more efficient big O than sort + int position = Collections.binarySearch(registered, registeredProvider); + if (position < 0) { + registered.add(-(position + 1), registeredProvider); + } else { + registered.add(position, registeredProvider); + } + + } + Bukkit.getServer().getPluginManager().callEvent(new ServiceRegisterEvent(registeredProvider)); + } + + /** + * Unregister all the providers registered by a particular plugin. + * + * @param plugin The plugin + */ + public void unregisterAll(Plugin plugin) { + ArrayList unregisteredEvents = new ArrayList(); + synchronized (providers) { + Iterator, List>>> it = providers.entrySet().iterator(); + + try { + while (it.hasNext()) { + Map.Entry, List>> entry = it.next(); + Iterator> it2 = entry.getValue().iterator(); + + try { + // Removed entries that are from this plugin + + while (it2.hasNext()) { + RegisteredServiceProvider registered = it2.next(); + + if (registered.getPlugin().equals(plugin)) { + it2.remove(); + unregisteredEvents.add(new ServiceUnregisterEvent(registered)); + } + } + } catch (NoSuchElementException e) { // Why does Java suck + } + + // Get rid of the empty list + if (entry.getValue().size() == 0) { + it.remove(); + } + } + } catch (NoSuchElementException e) {} + } + for (ServiceUnregisterEvent event : unregisteredEvents) { + Bukkit.getServer().getPluginManager().callEvent(event); + } + } + + /** + * Unregister a particular provider for a particular service. + * + * @param service The service interface + * @param provider The service provider implementation + */ + public void unregister(Class service, Object provider) { + ArrayList unregisteredEvents = new ArrayList(); + synchronized (providers) { + Iterator, List>>> it = providers.entrySet().iterator(); + + try { + while (it.hasNext()) { + Map.Entry, List>> entry = it.next(); + + // We want a particular service + if (entry.getKey() != service) { + continue; + } + + Iterator> it2 = entry.getValue().iterator(); + + try { + // Removed entries that are from this plugin + + while (it2.hasNext()) { + RegisteredServiceProvider registered = it2.next(); + + if (registered.getProvider() == provider) { + it2.remove(); + unregisteredEvents.add(new ServiceUnregisterEvent(registered)); + } + } + } catch (NoSuchElementException e) { // Why does Java suck + } + + // Get rid of the empty list + if (entry.getValue().size() == 0) { + it.remove(); + } + } + } catch (NoSuchElementException e) {} + } + for (ServiceUnregisterEvent event : unregisteredEvents) { + Bukkit.getServer().getPluginManager().callEvent(event); + } + } + + /** + * Unregister a particular provider. + * + * @param provider The service provider implementation + */ + public void unregister(Object provider) { + ArrayList unregisteredEvents = new ArrayList(); + synchronized (providers) { + Iterator, List>>> it = providers.entrySet().iterator(); + + try { + while (it.hasNext()) { + Map.Entry, List>> entry = it.next(); + Iterator> it2 = entry.getValue().iterator(); + + try { + // Removed entries that are from this plugin + + while (it2.hasNext()) { + RegisteredServiceProvider registered = it2.next(); + + if (registered.getProvider().equals(provider)) { + it2.remove(); + unregisteredEvents.add(new ServiceUnregisterEvent(registered)); + } + } + } catch (NoSuchElementException e) { // Why does Java suck + } + + // Get rid of the empty list + if (entry.getValue().size() == 0) { + it.remove(); + } + } + } catch (NoSuchElementException e) {} + } + for (ServiceUnregisterEvent event : unregisteredEvents) { + Bukkit.getServer().getPluginManager().callEvent(event); + } + } + + /** + * Queries for a provider. This may return if no provider has been + * registered for a service. The highest priority provider is returned. + * + * @param The service interface + * @param service The service interface + * @return provider or null + */ + public T load(Class service) { + synchronized (providers) { + List> registered = providers.get(service); + + if (registered == null) { + return null; + } + + // This should not be null! + return service.cast(registered.get(0).getProvider()); + } + } + + /** + * Queries for a provider registration. This may return if no provider + * has been registered for a service. + * + * @param The service interface + * @param service The service interface + * @return provider registration or null + */ + @SuppressWarnings("unchecked") + public RegisteredServiceProvider getRegistration(Class service) { + synchronized (providers) { + List> registered = providers.get(service); + + if (registered == null) { + return null; + } + + // This should not be null! + return (RegisteredServiceProvider) registered.get(0); + } + } + + /** + * Get registrations of providers for a plugin. + * + * @param plugin The plugin + * @return provider registration or null + */ + public List> getRegistrations(Plugin plugin) { + ImmutableList.Builder> ret = ImmutableList.>builder(); + synchronized (providers) { + for (List> registered : providers.values()) { + for (RegisteredServiceProvider provider : registered) { + if (provider.getPlugin().equals(plugin)) { + ret.add(provider); + } + } + } + } + return ret.build(); + } + + /** + * Get registrations of providers for a service. The returned list is + * an unmodifiable copy. + * + * @param The service interface + * @param service The service interface + * @return a copy of the list of registrations + */ + @SuppressWarnings("unchecked") + public List> getRegistrations(Class service) { + ImmutableList.Builder> ret; + synchronized (providers) { + List> registered = providers.get(service); + + if (registered == null) { + return ImmutableList.>of(); + } + + ret = ImmutableList.>builder(); + + for (RegisteredServiceProvider provider : registered) { + ret.add((RegisteredServiceProvider) provider); + } + + } + return ret.build(); + } + + /** + * Get a list of known services. A service is known if it has registered + * providers for it. + * + * @return a copy of the set of known services + */ + public Set> getKnownServices() { + synchronized (providers) { + return ImmutableSet.>copyOf(providers.keySet()); + } + } + + /** + * Returns whether a provider has been registered for a service. + * + * @param service + * @param service service to check + * @return true if and only if there are registered providers + */ + public boolean isProvidedFor(Class service) { + synchronized (providers) { + return providers.containsKey(service); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java new file mode 100644 index 0000000..164be93 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java @@ -0,0 +1,97 @@ +package org.bukkit.plugin; + +import org.bukkit.event.Event; +import org.bukkit.event.EventException; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +/** + * Extends RegisteredListener to include timing information + */ +public class TimedRegisteredListener extends RegisteredListener { + private int count; + private long totalTime; + private Class eventClass; + private boolean multiple = false; + + public TimedRegisteredListener(final Listener pluginListener, final EventExecutor eventExecutor, final EventPriority eventPriority, final Plugin registeredPlugin, final boolean listenCancelled) { + super(pluginListener, eventExecutor, eventPriority, registeredPlugin, listenCancelled); + } + + @Override + public void callEvent(Event event) throws EventException { + if (event.isAsynchronous()) { + super.callEvent(event); + return; + } + count++; + Class newEventClass = event.getClass(); + if (this.eventClass == null) { + this.eventClass = newEventClass; + } else if (!this.eventClass.equals(newEventClass)) { + multiple = true; + this.eventClass = getCommonSuperclass(newEventClass, this.eventClass).asSubclass(Event.class); + } + long start = System.nanoTime(); + super.callEvent(event); + totalTime += System.nanoTime() - start; + } + + private static Class getCommonSuperclass(Class class1, Class class2) { + while (!class1.isAssignableFrom(class2)) { + class1 = class1.getSuperclass(); + } + return class1; + } + + /** + * Resets the call count and total time for this listener + */ + public void reset() { + count = 0; + totalTime = 0; + } + + /** + * Gets the total times this listener has been called + * + * @return Times this listener has been called + */ + public int getCount() { + return count; + } + + /** + * Gets the total time calls to this listener have taken + * + * @return Total time for all calls of this listener + */ + public long getTotalTime() { + return totalTime; + } + + /** + * Gets the class of the events this listener handled. If it handled + * multiple classes of event, the closest shared superclass will be + * returned, such that for any event this listener has handled, + * this.getEventClass().isAssignableFrom(event.getClass()) + * and no class this.getEventClass().isAssignableFrom(clazz) + * {@literal && this.getEventClass() != clazz &&} + * event.getClass().isAssignableFrom(clazz) for all handled events. + * + * @return the event class handled by this RegisteredListener + */ + public Class getEventClass() { + return eventClass; + } + + /** + * Gets whether this listener has handled multiple events, such that for + * some two events, eventA.getClass() != eventB.getClass(). + * + * @return true if this listener has handled multiple events + */ + public boolean hasMultiple() { + return multiple; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/UnknownDependencyException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/UnknownDependencyException.java new file mode 100644 index 0000000..a80251e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/UnknownDependencyException.java @@ -0,0 +1,46 @@ +package org.bukkit.plugin; + +/** + * Thrown when attempting to load an invalid Plugin file + */ +public class UnknownDependencyException extends RuntimeException { + + private static final long serialVersionUID = 5721389371901775895L; + + /** + * Constructs a new UnknownDependencyException based on the given + * Exception + * + * @param throwable Exception that triggered this Exception + */ + public UnknownDependencyException(final Throwable throwable) { + super(throwable); + } + + /** + * Constructs a new UnknownDependencyException with the given message + * + * @param message Brief message explaining the cause of the exception + */ + public UnknownDependencyException(final String message) { + super(message); + } + + /** + * Constructs a new UnknownDependencyException based on the given + * Exception + * + * @param message Brief message explaining the cause of the exception + * @param throwable Exception that triggered this Exception + */ + public UnknownDependencyException(final Throwable throwable, final String message) { + super(message, throwable); + } + + /** + * Constructs a new UnknownDependencyException + */ + public UnknownDependencyException() { + + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/JavaPlugin.java new file mode 100644 index 0000000..c961b18 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/JavaPlugin.java @@ -0,0 +1,560 @@ +package org.bukkit.plugin.java; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.lang.Validate; +import org.bukkit.Server; +import org.bukkit.Warning.WarningState; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.plugin.AuthorNagException; +import org.bukkit.plugin.PluginAwareness; +import org.bukkit.plugin.PluginBase; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginLoader; +import org.bukkit.plugin.PluginLogger; + +import com.avaje.ebean.EbeanServer; +import com.avaje.ebean.EbeanServerFactory; +import com.avaje.ebean.config.DataSourceConfig; +import com.avaje.ebean.config.ServerConfig; +import com.avaje.ebeaninternal.api.SpiEbeanServer; +import com.avaje.ebeaninternal.server.ddl.DdlGenerator; +import com.google.common.base.Charsets; +import com.google.common.io.ByteStreams; + +/** + * Represents a Java plugin + */ +public abstract class JavaPlugin extends PluginBase { + private boolean isEnabled = false; + private PluginLoader loader = null; + private Server server = null; + private File file = null; + private PluginDescriptionFile description = null; + private File dataFolder = null; + private ClassLoader classLoader = null; + private boolean naggable = true; + private EbeanServer ebean = null; + private FileConfiguration newConfig = null; + private File configFile = null; + private PluginLogger logger = null; + + public JavaPlugin() { + final ClassLoader classLoader = this.getClass().getClassLoader(); + if (!(classLoader instanceof PluginClassLoader)) { + throw new IllegalStateException("JavaPlugin requires " + PluginClassLoader.class.getName()); + } + ((PluginClassLoader) classLoader).initialize(this); + } + + /** + * @deprecated This method is intended for unit testing purposes when the + * other {@linkplain #JavaPlugin(JavaPluginLoader, + * PluginDescriptionFile, File, File) constructor} cannot be used. + *

+ * Its existence may be temporary. + * @param loader the plugin loader + * @param server the server instance + * @param description the plugin's description + * @param dataFolder the plugin's data folder + * @param file the location of the plugin + */ + @Deprecated + protected JavaPlugin(final PluginLoader loader, final Server server, final PluginDescriptionFile description, final File dataFolder, final File file) { + final ClassLoader classLoader = this.getClass().getClassLoader(); + if (classLoader instanceof PluginClassLoader) { + throw new IllegalStateException("Cannot use initialization constructor at runtime"); + } + init(loader, server, description, dataFolder, file, classLoader); + } + + protected JavaPlugin(final JavaPluginLoader loader, final PluginDescriptionFile description, final File dataFolder, final File file) { + final ClassLoader classLoader = this.getClass().getClassLoader(); + if (classLoader instanceof PluginClassLoader) { + throw new IllegalStateException("Cannot use initialization constructor at runtime"); + } + init(loader, loader.server, description, dataFolder, file, classLoader); + } + + /** + * Returns the folder that the plugin data's files are located in. The + * folder may not yet exist. + * + * @return The folder. + */ + @Override + public final File getDataFolder() { + return dataFolder; + } + + /** + * Gets the associated PluginLoader responsible for this plugin + * + * @return PluginLoader that controls this plugin + */ + @Override + public final PluginLoader getPluginLoader() { + return loader; + } + + /** + * Returns the Server instance currently running this plugin + * + * @return Server running this plugin + */ + @Override + public final Server getServer() { + return server; + } + + /** + * Returns a value indicating whether or not this plugin is currently + * enabled + * + * @return true if this plugin is enabled, otherwise false + */ + @Override + public final boolean isEnabled() { + return isEnabled; + } + + /** + * Returns the file which contains this plugin + * + * @return File containing this plugin + */ + protected File getFile() { + return file; + } + + /** + * Returns the plugin.yaml file containing the details for this plugin + * + * @return Contents of the plugin.yaml file + */ + @Override + public final PluginDescriptionFile getDescription() { + return description; + } + + @Override + public FileConfiguration getConfig() { + if (newConfig == null) { + reloadConfig(); + } + return newConfig; + } + + /** + * Provides a reader for a text file located inside the jar. The behavior + * of this method adheres to {@link PluginAwareness.Flags#UTF8}, or if not + * defined, uses UTF8 if {@link FileConfiguration#UTF8_OVERRIDE} is + * specified, or system default otherwise. + * + * @param file the filename of the resource to load + * @return null if {@link #getResource(String)} returns null + * @throws IllegalArgumentException if file is null + * @see ClassLoader#getResourceAsStream(String) + */ + @SuppressWarnings("deprecation") + protected final Reader getTextResource(String file) { + final InputStream in = getResource(file); + + return in == null ? null : new InputStreamReader(in, isStrictlyUTF8() || FileConfiguration.UTF8_OVERRIDE ? Charsets.UTF_8 : Charset.defaultCharset()); + } + + @SuppressWarnings("deprecation") + @Override + public void reloadConfig() { + newConfig = YamlConfiguration.loadConfiguration(configFile); + + final InputStream defConfigStream = getResource("config.yml"); + if (defConfigStream == null) { + return; + } + + final YamlConfiguration defConfig; + if (isStrictlyUTF8() || FileConfiguration.UTF8_OVERRIDE) { + defConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(defConfigStream, Charsets.UTF_8)); + } else { + final byte[] contents; + defConfig = new YamlConfiguration(); + try { + contents = ByteStreams.toByteArray(defConfigStream); + } catch (final IOException e) { + getLogger().log(Level.SEVERE, "Unexpected failure reading config.yml", e); + return; + } + + final String text = new String(contents, Charset.defaultCharset()); + if (!text.equals(new String(contents, Charsets.UTF_8))) { + getLogger().warning("Default system encoding may have misread config.yml from plugin jar"); + } + + try { + defConfig.loadFromString(text); + } catch (final InvalidConfigurationException e) { + getLogger().log(Level.SEVERE, "Cannot load configuration from jar", e); + } + } + + newConfig.setDefaults(defConfig); + } + + private boolean isStrictlyUTF8() { + return getDescription().getAwareness().contains(PluginAwareness.Flags.UTF8); + } + + @Override + public void saveConfig() { + try { + getConfig().save(configFile); + } catch (IOException ex) { + logger.log(Level.SEVERE, "Could not save config to " + configFile, ex); + } + } + + @Override + public void saveDefaultConfig() { + if (!configFile.exists()) { + saveResource("config.yml", false); + } + } + + @Override + public void saveResource(String resourcePath, boolean replace) { + if (resourcePath == null || resourcePath.equals("")) { + throw new IllegalArgumentException("ResourcePath cannot be null or empty"); + } + + resourcePath = resourcePath.replace('\\', '/'); + InputStream in = getResource(resourcePath); + if (in == null) { + throw new IllegalArgumentException("The embedded resource '" + resourcePath + "' cannot be found in " + file); + } + + File outFile = new File(dataFolder, resourcePath); + int lastIndex = resourcePath.lastIndexOf('/'); + File outDir = new File(dataFolder, resourcePath.substring(0, lastIndex >= 0 ? lastIndex : 0)); + + if (!outDir.exists()) { + outDir.mkdirs(); + } + + try { + if (!outFile.exists() || replace) { + OutputStream out = new FileOutputStream(outFile); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + out.close(); + in.close(); + } else { + logger.log(Level.WARNING, "Could not save " + outFile.getName() + " to " + outFile + " because " + outFile.getName() + " already exists."); + } + } catch (IOException ex) { + logger.log(Level.SEVERE, "Could not save " + outFile.getName() + " to " + outFile, ex); + } + } + + @Override + public InputStream getResource(String filename) { + if (filename == null) { + throw new IllegalArgumentException("Filename cannot be null"); + } + + try { + URL url = getClassLoader().getResource(filename); + + if (url == null) { + return null; + } + + URLConnection connection = url.openConnection(); + connection.setUseCaches(false); + return connection.getInputStream(); + } catch (IOException ex) { + return null; + } + } + + /** + * Returns the ClassLoader which holds this plugin + * + * @return ClassLoader holding this plugin + */ + protected final ClassLoader getClassLoader() { + return classLoader; + } + + /** + * Sets the enabled state of this plugin + * + * @param enabled true if enabled, otherwise false + */ + protected final void setEnabled(final boolean enabled) { + if (isEnabled != enabled) { + isEnabled = enabled; + + if (isEnabled) { + onEnable(); + } else { + onDisable(); + } + } + } + + /** + * @param loader the plugin loader + * @param server the server instance + * @param description the plugin's description + * @param dataFolder the plugin's data folder + * @param file the location of the plugin + * @param classLoader the class loader + * @deprecated This method is legacy and will be removed - it must be + * replaced by the specially provided constructor(s). + */ + @Deprecated + protected final void initialize(PluginLoader loader, Server server, PluginDescriptionFile description, File dataFolder, File file, ClassLoader classLoader) { + if (server.getWarningState() == WarningState.OFF) { + return; + } + getLogger().log(Level.WARNING, getClass().getName() + " is already initialized", server.getWarningState() == WarningState.DEFAULT ? null : new AuthorNagException("Explicit initialization")); + } + + final void init(PluginLoader loader, Server server, PluginDescriptionFile description, File dataFolder, File file, ClassLoader classLoader) { + this.loader = loader; + this.server = server; + this.file = file; + this.description = description; + this.dataFolder = dataFolder; + this.classLoader = classLoader; + this.configFile = new File(dataFolder, "config.yml"); + this.logger = new PluginLogger(this); + + if (description.isDatabaseEnabled()) { + ServerConfig db = new ServerConfig(); + + db.setDefaultServer(false); + db.setRegister(false); + db.setClasses(getDatabaseClasses()); + db.setName(description.getName()); + server.configureDbConfig(db); + + DataSourceConfig ds = db.getDataSourceConfig(); + + ds.setUrl(replaceDatabaseString(ds.getUrl())); + dataFolder.mkdirs(); + + ClassLoader previous = Thread.currentThread().getContextClassLoader(); + + Thread.currentThread().setContextClassLoader(classLoader); + ebean = EbeanServerFactory.create(db); + Thread.currentThread().setContextClassLoader(previous); + } + } + + /** + * Provides a list of all classes that should be persisted in the database + * + * @return List of Classes that are Ebeans + */ + public List> getDatabaseClasses() { + return new ArrayList>(); + } + + private String replaceDatabaseString(String input) { + input = input.replaceAll("\\{DIR\\}", dataFolder.getPath().replaceAll("\\\\", "/") + "/"); + input = input.replaceAll("\\{NAME\\}", description.getName().replaceAll("[^\\w_-]", "")); + return input; + } + + /** + * Gets the initialization status of this plugin + * + * @return true if this plugin is initialized, otherwise false + * @deprecated This method cannot return false, as {@link + * JavaPlugin} is now initialized in the constructor. + */ + @Deprecated + public final boolean isInitialized() { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + return null; + } + + /** + * Gets the command with the given name, specific to this plugin. Commands + * need to be registered in the {@link PluginDescriptionFile#getCommands() + * PluginDescriptionFile} to exist at runtime. + * + * @param name name or alias of the command + * @return the plugin command if found, otherwise null + */ + public PluginCommand getCommand(String name) { + String alias = name.toLowerCase(); + PluginCommand command = getServer().getPluginCommand(alias); + + if (command == null || command.getPlugin() != this) { + command = getServer().getPluginCommand(description.getName().toLowerCase() + ":" + alias); + } + + if (command != null && command.getPlugin() == this) { + return command; + } else { + return null; + } + } + + @Override + public void onLoad() {} + + @Override + public void onDisable() {} + + @Override + public void onEnable() {} + + @Override + public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { + return null; + } + + @Override + public final boolean isNaggable() { + return naggable; + } + + @Override + public final void setNaggable(boolean canNag) { + this.naggable = canNag; + } + + @Override + public EbeanServer getDatabase() { + return ebean; + } + + protected void installDDL() { + SpiEbeanServer serv = (SpiEbeanServer) getDatabase(); + DdlGenerator gen = serv.getDdlGenerator(); + + gen.runScript(false, gen.generateCreateDdl()); + } + + protected void removeDDL() { + SpiEbeanServer serv = (SpiEbeanServer) getDatabase(); + DdlGenerator gen = serv.getDdlGenerator(); + + gen.runScript(true, gen.generateDropDdl()); + } + + @Override + public final Logger getLogger() { + return logger; + } + + @Override + public String toString() { + return description.getFullName(); + } + + /** + * This method provides fast access to the plugin that has {@link + * #getProvidingPlugin(Class) provided} the given plugin class, which is + * usually the plugin that implemented it. + *

+ * An exception to this would be if plugin's jar that contained the class + * does not extend the class, where the intended plugin would have + * resided in a different jar / classloader. + * + * @param a class that extends JavaPlugin + * @param clazz the class desired + * @return the plugin that provides and implements said class + * @throws IllegalArgumentException if clazz is null + * @throws IllegalArgumentException if clazz does not extend {@link + * JavaPlugin} + * @throws IllegalStateException if clazz was not provided by a plugin, + * for example, if called with + * JavaPlugin.getPlugin(JavaPlugin.class) + * @throws IllegalStateException if called from the static initializer for + * given JavaPlugin + * @throws ClassCastException if plugin that provided the class does not + * extend the class + */ + public static T getPlugin(Class clazz) { + Validate.notNull(clazz, "Null class cannot have a plugin"); + if (!JavaPlugin.class.isAssignableFrom(clazz)) { + throw new IllegalArgumentException(clazz + " does not extend " + JavaPlugin.class); + } + final ClassLoader cl = clazz.getClassLoader(); + if (!(cl instanceof PluginClassLoader)) { + throw new IllegalArgumentException(clazz + " is not initialized by " + PluginClassLoader.class); + } + JavaPlugin plugin = ((PluginClassLoader) cl).plugin; + if (plugin == null) { + throw new IllegalStateException("Cannot get plugin for " + clazz + " from a static initializer"); + } + return clazz.cast(plugin); + } + + /** + * This method provides fast access to the plugin that has provided the + * given class. + * + * @param clazz a class belonging to a plugin + * @return the plugin that provided the class + * @throws IllegalArgumentException if the class is not provided by a + * JavaPlugin + * @throws IllegalArgumentException if class is null + * @throws IllegalStateException if called from the static initializer for + * given JavaPlugin + */ + public static JavaPlugin getProvidingPlugin(Class clazz) { + Validate.notNull(clazz, "Null class cannot have a plugin"); + final ClassLoader cl = clazz.getClassLoader(); + if (!(cl instanceof PluginClassLoader)) { + throw new IllegalArgumentException(clazz + " is not provided by " + PluginClassLoader.class); + } + JavaPlugin plugin = ((PluginClassLoader) cl).plugin; + if (plugin == null) { + throw new IllegalStateException("Cannot get plugin for " + clazz + " from a static initializer"); + } + return plugin; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java new file mode 100644 index 0000000..b057b05 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -0,0 +1,377 @@ +package org.bukkit.plugin.java; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.logging.Level; +import java.util.regex.Pattern; + +import org.apache.commons.lang.Validate; +import org.bukkit.Server; +import org.bukkit.Warning; +import org.bukkit.Warning.WarningState; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.event.Event; +import org.bukkit.event.EventException; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.plugin.AuthorNagException; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.InvalidDescriptionException; +import org.bukkit.plugin.InvalidPluginException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginLoader; +import org.bukkit.plugin.RegisteredListener; +import org.bukkit.plugin.TimedRegisteredListener; +import org.bukkit.plugin.UnknownDependencyException; +import org.yaml.snakeyaml.error.YAMLException; + +/** + * Represents a Java plugin loader, allowing plugins in the form of .jar + */ +public final class JavaPluginLoader implements PluginLoader { + final Server server; + private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), }; + private final Map> classes = new java.util.concurrent.ConcurrentHashMap>(); // Spigot + private final Map loaders = new LinkedHashMap(); + + /** + * This class was not meant to be constructed explicitly + * + * @param instance the server instance + */ + @Deprecated + public JavaPluginLoader(Server instance) { + Validate.notNull(instance, "Server cannot be null"); + server = instance; + } + + public Plugin loadPlugin(final File file) throws InvalidPluginException { + Validate.notNull(file, "File cannot be null"); + + if (!file.exists()) { + throw new InvalidPluginException(new FileNotFoundException(file.getPath() + " does not exist")); + } + + final PluginDescriptionFile description; + try { + description = getPluginDescription(file); + } catch (InvalidDescriptionException ex) { + throw new InvalidPluginException(ex); + } + + final File parentFile = file.getParentFile(); + final File dataFolder = new File(parentFile, description.getName()); + @SuppressWarnings("deprecation") + final File oldDataFolder = new File(parentFile, description.getRawName()); + + // Found old data folder + if (dataFolder.equals(oldDataFolder)) { + // They are equal -- nothing needs to be done! + } else if (dataFolder.isDirectory() && oldDataFolder.isDirectory()) { + server.getLogger().warning(String.format( + "While loading %s (%s) found old-data folder: `%s' next to the new one `%s'", + description.getFullName(), + file, + oldDataFolder, + dataFolder + )); + } else if (oldDataFolder.isDirectory() && !dataFolder.exists()) { + if (!oldDataFolder.renameTo(dataFolder)) { + throw new InvalidPluginException("Unable to rename old data folder: `" + oldDataFolder + "' to: `" + dataFolder + "'"); + } + server.getLogger().log(Level.INFO, String.format( + "While loading %s (%s) renamed data folder: `%s' to `%s'", + description.getFullName(), + file, + oldDataFolder, + dataFolder + )); + } + + if (dataFolder.exists() && !dataFolder.isDirectory()) { + throw new InvalidPluginException(String.format( + "Projected datafolder: `%s' for %s (%s) exists and is not a directory", + dataFolder, + description.getFullName(), + file + )); + } + + for (final String pluginName : description.getDepend()) { + if (loaders == null) { + throw new UnknownDependencyException(pluginName); + } + PluginClassLoader current = loaders.get(pluginName); + + if (current == null) { + throw new UnknownDependencyException(pluginName); + } + } + + final PluginClassLoader loader; + try { + loader = new PluginClassLoader(this, getClass().getClassLoader(), description, dataFolder, file); + } catch (InvalidPluginException ex) { + throw ex; + } catch (Throwable ex) { + throw new InvalidPluginException(ex); + } + + loaders.put(description.getName(), loader); + + return loader.plugin; + } + + public PluginDescriptionFile getPluginDescription(File file) throws InvalidDescriptionException { + Validate.notNull(file, "File cannot be null"); + + JarFile jar = null; + InputStream stream = null; + + try { + jar = new JarFile(file); + JarEntry entry = jar.getJarEntry("plugin.yml"); + + if (entry == null) { + throw new InvalidDescriptionException(new FileNotFoundException("Jar does not contain plugin.yml")); + } + + stream = jar.getInputStream(entry); + + return new PluginDescriptionFile(stream); + + } catch (IOException ex) { + throw new InvalidDescriptionException(ex); + } catch (YAMLException ex) { + throw new InvalidDescriptionException(ex); + } finally { + if (jar != null) { + try { + jar.close(); + } catch (IOException e) { + } + } + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + } + } + } + } + + public Pattern[] getPluginFileFilters() { + return fileFilters.clone(); + } + + Class getClassByName(final String name) { + Class cachedClass = classes.get(name); + + if (cachedClass != null) { + return cachedClass; + } else { + for (String current : loaders.keySet()) { + PluginClassLoader loader = loaders.get(current); + + try { + cachedClass = loader.findClass(name, false); + } catch (ClassNotFoundException cnfe) {} + if (cachedClass != null) { + return cachedClass; + } + } + } + return null; + } + + void setClass(final String name, final Class clazz) { + if (!classes.containsKey(name)) { + classes.put(name, clazz); + + if (ConfigurationSerializable.class.isAssignableFrom(clazz)) { + Class serializable = clazz.asSubclass(ConfigurationSerializable.class); + ConfigurationSerialization.registerClass(serializable); + } + } + } + + private void removeClass(String name) { + Class clazz = classes.remove(name); + + try { + if ((clazz != null) && (ConfigurationSerializable.class.isAssignableFrom(clazz))) { + Class serializable = clazz.asSubclass(ConfigurationSerializable.class); + ConfigurationSerialization.unregisterClass(serializable); + } + } catch (NullPointerException ex) { + // Boggle! + // (Native methods throwing NPEs is not fun when you can't stop it before-hand) + } + } + + public Map, Set> createRegisteredListeners(Listener listener, final Plugin plugin) { + Validate.notNull(plugin, "Plugin can not be null"); + Validate.notNull(listener, "Listener can not be null"); + + boolean useTimings = server.getPluginManager().useTimings(); + Map, Set> ret = new HashMap, Set>(); + Set methods; + try { + Method[] publicMethods = listener.getClass().getMethods(); + Method[] privateMethods = listener.getClass().getDeclaredMethods(); + methods = new HashSet(publicMethods.length + privateMethods.length, 1.0f); + for (Method method : publicMethods) { + methods.add(method); + } + for (Method method : privateMethods) { + methods.add(method); + } + } catch (NoClassDefFoundError e) { + plugin.getLogger().severe("Plugin " + plugin.getDescription().getFullName() + " has failed to register events for " + listener.getClass() + " because " + e.getMessage() + " does not exist."); + return ret; + } + + for (final Method method : methods) { + final EventHandler eh = method.getAnnotation(EventHandler.class); + if (eh == null) continue; + // Do not register bridge or synthetic methods to avoid event duplication + // Fixes SPIGOT-893 + if (method.isBridge() || method.isSynthetic()) { + continue; + } + final Class checkClass; + if (method.getParameterTypes().length != 1 || !Event.class.isAssignableFrom(checkClass = method.getParameterTypes()[0])) { + plugin.getLogger().severe(plugin.getDescription().getFullName() + " attempted to register an invalid EventHandler method signature \"" + method.toGenericString() + "\" in " + listener.getClass()); + continue; + } + final Class eventClass = checkClass.asSubclass(Event.class); + method.setAccessible(true); + Set eventSet = ret.get(eventClass); + if (eventSet == null) { + eventSet = new HashSet(); + ret.put(eventClass, eventSet); + } + + for (Class clazz = eventClass; Event.class.isAssignableFrom(clazz); clazz = clazz.getSuperclass()) { + // This loop checks for extending deprecated events + if (clazz.getAnnotation(Deprecated.class) != null) { + Warning warning = clazz.getAnnotation(Warning.class); + WarningState warningState = server.getWarningState(); + if (!warningState.printFor(warning)) { + break; + } + plugin.getLogger().log( + Level.WARNING, + String.format( + "\"%s\" has registered a listener for %s on method \"%s\", but the event is Deprecated." + + " \"%s\"; please notify the authors %s.", + plugin.getDescription().getFullName(), + clazz.getName(), + method.toGenericString(), + (warning != null && warning.reason().length() != 0) ? warning.reason() : "Server performance will be affected", + Arrays.toString(plugin.getDescription().getAuthors().toArray())), + warningState == WarningState.ON ? new AuthorNagException(null) : null); + break; + } + } + + EventExecutor executor = new co.aikar.timings.TimedEventExecutor(new EventExecutor() { // Spigot + public void execute(Listener listener, Event event) throws EventException { + try { + if (!eventClass.isAssignableFrom(event.getClass())) { + return; + } + method.invoke(listener, event); + } catch (InvocationTargetException ex) { + throw new EventException(ex.getCause()); + } catch (Throwable t) { + throw new EventException(t); + } + } + }, plugin, method, eventClass); // Spigot + if (false) { // Spigot - RL handles useTimings check now + eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); + } else { + eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); + } + } + return ret; + } + + public void enablePlugin(final Plugin plugin) { + Validate.isTrue(plugin instanceof JavaPlugin, "Plugin is not associated with this PluginLoader"); + + if (!plugin.isEnabled()) { + plugin.getLogger().info("Enabling " + plugin.getDescription().getFullName()); + + JavaPlugin jPlugin = (JavaPlugin) plugin; + + String pluginName = jPlugin.getDescription().getName(); + + if (!loaders.containsKey(pluginName)) { + loaders.put(pluginName, (PluginClassLoader) jPlugin.getClassLoader()); + } + + try { + jPlugin.setEnabled(true); + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Error occurred while enabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + // PaperSpigot start - Disable plugins that fail to load + disablePlugin(jPlugin); + return; + // PaperSpigot end + } + + // Perhaps abort here, rather than continue going, but as it stands, + // an abort is not possible the way it's currently written + server.getPluginManager().callEvent(new PluginEnableEvent(plugin)); + } + } + + public void disablePlugin(Plugin plugin) { + Validate.isTrue(plugin instanceof JavaPlugin, "Plugin is not associated with this PluginLoader"); + + if (plugin.isEnabled()) { + String message = String.format("Disabling %s", plugin.getDescription().getFullName()); + plugin.getLogger().info(message); + + server.getPluginManager().callEvent(new PluginDisableEvent(plugin)); + + JavaPlugin jPlugin = (JavaPlugin) plugin; + ClassLoader cloader = jPlugin.getClassLoader(); + + try { + jPlugin.setEnabled(false); + } catch (Throwable ex) { + server.getLogger().log(Level.SEVERE, "Error occurred while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + + loaders.remove(jPlugin.getDescription().getName()); + + if (cloader instanceof PluginClassLoader) { + PluginClassLoader loader = (PluginClassLoader) cloader; + Set names = loader.getClasses(); + + for (String name : names) { + removeClass(name); + } + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java new file mode 100644 index 0000000..b2cbf9e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -0,0 +1,131 @@ +package org.bukkit.plugin.java; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.Validate; +import org.bukkit.plugin.InvalidPluginException; +import org.bukkit.plugin.PluginDescriptionFile; + +/** + * A ClassLoader for plugins, to allow shared classes across multiple plugins + */ +public final class PluginClassLoader extends URLClassLoader { // Spigot + public JavaPlugin getPlugin() { return plugin; } // Spigot + private final JavaPluginLoader loader; + private final Map> classes = new java.util.concurrent.ConcurrentHashMap>(); // Spigot + private final PluginDescriptionFile description; + private final File dataFolder; + private final File file; + final JavaPlugin plugin; + private JavaPlugin pluginInit; + private IllegalStateException pluginState; + + // Spigot Start + static + { + try + { + java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod( "registerAsParallelCapable" ); + if ( method != null ) + { + boolean oldAccessible = method.isAccessible(); + method.setAccessible( true ); + method.invoke( null ); + method.setAccessible( oldAccessible ); + org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.INFO, "Set PluginClassLoader as parallel capable" ); + } + } catch ( NoSuchMethodException ex ) + { + // Ignore + } catch ( Exception ex ) + { + org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.WARNING, "Error setting PluginClassLoader as parallel capable", ex ); + } + } + // Spigot End + + PluginClassLoader(final JavaPluginLoader loader, final ClassLoader parent, final PluginDescriptionFile description, final File dataFolder, final File file) throws InvalidPluginException, MalformedURLException { + super(new URL[] {file.toURI().toURL()}, parent); + Validate.notNull(loader, "Loader cannot be null"); + + this.loader = loader; + this.description = description; + this.dataFolder = dataFolder; + this.file = file; + + try { + Class jarClass; + try { + jarClass = Class.forName(description.getMain(), true, this); + } catch (ClassNotFoundException ex) { + throw new InvalidPluginException("Cannot find main class `" + description.getMain() + "'", ex); + } + + Class pluginClass; + try { + pluginClass = jarClass.asSubclass(JavaPlugin.class); + } catch (ClassCastException ex) { + throw new InvalidPluginException("main class `" + description.getMain() + "' does not extend JavaPlugin", ex); + } + + plugin = pluginClass.newInstance(); + } catch (IllegalAccessException ex) { + throw new InvalidPluginException("No public constructor", ex); + } catch (InstantiationException ex) { + throw new InvalidPluginException("Abnormal plugin type", ex); + } + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + return findClass(name, true); + } + + Class findClass(String name, boolean checkGlobal) throws ClassNotFoundException { + if (name.startsWith("org.bukkit.") || name.startsWith("net.minecraft.")) { + throw new ClassNotFoundException(name); + } + Class result = classes.get(name); + + if (result == null) { + if (checkGlobal) { + result = loader.getClassByName(name); + } + + if (result == null) { + result = super.findClass(name); + + if (result != null) { + loader.setClass(name, result); + } + } + + classes.put(name, result); + } + + return result; + } + + Set getClasses() { + return classes.keySet(); + } + + synchronized void initialize(JavaPlugin javaPlugin) { + Validate.notNull(javaPlugin, "Initializing plugin cannot be null"); + Validate.isTrue(javaPlugin.getClass().getClassLoader() == this, "Cannot initialize plugin outside of this class loader"); + if (this.plugin != null || this.pluginInit != null) { + throw new IllegalArgumentException("Plugin already initialized!", pluginState); + } + + pluginState = new IllegalStateException("Initial initialization"); + this.pluginInit = javaPlugin; + + javaPlugin.init(loader, loader.server, description, dataFolder, file, this); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ChannelNameTooLongException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ChannelNameTooLongException.java new file mode 100644 index 0000000..80ef8a2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ChannelNameTooLongException.java @@ -0,0 +1,15 @@ +package org.bukkit.plugin.messaging; + +/** + * Thrown if a Plugin Channel is too long. + */ +@SuppressWarnings("serial") +public class ChannelNameTooLongException extends RuntimeException { + public ChannelNameTooLongException() { + super("Attempted to send a Plugin Message to a channel that was too large. The maximum length a channel may be is " + Messenger.MAX_CHANNEL_SIZE + " chars."); + } + + public ChannelNameTooLongException(String channel) { + super("Attempted to send a Plugin Message to a channel that was too large. The maximum length a channel may be is " + Messenger.MAX_CHANNEL_SIZE + " chars (attempted " + channel.length() + " - '" + channel + "."); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ChannelNotRegisteredException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ChannelNotRegisteredException.java new file mode 100644 index 0000000..2266f17 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ChannelNotRegisteredException.java @@ -0,0 +1,15 @@ +package org.bukkit.plugin.messaging; + +/** + * Thrown if a Plugin attempts to send a message on an unregistered channel. + */ +@SuppressWarnings("serial") +public class ChannelNotRegisteredException extends RuntimeException { + public ChannelNotRegisteredException() { + this("Attempted to send a plugin message through an unregistered channel."); + } + + public ChannelNotRegisteredException(String channel) { + super("Attempted to send a plugin message through the unregistered channel `" + channel + "'."); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/MessageTooLargeException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/MessageTooLargeException.java new file mode 100644 index 0000000..61af8c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/MessageTooLargeException.java @@ -0,0 +1,23 @@ +package org.bukkit.plugin.messaging; + +/** + * Thrown if a Plugin Message is sent that is too large to be sent. + */ +@SuppressWarnings("serial") +public class MessageTooLargeException extends RuntimeException { + public MessageTooLargeException() { + this("Attempted to send a plugin message that was too large. The maximum length a plugin message may be is " + Messenger.MAX_MESSAGE_SIZE + " bytes."); + } + + public MessageTooLargeException(byte[] message) { + this(message.length); + } + + public MessageTooLargeException(int length) { + this("Attempted to send a plugin message that was too large. The maximum length a plugin message may be is " + Messenger.MAX_MESSAGE_SIZE + " bytes (tried to send one that is " + length + " bytes long)."); + } + + public MessageTooLargeException(String msg) { + super(msg); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/Messenger.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/Messenger.java new file mode 100644 index 0000000..655afaf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/Messenger.java @@ -0,0 +1,216 @@ +package org.bukkit.plugin.messaging; + +import java.util.Set; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +/** + * A class responsible for managing the registrations of plugin channels and + * their listeners. + */ +public interface Messenger { + + /** + * Represents the largest size that an individual Plugin Message may be. + */ + public static final int MAX_MESSAGE_SIZE = 32766; + + /** + * Represents the largest size that a Plugin Channel may be. + */ + public static final int MAX_CHANNEL_SIZE = 20; + + /** + * Checks if the specified channel is a reserved name. + * + * @param channel Channel name to check. + * @return True if the channel is reserved, otherwise false. + * @throws IllegalArgumentException Thrown if channel is null. + */ + public boolean isReservedChannel(String channel); + + /** + * Registers the specific plugin to the requested outgoing plugin channel, + * allowing it to send messages through that channel to any clients. + * + * @param plugin Plugin that wishes to send messages through the channel. + * @param channel Channel to register. + * @throws IllegalArgumentException Thrown if plugin or channel is null. + */ + public void registerOutgoingPluginChannel(Plugin plugin, String channel); + + /** + * Unregisters the specific plugin from the requested outgoing plugin + * channel, no longer allowing it to send messages through that channel to + * any clients. + * + * @param plugin Plugin that no longer wishes to send messages through the + * channel. + * @param channel Channel to unregister. + * @throws IllegalArgumentException Thrown if plugin or channel is null. + */ + public void unregisterOutgoingPluginChannel(Plugin plugin, String channel); + + /** + * Unregisters the specific plugin from all outgoing plugin channels, no + * longer allowing it to send any plugin messages. + * + * @param plugin Plugin that no longer wishes to send plugin messages. + * @throws IllegalArgumentException Thrown if plugin is null. + */ + public void unregisterOutgoingPluginChannel(Plugin plugin); + + /** + * Registers the specific plugin for listening on the requested incoming + * plugin channel, allowing it to act upon any plugin messages. + * + * @param plugin Plugin that wishes to register to this channel. + * @param channel Channel to register. + * @param listener Listener to receive messages on. + * @return The resulting registration that was made as a result of this + * method. + * @throws IllegalArgumentException Thrown if plugin, channel or listener + * is null, or the listener is already registered for this channel. + */ + public PluginMessageListenerRegistration registerIncomingPluginChannel(Plugin plugin, String channel, PluginMessageListener listener); + + /** + * Unregisters the specific plugin's listener from listening on the + * requested incoming plugin channel, no longer allowing it to act upon + * any plugin messages. + * + * @param plugin Plugin that wishes to unregister from this channel. + * @param channel Channel to unregister. + * @param listener Listener to stop receiving messages on. + * @throws IllegalArgumentException Thrown if plugin, channel or listener + * is null. + */ + public void unregisterIncomingPluginChannel(Plugin plugin, String channel, PluginMessageListener listener); + + /** + * Unregisters the specific plugin from listening on the requested + * incoming plugin channel, no longer allowing it to act upon any plugin + * messages. + * + * @param plugin Plugin that wishes to unregister from this channel. + * @param channel Channel to unregister. + * @throws IllegalArgumentException Thrown if plugin or channel is null. + */ + public void unregisterIncomingPluginChannel(Plugin plugin, String channel); + + /** + * Unregisters the specific plugin from listening on all plugin channels + * through all listeners. + * + * @param plugin Plugin that wishes to unregister from this channel. + * @throws IllegalArgumentException Thrown if plugin is null. + */ + public void unregisterIncomingPluginChannel(Plugin plugin); + + /** + * Gets a set containing all the outgoing plugin channels. + * + * @return List of all registered outgoing plugin channels. + */ + public Set getOutgoingChannels(); + + /** + * Gets a set containing all the outgoing plugin channels that the + * specified plugin is registered to. + * + * @param plugin Plugin to retrieve channels for. + * @return List of all registered outgoing plugin channels that a plugin + * is registered to. + * @throws IllegalArgumentException Thrown if plugin is null. + */ + public Set getOutgoingChannels(Plugin plugin); + + /** + * Gets a set containing all the incoming plugin channels. + * + * @return List of all registered incoming plugin channels. + */ + public Set getIncomingChannels(); + + /** + * Gets a set containing all the incoming plugin channels that the + * specified plugin is registered for. + * + * @param plugin Plugin to retrieve channels for. + * @return List of all registered incoming plugin channels that the plugin + * is registered for. + * @throws IllegalArgumentException Thrown if plugin is null. + */ + public Set getIncomingChannels(Plugin plugin); + + /** + * Gets a set containing all the incoming plugin channel registrations + * that the specified plugin has. + * + * @param plugin Plugin to retrieve registrations for. + * @return List of all registrations that the plugin has. + * @throws IllegalArgumentException Thrown if plugin is null. + */ + public Set getIncomingChannelRegistrations(Plugin plugin); + + /** + * Gets a set containing all the incoming plugin channel registrations + * that are on the requested channel. + * + * @param channel Channel to retrieve registrations for. + * @return List of all registrations that are on the channel. + * @throws IllegalArgumentException Thrown if channel is null. + */ + public Set getIncomingChannelRegistrations(String channel); + + /** + * Gets a set containing all the incoming plugin channel registrations + * that the specified plugin has on the requested channel. + * + * @param plugin Plugin to retrieve registrations for. + * @param channel Channel to filter registrations by. + * @return List of all registrations that the plugin has. + * @throws IllegalArgumentException Thrown if plugin or channel is null. + */ + public Set getIncomingChannelRegistrations(Plugin plugin, String channel); + + /** + * Checks if the specified plugin message listener registration is valid. + *

+ * A registration is considered valid if it has not be unregistered and + * that the plugin is still enabled. + * + * @param registration Registration to check. + * @return True if the registration is valid, otherwise false. + */ + public boolean isRegistrationValid(PluginMessageListenerRegistration registration); + + /** + * Checks if the specified plugin has registered to receive incoming + * messages through the requested channel. + * + * @param plugin Plugin to check registration for. + * @param channel Channel to test for. + * @return True if the channel is registered, else false. + */ + public boolean isIncomingChannelRegistered(Plugin plugin, String channel); + + /** + * Checks if the specified plugin has registered to send outgoing messages + * through the requested channel. + * + * @param plugin Plugin to check registration for. + * @param channel Channel to test for. + * @return True if the channel is registered, else false. + */ + public boolean isOutgoingChannelRegistered(Plugin plugin, String channel); + + /** + * Dispatches the specified incoming message to any registered listeners. + * + * @param source Source of the message. + * @param channel Channel that the message was sent by. + * @param message Raw payload of the message. + */ + public void dispatchIncomingMessage(Player source, String channel, byte[] message); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginChannelDirection.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginChannelDirection.java new file mode 100644 index 0000000..3d7ec2e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginChannelDirection.java @@ -0,0 +1,17 @@ +package org.bukkit.plugin.messaging; + +/** + * Represents the different directions a plugin channel may go. + */ +public enum PluginChannelDirection { + + /** + * The plugin channel is being sent to the server from a client. + */ + INCOMING, + + /** + * The plugin channel is being sent to a client from the server. + */ + OUTGOING +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageListener.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageListener.java new file mode 100644 index 0000000..f1aa080 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageListener.java @@ -0,0 +1,20 @@ +package org.bukkit.plugin.messaging; + +import org.bukkit.entity.Player; + +/** + * A listener for a specific Plugin Channel, which will receive notifications + * of messages sent from a client. + */ +public interface PluginMessageListener { + + /** + * A method that will be thrown when a PluginMessageSource sends a plugin + * message on a registered channel. + * + * @param channel Channel that the message was sent through. + * @param player Source of the message. + * @param message The raw message that was sent. + */ + public void onPluginMessageReceived(String channel, Player player, byte[] message); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageListenerRegistration.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageListenerRegistration.java new file mode 100644 index 0000000..29929bf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageListenerRegistration.java @@ -0,0 +1,104 @@ +package org.bukkit.plugin.messaging; + +import org.bukkit.plugin.Plugin; + +/** + * Contains information about a {@link Plugin}s registration to a plugin + * channel. + */ +public final class PluginMessageListenerRegistration { + private final Messenger messenger; + private final Plugin plugin; + private final String channel; + private final PluginMessageListener listener; + + public PluginMessageListenerRegistration(Messenger messenger, Plugin plugin, String channel, PluginMessageListener listener) { + if (messenger == null) { + throw new IllegalArgumentException("Messenger cannot be null!"); + } + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null!"); + } + if (channel == null) { + throw new IllegalArgumentException("Channel cannot be null!"); + } + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null!"); + } + + this.messenger = messenger; + this.plugin = plugin; + this.channel = channel; + this.listener = listener; + } + + /** + * Gets the plugin channel that this registration is about. + * + * @return Plugin channel. + */ + public String getChannel() { + return channel; + } + + /** + * Gets the registered listener described by this registration. + * + * @return Registered listener. + */ + public PluginMessageListener getListener() { + return listener; + } + + /** + * Gets the plugin that this registration is for. + * + * @return Registered plugin. + */ + public Plugin getPlugin() { + return plugin; + } + + /** + * Checks if this registration is still valid. + * + * @return True if this registration is still valid, otherwise false. + */ + public boolean isValid() { + return messenger.isRegistrationValid(this); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final PluginMessageListenerRegistration other = (PluginMessageListenerRegistration) obj; + if (this.messenger != other.messenger && (this.messenger == null || !this.messenger.equals(other.messenger))) { + return false; + } + if (this.plugin != other.plugin && (this.plugin == null || !this.plugin.equals(other.plugin))) { + return false; + } + if ((this.channel == null) ? (other.channel != null) : !this.channel.equals(other.channel)) { + return false; + } + if (this.listener != other.listener && (this.listener == null || !this.listener.equals(other.listener))) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 53 * hash + (this.messenger != null ? this.messenger.hashCode() : 0); + hash = 53 * hash + (this.plugin != null ? this.plugin.hashCode() : 0); + hash = 53 * hash + (this.channel != null ? this.channel.hashCode() : 0); + hash = 53 * hash + (this.listener != null ? this.listener.hashCode() : 0); + return hash; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageRecipient.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageRecipient.java new file mode 100644 index 0000000..e5c5916 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/PluginMessageRecipient.java @@ -0,0 +1,38 @@ +package org.bukkit.plugin.messaging; + +import java.util.Set; +import org.bukkit.plugin.Plugin; + +/** + * Represents a possible recipient for a Plugin Message. + */ +public interface PluginMessageRecipient { + /** + * Sends this recipient a Plugin Message on the specified outgoing + * channel. + *

+ * The message may not be larger than {@link Messenger#MAX_MESSAGE_SIZE} + * bytes, and the plugin must be registered to send messages on the + * specified channel. + * + * @param source The plugin that sent this message. + * @param channel The channel to send this message on. + * @param message The raw message to send. + * @throws IllegalArgumentException Thrown if the source plugin is + * disabled. + * @throws IllegalArgumentException Thrown if source, channel or message + * is null. + * @throws MessageTooLargeException Thrown if the message is too big. + * @throws ChannelNotRegisteredException Thrown if the channel is not + * registered for this plugin. + */ + public void sendPluginMessage(Plugin source, String channel, byte[] message); + + /** + * Gets a set containing all the Plugin Channels that this client is + * listening on. + * + * @return Set containing all the channels that this client may accept. + */ + public Set getListeningPluginChannels(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ReservedChannelException.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ReservedChannelException.java new file mode 100644 index 0000000..0221f04 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/ReservedChannelException.java @@ -0,0 +1,16 @@ +package org.bukkit.plugin.messaging; + +/** + * Thrown if a plugin attempts to register for a reserved channel (such as + * "REGISTER") + */ +@SuppressWarnings("serial") +public class ReservedChannelException extends RuntimeException { + public ReservedChannelException() { + this("Attempted to register for a reserved channel name."); + } + + public ReservedChannelException(String name) { + super("Attempted to register for a reserved channel name ('" + name + "')"); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java new file mode 100644 index 0000000..4c171e8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java @@ -0,0 +1,489 @@ +package org.bukkit.plugin.messaging; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +/** + * Standard implementation to {@link Messenger} + */ +public class StandardMessenger implements Messenger { + private final Map> incomingByChannel = new HashMap>(); + private final Map> incomingByPlugin = new HashMap>(); + private final Map> outgoingByChannel = new HashMap>(); + private final Map> outgoingByPlugin = new HashMap>(); + private final Object incomingLock = new Object(); + private final Object outgoingLock = new Object(); + + private void addToOutgoing(Plugin plugin, String channel) { + synchronized (outgoingLock) { + Set plugins = outgoingByChannel.get(channel); + Set channels = outgoingByPlugin.get(plugin); + + if (plugins == null) { + plugins = new HashSet(); + outgoingByChannel.put(channel, plugins); + } + + if (channels == null) { + channels = new HashSet(); + outgoingByPlugin.put(plugin, channels); + } + + plugins.add(plugin); + channels.add(channel); + } + } + + private void removeFromOutgoing(Plugin plugin, String channel) { + synchronized (outgoingLock) { + Set plugins = outgoingByChannel.get(channel); + Set channels = outgoingByPlugin.get(plugin); + + if (plugins != null) { + plugins.remove(plugin); + + if (plugins.isEmpty()) { + outgoingByChannel.remove(channel); + } + } + + if (channels != null) { + channels.remove(channel); + + if (channels.isEmpty()) { + outgoingByChannel.remove(channel); + } + } + } + } + + private void removeFromOutgoing(Plugin plugin) { + synchronized (outgoingLock) { + Set channels = outgoingByPlugin.get(plugin); + + if (channels != null) { + String[] toRemove = channels.toArray(new String[0]); + + outgoingByPlugin.remove(plugin); + + for (String channel : toRemove) { + removeFromOutgoing(plugin, channel); + } + } + } + } + + private void addToIncoming(PluginMessageListenerRegistration registration) { + synchronized (incomingLock) { + Set registrations = incomingByChannel.get(registration.getChannel()); + + if (registrations == null) { + registrations = new HashSet(); + incomingByChannel.put(registration.getChannel(), registrations); + } else { + if (registrations.contains(registration)) { + throw new IllegalArgumentException("This registration already exists"); + } + } + + registrations.add(registration); + + registrations = incomingByPlugin.get(registration.getPlugin()); + + if (registrations == null) { + registrations = new HashSet(); + incomingByPlugin.put(registration.getPlugin(), registrations); + } else { + if (registrations.contains(registration)) { + throw new IllegalArgumentException("This registration already exists"); + } + } + + registrations.add(registration); + } + } + + private void removeFromIncoming(PluginMessageListenerRegistration registration) { + synchronized (incomingLock) { + Set registrations = incomingByChannel.get(registration.getChannel()); + + if (registrations != null) { + registrations.remove(registration); + + if (registrations.isEmpty()) { + incomingByChannel.remove(registration.getChannel()); + } + } + + registrations = incomingByPlugin.get(registration.getPlugin()); + + if (registrations != null) { + registrations.remove(registration); + + if (registrations.isEmpty()) { + incomingByPlugin.remove(registration.getPlugin()); + } + } + } + } + + private void removeFromIncoming(Plugin plugin, String channel) { + synchronized (incomingLock) { + Set registrations = incomingByPlugin.get(plugin); + + if (registrations != null) { + PluginMessageListenerRegistration[] toRemove = registrations.toArray(new PluginMessageListenerRegistration[0]); + + for (PluginMessageListenerRegistration registration : toRemove) { + if (registration.getChannel().equals(channel)) { + removeFromIncoming(registration); + } + } + } + } + } + + private void removeFromIncoming(Plugin plugin) { + synchronized (incomingLock) { + Set registrations = incomingByPlugin.get(plugin); + + if (registrations != null) { + PluginMessageListenerRegistration[] toRemove = registrations.toArray(new PluginMessageListenerRegistration[0]); + + incomingByPlugin.remove(plugin); + + for (PluginMessageListenerRegistration registration : toRemove) { + removeFromIncoming(registration); + } + } + } + } + + public boolean isReservedChannel(String channel) { + validateChannel(channel); + + return channel.equals("REGISTER") || channel.equals("UNREGISTER"); + } + + public void registerOutgoingPluginChannel(Plugin plugin, String channel) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + validateChannel(channel); + if (isReservedChannel(channel)) { + throw new ReservedChannelException(channel); + } + + addToOutgoing(plugin, channel); + } + + public void unregisterOutgoingPluginChannel(Plugin plugin, String channel) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + validateChannel(channel); + + removeFromOutgoing(plugin, channel); + } + + public void unregisterOutgoingPluginChannel(Plugin plugin) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + + removeFromOutgoing(plugin); + } + + public PluginMessageListenerRegistration registerIncomingPluginChannel(Plugin plugin, String channel, PluginMessageListener listener) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + validateChannel(channel); + if (isReservedChannel(channel)) { + throw new ReservedChannelException(channel); + } + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + + PluginMessageListenerRegistration result = new PluginMessageListenerRegistration(this, plugin, channel, listener); + + addToIncoming(result); + + return result; + } + + public void unregisterIncomingPluginChannel(Plugin plugin, String channel, PluginMessageListener listener) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + if (listener == null) { + throw new IllegalArgumentException("Listener cannot be null"); + } + validateChannel(channel); + + removeFromIncoming(new PluginMessageListenerRegistration(this, plugin, channel, listener)); + } + + public void unregisterIncomingPluginChannel(Plugin plugin, String channel) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + validateChannel(channel); + + removeFromIncoming(plugin, channel); + } + + public void unregisterIncomingPluginChannel(Plugin plugin) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + + removeFromIncoming(plugin); + } + + public Set getOutgoingChannels() { + synchronized (outgoingLock) { + Set keys = outgoingByChannel.keySet(); + return ImmutableSet.copyOf(keys); + } + } + + public Set getOutgoingChannels(Plugin plugin) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + + synchronized (outgoingLock) { + Set channels = outgoingByPlugin.get(plugin); + + if (channels != null) { + return ImmutableSet.copyOf(channels); + } else { + return ImmutableSet.of(); + } + } + } + + public Set getIncomingChannels() { + synchronized (incomingLock) { + Set keys = incomingByChannel.keySet(); + return ImmutableSet.copyOf(keys); + } + } + + public Set getIncomingChannels(Plugin plugin) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + + synchronized (incomingLock) { + Set registrations = incomingByPlugin.get(plugin); + + if (registrations != null) { + Builder builder = ImmutableSet.builder(); + + for (PluginMessageListenerRegistration registration : registrations) { + builder.add(registration.getChannel()); + } + + return builder.build(); + } else { + return ImmutableSet.of(); + } + } + } + + public Set getIncomingChannelRegistrations(Plugin plugin) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + + synchronized (incomingLock) { + Set registrations = incomingByPlugin.get(plugin); + + if (registrations != null) { + return ImmutableSet.copyOf(registrations); + } else { + return ImmutableSet.of(); + } + } + } + + public Set getIncomingChannelRegistrations(String channel) { + validateChannel(channel); + + synchronized (incomingLock) { + Set registrations = incomingByChannel.get(channel); + + if (registrations != null) { + return ImmutableSet.copyOf(registrations); + } else { + return ImmutableSet.of(); + } + } + } + + public Set getIncomingChannelRegistrations(Plugin plugin, String channel) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + validateChannel(channel); + + synchronized (incomingLock) { + Set registrations = incomingByPlugin.get(plugin); + + if (registrations != null) { + Builder builder = ImmutableSet.builder(); + + for (PluginMessageListenerRegistration registration : registrations) { + if (registration.getChannel().equals(channel)) { + builder.add(registration); + } + } + + return builder.build(); + } else { + return ImmutableSet.of(); + } + } + } + + public boolean isRegistrationValid(PluginMessageListenerRegistration registration) { + if (registration == null) { + throw new IllegalArgumentException("Registration cannot be null"); + } + + synchronized (incomingLock) { + Set registrations = incomingByPlugin.get(registration.getPlugin()); + + if (registrations != null) { + return registrations.contains(registration); + } + + return false; + } + } + + public boolean isIncomingChannelRegistered(Plugin plugin, String channel) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + validateChannel(channel); + + synchronized (incomingLock) { + Set registrations = incomingByPlugin.get(plugin); + + if (registrations != null) { + for (PluginMessageListenerRegistration registration : registrations) { + if (registration.getChannel().equals(channel)) { + return true; + } + } + } + + return false; + } + } + + public boolean isOutgoingChannelRegistered(Plugin plugin, String channel) { + if (plugin == null) { + throw new IllegalArgumentException("Plugin cannot be null"); + } + validateChannel(channel); + + synchronized (outgoingLock) { + Set channels = outgoingByPlugin.get(plugin); + + if (channels != null) { + return channels.contains(channel); + } + + return false; + } + } + + public void dispatchIncomingMessage(Player source, String channel, byte[] message) { + if (source == null) { + throw new IllegalArgumentException("Player source cannot be null"); + } + if (message == null) { + throw new IllegalArgumentException("Message cannot be null"); + } + validateChannel(channel); + + Set registrations = getIncomingChannelRegistrations(channel); + + for (PluginMessageListenerRegistration registration : registrations) { + // Spigot Start + try + { + registration.getListener().onPluginMessageReceived( channel, source, message ); + } catch ( Throwable t ) + { + org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.WARNING, "Could not pass incoming plugin message to " + registration.getPlugin(), t ); + } + // Spigot End + } + } + + /** + * Validates a Plugin Channel name. + * + * @param channel Channel name to validate. + */ + public static void validateChannel(String channel) { + if (channel == null) { + throw new IllegalArgumentException("Channel cannot be null"); + } + if (channel.length() > Messenger.MAX_CHANNEL_SIZE) { + throw new ChannelNameTooLongException(channel); + } + } + + /** + * Validates the input of a Plugin Message, ensuring the arguments are all + * valid. + * + * @param messenger Messenger to use for validation. + * @param source Source plugin of the Message. + * @param channel Plugin Channel to send the message by. + * @param message Raw message payload to send. + * @throws IllegalArgumentException Thrown if the source plugin is + * disabled. + * @throws IllegalArgumentException Thrown if source, channel or message + * is null. + * @throws MessageTooLargeException Thrown if the message is too big. + * @throws ChannelNameTooLongException Thrown if the channel name is too + * long. + * @throws ChannelNotRegisteredException Thrown if the channel is not + * registered for this plugin. + */ + public static void validatePluginMessage(Messenger messenger, Plugin source, String channel, byte[] message) { + if (messenger == null) { + throw new IllegalArgumentException("Messenger cannot be null"); + } + if (source == null) { + throw new IllegalArgumentException("Plugin source cannot be null"); + } + if (!source.isEnabled()) { + throw new IllegalArgumentException("Plugin must be enabled to send messages"); + } + if (message == null) { + throw new IllegalArgumentException("Message cannot be null"); + } + if (!messenger.isOutgoingChannelRegistered(source, channel)) { + throw new ChannelNotRegisteredException(channel); + } + if (message.length > Messenger.MAX_MESSAGE_SIZE) { + throw new MessageTooLargeException(message); + } + validateChannel(channel); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/Potion.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/Potion.java new file mode 100644 index 0000000..36f2f1a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/Potion.java @@ -0,0 +1,451 @@ +package org.bukkit.potion; + +import java.util.Collection; + +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.ItemStack; + +import com.google.common.collect.ImmutableList; + +/** + * Represents a minecraft potion + */ +public class Potion { + private boolean extended = false; + private boolean splash = false; + private int level = 1; + private int name = -1; + private PotionType type; + + /** + * Construct a new potion of the given type. Unless the type is {@link + * PotionType#WATER}, it will be level one, without extended duration. + * Don't use this constructor to create a no-effect potion other than + * water bottle. + * + * @param type The potion type + * @see #Potion(int) + */ + public Potion(PotionType type) { + this.type = type; + if (type != null) { + this.name = type.getDamageValue(); + } + if (type == null || type == PotionType.WATER) { + this.level = 0; + } + } + + /** + * @param type the type of the potion + * @param tier the tier of the potion + * @deprecated In favour of {@link #Potion(PotionType, int)} + */ + @Deprecated + public Potion(PotionType type, Tier tier) { + this(type, tier == Tier.TWO ? 2 : 1); + Validate.notNull(type, "Type cannot be null"); + } + + /** + * @param type the type of the potion + * @param tier the tier of the potion + * @param splash whether the potion is a splash potion + * @deprecated In favour of {@link #Potion(PotionType, int, boolean)} + */ + @Deprecated + public Potion(PotionType type, Tier tier, boolean splash) { + this(type, tier == Tier.TWO ? 2 : 1, splash); + } + + /** + * @param type the type of the potion + * @param tier the tier of the potion + * @param splash whether the potion is a splash potion + * @param extended whether the potion has an extended duration + * @deprecated In favour of {@link #Potion(PotionType, int, boolean, + * boolean)} + */ + @Deprecated + public Potion(PotionType type, Tier tier, boolean splash, boolean extended) { + this(type, tier, splash); + this.extended = extended; + } + + /** + * Create a new potion of the given type and level. + * + * @param type The type of potion. + * @param level The potion's level. + */ + public Potion(PotionType type, int level) { + this(type); + Validate.notNull(type, "Type cannot be null"); + Validate.isTrue(type != PotionType.WATER, "Water bottles don't have a level!"); + Validate.isTrue(level > 0 && level < 3, "Level must be 1 or 2"); + this.level = level; + } + + /** + * Create a new potion of the given type and level. + * + * @param type The type of potion. + * @param level The potion's level. + * @param splash Whether it is a splash potion. + * @deprecated In favour of using {@link #Potion(PotionType)} with {@link + * #splash()}. + */ + @Deprecated + public Potion(PotionType type, int level, boolean splash) { + this(type, level); + this.splash = splash; + } + + /** + * Create a new potion of the given type and level. + * + * @param type The type of potion. + * @param level The potion's level. + * @param splash Whether it is a splash potion. + * @param extended Whether it has an extended duration. + * @deprecated In favour of using {@link #Potion(PotionType)} with {@link + * #extend()} and possibly {@link #splash()}. + */ + @Deprecated + public Potion(PotionType type, int level, boolean splash, boolean extended) { + this(type, level, splash); + this.extended = extended; + } + + /** + * Create a potion with a specific name. + * + * @param name The name index (0-63) + */ + public Potion(int name) { + this(PotionType.getByDamageValue(name & POTION_BIT)); + this.name = name & NAME_BIT; + if ((name & POTION_BIT) == 0) { + // If it's 0 it would've become PotionType.WATER, but it should actually be mundane potion + this.type = null; + } + } + + /** + * Chain this to the constructor to make the potion a splash potion. + * + * @return The potion. + */ + public Potion splash() { + setSplash(true); + return this; + } + + /** + * Chain this to the constructor to extend the potion's duration. + * + * @return The potion. + */ + public Potion extend() { + setHasExtendedDuration(true); + return this; + } + + /** + * Applies the effects of this potion to the given {@link ItemStack}. The + * ItemStack must be a potion. + * + * @param to The itemstack to apply to + */ + public void apply(ItemStack to) { + Validate.notNull(to, "itemstack cannot be null"); + Validate.isTrue(to.getType() == Material.POTION, "given itemstack is not a potion"); + to.setDurability(toDamageValue()); + } + + /** + * Applies the effects that would be applied by this potion to the given + * {@link LivingEntity}. + * + * @see LivingEntity#addPotionEffects(Collection) + * @param to The entity to apply the effects to + */ + public void apply(LivingEntity to) { + Validate.notNull(to, "entity cannot be null"); + to.addPotionEffects(getEffects()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + Potion other = (Potion) obj; + return extended == other.extended && splash == other.splash && level == other.level && type == other.type; + } + + /** + * Returns a collection of {@link PotionEffect}s that this {@link Potion} + * would confer upon a {@link LivingEntity}. + * + * @see PotionBrewer#getEffectsFromDamage(int) + * @see Potion#toDamageValue() + * @return The effects that this potion applies + */ + public Collection getEffects() { + if (type == null) return ImmutableList.of(); + return getBrewer().getEffectsFromDamage(toDamageValue()); + } + + /** + * Returns the level of this potion. + * + * @return The level of this potion + */ + public int getLevel() { + return level; + } + + /** + * Returns the {@link Tier} of this potion. + * + * @return The tier of this potion + */ + @Deprecated + public Tier getTier() { + return level == 2 ? Tier.TWO : Tier.ONE; + } + + /** + * Returns the {@link PotionType} of this potion. + * + * @return The type of this potion + */ + public PotionType getType() { + return type; + } + + /** + * Returns whether this potion has an extended duration. + * + * @return Whether this potion has extended duration + */ + public boolean hasExtendedDuration() { + return extended; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = prime + level; + result = prime * result + (extended ? 1231 : 1237); + result = prime * result + (splash ? 1231 : 1237); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + /** + * Returns whether this potion is a splash potion. + * + * @return Whether this is a splash potion + */ + public boolean isSplash() { + return splash; + } + + /** + * Set whether this potion has extended duration. This will cause the + * potion to have roughly 8/3 more duration than a regular potion. + * + * @param isExtended Whether the potion should have extended duration + */ + public void setHasExtendedDuration(boolean isExtended) { + Validate.isTrue(type == null || !type.isInstant(), "Instant potions cannot be extended"); + extended = isExtended; + } + + /** + * Sets whether this potion is a splash potion. Splash potions can be + * thrown for a radius effect. + * + * @param isSplash Whether this is a splash potion + */ + public void setSplash(boolean isSplash) { + splash = isSplash; + } + + /** + * Sets the {@link Tier} of this potion. + * + * @param tier The new tier of this potion + * @deprecated In favour of {@link #setLevel(int)} + */ + @Deprecated + public void setTier(Tier tier) { + Validate.notNull(tier, "tier cannot be null"); + this.level = (tier == Tier.TWO ? 2 : 1); + } + + /** + * Sets the {@link PotionType} of this potion. + * + * @param type The new type of this potion + */ + public void setType(PotionType type) { + this.type = type; + } + + /** + * Sets the level of this potion. + * + * @param level The new level of this potion + */ + public void setLevel(int level) { + Validate.notNull(this.type, "No-effect potions don't have a level."); + int max = type.getMaxLevel(); + Validate.isTrue(level > 0 && level <= max, "Level must be " + (max == 1 ? "" : "between 1 and ") + max + " for this potion"); + this.level = level; + } + + /** + * Converts this potion to a valid potion damage short, usable for potion + * item stacks. + * + * @return The damage value of this potion + * @deprecated Magic value + */ + @Deprecated + public short toDamageValue() { + short damage; + if (type == PotionType.WATER) { + return 0; + } else if (type == null) { + // Without this, mundanePotion.toDamageValue() would return 0 + damage = (short) (name == 0 ? 8192 : name); + } else { + damage = (short) (level - 1); + damage <<= TIER_SHIFT; + damage |= (short) type.getDamageValue(); + } + if (splash) { + damage |= SPLASH_BIT; + } + if (extended) { + damage |= EXTENDED_BIT; + } + return damage; + } + + /** + * Converts this potion to an {@link ItemStack} with the specified amount + * and a correct damage value. + * + * @param amount The amount of the ItemStack + * @return The created ItemStack + */ + public ItemStack toItemStack(int amount) { + return new ItemStack(Material.POTION, amount, toDamageValue()); + } + + @Deprecated + public enum Tier { + ONE(0), + TWO(0x20); + + private int damageBit; + + Tier(int bit) { + damageBit = bit; + } + + public int getDamageBit() { + return damageBit; + } + + public static Tier getByDamageBit(int damageBit) { + for (Tier tier : Tier.values()) { + if (tier.damageBit == damageBit) + return tier; + } + return null; + } + } + + private static PotionBrewer brewer; + + private static final int EXTENDED_BIT = 0x40; + private static final int POTION_BIT = 0xF; + private static final int SPLASH_BIT = 0x4000; + private static final int TIER_BIT = 0x20; + private static final int TIER_SHIFT = 5; + private static final int NAME_BIT = 0x3F; + + /** + * + * @param damage the damage value + * @return the produced potion + * @deprecated Magic value + */ + @Deprecated + public static Potion fromDamage(int damage) { + PotionType type = PotionType.getByDamageValue(damage & POTION_BIT); + Potion potion; + if (type == null || type == PotionType.WATER) { + potion = new Potion(damage & NAME_BIT); + } else { + int level = (damage & TIER_BIT) >> TIER_SHIFT; + level++; + potion = new Potion(type, level); + } + if ((damage & SPLASH_BIT) > 0) { + potion = potion.splash(); + } + if ((type == null || !type.isInstant()) && (damage & EXTENDED_BIT) > 0) { + potion = potion.extend(); + } + return potion; + } + + public static Potion fromItemStack(ItemStack item) { + Validate.notNull(item, "item cannot be null"); + if (item.getType() != Material.POTION) + throw new IllegalArgumentException("item is not a potion"); + return fromDamage(item.getDurability()); + } + + /** + * Returns an instance of {@link PotionBrewer}. + * + * @return An instance of PotionBrewer + */ + public static PotionBrewer getBrewer() { + return brewer; + } + + /** + * Sets the current instance of {@link PotionBrewer}. Generally not to be + * used from within a plugin. + * + * @param other The new PotionBrewer + */ + public static void setPotionBrewer(PotionBrewer other) { + if (brewer != null) + throw new IllegalArgumentException("brewer can only be set internally"); + brewer = other; + } + + /** + * + * @return the name id + * @deprecated Magic value + */ + @Deprecated + public int getNameId() { + return name; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionBrewer.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionBrewer.java new file mode 100644 index 0000000..5275517 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionBrewer.java @@ -0,0 +1,31 @@ +package org.bukkit.potion; + +import java.util.Collection; + +/** + * Represents a brewer that can create {@link PotionEffect}s. + */ +public interface PotionBrewer { + + /** + * Creates a {@link PotionEffect} from the given {@link PotionEffectType}, + * applying duration modifiers and checks. + * + * @param potion The type of potion + * @param duration The duration in ticks + * @param amplifier The amplifier of the effect + * @return The resulting potion effect + */ + public PotionEffect createEffect(PotionEffectType potion, int duration, int amplifier); + + /** + * Returns a collection of {@link PotionEffect} that would be applied from + * a potion with the given data value. + * + * @param damage The data value of the potion + * @return The list of effects + * @deprecated Magic value + */ + @Deprecated + public Collection getEffectsFromDamage(int damage); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffect.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffect.java new file mode 100644 index 0000000..75bfa27 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffect.java @@ -0,0 +1,204 @@ +package org.bukkit.potion; + +import java.util.Map; +import java.util.NoSuchElementException; + +import org.apache.commons.lang.Validate; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; +import org.bukkit.entity.LivingEntity; + +import com.google.common.collect.ImmutableMap; + +/** + * Represents a potion effect, that can be added to a {@link LivingEntity}. A + * potion effect has a duration that it will last for, an amplifier that will + * enhance its effects, and a {@link PotionEffectType}, that represents its + * effect on an entity. + */ +@SerializableAs("PotionEffect") +public class PotionEffect implements ConfigurationSerializable { + private static final String AMPLIFIER = "amplifier"; + private static final String DURATION = "duration"; + private static final String TYPE = "effect"; + private static final String AMBIENT = "ambient"; + private static final String PARTICLES = "has-particles"; + private final int amplifier; + private final int duration; + private final PotionEffectType type; + private final boolean ambient; + private final boolean particles; + + /** + * Creates a potion effect. + * @param type effect type + * @param duration measured in ticks, see {@link + * PotionEffect#getDuration()} + * @param amplifier the amplifier, see {@link PotionEffect#getAmplifier()} + * @param ambient the ambient status, see {@link PotionEffect#isAmbient()} + * @param particles the particle status, see {@link PotionEffect#hasParticles()} + */ + public PotionEffect(PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles){ + Validate.notNull(type, "effect type cannot be null"); + this.type = type; + this.duration = duration; + this.amplifier = amplifier; + this.ambient = ambient; + this.particles = particles; + } + + /** + * Creates a potion effect. Assumes that particles are visible + * + * @param type effect type + * @param duration measured in ticks, see {@link + * PotionEffect#getDuration()} + * @param amplifier the amplifier, see {@link PotionEffect#getAmplifier()} + * @param ambient the ambient status, see {@link PotionEffect#isAmbient()} + */ + public PotionEffect(PotionEffectType type, int duration, int amplifier, boolean ambient) { + this(type, duration, amplifier, ambient, true); + } + + /** + * Creates a potion effect. Assumes ambient is true. + * + * @param type Effect type + * @param duration measured in ticks + * @param amplifier the amplifier for the effect + * @see PotionEffect#PotionEffect(PotionEffectType, int, int, boolean) + */ + public PotionEffect(PotionEffectType type, int duration, int amplifier) { + this(type, duration, amplifier, true); + } + + /** + * Constructor for deserialization. + * + * @param map the map to deserialize from + */ + public PotionEffect(Map map) { + this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true)); + } + + private static PotionEffectType getEffectType(Map map) { + int type = getInt(map, TYPE); + PotionEffectType effect = PotionEffectType.getById(type); + if (effect != null) { + return effect; + } + throw new NoSuchElementException(map + " does not contain " + TYPE); + } + + private static int getInt(Map map, Object key) { + Object num = map.get(key); + if (num instanceof Integer) { + return (Integer) num; + } + throw new NoSuchElementException(map + " does not contain " + key); + } + + private static boolean getBool(Map map, Object key, boolean def) { + Object bool = map.get(key); + if (bool instanceof Boolean) { + return (Boolean) bool; + } + return def; + } + + public Map serialize() { + return ImmutableMap.of( + TYPE, type.getId(), + DURATION, duration, + AMPLIFIER, amplifier, + AMBIENT, ambient, + PARTICLES, particles + ); + } + + /** + * Attempts to add the effect represented by this object to the given + * {@link LivingEntity}. + * + * @see LivingEntity#addPotionEffect(PotionEffect) + * @param entity The entity to add this effect to + * @return Whether the effect could be added + */ + public boolean apply(LivingEntity entity) { + return entity.addPotionEffect(this); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PotionEffect)) { + return false; + } + PotionEffect that = (PotionEffect) obj; + return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles; + } + + /** + * Returns the amplifier of this effect. A higher amplifier means the + * potion effect happens more often over its duration and in some cases + * has more effect on its target. + * + * @return The effect amplifier + */ + public int getAmplifier() { + return amplifier; + } + + /** + * Returns the duration (in ticks) that this effect will run for when + * applied to a {@link LivingEntity}. + * + * @return The duration of the effect + */ + public int getDuration() { + return duration; + } + + /** + * Returns the {@link PotionEffectType} of this effect. + * + * @return The potion type of this effect + */ + public PotionEffectType getType() { + return type; + } + + /** + * Makes potion effect produce more, translucent, particles. + * + * @return if this effect is ambient + */ + public boolean isAmbient() { + return ambient; + } + + /** + * @return whether this effect has particles or not + */ + public boolean hasParticles(){ + return particles; + } + + @Override + public int hashCode() { + int hash = 1; + hash = hash * 31 + type.hashCode(); + hash = hash * 31 + amplifier; + hash = hash * 31 + duration; + hash ^= 0x22222222 >> (ambient ? 1 : -1); + hash ^= 0x22222222 >> (particles ? 1 : -1); + return hash; + } + + @Override + public String toString() { + return type.getName() + (ambient ? ":(" : ":") + duration + "t-x" + amplifier + (ambient ? ")" : ""); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffectType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffectType.java new file mode 100644 index 0000000..4919d59 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffectType.java @@ -0,0 +1,269 @@ +package org.bukkit.potion; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.Validate; + +/** + * Represents a type of potion and its effect on an entity. + */ +public abstract class PotionEffectType { + /** + * Increases movement speed. + */ + public static final PotionEffectType SPEED = new PotionEffectTypeWrapper(1); + + /** + * Decreases movement speed. + */ + public static final PotionEffectType SLOW = new PotionEffectTypeWrapper(2); + + /** + * Increases dig speed. + */ + public static final PotionEffectType FAST_DIGGING = new PotionEffectTypeWrapper(3); + + /** + * Decreases dig speed. + */ + public static final PotionEffectType SLOW_DIGGING = new PotionEffectTypeWrapper(4); + + /** + * Increases damage dealt. + */ + public static final PotionEffectType INCREASE_DAMAGE = new PotionEffectTypeWrapper(5); + + /** + * Heals an entity. + */ + public static final PotionEffectType HEAL = new PotionEffectTypeWrapper(6); + + /** + * Hurts an entity. + */ + public static final PotionEffectType HARM = new PotionEffectTypeWrapper(7); + + /** + * Increases jump height. + */ + public static final PotionEffectType JUMP = new PotionEffectTypeWrapper(8); + + /** + * Warps vision on the client. + */ + public static final PotionEffectType CONFUSION = new PotionEffectTypeWrapper(9); + + /** + * Regenerates health. + */ + public static final PotionEffectType REGENERATION = new PotionEffectTypeWrapper(10); + + /** + * Decreases damage dealt to an entity. + */ + public static final PotionEffectType DAMAGE_RESISTANCE = new PotionEffectTypeWrapper(11); + + /** + * Stops fire damage. + */ + public static final PotionEffectType FIRE_RESISTANCE = new PotionEffectTypeWrapper(12); + + /** + * Allows breathing underwater. + */ + public static final PotionEffectType WATER_BREATHING = new PotionEffectTypeWrapper(13); + + /** + * Grants invisibility. + */ + public static final PotionEffectType INVISIBILITY = new PotionEffectTypeWrapper(14); + + /** + * Blinds an entity. + */ + public static final PotionEffectType BLINDNESS = new PotionEffectTypeWrapper(15); + + /** + * Allows an entity to see in the dark. + */ + public static final PotionEffectType NIGHT_VISION = new PotionEffectTypeWrapper(16); + + /** + * Increases hunger. + */ + public static final PotionEffectType HUNGER = new PotionEffectTypeWrapper(17); + + /** + * Decreases damage dealt by an entity. + */ + public static final PotionEffectType WEAKNESS = new PotionEffectTypeWrapper(18); + + /** + * Deals damage to an entity over time. + */ + public static final PotionEffectType POISON = new PotionEffectTypeWrapper(19); + + /** + * Deals damage to an entity over time and gives the health to the + * shooter. + */ + public static final PotionEffectType WITHER = new PotionEffectTypeWrapper(20); + + /** + * Increases the maximum health of an entity. + */ + public static final PotionEffectType HEALTH_BOOST = new PotionEffectTypeWrapper(21); + + /** + * Increases the maximum health of an entity with health that cannot be + * regenerated, but is refilled every 30 seconds. + */ + public static final PotionEffectType ABSORPTION = new PotionEffectTypeWrapper(22); + + /** + * Increases the food level of an entity each tick. + */ + public static final PotionEffectType SATURATION = new PotionEffectTypeWrapper(23); + + private final int id; + + protected PotionEffectType(int id) { + this.id = id; + } + + /** + * Creates a PotionEffect from this PotionEffectType, applying duration + * modifiers and checks. + * + * @see PotionBrewer#createEffect(PotionEffectType, int, int) + * @param duration time in ticks + * @param amplifier the effect's amplifier + * @return a resulting potion effect + */ + public PotionEffect createEffect(int duration, int amplifier) { + return Potion.getBrewer().createEffect(this, duration, amplifier); + } + + /** + * Returns the duration modifier applied to effects of this type. + * + * @return duration modifier + */ + public abstract double getDurationModifier(); + + /** + * Returns the unique ID of this type. + * + * @return Unique ID + * @deprecated Magic value + */ + @Deprecated + public int getId() { + return id; + } + + /** + * Returns the name of this effect type. + * + * @return The name of this effect type + */ + public abstract String getName(); + + /** + * Returns whether the effect of this type happens once, immediately. + * + * @return whether this type is normally instant + */ + public abstract boolean isInstant(); + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof PotionEffectType)) { + return false; + } + final PotionEffectType other = (PotionEffectType) obj; + if (this.id != other.id) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return id; + } + + @Override + public String toString() { + return "PotionEffectType[" + id + ", " + getName() + "]"; + } + + private static final PotionEffectType[] byId = new PotionEffectType[24]; + private static final Map byName = new HashMap(); + // will break on updates. + private static boolean acceptingNew = true; + + /** + * Gets the effect type specified by the unique id. + * + * @param id Unique ID to fetch + * @return Resulting type, or null if not found. + * @deprecated Magic value + */ + @Deprecated + public static PotionEffectType getById(int id) { + if (id >= byId.length || id < 0) + return null; + return byId[id]; + } + + /** + * Gets the effect type specified by the given name. + * + * @param name Name of PotionEffectType to fetch + * @return Resulting PotionEffectType, or null if not found. + */ + public static PotionEffectType getByName(String name) { + Validate.notNull(name, "name cannot be null"); + return byName.get(name.toLowerCase()); + } + + /** + * Registers an effect type with the given object. + *

+ * Generally not to be used from within a plugin. + * + * @param type PotionType to register + */ + public static void registerPotionEffectType(PotionEffectType type) { + if (byId[type.id] != null || byName.containsKey(type.getName().toLowerCase())) { + throw new IllegalArgumentException("Cannot set already-set type"); + } else if (!acceptingNew) { + throw new IllegalStateException( + "No longer accepting new potion effect types (can only be done by the server implementation)"); + } + + byId[type.id] = type; + byName.put(type.getName().toLowerCase(), type); + } + + /** + * Stops accepting any effect type registrations. + */ + public static void stopAcceptingRegistrations() { + acceptingNew = false; + } + + /** + * Returns an array of all the registered {@link PotionEffectType}s. + * + * @return Array of types. + */ + public static PotionEffectType[] values() { + return byId.clone(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java new file mode 100644 index 0000000..5db1ce8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionEffectTypeWrapper.java @@ -0,0 +1,31 @@ +package org.bukkit.potion; + +public class PotionEffectTypeWrapper extends PotionEffectType { + protected PotionEffectTypeWrapper(int id) { + super(id); + } + + @Override + public double getDurationModifier() { + return getType().getDurationModifier(); + } + + @Override + public String getName() { + return getType().getName(); + } + + /** + * Get the potion type bound to this wrapper. + * + * @return The potion effect type + */ + public PotionEffectType getType() { + return PotionEffectType.getById(getId()); + } + + @Override + public boolean isInstant() { + return getType().isInstant(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionType.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionType.java new file mode 100644 index 0000000..6ad9a91 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/potion/PotionType.java @@ -0,0 +1,75 @@ +package org.bukkit.potion; + +public enum PotionType { + WATER(0, null, 0), + REGEN(1, PotionEffectType.REGENERATION, 2), + SPEED(2, PotionEffectType.SPEED, 2), + FIRE_RESISTANCE(3, PotionEffectType.FIRE_RESISTANCE, 1), + POISON(4, PotionEffectType.POISON, 2), + INSTANT_HEAL(5, PotionEffectType.HEAL, 2), + NIGHT_VISION(6, PotionEffectType.NIGHT_VISION, 1), + WEAKNESS(8, PotionEffectType.WEAKNESS, 1), + STRENGTH(9, PotionEffectType.INCREASE_DAMAGE, 2), + SLOWNESS(10, PotionEffectType.SLOW, 1), + JUMP(11, PotionEffectType.JUMP, 2), + INSTANT_DAMAGE(12, PotionEffectType.HARM, 2), + WATER_BREATHING(13, PotionEffectType.WATER_BREATHING, 1), + INVISIBILITY(14, PotionEffectType.INVISIBILITY, 1), + ; + + private final int damageValue, maxLevel; + private final PotionEffectType effect; + + PotionType(int damageValue, PotionEffectType effect, int maxLevel) { + this.damageValue = damageValue; + this.effect = effect; + this.maxLevel = maxLevel; + } + + public PotionEffectType getEffectType() { + return effect; + } + + /** + * + * @return the damage value + * @deprecated Magic value + */ + @Deprecated + public int getDamageValue() { + return damageValue; + } + + public int getMaxLevel() { + return maxLevel; + } + + public boolean isInstant() { + return effect == null ? true : effect.isInstant(); + } + + /** + * + * @param damage the damage value + * @return the matching potion type or null + * @deprecated Magic value + */ + @Deprecated + public static PotionType getByDamageValue(int damage) { + for (PotionType type : PotionType.values()) { + if (type.damageValue == damage) + return type; + } + return null; + } + + public static PotionType getByEffect(PotionEffectType effectType) { + if (effectType == null) + return WATER; + for (PotionType type : PotionType.values()) { + if (effectType.equals(type.effect)) + return type; + } + return null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/projectiles/BlockProjectileSource.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/projectiles/BlockProjectileSource.java new file mode 100644 index 0000000..e713c0d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/projectiles/BlockProjectileSource.java @@ -0,0 +1,13 @@ +package org.bukkit.projectiles; + +import org.bukkit.block.Block; + +public interface BlockProjectileSource extends ProjectileSource { + + /** + * Gets the block this projectile source belongs to. + * + * @return Block for the projectile source + */ + public Block getBlock(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/projectiles/ProjectileSource.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/projectiles/ProjectileSource.java new file mode 100644 index 0000000..cf90946 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/projectiles/ProjectileSource.java @@ -0,0 +1,30 @@ +package org.bukkit.projectiles; + +import org.bukkit.entity.Projectile; +import org.bukkit.util.Vector; + +/** + * Represents a valid source of a projectile. + */ +public interface ProjectileSource { + + /** + * Launches a {@link Projectile} from the ProjectileSource. + * + * @param a projectile subclass + * @param projectile class of the projectile to launch + * @return the launched projectile + */ + public T launchProjectile(Class projectile); + + /** + * Launches a {@link Projectile} from the ProjectileSource with an + * initial velocity. + * + * @param a projectile subclass + * @param projectile class of the projectile to launch + * @param velocity the velocity with which to launch + * @return the launched projectile + */ + public T launchProjectile(Class projectile, Vector velocity); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitRunnable.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitRunnable.java new file mode 100644 index 0000000..c146ec7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitRunnable.java @@ -0,0 +1,149 @@ +package org.bukkit.scheduler; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +/** + * This class is provided as an easy way to handle scheduling tasks. + */ +public abstract class BukkitRunnable implements Runnable { + private int taskId = -1; + + /** + * Attempts to cancel this task. + * + * @throws IllegalStateException if task was not scheduled yet + */ + public synchronized void cancel() throws IllegalStateException { + Bukkit.getScheduler().cancelTask(getTaskId()); + } + + /** + * Schedules this in the Bukkit scheduler to run on next tick. + * + * @param plugin the reference to the plugin scheduling task + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalStateException if this was already scheduled + * @see BukkitScheduler#runTask(Plugin, Runnable) + */ + public synchronized BukkitTask runTask(Plugin plugin) throws IllegalArgumentException, IllegalStateException { + checkState(); + return setupId(Bukkit.getScheduler().runTask(plugin, (Runnable) this)); + } + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Schedules this in the Bukkit scheduler to run asynchronously. + * + * @param plugin the reference to the plugin scheduling task + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalStateException if this was already scheduled + * @see BukkitScheduler#runTaskAsynchronously(Plugin, Runnable) + */ + public synchronized BukkitTask runTaskAsynchronously(Plugin plugin) throws IllegalArgumentException, IllegalStateException { + checkState(); + return setupId(Bukkit.getScheduler().runTaskAsynchronously(plugin, (Runnable) this)); + } + + /** + * Schedules this to run after the specified number of server ticks. + * + * @param plugin the reference to the plugin scheduling task + * @param delay the ticks to wait before running the task + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalStateException if this was already scheduled + * @see BukkitScheduler#runTaskLater(Plugin, Runnable, long) + */ + public synchronized BukkitTask runTaskLater(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException { + checkState(); + return setupId(Bukkit.getScheduler().runTaskLater(plugin, (Runnable) this, delay)); + } + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Schedules this to run asynchronously after the specified number of + * server ticks. + * + * @param plugin the reference to the plugin scheduling task + * @param delay the ticks to wait before running the task + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalStateException if this was already scheduled + * @see BukkitScheduler#runTaskLaterAsynchronously(Plugin, Runnable, long) + */ + public synchronized BukkitTask runTaskLaterAsynchronously(Plugin plugin, long delay) throws IllegalArgumentException, IllegalStateException { + checkState(); + return setupId(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, (Runnable) this, delay)); + } + + /** + * Schedules this to repeatedly run until cancelled, starting after the + * specified number of server ticks. + * + * @param plugin the reference to the plugin scheduling task + * @param delay the ticks to wait before running the task + * @param period the ticks to wait between runs + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalStateException if this was already scheduled + * @see BukkitScheduler#runTaskTimer(Plugin, Runnable, long, long) + */ + public synchronized BukkitTask runTaskTimer(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException { + checkState(); + return setupId(Bukkit.getScheduler().runTaskTimer(plugin, (Runnable) this, delay, period)); + } + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Schedules this to repeatedly run asynchronously until cancelled, + * starting after the specified number of server ticks. + * + * @param plugin the reference to the plugin scheduling task + * @param delay the ticks to wait before running the task for the first + * time + * @param period the ticks to wait between runs + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalStateException if this was already scheduled + * @see BukkitScheduler#runTaskTimerAsynchronously(Plugin, Runnable, long, + * long) + */ + public synchronized BukkitTask runTaskTimerAsynchronously(Plugin plugin, long delay, long period) throws IllegalArgumentException, IllegalStateException { + checkState(); + return setupId(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, (Runnable) this, delay, period)); + } + + /** + * Gets the task id for this runnable. + * + * @return the task id that this runnable was scheduled as + * @throws IllegalStateException if task was not scheduled yet + */ + public synchronized int getTaskId() throws IllegalStateException { + final int id = taskId; + if (id == -1) { + throw new IllegalStateException("Not scheduled yet"); + } + return id; + } + + private void checkState() { + if (taskId != -1) { + throw new IllegalStateException("Already scheduled as " + taskId); + } + } + + private BukkitTask setupId(final BukkitTask task) { + this.taskId = task.getTaskId(); + return task; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitScheduler.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitScheduler.java new file mode 100644 index 0000000..6e28205 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitScheduler.java @@ -0,0 +1,369 @@ +package org.bukkit.scheduler; + +import org.bukkit.plugin.Plugin; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.List; + +public interface BukkitScheduler { + + /** + * Schedules a once off task to occur after a delay. + *

+ * This task will be executed by the main server thread. + * + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @param delay Delay in server ticks before executing task + * @return Task id number (-1 if scheduling failed) + */ + public int scheduleSyncDelayedTask(Plugin plugin, Runnable task, long delay); + + /** + * @deprecated Use {@link BukkitRunnable#runTaskLater(Plugin, long)} + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @param delay Delay in server ticks before executing task + * @return Task id number (-1 if scheduling failed) + */ + @Deprecated + public int scheduleSyncDelayedTask(Plugin plugin, BukkitRunnable task, long delay); + + /** + * Schedules a once off task to occur as soon as possible. + *

+ * This task will be executed by the main server thread. + * + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @return Task id number (-1 if scheduling failed) + */ + public int scheduleSyncDelayedTask(Plugin plugin, Runnable task); + + /** + * @deprecated Use {@link BukkitRunnable#runTask(Plugin)} + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @return Task id number (-1 if scheduling failed) + */ + @Deprecated + public int scheduleSyncDelayedTask(Plugin plugin, BukkitRunnable task); + + /** + * Schedules a repeating task. + *

+ * This task will be executed by the main server thread. + * + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @param delay Delay in server ticks before executing first repeat + * @param period Period in server ticks of the task + * @return Task id number (-1 if scheduling failed) + */ + public int scheduleSyncRepeatingTask(Plugin plugin, Runnable task, long delay, long period); + + /** + * @deprecated Use {@link BukkitRunnable#runTaskTimer(Plugin, long, long)} * + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @param delay Delay in server ticks before executing first repeat + * @param period Period in server ticks of the task + * @return Task id number (-1 if scheduling failed) + */ + @Deprecated + public int scheduleSyncRepeatingTask(Plugin plugin, BukkitRunnable task, long delay, long period); + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Schedules a once off task to occur after a delay. This task will be + * executed by a thread managed by the scheduler. + * + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @param delay Delay in server ticks before executing task + * @return Task id number (-1 if scheduling failed) + * @deprecated This name is misleading, as it does not schedule "a sync" + * task, but rather, "an async" task + */ + @Deprecated + public int scheduleAsyncDelayedTask(Plugin plugin, Runnable task, long delay); + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Schedules a once off task to occur as soon as possible. This task will + * be executed by a thread managed by the scheduler. + * + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @return Task id number (-1 if scheduling failed) + * @deprecated This name is misleading, as it does not schedule "a sync" + * task, but rather, "an async" task + */ + @Deprecated + public int scheduleAsyncDelayedTask(Plugin plugin, Runnable task); + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Schedules a repeating task. This task will be executed by a thread + * managed by the scheduler. + * + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @param delay Delay in server ticks before executing first repeat + * @param period Period in server ticks of the task + * @return Task id number (-1 if scheduling failed) + * @deprecated This name is misleading, as it does not schedule "a sync" + * task, but rather, "an async" task + */ + @Deprecated + public int scheduleAsyncRepeatingTask(Plugin plugin, Runnable task, long delay, long period); + + /** + * Calls a method on the main thread and returns a Future object. This + * task will be executed by the main server thread. + *

    + *
  • Note: The Future.get() methods must NOT be called from the main + * thread. + *
  • Note2: There is at least an average of 10ms latency until the + * isDone() method returns true. + *
+ * @param The callable's return type + * @param plugin Plugin that owns the task + * @param task Task to be executed + * @return Future Future object related to the task + */ + public Future callSyncMethod(Plugin plugin, Callable task); + + /** + * Removes task from scheduler. + * + * @param taskId Id number of task to be removed + */ + public void cancelTask(int taskId); + + /** + * Removes all tasks associated with a particular plugin from the + * scheduler. + * + * @param plugin Owner of tasks to be removed + */ + public void cancelTasks(Plugin plugin); + + /** + * Removes all tasks from the scheduler. + */ + public void cancelAllTasks(); + + /** + * Check if the task currently running. + *

+ * A repeating task might not be running currently, but will be running in + * the future. A task that has finished, and does not repeat, will not be + * running ever again. + *

+ * Explicitly, a task is running if there exists a thread for it, and that + * thread is alive. + * + * @param taskId The task to check. + *

+ * @return If the task is currently running. + */ + public boolean isCurrentlyRunning(int taskId); + + /** + * Check if the task queued to be run later. + *

+ * If a repeating task is currently running, it might not be queued now + * but could be in the future. A task that is not queued, and not running, + * will not be queued again. + * + * @param taskId The task to check. + *

+ * @return If the task is queued to be run. + */ + public boolean isQueued(int taskId); + + /** + * Returns a list of all active workers. + *

+ * This list contains asynch tasks that are being executed by separate + * threads. + * + * @return Active workers + */ + public List getActiveWorkers(); + + /** + * Returns a list of all pending tasks. The ordering of the tasks is not + * related to their order of execution. + * + * @return Active workers + */ + public List getPendingTasks(); + + /** + * Returns a task that will run on the next server tick. + * + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + public BukkitTask runTask(Plugin plugin, Runnable task) throws IllegalArgumentException; + + /** + * @deprecated Use {@link BukkitRunnable#runTask(Plugin)} + * + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + @Deprecated + public BukkitTask runTask(Plugin plugin, BukkitRunnable task) throws IllegalArgumentException; + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Returns a task that will run asynchronously. + * + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + public BukkitTask runTaskAsynchronously(Plugin plugin, Runnable task) throws IllegalArgumentException; + + /** + * @deprecated Use {@link BukkitRunnable#runTaskAsynchronously(Plugin)} + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + @Deprecated + public BukkitTask runTaskAsynchronously(Plugin plugin, BukkitRunnable task) throws IllegalArgumentException; + + /** + * Returns a task that will run after the specified number of server + * ticks. + * + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @param delay the ticks to wait before running the task + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + public BukkitTask runTaskLater(Plugin plugin, Runnable task, long delay) throws IllegalArgumentException; + + /** + * @deprecated Use {@link BukkitRunnable#runTaskLater(Plugin, long)} + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @param delay the ticks to wait before running the task + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + @Deprecated + public BukkitTask runTaskLater(Plugin plugin, BukkitRunnable task, long delay) throws IllegalArgumentException; + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Returns a task that will run asynchronously after the specified number + * of server ticks. + * + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @param delay the ticks to wait before running the task + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + public BukkitTask runTaskLaterAsynchronously(Plugin plugin, Runnable task, long delay) throws IllegalArgumentException; + + /** + * @deprecated Use {@link BukkitRunnable#runTaskLaterAsynchronously(Plugin, long)} + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @param delay the ticks to wait before running the task + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + @Deprecated + public BukkitTask runTaskLaterAsynchronously(Plugin plugin, BukkitRunnable task, long delay) throws IllegalArgumentException; + + /** + * Returns a task that will repeatedly run until cancelled, starting after + * the specified number of server ticks. + * + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @param delay the ticks to wait before running the task + * @param period the ticks to wait between runs + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + public BukkitTask runTaskTimer(Plugin plugin, Runnable task, long delay, long period) throws IllegalArgumentException; + + /** + * @deprecated Use {@link BukkitRunnable#runTaskTimer(Plugin, long, long)} + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @param delay the ticks to wait before running the task + * @param period the ticks to wait between runs + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + @Deprecated + public BukkitTask runTaskTimer(Plugin plugin, BukkitRunnable task, long delay, long period) throws IllegalArgumentException; + + /** + * Asynchronous tasks should never access any API in Bukkit. Great care + * should be taken to assure the thread-safety of asynchronous tasks. + *

+ * Returns a task that will repeatedly run asynchronously until cancelled, + * starting after the specified number of server ticks. + * + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @param delay the ticks to wait before running the task for the first + * time + * @param period the ticks to wait between runs + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + public BukkitTask runTaskTimerAsynchronously(Plugin plugin, Runnable task, long delay, long period) throws IllegalArgumentException; + + /** + * @deprecated Use {@link BukkitRunnable#runTaskTimerAsynchronously(Plugin, long, long)} + * @param plugin the reference to the plugin scheduling task + * @param task the task to be run + * @param delay the ticks to wait before running the task for the first + * time + * @param period the ticks to wait between runs + * @return a BukkitTask that contains the id number + * @throws IllegalArgumentException if plugin is null + * @throws IllegalArgumentException if task is null + */ + @Deprecated + public BukkitTask runTaskTimerAsynchronously(Plugin plugin, BukkitRunnable task, long delay, long period) throws IllegalArgumentException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitTask.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitTask.java new file mode 100644 index 0000000..e447e64 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitTask.java @@ -0,0 +1,35 @@ +package org.bukkit.scheduler; + +import org.bukkit.plugin.Plugin; + +/** + * Represents a task being executed by the scheduler + */ +public interface BukkitTask { + + /** + * Returns the taskId for the task. + * + * @return Task id number + */ + public int getTaskId(); + + /** + * Returns the Plugin that owns this task. + * + * @return The Plugin that owns the task + */ + public Plugin getOwner(); + + /** + * Returns true if the Task is a sync task. + * + * @return true if the task is run by main thread + */ + public boolean isSync(); + + /** + * Will attempt to cancel this task. + */ + public void cancel(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitWorker.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitWorker.java new file mode 100644 index 0000000..fe1afbd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scheduler/BukkitWorker.java @@ -0,0 +1,34 @@ +package org.bukkit.scheduler; + +import org.bukkit.plugin.Plugin; + +/** + * Represents a worker thread for the scheduler. This gives information about + * the Thread object for the task, owner of the task and the taskId. + *

+ * Workers are used to execute async tasks. + */ +public interface BukkitWorker { + + /** + * Returns the taskId for the task being executed by this worker. + * + * @return Task id number + */ + public int getTaskId(); + + /** + * Returns the Plugin that owns this task. + * + * @return The Plugin that owns the task + */ + public Plugin getOwner(); + + /** + * Returns the thread for the worker. + * + * @return The Thread object for the worker + */ + public Thread getThread(); + +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Criterias.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Criterias.java new file mode 100644 index 0000000..cd81c87 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Criterias.java @@ -0,0 +1,20 @@ +package org.bukkit.scoreboard; + +/** + * Criteria names which trigger an objective to be modified by actions in-game + */ +public class Criterias { + public static final String HEALTH; + public static final String PLAYER_KILLS; + public static final String TOTAL_KILLS; + public static final String DEATHS; + + static { + HEALTH="health"; + PLAYER_KILLS="playerKillCount"; + TOTAL_KILLS="totalKillCount"; + DEATHS="deathCount"; + } + + private Criterias() {} +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/DisplaySlot.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/DisplaySlot.java new file mode 100644 index 0000000..5d58a18 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/DisplaySlot.java @@ -0,0 +1,10 @@ +package org.bukkit.scoreboard; + +/** + * Locations for displaying objectives to the player + */ +public enum DisplaySlot { + BELOW_NAME, + PLAYER_LIST, + SIDEBAR; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/NameTagVisibility.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/NameTagVisibility.java new file mode 100644 index 0000000..3137bf6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/NameTagVisibility.java @@ -0,0 +1,21 @@ +package org.bukkit.scoreboard; + +public enum NameTagVisibility { + + /** + * Always show the player's nametag. + */ + ALWAYS, + /** + * Never show the player's nametag. + */ + NEVER, + /** + * Show the player's nametag only to his own team members. + */ + HIDE_FOR_OTHER_TEAMS, + /** + * Show the player's nametag only to members of other teams. + */ + HIDE_FOR_OWN_TEAM; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Objective.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Objective.java new file mode 100644 index 0000000..321aac7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Objective.java @@ -0,0 +1,110 @@ +package org.bukkit.scoreboard; + +import org.bukkit.OfflinePlayer; + +/** + * An objective on a scoreboard that can show scores specific to entries. This + * objective is only relevant to the display of the associated {@link + * #getScoreboard() scoreboard}. + */ +public interface Objective { + + /** + * Gets the name of this Objective + * + * @return this objective'ss name + * @throws IllegalStateException if this objective has been unregistered + */ + String getName() throws IllegalStateException; + + /** + * Gets the name displayed to players for this objective + * + * @return this objective's display name + * @throws IllegalStateException if this objective has been unregistered + */ + String getDisplayName() throws IllegalStateException; + + /** + * Sets the name displayed to players for this objective. + * + * @param displayName Display name to set + * @throws IllegalStateException if this objective has been unregistered + * @throws IllegalArgumentException if displayName is null + * @throws IllegalArgumentException if displayName is longer than 32 + * characters. + */ + void setDisplayName(String displayName) throws IllegalStateException, IllegalArgumentException; + + /** + * Gets the criteria this objective tracks. + * + * @return this objective's criteria + * @throws IllegalStateException if this objective has been unregistered + */ + String getCriteria() throws IllegalStateException; + + /** + * Gets if the objective's scores can be modified directly by a plugin. + * + * @return true if scores are modifiable + * @throws IllegalStateException if this objective has been unregistered + * @see Criterias#HEALTH + */ + boolean isModifiable() throws IllegalStateException; + + /** + * Gets the scoreboard to which this objective is attached. + * + * @return Owning scoreboard, or null if it has been {@link #unregister() + * unregistered} + */ + Scoreboard getScoreboard(); + + /** + * Unregisters this objective from the {@link Scoreboard scoreboard.} + * + * @throws IllegalStateException if this objective has been unregistered + */ + void unregister() throws IllegalStateException; + + /** + * Sets this objective to display on the specified slot for the + * scoreboard, removing it from any other display slot. + * + * @param slot display slot to change, or null to not display + * @throws IllegalStateException if this objective has been unregistered + */ + void setDisplaySlot(DisplaySlot slot) throws IllegalStateException; + + /** + * Gets the display slot this objective is displayed at. + * + * @return the display slot for this objective, or null if not displayed + * @throws IllegalStateException if this objective has been unregistered + */ + DisplaySlot getDisplaySlot() throws IllegalStateException; + + /** + * Gets a player's Score for an Objective on this Scoreboard + * + * @param player Player for the Score + * @return Score tracking the Objective and player specified + * @throws IllegalArgumentException if player is null + * @throws IllegalStateException if this objective has been unregistered + * @deprecated Scoreboards can contain entries that aren't players + * @see #getScore(String) + */ + @Deprecated + Score getScore(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException; + + /** + * Gets an entry's Score for an Objective on this Scoreboard. + * + * @param entry Entry for the Score + * @return Score tracking the Objective and entry specified + * @throws IllegalArgumentException if entry is null + * @throws IllegalStateException if this objective has been unregistered + */ + Score getScore(String entry) throws IllegalArgumentException, IllegalStateException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Score.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Score.java new file mode 100644 index 0000000..2410cbd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Score.java @@ -0,0 +1,72 @@ +package org.bukkit.scoreboard; + +import org.bukkit.OfflinePlayer; + +/** + * A score entry for an {@link #getEntry() entry} on an {@link + * #getObjective() objective}. Changing this will not affect any other + * objective or scoreboard. + */ +public interface Score { + + /** + * Gets the OfflinePlayer being tracked by this Score + * + * @return this Score's tracked player + * @deprecated Scoreboards can contain entries that aren't players + * @see #getEntry() + */ + @Deprecated + OfflinePlayer getPlayer(); + + /** + * Gets the entry being tracked by this Score + * + * @return this Score's tracked entry + */ + String getEntry(); + + /** + * Gets the Objective being tracked by this Score + * + * @return this Score's tracked objective + */ + Objective getObjective(); + + /** + * Gets the current score + * + * @return the current score + * @throws IllegalStateException if the associated objective has been + * unregistered + */ + int getScore() throws IllegalStateException; + + /** + * Sets the current score. + * + * @param score New score + * @throws IllegalStateException if the associated objective has been + * unregistered + */ + void setScore(int score) throws IllegalStateException; + + // Spigot start + /** + * Shows if this score has been set at any point in time. + * + * @return if this score has been set before + * @throws IllegalStateException if the associated objective has been + * unregistered + */ + boolean isScoreSet() throws IllegalStateException; + // Spigot end + + /** + * Gets the scoreboard for the associated objective. + * + * @return the owning objective's scoreboard, or null if it has been + * {@link Objective#unregister() unregistered} + */ + Scoreboard getScoreboard(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Scoreboard.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Scoreboard.java new file mode 100644 index 0000000..7008610 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Scoreboard.java @@ -0,0 +1,171 @@ +package org.bukkit.scoreboard; + +import java.util.Set; + +import org.bukkit.OfflinePlayer; + +/** + * A scoreboard + */ +public interface Scoreboard { + + /** + * Registers an Objective on this Scoreboard + * + * @param name Name of the Objective + * @param criteria Criteria for the Objective + * @return The registered Objective + * @throws IllegalArgumentException if name is null + * @throws IllegalArgumentException if criteria is null + * @throws IllegalArgumentException if an objective by that name already + * exists + */ + Objective registerNewObjective(String name, String criteria) throws IllegalArgumentException; + + /** + * Gets an Objective on this Scoreboard by name + * + * @param name Name of the Objective + * @return the Objective or null if it does not exist + * @throws IllegalArgumentException if name is null + */ + Objective getObjective(String name) throws IllegalArgumentException; + + /** + * Gets all Objectives of a Criteria on the Scoreboard + * + * @param criteria Criteria to search by + * @return an immutable set of Objectives using the specified Criteria + */ + Set getObjectivesByCriteria(String criteria) throws IllegalArgumentException; + + /** + * Gets all Objectives on this Scoreboard + * + * @return An immutable set of all Objectives on this Scoreboard + */ + Set getObjectives(); + + /** + * Gets the Objective currently displayed in a DisplaySlot on this + * Scoreboard + * + * @param slot The DisplaySlot + * @return the Objective currently displayed or null if nothing is + * displayed in that DisplaySlot + * @throws IllegalArgumentException if slot is null + */ + Objective getObjective(DisplaySlot slot) throws IllegalArgumentException; + + /** + * Gets all scores for a player on this Scoreboard + * + * @param player the player whose scores are being retrieved + * @return immutable set of all scores tracked for the player + * @throws IllegalArgumentException if player is null + * @deprecated Scoreboards can contain entries that aren't players + * @see #getScores(String) + */ + @Deprecated + Set getScores(OfflinePlayer player) throws IllegalArgumentException; + + /** + * Gets all scores for an entry on this Scoreboard + * + * @param entry the entry whose scores are being retrieved + * @return immutable set of all scores tracked for the entry + * @throws IllegalArgumentException if entry is null + */ + Set getScores(String entry) throws IllegalArgumentException; + + /** + * Removes all scores for a player on this Scoreboard + * + * @param player the player to drop all current scores for + * @throws IllegalArgumentException if player is null + * @deprecated Scoreboards can contain entries that aren't players + * @see #resetScores(String) + */ + @Deprecated + void resetScores(OfflinePlayer player) throws IllegalArgumentException; + + /** + * Removes all scores for an entry on this Scoreboard + * + * @param entry the entry to drop all current scores for + * @throws IllegalArgumentException if entry is null + */ + void resetScores(String entry) throws IllegalArgumentException; + + /** + * Gets a player's Team on this Scoreboard + * + * @param player the player to search for + * @return the player's Team or null if the player is not on a team + * @throws IllegalArgumentException if player is null + * @deprecated Scoreboards can contain entries that aren't players + * @see #getEntryTeam(String) + */ + @Deprecated + Team getPlayerTeam(OfflinePlayer player) throws IllegalArgumentException; + + /** + * Gets a entries Team on this Scoreboard + * + * @param entry the entry to search for + * @return the entries Team or null if the entry is not on a team + * @throws IllegalArgumentException if entry is null + */ + Team getEntryTeam(String entry) throws IllegalArgumentException; + + /** + * Gets a Team by name on this Scoreboard + * + * @param teamName Team name + * @return the matching Team or null if no matches + * @throws IllegalArgumentException if teamName is null + */ + Team getTeam(String teamName) throws IllegalArgumentException; + + /** + * Gets all teams on this Scoreboard + * + * @return an immutable set of Teams + */ + Set getTeams(); + + /** + * Registers a Team on this Scoreboard + * + * @param name Team name + * @return registered Team + * @throws IllegalArgumentException if name is null + * @throws IllegalArgumentException if team by that name already exists + */ + Team registerNewTeam(String name) throws IllegalArgumentException; + + /** + * Gets all players tracked by this Scoreboard + * + * @return immutable set of all tracked players + * @deprecated Scoreboards can contain entries that aren't players + * @see #getEntries() + */ + @Deprecated + Set getPlayers(); + + /** + * Gets all entries tracked by this Scoreboard + * + * @return immutable set of all tracked entries + */ + Set getEntries(); + + /** + * Clears any objective in the specified slot. + * + * @param slot the slot to remove objectives + * @throws IllegalArgumentException if slot is null + */ + void clearSlot(DisplaySlot slot) throws IllegalArgumentException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/ScoreboardManager.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/ScoreboardManager.java new file mode 100644 index 0000000..00b67a1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/ScoreboardManager.java @@ -0,0 +1,29 @@ +package org.bukkit.scoreboard; + +import java.lang.ref.WeakReference; + +/** + * Manager of Scoreboards + */ +public interface ScoreboardManager { + + /** + * Gets the primary Scoreboard controlled by the server. + *

+ * This Scoreboard is saved by the server, is affected by the /scoreboard + * command, and is the scoreboard shown by default to players. + * + * @return the default sever scoreboard + */ + Scoreboard getMainScoreboard(); + + /** + * Gets a new Scoreboard to be tracked by the server. This scoreboard will + * be tracked as long as a reference is kept, either by a player or by a + * plugin. + * + * @return the registered Scoreboard + * @see WeakReference + */ + Scoreboard getNewScoreboard(); +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Team.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Team.java new file mode 100644 index 0000000..0fdcebd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/scoreboard/Team.java @@ -0,0 +1,240 @@ +package org.bukkit.scoreboard; + +import java.util.Set; + +import org.bukkit.OfflinePlayer; +import org.bukkit.potion.PotionEffectType; + +/** + * A team on a scoreboard that has a common display theme and other + * properties. This team is only relevant to the display of the associated + * {@link #getScoreboard() scoreboard}. + */ +public interface Team { + + /** + * Gets the name of this Team + * + * @return Objective name + * @throws IllegalStateException if this team has been unregistered + */ + String getName() throws IllegalStateException; + + /** + * Gets the name displayed to entries for this team + * + * @return Team display name + * @throws IllegalStateException if this team has been unregistered + */ + String getDisplayName() throws IllegalStateException; + + /** + * Sets the name displayed to entries for this team + * + * @param displayName New display name + * @throws IllegalArgumentException if displayName is longer than 32 + * characters. + * @throws IllegalStateException if this team has been unregistered + */ + void setDisplayName(String displayName) throws IllegalStateException, IllegalArgumentException; + + /** + * Gets the prefix prepended to the display of entries on this team. + * + * @return Team prefix + * @throws IllegalStateException if this team has been unregistered + */ + String getPrefix() throws IllegalStateException; + + /** + * Sets the prefix prepended to the display of entries on this team. + * + * @param prefix New prefix + * @throws IllegalArgumentException if prefix is null + * @throws IllegalArgumentException if prefix is longer than 16 + * characters + * @throws IllegalStateException if this team has been unregistered + */ + void setPrefix(String prefix) throws IllegalStateException, IllegalArgumentException; + + /** + * Gets the suffix appended to the display of entries on this team. + * + * @return the team's current suffix + * @throws IllegalStateException if this team has been unregistered + */ + String getSuffix() throws IllegalStateException; + + /** + * Sets the suffix appended to the display of entries on this team. + * + * @param suffix the new suffix for this team. + * @throws IllegalArgumentException if suffix is null + * @throws IllegalArgumentException if suffix is longer than 16 + * characters + * @throws IllegalStateException if this team has been unregistered + */ + void setSuffix(String suffix) throws IllegalStateException, IllegalArgumentException; + + /** + * Gets the team friendly fire state + * + * @return true if friendly fire is enabled + * @throws IllegalStateException if this team has been unregistered + */ + boolean allowFriendlyFire() throws IllegalStateException; + + /** + * Sets the team friendly fire state + * + * @param enabled true if friendly fire is to be allowed + * @throws IllegalStateException if this team has been unregistered + */ + void setAllowFriendlyFire(boolean enabled) throws IllegalStateException; + + /** + * Gets the team's ability to see {@link PotionEffectType#INVISIBILITY + * invisible} teammates. + * + * @return true if team members can see invisible members + * @throws IllegalStateException if this team has been unregistered + */ + boolean canSeeFriendlyInvisibles() throws IllegalStateException; + + /** + * Sets the team's ability to see {@link PotionEffectType#INVISIBILITY + * invisible} teammates. + * + * @param enabled true if invisible teammates are to be visible + * @throws IllegalStateException if this team has been unregistered + */ + void setCanSeeFriendlyInvisibles(boolean enabled) throws IllegalStateException; + + /** + * Gets the team's ability to see name tags + * + * @return the current name tag visibilty for the team + * @throws IllegalArgumentException if this team has been unregistered + */ + NameTagVisibility getNameTagVisibility() throws IllegalArgumentException; + + /** + * Set's the team's ability to see name tags + * + * @param visibility The nameTagVisibilty to set + * @throws IllegalArgumentException if this team has been unregistered + */ + void setNameTagVisibility(NameTagVisibility visibility) throws IllegalArgumentException; + + /** + * Gets the Set of players on the team + * + * @return players on the team + * @throws IllegalStateException if this team has been unregistered\ + * @deprecated Teams can contain entries that aren't players + * @see #getEntries() + */ + @Deprecated + Set getPlayers() throws IllegalStateException; + + /** + * Gets the Set of entries on the team + * + * @return entries on the team + * @throws IllegalStateException if this entries has been unregistered\ + */ + Set getEntries() throws IllegalStateException; + + /** + * Gets the size of the team + * + * @return number of entries on the team + * @throws IllegalStateException if this team has been unregistered + */ + int getSize() throws IllegalStateException; + + /** + * Gets the Scoreboard to which this team is attached + * + * @return Owning scoreboard, or null if this team has been {@link + * #unregister() unregistered} + */ + Scoreboard getScoreboard(); + + /** + * This puts the specified player onto this team for the scoreboard. + *

+ * This will remove the player from any other team on the scoreboard. + * + * @param player the player to add + * @throws IllegalArgumentException if player is null + * @throws IllegalStateException if this team has been unregistered + * @deprecated Teams can contain entries that aren't players + * @see #addEntry(String) + */ + @Deprecated + void addPlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException; + + /** + * This puts the specified entry onto this team for the scoreboard. + *

+ * This will remove the entry from any other team on the scoreboard. + * + * @param entry the entry to add + * @throws IllegalArgumentException if entry is null + * @throws IllegalStateException if this team has been unregistered + */ + void addEntry(String entry) throws IllegalStateException, IllegalArgumentException; + + /** + * Removes the player from this team. + * + * @param player the player to remove + * @return if the player was on this team + * @throws IllegalArgumentException if player is null + * @throws IllegalStateException if this team has been unregistered + * @deprecated Teams can contain entries that aren't players + * @see #removeEntry(String) + */ + @Deprecated + boolean removePlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException; + + /** + * Removes the entry from this team. + * + * @param entry the entry to remove + * @throws IllegalArgumentException if entry is null + * @throws IllegalStateException if this team has been unregistered + * @return if the entry was a part of this team + */ + boolean removeEntry(String entry) throws IllegalStateException, IllegalArgumentException; + + /** + * Unregisters this team from the Scoreboard + * + * @throws IllegalStateException if this team has been unregistered + */ + void unregister() throws IllegalStateException; + + /** + * Checks to see if the specified player is a member of this team. + * + * @param player the player to search for + * @return true if the player is a member of this team + * @throws IllegalArgumentException if player is null + * @throws IllegalStateException if this team has been unregistered + * @deprecated Teams can contain entries that aren't players + * @see #hasEntry(String) + */ + @Deprecated + boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException; + /** + * Checks to see if the specified entry is a member of this team. + * + * @param entry the entry to search for + * @return true if the entry is a member of this team + * @throws IllegalArgumentException if entry is null + * @throws IllegalStateException if this team has been unregistered + */ + boolean hasEntry(String entry) throws IllegalArgumentException,IllegalStateException; +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/BlockIterator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/BlockIterator.java new file mode 100644 index 0000000..5c85778 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/BlockIterator.java @@ -0,0 +1,357 @@ +package org.bukkit.util; + +import static org.bukkit.util.NumberConversions.*; + +import org.bukkit.World; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.LivingEntity; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * This class performs ray tracing and iterates along blocks on a line + */ +public class BlockIterator implements Iterator { + + private final World world; + private final int maxDistance; + + private static final int gridSize = 1 << 24; + + private boolean end = false; + + private Block[] blockQueue = new Block[3]; + private int currentBlock = 0; + private int currentDistance = 0; + private int maxDistanceInt; + + private int secondError; + private int thirdError; + + private int secondStep; + private int thirdStep; + + private BlockFace mainFace; + private BlockFace secondFace; + private BlockFace thirdFace; + + /** + * Constructs the BlockIterator + * + * @param world The world to use for tracing + * @param start A Vector giving the initial location for the trace + * @param direction A Vector pointing in the direction for the trace + * @param yOffset The trace begins vertically offset from the start vector + * by this value + * @param maxDistance This is the maximum distance in blocks for the + * trace. Setting this value above 140 may lead to problems with + * unloaded chunks. A value of 0 indicates no limit + * + */ + public BlockIterator(World world, Vector start, Vector direction, double yOffset, int maxDistance) { + this.world = world; + this.maxDistance = maxDistance; + + Vector startClone = start.clone(); + + startClone.setY(startClone.getY() + yOffset); + + currentDistance = 0; + + double mainDirection = 0; + double secondDirection = 0; + double thirdDirection = 0; + + double mainPosition = 0; + double secondPosition = 0; + double thirdPosition = 0; + + Block startBlock = this.world.getBlockAt(floor(startClone.getX()), floor(startClone.getY()), floor(startClone.getZ())); + + if (getXLength(direction) > mainDirection) { + mainFace = getXFace(direction); + mainDirection = getXLength(direction); + mainPosition = getXPosition(direction, startClone, startBlock); + + secondFace = getYFace(direction); + secondDirection = getYLength(direction); + secondPosition = getYPosition(direction, startClone, startBlock); + + thirdFace = getZFace(direction); + thirdDirection = getZLength(direction); + thirdPosition = getZPosition(direction, startClone, startBlock); + } + if (getYLength(direction) > mainDirection) { + mainFace = getYFace(direction); + mainDirection = getYLength(direction); + mainPosition = getYPosition(direction, startClone, startBlock); + + secondFace = getZFace(direction); + secondDirection = getZLength(direction); + secondPosition = getZPosition(direction, startClone, startBlock); + + thirdFace = getXFace(direction); + thirdDirection = getXLength(direction); + thirdPosition = getXPosition(direction, startClone, startBlock); + } + if (getZLength(direction) > mainDirection) { + mainFace = getZFace(direction); + mainDirection = getZLength(direction); + mainPosition = getZPosition(direction, startClone, startBlock); + + secondFace = getXFace(direction); + secondDirection = getXLength(direction); + secondPosition = getXPosition(direction, startClone, startBlock); + + thirdFace = getYFace(direction); + thirdDirection = getYLength(direction); + thirdPosition = getYPosition(direction, startClone, startBlock); + } + + // trace line backwards to find intercept with plane perpendicular to the main axis + + double d = mainPosition / mainDirection; // how far to hit face behind + double secondd = secondPosition - secondDirection * d; + double thirdd = thirdPosition - thirdDirection * d; + + // Guarantee that the ray will pass though the start block. + // It is possible that it would miss due to rounding + // This should only move the ray by 1 grid position + secondError = floor(secondd * gridSize); + secondStep = round(secondDirection / mainDirection * gridSize); + thirdError = floor(thirdd * gridSize); + thirdStep = round(thirdDirection / mainDirection * gridSize); + + if (secondError + secondStep <= 0) { + secondError = -secondStep + 1; + } + + if (thirdError + thirdStep <= 0) { + thirdError = -thirdStep + 1; + } + + Block lastBlock; + + lastBlock = startBlock.getRelative(mainFace.getOppositeFace()); + + if (secondError < 0) { + secondError += gridSize; + lastBlock = lastBlock.getRelative(secondFace.getOppositeFace()); + } + + if (thirdError < 0) { + thirdError += gridSize; + lastBlock = lastBlock.getRelative(thirdFace.getOppositeFace()); + } + + // This means that when the variables are positive, it means that the coord=1 boundary has been crossed + secondError -= gridSize; + thirdError -= gridSize; + + blockQueue[0] = lastBlock; + currentBlock = -1; + + scan(); + + boolean startBlockFound = false; + + for (int cnt = currentBlock; cnt >= 0; cnt--) { + if (blockEquals(blockQueue[cnt], startBlock)) { + currentBlock = cnt; + startBlockFound = true; + break; + } + } + + if (!startBlockFound) { + throw new IllegalStateException("Start block missed in BlockIterator"); + } + + // Calculate the number of planes passed to give max distance + maxDistanceInt = round(maxDistance / (Math.sqrt(mainDirection * mainDirection + secondDirection * secondDirection + thirdDirection * thirdDirection) / mainDirection)); + + } + + private boolean blockEquals(Block a, Block b) { + return a.getX() == b.getX() && a.getY() == b.getY() && a.getZ() == b.getZ(); + } + + private BlockFace getXFace(Vector direction) { + return ((direction.getX() > 0) ? BlockFace.EAST : BlockFace.WEST); + } + + private BlockFace getYFace(Vector direction) { + return ((direction.getY() > 0) ? BlockFace.UP : BlockFace.DOWN); + } + + private BlockFace getZFace(Vector direction) { + return ((direction.getZ() > 0) ? BlockFace.SOUTH : BlockFace.NORTH); + } + + private double getXLength(Vector direction) { + return Math.abs(direction.getX()); + } + + private double getYLength(Vector direction) { + return Math.abs(direction.getY()); + } + + private double getZLength(Vector direction) { + return Math.abs(direction.getZ()); + } + + private double getPosition(double direction, double position, int blockPosition) { + return direction > 0 ? (position - blockPosition) : (blockPosition + 1 - position); + } + + private double getXPosition(Vector direction, Vector position, Block block) { + return getPosition(direction.getX(), position.getX(), block.getX()); + } + + private double getYPosition(Vector direction, Vector position, Block block) { + return getPosition(direction.getY(), position.getY(), block.getY()); + } + + private double getZPosition(Vector direction, Vector position, Block block) { + return getPosition(direction.getZ(), position.getZ(), block.getZ()); + } + + /** + * Constructs the BlockIterator + * + * @param loc The location for the start of the ray trace + * @param yOffset The trace begins vertically offset from the start vector + * by this value + * @param maxDistance This is the maximum distance in blocks for the + * trace. Setting this value above 140 may lead to problems with + * unloaded chunks. A value of 0 indicates no limit + */ + public BlockIterator(Location loc, double yOffset, int maxDistance) { + this(loc.getWorld(), loc.toVector(), loc.getDirection(), yOffset, maxDistance); + } + + /** + * Constructs the BlockIterator. + * + * @param loc The location for the start of the ray trace + * @param yOffset The trace begins vertically offset from the start vector + * by this value + */ + + public BlockIterator(Location loc, double yOffset) { + this(loc.getWorld(), loc.toVector(), loc.getDirection(), yOffset, 0); + } + + /** + * Constructs the BlockIterator. + * + * @param loc The location for the start of the ray trace + */ + + public BlockIterator(Location loc) { + this(loc, 0D); + } + + /** + * Constructs the BlockIterator. + * + * @param entity Information from the entity is used to set up the trace + * @param maxDistance This is the maximum distance in blocks for the + * trace. Setting this value above 140 may lead to problems with + * unloaded chunks. A value of 0 indicates no limit + */ + + public BlockIterator(LivingEntity entity, int maxDistance) { + this(entity.getLocation(), entity.getEyeHeight(), maxDistance); + } + + /** + * Constructs the BlockIterator. + * + * @param entity Information from the entity is used to set up the trace + */ + + public BlockIterator(LivingEntity entity) { + this(entity, 0); + } + + /** + * Returns true if the iteration has more elements + */ + + public boolean hasNext() { + scan(); + return currentBlock != -1; + } + + /** + * Returns the next Block in the trace + * + * @return the next Block in the trace + */ + + public Block next() { + scan(); + if (currentBlock <= -1) { + throw new NoSuchElementException(); + } else { + return blockQueue[currentBlock--]; + } + } + + public void remove() { + throw new UnsupportedOperationException("[BlockIterator] doesn't support block removal"); + } + + private void scan() { + if (currentBlock >= 0) { + return; + } + if (maxDistance != 0 && currentDistance > maxDistanceInt) { + end = true; + return; + } + if (end) { + return; + } + + currentDistance++; + + secondError += secondStep; + thirdError += thirdStep; + + if (secondError > 0 && thirdError > 0) { + blockQueue[2] = blockQueue[0].getRelative(mainFace); + if (((long) secondStep) * ((long) thirdError) < ((long) thirdStep) * ((long) secondError)) { + blockQueue[1] = blockQueue[2].getRelative(secondFace); + blockQueue[0] = blockQueue[1].getRelative(thirdFace); + } else { + blockQueue[1] = blockQueue[2].getRelative(thirdFace); + blockQueue[0] = blockQueue[1].getRelative(secondFace); + } + thirdError -= gridSize; + secondError -= gridSize; + currentBlock = 2; + return; + } else if (secondError > 0) { + blockQueue[1] = blockQueue[0].getRelative(mainFace); + blockQueue[0] = blockQueue[1].getRelative(secondFace); + secondError -= gridSize; + currentBlock = 1; + return; + } else if (thirdError > 0) { + blockQueue[1] = blockQueue[0].getRelative(mainFace); + blockQueue[0] = blockQueue[1].getRelative(thirdFace); + thirdError -= gridSize; + currentBlock = 1; + return; + } else { + blockQueue[0] = blockQueue[0].getRelative(mainFace); + currentBlock = 0; + return; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/BlockVector.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/BlockVector.java new file mode 100644 index 0000000..bdf8f6d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/BlockVector.java @@ -0,0 +1,128 @@ +package org.bukkit.util; + +import java.util.Map; +import org.bukkit.configuration.serialization.SerializableAs; + +/** + * A vector with a hash function that floors the X, Y, Z components, a la + * BlockVector in WorldEdit. BlockVectors can be used in hash sets and + * hash maps. Be aware that BlockVectors are mutable, but it is important + * that BlockVectors are never changed once put into a hash set or hash map. + */ +@SerializableAs("BlockVector") +public class BlockVector extends Vector { + + /** + * Construct the vector with all components as 0. + */ + public BlockVector() { + this.x = 0; + this.y = 0; + this.z = 0; + } + + /** + * Construct the vector with another vector. + * + * @param vec The other vector. + */ + public BlockVector(Vector vec) { + this.x = vec.getX(); + this.y = vec.getY(); + this.z = vec.getZ(); + } + + /** + * Construct the vector with provided integer components. + * + * @param x X component + * @param y Y component + * @param z Z component + */ + public BlockVector(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Construct the vector with provided double components. + * + * @param x X component + * @param y Y component + * @param z Z component + */ + public BlockVector(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Construct the vector with provided float components. + * + * @param x X component + * @param y Y component + * @param z Z component + */ + public BlockVector(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Checks if another object is equivalent. + * + * @param obj The other object + * @return whether the other object is equivalent + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof BlockVector)) { + return false; + } + BlockVector other = (BlockVector) obj; + + return (int) other.getX() == (int) this.x && (int) other.getY() == (int) this.y && (int) other.getZ() == (int) this.z; + + } + + /** + * Returns a hash code for this vector. + * + * @return hash code + */ + @Override + public int hashCode() { + return (Integer.valueOf((int) x).hashCode() >> 13) ^ (Integer.valueOf((int) y).hashCode() >> 7) ^ Integer.valueOf((int) z).hashCode(); + } + + /** + * Get a new block vector. + * + * @return vector + */ + @Override + public BlockVector clone() { + return (BlockVector) super.clone(); + } + + public static BlockVector deserialize(Map args) { + double x = 0; + double y = 0; + double z = 0; + + if (args.containsKey("x")) { + x = (Double) args.get("x"); + } + if (args.containsKey("y")) { + y = (Double) args.get("y"); + } + if (args.containsKey("z")) { + z = (Double) args.get("z"); + } + + return new BlockVector(x, y, z); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/CachedServerIcon.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/CachedServerIcon.java new file mode 100644 index 0000000..0480470 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/CachedServerIcon.java @@ -0,0 +1,17 @@ +package org.bukkit.util; + +import org.bukkit.Server; +import org.bukkit.event.server.ServerListPingEvent; + +/** + * This is a cached version of a server-icon. It's internal representation + * and implementation is undefined. + * + * @see Server#getServerIcon() + * @see Server#loadServerIcon(java.awt.image.BufferedImage) + * @see Server#loadServerIcon(java.io.File) + * @see ServerListPingEvent#setServerIcon(CachedServerIcon) + */ +public interface CachedServerIcon { + public String getData(); // Spigot +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/ChatPaginator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/ChatPaginator.java new file mode 100644 index 0000000..24802d1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/ChatPaginator.java @@ -0,0 +1,169 @@ +package org.bukkit.util; + +import org.bukkit.ChatColor; + +import java.util.LinkedList; +import java.util.List; + +/** + * The ChatPaginator takes a raw string of arbitrary length and breaks it down + * into an array of strings appropriate for displaying on the Minecraft player + * console. + */ +public class ChatPaginator { + public static final int GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH = 55; // Will never wrap, even with the largest characters + public static final int AVERAGE_CHAT_PAGE_WIDTH = 65; // Will typically not wrap using an average character distribution + public static final int UNBOUNDED_PAGE_WIDTH = Integer.MAX_VALUE; + public static final int OPEN_CHAT_PAGE_HEIGHT = 20; // The height of an expanded chat window + public static final int CLOSED_CHAT_PAGE_HEIGHT = 10; // The height of the default chat window + public static final int UNBOUNDED_PAGE_HEIGHT = Integer.MAX_VALUE; + + /** + * Breaks a raw string up into pages using the default width and height. + * + * @param unpaginatedString The raw string to break. + * @param pageNumber The page number to fetch. + * @return A single chat page. + */ + public static ChatPage paginate(String unpaginatedString, int pageNumber) { + return paginate(unpaginatedString, pageNumber, GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH, CLOSED_CHAT_PAGE_HEIGHT); + } + + /** + * Breaks a raw string up into pages using a provided width and height. + * + * @param unpaginatedString The raw string to break. + * @param pageNumber The page number to fetch. + * @param lineLength The desired width of a chat line. + * @param pageHeight The desired number of lines in a page. + * @return A single chat page. + */ + public static ChatPage paginate(String unpaginatedString, int pageNumber, int lineLength, int pageHeight) { + String[] lines = wordWrap(unpaginatedString, lineLength); + + int totalPages = lines.length / pageHeight + (lines.length % pageHeight == 0 ? 0 : 1); + int actualPageNumber = pageNumber <= totalPages ? pageNumber : totalPages; + + int from = (actualPageNumber - 1) * pageHeight; + int to = from + pageHeight <= lines.length ? from + pageHeight : lines.length; + String[] selectedLines = Java15Compat.Arrays_copyOfRange(lines, from, to); + + return new ChatPage(selectedLines, actualPageNumber, totalPages); + } + + /** + * Breaks a raw string up into a series of lines. Words are wrapped using + * spaces as decimeters and the newline character is respected. + * + * @param rawString The raw string to break. + * @param lineLength The length of a line of text. + * @return An array of word-wrapped lines. + */ + public static String[] wordWrap(String rawString, int lineLength) { + // A null string is a single line + if (rawString == null) { + return new String[] {""}; + } + + // A string shorter than the lineWidth is a single line + if (rawString.length() <= lineLength && !rawString.contains("\n")) { + return new String[] {rawString}; + } + + char[] rawChars = (rawString + ' ').toCharArray(); // add a trailing space to trigger pagination + StringBuilder word = new StringBuilder(); + StringBuilder line = new StringBuilder(); + List lines = new LinkedList(); + int lineColorChars = 0; + + for (int i = 0; i < rawChars.length; i++) { + char c = rawChars[i]; + + // skip chat color modifiers + if (c == ChatColor.COLOR_CHAR) { + word.append(ChatColor.getByChar(rawChars[i + 1])); + lineColorChars += 2; + i++; // Eat the next character as we have already processed it + continue; + } + + if (c == ' ' || c == '\n') { + if (line.length() == 0 && word.length() > lineLength) { // special case: extremely long word begins a line + for (String partialWord : word.toString().split("(?<=\\G.{" + lineLength + "})")) { + lines.add(partialWord); + } + } else if (line.length() + word.length() - lineColorChars == lineLength) { // Line exactly the correct length...newline + line.append(word); + lines.add(line.toString()); + line = new StringBuilder(); + lineColorChars = 0; + } else if (line.length() + 1 + word.length() - lineColorChars > lineLength) { // Line too long...break the line + for (String partialWord : word.toString().split("(?<=\\G.{" + lineLength + "})")) { + lines.add(line.toString()); + line = new StringBuilder(partialWord); + } + lineColorChars = 0; + } else { + if (line.length() > 0) { + line.append(' '); + } + line.append(word); + } + word = new StringBuilder(); + + if (c == '\n') { // Newline forces the line to flush + lines.add(line.toString()); + line = new StringBuilder(); + } + } else { + word.append(c); + } + } + + if(line.length() > 0) { // Only add the last line if there is anything to add + lines.add(line.toString()); + } + + // Iterate over the wrapped lines, applying the last color from one line to the beginning of the next + if (lines.get(0).length() == 0 || lines.get(0).charAt(0) != ChatColor.COLOR_CHAR) { + lines.set(0, ChatColor.WHITE + lines.get(0)); + } + for (int i = 1; i < lines.size(); i++) { + final String pLine = lines.get(i-1); + final String subLine = lines.get(i); + + char color = pLine.charAt(pLine.lastIndexOf(ChatColor.COLOR_CHAR) + 1); + if (subLine.length() == 0 || subLine.charAt(0) != ChatColor.COLOR_CHAR) { + lines.set(i, ChatColor.getByChar(color) + subLine); + } + } + + return lines.toArray(new String[lines.size()]); + } + + public static class ChatPage { + + private String[] lines; + private int pageNumber; + private int totalPages; + + public ChatPage(String[] lines, int pageNumber, int totalPages) { + this.lines = lines; + this.pageNumber = pageNumber; + this.totalPages = totalPages; + } + + public int getPageNumber() { + return pageNumber; + } + + public int getTotalPages() { + return totalPages; + } + + public String[] getLines() { + + return lines; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/EulerAngle.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/EulerAngle.java new file mode 100644 index 0000000..7778710 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/EulerAngle.java @@ -0,0 +1,147 @@ +package org.bukkit.util; + +/** + * EulerAngle is used to represent 3 angles, one for each + * axis (x, y, z). The angles are in radians + */ +public class EulerAngle { + + /** + * A EulerAngle with every axis set to 0 + */ + public static final EulerAngle ZERO = new EulerAngle(0, 0, 0); + + private final double x; + private final double y; + private final double z; + + /** + * Creates a EularAngle with each axis set to the + * passed angle in radians + * + * @param x the angle for the x axis in radians + * @param y the angle for the x axis in radians + * @param z the angle for the x axis in radians + */ + public EulerAngle(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Returns the angle on the x axis in radians + * + * @return the angle in radians + */ + public double getX() { + return x; + } + + /** + * Returns the angle on the y axis in radians + * + * @return the angle in radians + */ + public double getY() { + return y; + } + + /** + * Returns the angle on the z axis in radians + * + * @return the angle in radians + */ + public double getZ() { + return z; + } + + /** + * Return a EulerAngle which is the result of changing + * the x axis to the passed angle + * + * @param x the angle in radians + * @return the resultant EulerAngle + */ + public EulerAngle setX(double x) { + return new EulerAngle(x, y, z); + } + + /** + * Return a EulerAngle which is the result of changing + * the y axis to the passed angle + * + * @param y the angle in radians + * @return the resultant EulerAngle + */ + public EulerAngle setY(double y) { + return new EulerAngle(x, y, z); + } + + /** + * Return a EulerAngle which is the result of changing + * the z axis to the passed angle + * + * @param z the angle in radians + * @return the resultant EulerAngle + */ + public EulerAngle setZ(double z) { + return new EulerAngle(x, y, z); + } + + /** + * Creates a new EulerAngle which is the result of adding + * the x, y, z components to this EulerAngle + * + * @param x the angle to add to the x axis in radians + * @param y the angle to add to the y axis in radians + * @param z the angle to add to the z axis in radians + * @return the resultant EulerAngle + */ + public EulerAngle add(double x, double y, double z) { + return new EulerAngle( + this.x + x, + this.y + y, + this.z + z + ); + } + + /** + * Creates a new EulerAngle which is the result of subtracting + * the x, y, z components to this EulerAngle + * + * @param x the angle to subtract to the x axis in radians + * @param y the angle to subtract to the y axis in radians + * @param z the angle to subtract to the z axis in radians + * @return the resultant EulerAngle + */ + public EulerAngle subtract(double x, double y, double z) { + return add(-x, -y, -z); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + EulerAngle that = (EulerAngle) o; + + return Double.compare(that.x, x) == 0 + && Double.compare(that.y, y) == 0 + && Double.compare(that.z, z) == 0; + + } + + @Override + public int hashCode() { + int result; + long temp; + temp = Double.doubleToLongBits(x); + result = (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(y); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(z); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/FileUtil.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/FileUtil.java new file mode 100644 index 0000000..7cabf4c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/FileUtil.java @@ -0,0 +1,57 @@ +package org.bukkit.util; + +import java.nio.channels.FileChannel; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * Class containing file utilities + */ +public class FileUtil { + + /** + * This method copies one file to another location + * + * @param inFile the source filename + * @param outFile the target filename + * @return true on success + */ + public static boolean copy(File inFile, File outFile) { + if (!inFile.exists()) { + return false; + } + + FileChannel in = null; + FileChannel out = null; + + try { + in = new FileInputStream(inFile).getChannel(); + out = new FileOutputStream(outFile).getChannel(); + + long pos = 0; + long size = in.size(); + + while (pos < size) { + pos += in.transferTo(pos, 10 * 1024 * 1024, out); + } + } catch (IOException ioe) { + return false; + } finally { + try { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + } catch (IOException ioe) { + return false; + } + } + + return true; + + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/Java15Compat.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/Java15Compat.java new file mode 100644 index 0000000..c119742 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/Java15Compat.java @@ -0,0 +1,21 @@ +package org.bukkit.util; + +import java.lang.reflect.Array; + +public class Java15Compat { + @SuppressWarnings("unchecked") + public static T[] Arrays_copyOfRange(T[] original, int start, int end) { + if (original.length >= start && 0 <= start) { + if (start <= end) { + int length = end - start; + int copyLength = Math.min(length, original.length - start); + T[] copy = (T[]) Array.newInstance(original.getClass().getComponentType(), length); + + System.arraycopy(original, start, copy, 0, copyLength); + return copy; + } + throw new IllegalArgumentException(); + } + throw new ArrayIndexOutOfBoundsException(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/NumberConversions.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/NumberConversions.java new file mode 100644 index 0000000..e6af9ec --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/NumberConversions.java @@ -0,0 +1,124 @@ +package org.bukkit.util; + +/** + * Utils for casting number types to other number types + */ +public final class NumberConversions { + private NumberConversions() {} + + public static int floor(double num) { + final int floor = (int) num; + return floor == num ? floor : floor - (int) (Double.doubleToRawLongBits(num) >>> 63); + } + + public static int ceil(final double num) { + final int floor = (int) num; + return floor == num ? floor : floor + (int) (~Double.doubleToRawLongBits(num) >>> 63); + } + + public static int round(double num) { + return floor(num + 0.5d); + } + + public static double square(double num) { + return num * num; + } + + public static int toInt(Object object) { + if (object instanceof Number) { + return ((Number) object).intValue(); + } + + try { + return Integer.valueOf(object.toString()); + } catch (NumberFormatException e) { + } catch (NullPointerException e) { + } + return 0; + } + + public static float toFloat(Object object) { + if (object instanceof Number) { + return ((Number) object).floatValue(); + } + + try { + return Float.valueOf(object.toString()); + } catch (NumberFormatException e) { + } catch (NullPointerException e) { + } + return 0; + } + + public static double toDouble(Object object) { + if (object instanceof Number) { + return ((Number) object).doubleValue(); + } + + try { + return Double.valueOf(object.toString()); + } catch (NumberFormatException e) { + } catch (NullPointerException e) { + } + return 0; + } + + public static long toLong(Object object) { + if (object instanceof Number) { + return ((Number) object).longValue(); + } + + try { + return Long.valueOf(object.toString()); + } catch (NumberFormatException e) { + } catch (NullPointerException e) { + } + return 0; + } + + public static short toShort(Object object) { + if (object instanceof Number) { + return ((Number) object).shortValue(); + } + + try { + return Short.valueOf(object.toString()); + } catch (NumberFormatException e) { + } catch (NullPointerException e) { + } + return 0; + } + + public static byte toByte(Object object) { + if (object instanceof Number) { + return ((Number) object).byteValue(); + } + + try { + return Byte.valueOf(object.toString()); + } catch (NumberFormatException e) { + } catch (NullPointerException e) { + } + return 0; + } + + public static boolean isFinite(double d) { + return Math.abs(d) <= Double.MAX_VALUE; + } + + public static boolean isFinite(float f) { + return Math.abs(f) <= Float.MAX_VALUE; + } + + public static void checkFinite(double d, String message) { + if (!isFinite(d)) { + throw new IllegalArgumentException(message); + } + } + + public static void checkFinite(float d, String message) { + if (!isFinite(d)) { + throw new IllegalArgumentException(message); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/StringUtil.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/StringUtil.java new file mode 100644 index 0000000..7e79393 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/StringUtil.java @@ -0,0 +1,58 @@ +package org.bukkit.util; + +import java.util.Collection; +import org.apache.commons.lang.Validate; + +public class StringUtil { + + /** + * Copies all elements from the iterable collection of originals to the + * collection provided. + * + * @param the collection of strings + * @param token String to search for + * @param originals An iterable collection of strings to filter. + * @param collection The collection to add matches to + * @return the collection provided that would have the elements copied + * into + * @throws UnsupportedOperationException if the collection is immutable + * and originals contains a string which starts with the specified + * search string. + * @throws IllegalArgumentException if any parameter is is null + * @throws IllegalArgumentException if originals contains a null element. + * Note: the collection may be modified before this is thrown + */ + public static > T copyPartialMatches(final String token, final Iterable originals, final T collection) throws UnsupportedOperationException, IllegalArgumentException { + Validate.notNull(token, "Search token cannot be null"); + Validate.notNull(collection, "Collection cannot be null"); + Validate.notNull(originals, "Originals cannot be null"); + + for (String string : originals) { + if (startsWithIgnoreCase(string, token)) { + collection.add(string); + } + } + + return collection; + } + + /** + * This method uses a region to check case-insensitive equality. This + * means the internal array does not need to be copied like a + * toLowerCase() call would. + * + * @param string String to check + * @param prefix Prefix of string to compare + * @return true if provided string starts with, ignoring case, the prefix + * provided + * @throws NullPointerException if prefix is null + * @throws IllegalArgumentException if string is null + */ + public static boolean startsWithIgnoreCase(final String string, final String prefix) throws IllegalArgumentException, NullPointerException { + Validate.notNull(string, "Cannot check a null string for a match"); + if (string.length() < prefix.length()) { + return false; + } + return string.regionMatches(true, 0, prefix, 0, prefix.length()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/Vector.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/Vector.java new file mode 100644 index 0000000..685148e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/Vector.java @@ -0,0 +1,668 @@ +package org.bukkit.util; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Random; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; +import static org.bukkit.util.NumberConversions.checkFinite; + +/** + * Represents a mutable vector. Because the components of Vectors are mutable, + * storing Vectors long term may be dangerous if passing code modifies the + * Vector later. If you want to keep around a Vector, it may be wise to call + * clone() in order to get a copy. + */ +@SerializableAs("Vector") +public class Vector implements Cloneable, ConfigurationSerializable { + private static final long serialVersionUID = -2657651106777219169L; + + private static Random random = new Random(); + + /** + * Threshold for fuzzy equals(). + */ + private static final double epsilon = 0.000001; + + protected double x; + protected double y; + protected double z; + + /** + * Construct the vector with all components as 0. + */ + public Vector() { + this.x = 0; + this.y = 0; + this.z = 0; + } + + /** + * Construct the vector with provided integer components. + * + * @param x X component + * @param y Y component + * @param z Z component + */ + public Vector(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Construct the vector with provided double components. + * + * @param x X component + * @param y Y component + * @param z Z component + */ + public Vector(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Construct the vector with provided float components. + * + * @param x X component + * @param y Y component + * @param z Z component + */ + public Vector(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Adds a vector to this one + * + * @param vec The other vector + * @return the same vector + */ + public Vector add(Vector vec) { + x += vec.x; + y += vec.y; + z += vec.z; + return this; + } + + /** + * Subtracts a vector from this one. + * + * @param vec The other vector + * @return the same vector + */ + public Vector subtract(Vector vec) { + x -= vec.x; + y -= vec.y; + z -= vec.z; + return this; + } + + /** + * Multiplies the vector by another. + * + * @param vec The other vector + * @return the same vector + */ + public Vector multiply(Vector vec) { + x *= vec.x; + y *= vec.y; + z *= vec.z; + return this; + } + + /** + * Divides the vector by another. + * + * @param vec The other vector + * @return the same vector + */ + public Vector divide(Vector vec) { + x /= vec.x; + y /= vec.y; + z /= vec.z; + return this; + } + + /** + * Copies another vector + * + * @param vec The other vector + * @return the same vector + */ + public Vector copy(Vector vec) { + x = vec.x; + y = vec.y; + z = vec.z; + return this; + } + + /** + * Gets the magnitude of the vector, defined as sqrt(x^2+y^2+z^2). The + * value of this method is not cached and uses a costly square-root + * function, so do not repeatedly call this method to get the vector's + * magnitude. NaN will be returned if the inner result of the sqrt() + * function overflows, which will be caused if the length is too long. + * + * @return the magnitude + */ + public double length() { + return Math.sqrt(NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z)); + } + + /** + * Gets the magnitude of the vector squared. + * + * @return the magnitude + */ + public double lengthSquared() { + return NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z); + } + + /** + * Get the distance between this vector and another. The value of this + * method is not cached and uses a costly square-root function, so do not + * repeatedly call this method to get the vector's magnitude. NaN will be + * returned if the inner result of the sqrt() function overflows, which + * will be caused if the distance is too long. + * + * @param o The other vector + * @return the distance + */ + public double distance(Vector o) { + return Math.sqrt(NumberConversions.square(x - o.x) + NumberConversions.square(y - o.y) + NumberConversions.square(z - o.z)); + } + + /** + * Get the squared distance between this vector and another. + * + * @param o The other vector + * @return the distance + */ + public double distanceSquared(Vector o) { + return NumberConversions.square(x - o.x) + NumberConversions.square(y - o.y) + NumberConversions.square(z - o.z); + } + + /** + * Gets the angle between this vector and another in radians. + * + * @param other The other vector + * @return angle in radians + */ + public float angle(Vector other) { + double dot = dot(other) / (length() * other.length()); + + return (float) Math.acos(dot); + } + + /** + * Sets this vector to the midpoint between this vector and another. + * + * @param other The other vector + * @return this same vector (now a midpoint) + */ + public Vector midpoint(Vector other) { + x = (x + other.x) / 2; + y = (y + other.y) / 2; + z = (z + other.z) / 2; + return this; + } + + /** + * Gets a new midpoint vector between this vector and another. + * + * @param other The other vector + * @return a new midpoint vector + */ + public Vector getMidpoint(Vector other) { + double x = (this.x + other.x) / 2; + double y = (this.y + other.y) / 2; + double z = (this.z + other.z) / 2; + return new Vector(x, y, z); + } + + /** + * Performs scalar multiplication, multiplying all components with a + * scalar. + * + * @param m The factor + * @return the same vector + */ + public Vector multiply(int m) { + x *= m; + y *= m; + z *= m; + return this; + } + + /** + * Performs scalar multiplication, multiplying all components with a + * scalar. + * + * @param m The factor + * @return the same vector + */ + public Vector multiply(double m) { + x *= m; + y *= m; + z *= m; + return this; + } + + /** + * Performs scalar multiplication, multiplying all components with a + * scalar. + * + * @param m The factor + * @return the same vector + */ + public Vector multiply(float m) { + x *= m; + y *= m; + z *= m; + return this; + } + + /** + * Calculates the dot product of this vector with another. The dot product + * is defined as x1*x2+y1*y2+z1*z2. The returned value is a scalar. + * + * @param other The other vector + * @return dot product + */ + public double dot(Vector other) { + return x * other.x + y * other.y + z * other.z; + } + + /** + * Calculates the cross product of this vector with another. The cross + * product is defined as: + *

    + *
  • x = y1 * z2 - y2 * z1 + *
  • y = z1 * x2 - z2 * x1 + *
  • z = x1 * y2 - x2 * y1 + *
+ * + * @param o The other vector + * @return the same vector + */ + public Vector crossProduct(Vector o) { + double newX = y * o.z - o.y * z; + double newY = z * o.x - o.z * x; + double newZ = x * o.y - o.x * y; + + x = newX; + y = newY; + z = newZ; + return this; + } + + /** + * Converts this vector to a unit vector (a vector with length of 1). + * + * @return the same vector + */ + public Vector normalize() { + double length = length(); + + x /= length; + y /= length; + z /= length; + + return this; + } + + /** + * Zero this vector's components. + * + * @return the same vector + */ + public Vector zero() { + x = 0; + y = 0; + z = 0; + return this; + } + + /** + * Returns whether this vector is in an axis-aligned bounding box. + *

+ * The minimum and maximum vectors given must be truly the minimum and + * maximum X, Y and Z components. + * + * @param min Minimum vector + * @param max Maximum vector + * @return whether this vector is in the AABB + */ + public boolean isInAABB(Vector min, Vector max) { + return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z; + } + + /** + * Returns whether this vector is within a sphere. + * + * @param origin Sphere origin. + * @param radius Sphere radius + * @return whether this vector is in the sphere + */ + public boolean isInSphere(Vector origin, double radius) { + return (NumberConversions.square(origin.x - x) + NumberConversions.square(origin.y - y) + NumberConversions.square(origin.z - z)) <= NumberConversions.square(radius); + } + + /** + * Gets the X component. + * + * @return The X component. + */ + public double getX() { + return x; + } + + /** + * Gets the floored value of the X component, indicating the block that + * this vector is contained with. + * + * @return block X + */ + public int getBlockX() { + return NumberConversions.floor(x); + } + + /** + * Gets the Y component. + * + * @return The Y component. + */ + public double getY() { + return y; + } + + /** + * Gets the floored value of the Y component, indicating the block that + * this vector is contained with. + * + * @return block y + */ + public int getBlockY() { + return NumberConversions.floor(y); + } + + /** + * Gets the Z component. + * + * @return The Z component. + */ + public double getZ() { + return z; + } + + /** + * Gets the floored value of the Z component, indicating the block that + * this vector is contained with. + * + * @return block z + */ + public int getBlockZ() { + return NumberConversions.floor(z); + } + + /** + * Set the X component. + * + * @param x The new X component. + * @return This vector. + */ + public Vector setX(int x) { + this.x = x; + return this; + } + + /** + * Set the X component. + * + * @param x The new X component. + * @return This vector. + */ + public Vector setX(double x) { + this.x = x; + return this; + } + + /** + * Set the X component. + * + * @param x The new X component. + * @return This vector. + */ + public Vector setX(float x) { + this.x = x; + return this; + } + + /** + * Set the Y component. + * + * @param y The new Y component. + * @return This vector. + */ + public Vector setY(int y) { + this.y = y; + return this; + } + + /** + * Set the Y component. + * + * @param y The new Y component. + * @return This vector. + */ + public Vector setY(double y) { + this.y = y; + return this; + } + + /** + * Set the Y component. + * + * @param y The new Y component. + * @return This vector. + */ + public Vector setY(float y) { + this.y = y; + return this; + } + + /** + * Set the Z component. + * + * @param z The new Z component. + * @return This vector. + */ + public Vector setZ(int z) { + this.z = z; + return this; + } + + /** + * Set the Z component. + * + * @param z The new Z component. + * @return This vector. + */ + public Vector setZ(double z) { + this.z = z; + return this; + } + + /** + * Set the Z component. + * + * @param z The new Z component. + * @return This vector. + */ + public Vector setZ(float z) { + this.z = z; + return this; + } + + /** + * Checks to see if two objects are equal. + *

+ * Only two Vectors can ever return true. This method uses a fuzzy match + * to account for floating point errors. The epsilon can be retrieved + * with epsilon. + */ + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Vector)) { + return false; + } + + Vector other = (Vector) obj; + + return Math.abs(x - other.x) < epsilon && Math.abs(y - other.y) < epsilon && Math.abs(z - other.z) < epsilon && (this.getClass().equals(obj.getClass())); + } + + /** + * Returns a hash code for this vector + * + * @return hash code + */ + @Override + public int hashCode() { + int hash = 7; + + hash = 79 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32)); + hash = 79 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32)); + hash = 79 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32)); + return hash; + } + + /** + * Get a new vector. + * + * @return vector + */ + @Override + public Vector clone() { + try { + return (Vector) super.clone(); + } catch (CloneNotSupportedException e) { + throw new Error(e); + } + } + + /** + * Returns this vector's components as x,y,z. + */ + @Override + public String toString() { + return x + "," + y + "," + z; + } + + /** + * Gets a Location version of this vector with yaw and pitch being 0. + * + * @param world The world to link the location to. + * @return the location + */ + public Location toLocation(World world) { + return new Location(world, x, y, z); + } + + /** + * Gets a Location version of this vector. + * + * @param world The world to link the location to. + * @param yaw The desired yaw. + * @param pitch The desired pitch. + * @return the location + */ + public Location toLocation(World world, float yaw, float pitch) { + return new Location(world, x, y, z, yaw, pitch); + } + + /** + * Get the block vector of this vector. + * + * @return A block vector. + */ + public BlockVector toBlockVector() { + return new BlockVector(x, y, z); + } + + /** + * Get the threshold used for equals(). + * + * @return The epsilon. + */ + public static double getEpsilon() { + return epsilon; + } + + /** + * Gets the minimum components of two vectors. + * + * @param v1 The first vector. + * @param v2 The second vector. + * @return minimum + */ + public static Vector getMinimum(Vector v1, Vector v2) { + return new Vector(Math.min(v1.x, v2.x), Math.min(v1.y, v2.y), Math.min(v1.z, v2.z)); + } + + /** + * Gets the maximum components of two vectors. + * + * @param v1 The first vector. + * @param v2 The second vector. + * @return maximum + */ + public static Vector getMaximum(Vector v1, Vector v2) { + return new Vector(Math.max(v1.x, v2.x), Math.max(v1.y, v2.y), Math.max(v1.z, v2.z)); + } + + /** + * Gets a random vector with components having a random value between 0 + * and 1. + * + * @return A random vector. + */ + public static Vector getRandom() { + return new Vector(random.nextDouble(), random.nextDouble(), random.nextDouble()); + } + + public Map serialize() { + Map result = new LinkedHashMap(); + + result.put("x", getX()); + result.put("y", getY()); + result.put("z", getZ()); + + return result; + } + + public static Vector deserialize(Map args) { + double x = 0; + double y = 0; + double z = 0; + + if (args.containsKey("x")) { + x = (Double) args.get("x"); + } + if (args.containsKey("y")) { + y = (Double) args.get("y"); + } + if (args.containsKey("z")) { + z = (Double) args.get("z"); + } + + return new Vector(x, y, z); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java new file mode 100644 index 0000000..1372553 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/BukkitObjectInputStream.java @@ -0,0 +1,62 @@ +package org.bukkit.util.io; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; + +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +/** + * This class is designed to be used in conjunction with the {@link + * ConfigurationSerializable} API. It translates objects back to their + * original implementation after being serialized by {@link + * BukkitObjectInputStream}. + *

+ * Behavior of implementations extending this class is not guaranteed across + * future versions. + */ +public class BukkitObjectInputStream extends ObjectInputStream { + + /** + * Constructor provided to mirror super functionality. + * + * @throws IOException if an I/O error occurs while reading stream heade + * @see ObjectInputStream#ObjectInputStream() + */ + protected BukkitObjectInputStream() throws IOException, SecurityException { + super(); + super.enableResolveObject(true); + } + + /** + * Object input stream decoration constructor. + * + * @param in the input stream to wrap + * @throws IOException if an I/O error occurs while reading stream header + * @see ObjectInputStream#ObjectInputStream(InputStream) + */ + public BukkitObjectInputStream(InputStream in) throws IOException { + super(in); + super.enableResolveObject(true); + } + + @Override + protected Object resolveObject(Object obj) throws IOException { + if (obj instanceof Wrapper) { + try { + (obj = ConfigurationSerialization.deserializeObject(((Wrapper) obj).map)).getClass(); // NPE + } catch (Throwable ex) { + throw newIOException("Failed to deserialize object", ex); + } + } + + return super.resolveObject(obj); + } + + private static IOException newIOException(String string, Throwable cause) { + IOException exception = new IOException(string); + exception.initCause(cause); + return exception; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java new file mode 100644 index 0000000..8452850 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/BukkitObjectOutputStream.java @@ -0,0 +1,52 @@ +package org.bukkit.util.io; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.Serializable; + +import org.bukkit.configuration.serialization.ConfigurationSerializable; + +/** + * This class is designed to be used in conjunction with the {@link + * ConfigurationSerializable} API. It translates objects to an internal + * implementation for later deserialization using {@link + * BukkitObjectInputStream}. + *

+ * Behavior of implementations extending this class is not guaranteed across + * future versions. + */ +public class BukkitObjectOutputStream extends ObjectOutputStream { + + /** + * Constructor provided to mirror super functionality. + * + * @throws IOException if an I/O error occurs while writing stream header + * @see ObjectOutputStream#ObjectOutputStream() + */ + protected BukkitObjectOutputStream() throws IOException, SecurityException { + super(); + super.enableReplaceObject(true); + } + + /** + * Object output stream decoration constructor. + * + * @param out the stream to wrap + * @throws IOException if an I/O error occurs while writing stream header + * @see ObjectOutputStream#ObjectOutputStream(OutputStream) + */ + public BukkitObjectOutputStream(OutputStream out) throws IOException { + super(out); + super.enableReplaceObject(true); + } + + @Override + protected Object replaceObject(Object obj) throws IOException { + if (!(obj instanceof Serializable) && (obj instanceof ConfigurationSerializable)) { + obj = Wrapper.newWrapper((ConfigurationSerializable) obj); + } + + return super.replaceObject(obj); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/Wrapper.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/Wrapper.java new file mode 100644 index 0000000..e45605b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/io/Wrapper.java @@ -0,0 +1,23 @@ +package org.bukkit.util.io; + +import java.io.Serializable; +import java.util.Map; + +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; + +import com.google.common.collect.ImmutableMap; + +class Wrapper & Serializable> implements Serializable { + private static final long serialVersionUID = -986209235411767547L; + + final T map; + + static Wrapper> newWrapper(ConfigurationSerializable obj) { + return new Wrapper>(ImmutableMap.builder().put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(obj.getClass())).putAll(obj.serialize()).build()); + } + + private Wrapper(T map) { + this.map = map; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/NoiseGenerator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/NoiseGenerator.java new file mode 100644 index 0000000..72c92f3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/NoiseGenerator.java @@ -0,0 +1,176 @@ +package org.bukkit.util.noise; + +/** + * Base class for all noise generators + */ +public abstract class NoiseGenerator { + protected final int perm[] = new int[512]; + protected double offsetX; + protected double offsetY; + protected double offsetZ; + + /** + * Speedy floor, faster than (int)Math.floor(x) + * + * @param x Value to floor + * @return Floored value + */ + public static int floor(double x) { + return x >= 0 ? (int) x : (int) x - 1; + } + + protected static double fade(double x) { + return x * x * x * (x * (x * 6 - 15) + 10); + } + + protected static double lerp(double x, double y, double z) { + return y + x * (z - y); + } + + protected static double grad(int hash, double x, double y, double z) { + hash &= 15; + double u = hash < 8 ? x : y; + double v = hash < 4 ? y : hash == 12 || hash == 14 ? x : z; + return ((hash & 1) == 0 ? u : -u) + ((hash & 2) == 0 ? v : -v); + } + + /** + * Computes and returns the 1D noise for the given coordinate in 1D space + * + * @param x X coordinate + * @return Noise at given location, from range -1 to 1 + */ + public double noise(double x) { + return noise(x, 0, 0); + } + + /** + * Computes and returns the 2D noise for the given coordinates in 2D space + * + * @param x X coordinate + * @param y Y coordinate + * @return Noise at given location, from range -1 to 1 + */ + public double noise(double x, double y) { + return noise(x, y, 0); + } + + /** + * Computes and returns the 3D noise for the given coordinates in 3D space + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @return Noise at given location, from range -1 to 1 + */ + public abstract double noise(double x, double y, double z); + + /** + * Generates noise for the 1D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public double noise(double x, int octaves, double frequency, double amplitude) { + return noise(x, 0, 0, octaves, frequency, amplitude); + } + + /** + * Generates noise for the 1D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @param normalized If true, normalize the value to [-1, 1] + * @return Resulting noise + */ + public double noise(double x, int octaves, double frequency, double amplitude, boolean normalized) { + return noise(x, 0, 0, octaves, frequency, amplitude, normalized); + } + + /** + * Generates noise for the 2D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public double noise(double x, double y, int octaves, double frequency, double amplitude) { + return noise(x, y, 0, octaves, frequency, amplitude); + } + + /** + * Generates noise for the 2D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @param normalized If true, normalize the value to [-1, 1] + * @return Resulting noise + */ + public double noise(double x, double y, int octaves, double frequency, double amplitude, boolean normalized) { + return noise(x, y, 0, octaves, frequency, amplitude, normalized); + } + + /** + * Generates noise for the 3D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param z Z-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public double noise(double x, double y, double z, int octaves, double frequency, double amplitude) { + return noise(x, y, z, octaves, frequency, amplitude, false); + } + + /** + * Generates noise for the 3D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param z Z-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @param normalized If true, normalize the value to [-1, 1] + * @return Resulting noise + */ + public double noise(double x, double y, double z, int octaves, double frequency, double amplitude, boolean normalized) { + double result = 0; + double amp = 1; + double freq = 1; + double max = 0; + + for (int i = 0; i < octaves; i++) { + result += noise(x * freq, y * freq, z * freq) * amp; + max += amp; + freq *= frequency; + amp *= amplitude; + } + + if (normalized) { + result /= max; + } + + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/OctaveGenerator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/OctaveGenerator.java new file mode 100644 index 0000000..a87304b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/OctaveGenerator.java @@ -0,0 +1,199 @@ +package org.bukkit.util.noise; + +/** + * Creates noise using unbiased octaves + */ +public abstract class OctaveGenerator { + protected final NoiseGenerator[] octaves; + protected double xScale = 1; + protected double yScale = 1; + protected double zScale = 1; + + protected OctaveGenerator(NoiseGenerator[] octaves) { + this.octaves = octaves; + } + + /** + * Sets the scale used for all coordinates passed to this generator. + *

+ * This is the equivalent to setting each coordinate to the specified + * value. + * + * @param scale New value to scale each coordinate by + */ + public void setScale(double scale) { + setXScale(scale); + setYScale(scale); + setZScale(scale); + } + + /** + * Gets the scale used for each X-coordinates passed + * + * @return X scale + */ + public double getXScale() { + return xScale; + } + + /** + * Sets the scale used for each X-coordinates passed + * + * @param scale New X scale + */ + public void setXScale(double scale) { + xScale = scale; + } + + /** + * Gets the scale used for each Y-coordinates passed + * + * @return Y scale + */ + public double getYScale() { + return yScale; + } + + /** + * Sets the scale used for each Y-coordinates passed + * + * @param scale New Y scale + */ + public void setYScale(double scale) { + yScale = scale; + } + + /** + * Gets the scale used for each Z-coordinates passed + * + * @return Z scale + */ + public double getZScale() { + return zScale; + } + + /** + * Sets the scale used for each Z-coordinates passed + * + * @param scale New Z scale + */ + public void setZScale(double scale) { + zScale = scale; + } + + /** + * Gets a clone of the individual octaves used within this generator + * + * @return Clone of the individual octaves + */ + public NoiseGenerator[] getOctaves() { + return octaves.clone(); + } + + /** + * Generates noise for the 1D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public double noise(double x, double frequency, double amplitude) { + return noise(x, 0, 0, frequency, amplitude); + } + + /** + * Generates noise for the 1D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @param normalized If true, normalize the value to [-1, 1] + * @return Resulting noise + */ + public double noise(double x, double frequency, double amplitude, boolean normalized) { + return noise(x, 0, 0, frequency, amplitude, normalized); + } + + /** + * Generates noise for the 2D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public double noise(double x, double y, double frequency, double amplitude) { + return noise(x, y, 0, frequency, amplitude); + } + + /** + * Generates noise for the 2D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @param normalized If true, normalize the value to [-1, 1] + * @return Resulting noise + */ + public double noise(double x, double y, double frequency, double amplitude, boolean normalized) { + return noise(x, y, 0, frequency, amplitude, normalized); + } + + /** + * Generates noise for the 3D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param z Z-coordinate + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public double noise(double x, double y, double z, double frequency, double amplitude) { + return noise(x, y, z, frequency, amplitude, false); + } + + /** + * Generates noise for the 3D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param z Z-coordinate + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @param normalized If true, normalize the value to [-1, 1] + * @return Resulting noise + */ + public double noise(double x, double y, double z, double frequency, double amplitude, boolean normalized) { + double result = 0; + double amp = 1; + double freq = 1; + double max = 0; + + x *= xScale; + y *= yScale; + z *= zScale; + + for (NoiseGenerator octave : octaves) { + result += octave.noise(x * freq, y * freq, z * freq) * amp; + max += amp; + freq *= frequency; + amp *= amplitude; + } + + if (normalized) { + result /= max; + } + + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/PerlinNoiseGenerator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/PerlinNoiseGenerator.java new file mode 100644 index 0000000..5e034c1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/PerlinNoiseGenerator.java @@ -0,0 +1,217 @@ +package org.bukkit.util.noise; + +import java.util.Random; +import org.bukkit.World; + +/** + * Generates noise using the "classic" perlin generator + * + * @see SimplexNoiseGenerator "Improved" and faster version with slighly + * different results + */ +public class PerlinNoiseGenerator extends NoiseGenerator { + protected static final int grad3[][] = {{1, 1, 0}, {-1, 1, 0}, {1, -1, 0}, {-1, -1, 0}, + {1, 0, 1}, {-1, 0, 1}, {1, 0, -1}, {-1, 0, -1}, + {0, 1, 1}, {0, -1, 1}, {0, 1, -1}, {0, -1, -1}}; + private static final PerlinNoiseGenerator instance = new PerlinNoiseGenerator(); + + protected PerlinNoiseGenerator() { + int p[] = {151, 160, 137, 91, 90, 15, 131, 13, 201, + 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, + 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, + 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, + 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, + 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, + 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, + 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, + 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, + 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, + 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, + 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, + 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, + 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, + 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, + 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, + 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, + 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180}; + + for (int i = 0; i < 512; i++) { + perm[i] = p[i & 255]; + } + } + + /** + * Creates a seeded perlin noise generator for the given world + * + * @param world World to construct this generator for + */ + public PerlinNoiseGenerator(World world) { + this(new Random(world.getSeed())); + } + + /** + * Creates a seeded perlin noise generator for the given seed + * + * @param seed Seed to construct this generator for + */ + public PerlinNoiseGenerator(long seed) { + this(new Random(seed)); + } + + /** + * Creates a seeded perlin noise generator with the given Random + * + * @param rand Random to construct with + */ + public PerlinNoiseGenerator(Random rand) { + offsetX = rand.nextDouble() * 256; + offsetY = rand.nextDouble() * 256; + offsetZ = rand.nextDouble() * 256; + + for (int i = 0; i < 256; i++) { + perm[i] = rand.nextInt(256); + } + + for (int i = 0; i < 256; i++) { + int pos = rand.nextInt(256 - i) + i; + int old = perm[i]; + + perm[i] = perm[pos]; + perm[pos] = old; + perm[i + 256] = perm[i]; + } + } + + /** + * Computes and returns the 1D unseeded perlin noise for the given + * coordinates in 1D space + * + * @param x X coordinate + * @return Noise at given location, from range -1 to 1 + */ + public static double getNoise(double x) { + return instance.noise(x); + } + + /** + * Computes and returns the 2D unseeded perlin noise for the given + * coordinates in 2D space + * + * @param x X coordinate + * @param y Y coordinate + * @return Noise at given location, from range -1 to 1 + */ + public static double getNoise(double x, double y) { + return instance.noise(x, y); + } + + /** + * Computes and returns the 3D unseeded perlin noise for the given + * coordinates in 3D space + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @return Noise at given location, from range -1 to 1 + */ + public static double getNoise(double x, double y, double z) { + return instance.noise(x, y, z); + } + + /** + * Gets the singleton unseeded instance of this generator + * + * @return Singleton + */ + public static PerlinNoiseGenerator getInstance() { + return instance; + } + + @Override + public double noise(double x, double y, double z) { + x += offsetX; + y += offsetY; + z += offsetZ; + + int floorX = floor(x); + int floorY = floor(y); + int floorZ = floor(z); + + // Find unit cube containing the point + int X = floorX & 255; + int Y = floorY & 255; + int Z = floorZ & 255; + + // Get relative xyz coordinates of the point within the cube + x -= floorX; + y -= floorY; + z -= floorZ; + + // Compute fade curves for xyz + double fX = fade(x); + double fY = fade(y); + double fZ = fade(z); + + // Hash coordinates of the cube corners + int A = perm[X] + Y; + int AA = perm[A] + Z; + int AB = perm[A + 1] + Z; + int B = perm[X + 1] + Y; + int BA = perm[B] + Z; + int BB = perm[B + 1] + Z; + + return lerp(fZ, lerp(fY, lerp(fX, grad(perm[AA], x, y, z), + grad(perm[BA], x - 1, y, z)), + lerp(fX, grad(perm[AB], x, y - 1, z), + grad(perm[BB], x - 1, y - 1, z))), + lerp(fY, lerp(fX, grad(perm[AA + 1], x, y, z - 1), + grad(perm[BA + 1], x - 1, y, z - 1)), + lerp(fX, grad(perm[AB + 1], x, y - 1, z - 1), + grad(perm[BB + 1], x - 1, y - 1, z - 1)))); + } + + /** + * Generates noise for the 1D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public static double getNoise(double x, int octaves, double frequency, double amplitude) { + return instance.noise(x, octaves, frequency, amplitude); + } + + /** + * Generates noise for the 2D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public static double getNoise(double x, double y, int octaves, double frequency, double amplitude) { + return instance.noise(x, y, octaves, frequency, amplitude); + } + + /** + * Generates noise for the 3D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param z Z-coordinate + * @param octaves Number of octaves to use + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public static double getNoise(double x, double y, double z, int octaves, double frequency, double amplitude) { + return instance.noise(x, y, z, octaves, frequency, amplitude); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/PerlinOctaveGenerator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/PerlinOctaveGenerator.java new file mode 100644 index 0000000..55b7ad7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/PerlinOctaveGenerator.java @@ -0,0 +1,50 @@ +package org.bukkit.util.noise; + +import java.util.Random; +import org.bukkit.World; + +/** + * Creates perlin noise through unbiased octaves + */ +public class PerlinOctaveGenerator extends OctaveGenerator { + + /** + * Creates a perlin octave generator for the given world + * + * @param world World to construct this generator for + * @param octaves Amount of octaves to create + */ + public PerlinOctaveGenerator(World world, int octaves) { + this(new Random(world.getSeed()), octaves); + } + + /** + * Creates a perlin octave generator for the given world + * + * @param seed Seed to construct this generator for + * @param octaves Amount of octaves to create + */ + public PerlinOctaveGenerator(long seed, int octaves) { + this(new Random(seed), octaves); + } + + /** + * Creates a perlin octave generator for the given {@link Random} + * + * @param rand Random object to construct this generator for + * @param octaves Amount of octaves to create + */ + public PerlinOctaveGenerator(Random rand, int octaves) { + super(createOctaves(rand, octaves)); + } + + private static NoiseGenerator[] createOctaves(Random rand, int octaves) { + NoiseGenerator[] result = new NoiseGenerator[octaves]; + + for (int i = 0; i < octaves; i++) { + result[i] = new PerlinNoiseGenerator(rand); + } + + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/SimplexNoiseGenerator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/SimplexNoiseGenerator.java new file mode 100644 index 0000000..b052f3c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/SimplexNoiseGenerator.java @@ -0,0 +1,520 @@ +package org.bukkit.util.noise; + +import java.util.Random; +import org.bukkit.World; + +/** + * Generates simplex-based noise. + *

+ * This is a modified version of the freely published version in the paper by + * Stefan Gustavson at + * + * http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf + */ +public class SimplexNoiseGenerator extends PerlinNoiseGenerator { + protected static final double SQRT_3 = Math.sqrt(3); + protected static final double SQRT_5 = Math.sqrt(5); + protected static final double F2 = 0.5 * (SQRT_3 - 1); + protected static final double G2 = (3 - SQRT_3) / 6; + protected static final double G22 = G2 * 2.0 - 1; + protected static final double F3 = 1.0 / 3.0; + protected static final double G3 = 1.0 / 6.0; + protected static final double F4 = (SQRT_5 - 1.0) / 4.0; + protected static final double G4 = (5.0 - SQRT_5) / 20.0; + protected static final double G42 = G4 * 2.0; + protected static final double G43 = G4 * 3.0; + protected static final double G44 = G4 * 4.0 - 1.0; + protected static final int grad4[][] = {{0, 1, 1, 1}, {0, 1, 1, -1}, {0, 1, -1, 1}, {0, 1, -1, -1}, + {0, -1, 1, 1}, {0, -1, 1, -1}, {0, -1, -1, 1}, {0, -1, -1, -1}, + {1, 0, 1, 1}, {1, 0, 1, -1}, {1, 0, -1, 1}, {1, 0, -1, -1}, + {-1, 0, 1, 1}, {-1, 0, 1, -1}, {-1, 0, -1, 1}, {-1, 0, -1, -1}, + {1, 1, 0, 1}, {1, 1, 0, -1}, {1, -1, 0, 1}, {1, -1, 0, -1}, + {-1, 1, 0, 1}, {-1, 1, 0, -1}, {-1, -1, 0, 1}, {-1, -1, 0, -1}, + {1, 1, 1, 0}, {1, 1, -1, 0}, {1, -1, 1, 0}, {1, -1, -1, 0}, + {-1, 1, 1, 0}, {-1, 1, -1, 0}, {-1, -1, 1, 0}, {-1, -1, -1, 0}}; + protected static final int simplex[][] = { + {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 0, 0, 0}, {0, 2, 3, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 2, 3, 0}, + {0, 2, 1, 3}, {0, 0, 0, 0}, {0, 3, 1, 2}, {0, 3, 2, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 3, 2, 0}, + {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, + {1, 2, 0, 3}, {0, 0, 0, 0}, {1, 3, 0, 2}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {2, 3, 0, 1}, {2, 3, 1, 0}, + {1, 0, 2, 3}, {1, 0, 3, 2}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {2, 0, 3, 1}, {0, 0, 0, 0}, {2, 1, 3, 0}, + {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, + {2, 0, 1, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {3, 0, 1, 2}, {3, 0, 2, 1}, {0, 0, 0, 0}, {3, 1, 2, 0}, + {2, 1, 0, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {3, 1, 0, 2}, {0, 0, 0, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}}; + protected static double offsetW; + private static final SimplexNoiseGenerator instance = new SimplexNoiseGenerator(); + + protected SimplexNoiseGenerator() { + super(); + } + + /** + * Creates a seeded simplex noise generator for the given world + * + * @param world World to construct this generator for + */ + public SimplexNoiseGenerator(World world) { + this(new Random(world.getSeed())); + } + + /** + * Creates a seeded simplex noise generator for the given seed + * + * @param seed Seed to construct this generator for + */ + public SimplexNoiseGenerator(long seed) { + this(new Random(seed)); + } + + /** + * Creates a seeded simplex noise generator with the given Random + * + * @param rand Random to construct with + */ + public SimplexNoiseGenerator(Random rand) { + super(rand); + offsetW = rand.nextDouble() * 256; + } + + protected static double dot(int g[], double x, double y) { + return g[0] * x + g[1] * y; + } + + protected static double dot(int g[], double x, double y, double z) { + return g[0] * x + g[1] * y + g[2] * z; + } + + protected static double dot(int g[], double x, double y, double z, double w) { + return g[0] * x + g[1] * y + g[2] * z + g[3] * w; + } + + /** + * Computes and returns the 1D unseeded simplex noise for the given + * coordinates in 1D space + * + * @param xin X coordinate + * @return Noise at given location, from range -1 to 1 + */ + public static double getNoise(double xin) { + return instance.noise(xin); + } + + /** + * Computes and returns the 2D unseeded simplex noise for the given + * coordinates in 2D space + * + * @param xin X coordinate + * @param yin Y coordinate + * @return Noise at given location, from range -1 to 1 + */ + public static double getNoise(double xin, double yin) { + return instance.noise(xin, yin); + } + + /** + * Computes and returns the 3D unseeded simplex noise for the given + * coordinates in 3D space + * + * @param xin X coordinate + * @param yin Y coordinate + * @param zin Z coordinate + * @return Noise at given location, from range -1 to 1 + */ + public static double getNoise(double xin, double yin, double zin) { + return instance.noise(xin, yin, zin); + } + + /** + * Computes and returns the 4D simplex noise for the given coordinates in + * 4D space + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param w W coordinate + * @return Noise at given location, from range -1 to 1 + */ + public static double getNoise(double x, double y, double z, double w) { + return instance.noise(x, y, z, w); + } + + @Override + public double noise(double xin, double yin, double zin) { + xin += offsetX; + yin += offsetY; + zin += offsetZ; + + double n0, n1, n2, n3; // Noise contributions from the four corners + + // Skew the input space to determine which simplex cell we're in + double s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D + int i = floor(xin + s); + int j = floor(yin + s); + int k = floor(zin + s); + double t = (i + j + k) * G3; + double X0 = i - t; // Unskew the cell origin back to (x,y,z) space + double Y0 = j - t; + double Z0 = k - t; + double x0 = xin - X0; // The x,y,z distances from the cell origin + double y0 = yin - Y0; + double z0 = zin - Z0; + + // For the 3D case, the simplex shape is a slightly irregular tetrahedron. + + // Determine which simplex we are in. + int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords + int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords + if (x0 >= y0) { + if (y0 >= z0) { + i1 = 1; + j1 = 0; + k1 = 0; + i2 = 1; + j2 = 1; + k2 = 0; + } // X Y Z order + else if (x0 >= z0) { + i1 = 1; + j1 = 0; + k1 = 0; + i2 = 1; + j2 = 0; + k2 = 1; + } // X Z Y order + else { + i1 = 0; + j1 = 0; + k1 = 1; + i2 = 1; + j2 = 0; + k2 = 1; + } // Z X Y order + } else { // x0 y0) { + i1 = 1; + j1 = 0; + } // lower triangle, XY order: (0,0)->(1,0)->(1,1) + else { + i1 = 0; + j1 = 1; + } // upper triangle, YX order: (0,0)->(0,1)->(1,1) + + // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and + // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where + // c = (3-sqrt(3))/6 + + double x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords + double y1 = y0 - j1 + G2; + double x2 = x0 + G22; // Offsets for last corner in (x,y) unskewed coords + double y2 = y0 + G22; + + // Work out the hashed gradient indices of the three simplex corners + int ii = i & 255; + int jj = j & 255; + int gi0 = perm[ii + perm[jj]] % 12; + int gi1 = perm[ii + i1 + perm[jj + j1]] % 12; + int gi2 = perm[ii + 1 + perm[jj + 1]] % 12; + + // Calculate the contribution from the three corners + double t0 = 0.5 - x0 * x0 - y0 * y0; + if (t0 < 0) { + n0 = 0.0; + } else { + t0 *= t0; + n0 = t0 * t0 * dot(grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient + } + + double t1 = 0.5 - x1 * x1 - y1 * y1; + if (t1 < 0) { + n1 = 0.0; + } else { + t1 *= t1; + n1 = t1 * t1 * dot(grad3[gi1], x1, y1); + } + + double t2 = 0.5 - x2 * x2 - y2 * y2; + if (t2 < 0) { + n2 = 0.0; + } else { + t2 *= t2; + n2 = t2 * t2 * dot(grad3[gi2], x2, y2); + } + + // Add contributions from each corner to get the final noise value. + // The result is scaled to return values in the interval [-1,1]. + return 70.0 * (n0 + n1 + n2); + } + + /** + * Computes and returns the 4D simplex noise for the given coordinates in + * 4D space + * + * @param x X coordinate + * @param y Y coordinate + * @param z Z coordinate + * @param w W coordinate + * @return Noise at given location, from range -1 to 1 + */ + public double noise(double x, double y, double z, double w) { + x += offsetX; + y += offsetY; + z += offsetZ; + w += offsetW; + + double n0, n1, n2, n3, n4; // Noise contributions from the five corners + + // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in + double s = (x + y + z + w) * F4; // Factor for 4D skewing + int i = floor(x + s); + int j = floor(y + s); + int k = floor(z + s); + int l = floor(w + s); + + double t = (i + j + k + l) * G4; // Factor for 4D unskewing + double X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space + double Y0 = j - t; + double Z0 = k - t; + double W0 = l - t; + double x0 = x - X0; // The x,y,z,w distances from the cell origin + double y0 = y - Y0; + double z0 = z - Z0; + double w0 = w - W0; + + // For the 4D case, the simplex is a 4D shape I won't even try to describe. + // To find out which of the 24 possible simplices we're in, we need to + // determine the magnitude ordering of x0, y0, z0 and w0. + // The method below is a good way of finding the ordering of x,y,z,w and + // then find the correct traversal order for the simplex we’re in. + // First, six pair-wise comparisons are performed between each possible pair + // of the four coordinates, and the results are used to add up binary bits + // for an integer index. + int c1 = (x0 > y0) ? 32 : 0; + int c2 = (x0 > z0) ? 16 : 0; + int c3 = (y0 > z0) ? 8 : 0; + int c4 = (x0 > w0) ? 4 : 0; + int c5 = (y0 > w0) ? 2 : 0; + int c6 = (z0 > w0) ? 1 : 0; + int c = c1 + c2 + c3 + c4 + c5 + c6; + int i1, j1, k1, l1; // The integer offsets for the second simplex corner + int i2, j2, k2, l2; // The integer offsets for the third simplex corner + int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner + + // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order. + // Many values of c will never occur, since e.g. x>y>z>w makes x= 3 ? 1 : 0; + j1 = simplex[c][1] >= 3 ? 1 : 0; + k1 = simplex[c][2] >= 3 ? 1 : 0; + l1 = simplex[c][3] >= 3 ? 1 : 0; + + // The number 2 in the "simplex" array is at the second largest coordinate. + i2 = simplex[c][0] >= 2 ? 1 : 0; + j2 = simplex[c][1] >= 2 ? 1 : 0; + k2 = simplex[c][2] >= 2 ? 1 : 0; + l2 = simplex[c][3] >= 2 ? 1 : 0; + + // The number 1 in the "simplex" array is at the second smallest coordinate. + i3 = simplex[c][0] >= 1 ? 1 : 0; + j3 = simplex[c][1] >= 1 ? 1 : 0; + k3 = simplex[c][2] >= 1 ? 1 : 0; + l3 = simplex[c][3] >= 1 ? 1 : 0; + + // The fifth corner has all coordinate offsets = 1, so no need to look that up. + + double x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords + double y1 = y0 - j1 + G4; + double z1 = z0 - k1 + G4; + double w1 = w0 - l1 + G4; + + double x2 = x0 - i2 + G42; // Offsets for third corner in (x,y,z,w) coords + double y2 = y0 - j2 + G42; + double z2 = z0 - k2 + G42; + double w2 = w0 - l2 + G42; + + double x3 = x0 - i3 + G43; // Offsets for fourth corner in (x,y,z,w) coords + double y3 = y0 - j3 + G43; + double z3 = z0 - k3 + G43; + double w3 = w0 - l3 + G43; + + double x4 = x0 + G44; // Offsets for last corner in (x,y,z,w) coords + double y4 = y0 + G44; + double z4 = z0 + G44; + double w4 = w0 + G44; + + // Work out the hashed gradient indices of the five simplex corners + int ii = i & 255; + int jj = j & 255; + int kk = k & 255; + int ll = l & 255; + + int gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32; + int gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32; + int gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32; + int gi3 = perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32; + int gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; + + // Calculate the contribution from the five corners + double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; + if (t0 < 0) { + n0 = 0.0; + } else { + t0 *= t0; + n0 = t0 * t0 * dot(grad4[gi0], x0, y0, z0, w0); + } + + double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; + if (t1 < 0) { + n1 = 0.0; + } else { + t1 *= t1; + n1 = t1 * t1 * dot(grad4[gi1], x1, y1, z1, w1); + } + + double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; + if (t2 < 0) { + n2 = 0.0; + } else { + t2 *= t2; + n2 = t2 * t2 * dot(grad4[gi2], x2, y2, z2, w2); + } + + double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; + if (t3 < 0) { + n3 = 0.0; + } else { + t3 *= t3; + n3 = t3 * t3 * dot(grad4[gi3], x3, y3, z3, w3); + } + + double t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; + if (t4 < 0) { + n4 = 0.0; + } else { + t4 *= t4; + n4 = t4 * t4 * dot(grad4[gi4], x4, y4, z4, w4); + } + + // Sum up and scale the result to cover the range [-1,1] + return 27.0 * (n0 + n1 + n2 + n3 + n4); + } + + /** + * Gets the singleton unseeded instance of this generator + * + * @return Singleton + */ + public static SimplexNoiseGenerator getInstance() { + return instance; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/SimplexOctaveGenerator.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/SimplexOctaveGenerator.java new file mode 100644 index 0000000..61e66aa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/noise/SimplexOctaveGenerator.java @@ -0,0 +1,129 @@ +package org.bukkit.util.noise; + +import java.util.Random; +import org.bukkit.World; + +/** + * Creates simplex noise through unbiased octaves + */ +public class SimplexOctaveGenerator extends OctaveGenerator { + private double wScale = 1; + + /** + * Creates a simplex octave generator for the given world + * + * @param world World to construct this generator for + * @param octaves Amount of octaves to create + */ + public SimplexOctaveGenerator(World world, int octaves) { + this(new Random(world.getSeed()), octaves); + } + + /** + * Creates a simplex octave generator for the given world + * + * @param seed Seed to construct this generator for + * @param octaves Amount of octaves to create + */ + public SimplexOctaveGenerator(long seed, int octaves) { + this(new Random(seed), octaves); + } + + /** + * Creates a simplex octave generator for the given {@link Random} + * + * @param rand Random object to construct this generator for + * @param octaves Amount of octaves to create + */ + public SimplexOctaveGenerator(Random rand, int octaves) { + super(createOctaves(rand, octaves)); + } + + @Override + public void setScale(double scale) { + super.setScale(scale); + setWScale(scale); + } + + /** + * Gets the scale used for each W-coordinates passed + * + * @return W scale + */ + public double getWScale() { + return wScale; + } + + /** + * Sets the scale used for each W-coordinates passed + * + * @param scale New W scale + */ + public void setWScale(double scale) { + wScale = scale; + } + + /** + * Generates noise for the 3D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param z Z-coordinate + * @param w W-coordinate + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @return Resulting noise + */ + public double noise(double x, double y, double z, double w, double frequency, double amplitude) { + return noise(x, y, z, w, frequency, amplitude, false); + } + + /** + * Generates noise for the 3D coordinates using the specified number of + * octaves and parameters + * + * @param x X-coordinate + * @param y Y-coordinate + * @param z Z-coordinate + * @param w W-coordinate + * @param frequency How much to alter the frequency by each octave + * @param amplitude How much to alter the amplitude by each octave + * @param normalized If true, normalize the value to [-1, 1] + * @return Resulting noise + */ + public double noise(double x, double y, double z, double w, double frequency, double amplitude, boolean normalized) { + double result = 0; + double amp = 1; + double freq = 1; + double max = 0; + + x *= xScale; + y *= yScale; + z *= zScale; + w *= wScale; + + for (NoiseGenerator octave : octaves) { + result += ((SimplexNoiseGenerator) octave).noise(x * freq, y * freq, z * freq, w * freq) * amp; + max += amp; + freq *= frequency; + amp *= amplitude; + } + + if (normalized) { + result /= max; + } + + return result; + } + + private static NoiseGenerator[] createOctaves(Random rand, int octaves) { + NoiseGenerator[] result = new NoiseGenerator[octaves]; + + for (int i = 0; i < octaves; i++) { + result[i] = new SimplexNoiseGenerator(rand); + } + + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/BroadcastPermissions.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/BroadcastPermissions.java new file mode 100644 index 0000000..092370e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/BroadcastPermissions.java @@ -0,0 +1,22 @@ +package org.bukkit.util.permissions; + +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; + +public final class BroadcastPermissions { + private static final String ROOT = "bukkit.broadcast"; + private static final String PREFIX = ROOT + "."; + + private BroadcastPermissions() {} + + public static Permission registerPermissions(Permission parent) { + Permission broadcasts = DefaultPermissions.registerPermission(ROOT, "Allows the user to receive all broadcast messages", parent); + + DefaultPermissions.registerPermission(PREFIX + "admin", "Allows the user to receive administrative broadcasts", PermissionDefault.OP, broadcasts); + DefaultPermissions.registerPermission(PREFIX + "user", "Allows the user to receive user broadcasts", PermissionDefault.TRUE, broadcasts); + + broadcasts.recalculatePermissibles(); + + return broadcasts; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/CommandPermissions.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/CommandPermissions.java new file mode 100644 index 0000000..619646e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/CommandPermissions.java @@ -0,0 +1,23 @@ +package org.bukkit.util.permissions; + +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; + +public final class CommandPermissions { + private static final String ROOT = "bukkit.command"; + private static final String PREFIX = ROOT + "."; + + private CommandPermissions() {} + + public static Permission registerPermissions(Permission parent) { + Permission commands = DefaultPermissions.registerPermission(ROOT, "Gives the user the ability to use all CraftBukkit commands", parent); + + DefaultPermissions.registerPermission(PREFIX + "help", "Allows the user to view the vanilla help menu", PermissionDefault.TRUE, commands); + DefaultPermissions.registerPermission(PREFIX + "plugins", "Allows the user to view the list of plugins running on this server", PermissionDefault.TRUE, commands); + DefaultPermissions.registerPermission(PREFIX + "reload", "Allows the user to reload the server settings", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "version", "Allows the user to view the version of the server", PermissionDefault.TRUE, commands); + + commands.recalculatePermissibles(); + return commands; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java new file mode 100644 index 0000000..8c0df8e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/bukkit/util/permissions/DefaultPermissions.java @@ -0,0 +1,82 @@ +package org.bukkit.util.permissions; + +import java.util.Map; +import org.bukkit.Bukkit; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; + +public final class DefaultPermissions { + private static final String ROOT = "craftbukkit"; + private static final String LEGACY_PREFIX = "craft"; + + private DefaultPermissions() {} + + public static Permission registerPermission(Permission perm) { + return registerPermission(perm, true); + } + + public static Permission registerPermission(Permission perm, boolean withLegacy) { + Permission result = perm; + + try { + Bukkit.getPluginManager().addPermission(perm); + } catch (IllegalArgumentException ex) { + result = Bukkit.getPluginManager().getPermission(perm.getName()); + } + + if (withLegacy) { + Permission legacy = new Permission(LEGACY_PREFIX + result.getName(), result.getDescription(), PermissionDefault.FALSE); + legacy.getChildren().put(result.getName(), true); + registerPermission(perm, false); + } + + return result; + } + + public static Permission registerPermission(Permission perm, Permission parent) { + parent.getChildren().put(perm.getName(), true); + return registerPermission(perm); + } + + public static Permission registerPermission(String name, String desc) { + Permission perm = registerPermission(new Permission(name, desc)); + return perm; + } + + public static Permission registerPermission(String name, String desc, Permission parent) { + Permission perm = registerPermission(name, desc); + parent.getChildren().put(perm.getName(), true); + return perm; + } + + public static Permission registerPermission(String name, String desc, PermissionDefault def) { + Permission perm = registerPermission(new Permission(name, desc, def)); + return perm; + } + + public static Permission registerPermission(String name, String desc, PermissionDefault def, Permission parent) { + Permission perm = registerPermission(name, desc, def); + parent.getChildren().put(perm.getName(), true); + return perm; + } + + public static Permission registerPermission(String name, String desc, PermissionDefault def, Map children) { + Permission perm = registerPermission(new Permission(name, desc, def, children)); + return perm; + } + + public static Permission registerPermission(String name, String desc, PermissionDefault def, Map children, Permission parent) { + Permission perm = registerPermission(name, desc, def, children); + parent.getChildren().put(perm.getName(), true); + return perm; + } + + public static void registerCorePermissions() { + Permission parent = registerPermission(ROOT, "Gives the user the ability to use all CraftBukkit utilities and commands"); + + CommandPermissions.registerPermissions(parent); + BroadcastPermissions.registerPermissions(parent); + + parent.recalculatePermissibles(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/github/paperspigot/Title.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/github/paperspigot/Title.java new file mode 100644 index 0000000..27f9bc2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/github/paperspigot/Title.java @@ -0,0 +1,358 @@ +package org.github.paperspigot; + +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; + +import org.bukkit.entity.Player; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +/** + * Represents a title to may be sent to a {@link Player}. + *

+ *

A title can be sent without subtitle text.

+ */ +public final class Title { + + /** + * The default number of ticks for the title to fade in. + */ + public static final int DEFAULT_FADE_IN = 20; + /** + * The default number of ticks for the title to stay. + */ + public static final int DEFAULT_STAY = 200; + /** + * The default number of ticks for the title to fade out. + */ + public static final int DEFAULT_FADE_OUT = 20; + + private final BaseComponent[] title; + private final BaseComponent[] subtitle; + private final int fadeIn; + private final int stay; + private final int fadeOut; + + /** + * Create a title with the default time values and no subtitle. + *

+ *

Times use default values.

+ * + * @param title the main text of the title + * @throws NullPointerException if the title is null + */ + public Title(BaseComponent title) { + this(title, null); + } + + /** + * Create a title with the default time values and no subtitle. + *

+ *

Times use default values.

+ * + * @param title the main text of the title + * @throws NullPointerException if the title is null + */ + public Title(BaseComponent[] title) { + this(title, null); + } + + /** + * Create a title with the default time values and no subtitle. + *

+ *

Times use default values.

+ * + * @param title the main text of the title + * @throws NullPointerException if the title is null + */ + public Title(String title) { + this(title, null); + } + + /** + * Create a title with the default time values. + *

+ *

Times use default values.

+ * + * @param title the main text of the title + * @param subtitle the secondary text of the title + */ + public Title(BaseComponent title, BaseComponent subtitle) { + this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT); + } + + /** + * Create a title with the default time values. + *

+ *

Times use default values.

+ * + * @param title the main text of the title + * @param subtitle the secondary text of the title + */ + public Title(BaseComponent[] title, BaseComponent[] subtitle) { + this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT); + } + + /** + * Create a title with the default time values. + *

+ *

Times use default values.

+ * + * @param title the main text of the title + * @param subtitle the secondary text of the title + */ + public Title(String title, String subtitle) { + this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT); + } + + /** + * Creates a new title. + * + * @param title the main text of the title + * @param subtitle the secondary text of the title + * @param fadeIn the number of ticks for the title to fade in + * @param stay the number of ticks for the title to stay on screen + * @param fadeOut the number of ticks for the title to fade out + * @throws IllegalArgumentException if any of the times are negative + */ + public Title(BaseComponent title, BaseComponent subtitle, int fadeIn, int stay, int fadeOut) { + this( + new BaseComponent[]{checkNotNull(title, "title")}, + subtitle == null ? null : new BaseComponent[]{subtitle}, + fadeIn, + stay, + fadeOut + ); + } + + /** + * Creates a new title. + * + * @param title the main text of the title + * @param subtitle the secondary text of the title + * @param fadeIn the number of ticks for the title to fade in + * @param stay the number of ticks for the title to stay on screen + * @param fadeOut the number of ticks for the title to fade out + * @throws IllegalArgumentException if any of the times are negative + */ + public Title(BaseComponent[] title, BaseComponent[] subtitle, int fadeIn, int stay, int fadeOut) { + checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn); + checkArgument(stay >= 0, "Negative stay: %s", stay); + checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut); + this.title = checkNotNull(title, "title"); + this.subtitle = subtitle; + this.fadeIn = fadeIn; + this.stay = stay; + this.fadeOut = fadeOut; + } + + /** + * Creates a new title. + *

+ *

It is recommended to the {@link BaseComponent} constrctors.

+ * + * @param title the main text of the title + * @param subtitle the secondary text of the title + * @param fadeIn the number of ticks for the title to fade in + * @param stay the number of ticks for the title to stay on screen + * @param fadeOut the number of ticks for the title to fade out + */ + public Title(String title, String subtitle, int fadeIn, int stay, int fadeOut) { + this( + TextComponent.fromLegacyText(checkNotNull(title, "title")), + subtitle == null ? null : TextComponent.fromLegacyText(subtitle), + fadeIn, + stay, + fadeOut + ); + } + + /** + * Gets the text of this title + * + * @return the text + */ + public BaseComponent[] getTitle() { + return this.title; + } + + /** + * Gets the text of this title's subtitle + * + * @return the text + */ + public BaseComponent[] getSubtitle() { + return this.subtitle; + } + + /** + * Gets the number of ticks to fade in. + *

+ *

The returned value is never negative.

+ * + * @return the number of ticks to fade in + */ + public int getFadeIn() { + return this.fadeIn; + } + + /** + * Gets the number of ticks to stay. + *

+ *

The returned value is never negative.

+ * + * @return the number of ticks to stay + */ + public int getStay() { + return this.stay; + } + + /** + * Gets the number of ticks to fade out. + *

+ *

The returned value is never negative.

+ * + * @return the number of ticks to fade out + */ + public int getFadeOut() { + return this.fadeOut; + } + + public static Builder builder() { + return new Builder(); + } + + /** + * A builder for creating titles + */ + public static final class Builder { + + private BaseComponent[] title; + private BaseComponent[] subtitle; + private int fadeIn = DEFAULT_FADE_IN; + private int stay = DEFAULT_STAY; + private int fadeOut = DEFAULT_FADE_OUT; + + /** + * Sets the title to the given text. + * + * @param title the title text + * @return this builder instance + * @throws NullPointerException if the title is null + */ + public Builder title(BaseComponent title) { + return this.title(new BaseComponent[]{checkNotNull(title, "title")}); + } + + /** + * Sets the title to the given text. + * + * @param title the title text + * @return this builder instance + * @throws NullPointerException if the title is null + */ + public Builder title(BaseComponent[] title) { + this.title = checkNotNull(title, "title"); + return this; + } + + /** + * Sets the title to the given text. + *

+ *

It is recommended to the {@link BaseComponent} methods.

+ * + * @param title the title text + * @return this builder instance + * @throws NullPointerException if the title is null + */ + public Builder title(String title) { + return this.title(TextComponent.fromLegacyText(checkNotNull(title, "title"))); + } + + /** + * Sets the subtitle to the given text. + * + * @param subtitle the title text + * @return this builder instance + */ + public Builder subtitle(BaseComponent subtitle) { + return this.subtitle(subtitle == null ? null : new BaseComponent[]{subtitle}); + } + + /** + * Sets the subtitle to the given text. + * + * @param subtitle the title text + * @return this builder instance + */ + public Builder subtitle(BaseComponent[] subtitle) { + this.subtitle = subtitle; + return this; + } + + /** + * Sets the subtitle to the given text. + *

+ *

It is recommended to the {@link BaseComponent} methods.

+ * + * @param subtitle the title text + * @return this builder instance + */ + public Builder subtitle(String subtitle) { + return this.subtitle(subtitle == null ? null : TextComponent.fromLegacyText(subtitle)); + } + + /** + * Sets the number of ticks for the title to fade in + * + * @param fadeIn the number of ticks to fade in + * @return this builder instance + * @throws IllegalArgumentException if it is negative + */ + public Builder fadeIn(int fadeIn) { + checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn); + this.fadeIn = fadeIn; + return this; + } + + + /** + * Sets the number of ticks for the title to stay. + * + * @param stay the number of ticks to stay + * @return this builder instance + * @throws IllegalArgumentException if it is negative + */ + public Builder stay(int stay) { + checkArgument(stay >= 0, "Negative stay: %s", stay); + this.stay = stay; + return this; + } + + /** + * Sets the number of ticks for the title to fade out. + * + * @param fadeOut the number of ticks to fade out + * @return this builder instance + * @throws IllegalArgumentException if it is negative + */ + public Builder fadeOut(int fadeOut) { + checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut); + this.fadeOut = fadeOut; + return this; + } + + /** + * Create a title based on the values in the builder. + * + * @return a title from the values in this builder + * @throws IllegalStateException if title isn't specified + */ + public Title build() { + checkState(title != null, "Title not specified"); + return new Title(this.title, this.subtitle, this.fadeIn, this.stay, this.fadeOut); + } + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/github/paperspigot/event/block/BeaconEffectEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/github/paperspigot/event/block/BeaconEffectEvent.java new file mode 100644 index 0000000..67357a5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/github/paperspigot/event/block/BeaconEffectEvent.java @@ -0,0 +1,73 @@ +package org.github.paperspigot.event.block; + +import lombok.Getter; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.PotionEffectAddEvent; +import org.bukkit.potion.PotionEffect; + +/** + * Called when a beacon effect is being applied to a player. + */ +public class BeaconEffectEvent extends PotionEffectAddEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private PotionEffect effect; + private Player player; + private boolean primary; + @Getter private final Block block; + + public BeaconEffectEvent(Block block, PotionEffect effect, Player player, boolean primary) { + super(player, effect); + this.block = block; + this.effect = effect; + this.player = player; + this.primary = primary; + } + + /** + * Gets the potion effect being applied. + * + * @return Potion effect + */ + public PotionEffect getEffect() { + return effect; + } + + /** + * Sets the potion effect that will be applied. + * + * @param effect Potion effect + */ + public void setEffect(PotionEffect effect) { + this.effect = effect; + } + + /** + * Gets the player who the potion effect is being applied to. + * + * @return Affected player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets whether the effect is a primary beacon effect. + * + * @return true if this event represents a primary effect + */ + public boolean isPrimary() { + return primary; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/CustomTimingsHandler.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/CustomTimingsHandler.java new file mode 100644 index 0000000..e9c391d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/CustomTimingsHandler.java @@ -0,0 +1,79 @@ +/* + * This file is licensed under the MIT License (MIT). + * + * Copyright (c) 2014 Daniel Ennis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +/* +package org.spigotmc; + +import jdk.internal.reflect.Reflection; +import org.bukkit.Bukkit; +import org.bukkit.plugin.AuthorNagException; +import org.bukkit.plugin.Plugin; +import co.aikar.timings.NullTimingHandler; +import co.aikar.timings.Timing; +import co.aikar.timings.Timings; +import co.aikar.timings.TimingsManager; + +import java.lang.reflect.Method; +import java.util.logging.Level; + +/** + * This is here for legacy purposes incase any plugin used it. + * + * If you use this, migrate ASAP as this will be removed in the future! + * + * @deprecated + * @see co.aikar.timings.Timings#of + */ +/* +@Deprecated +public final class CustomTimingsHandler { + private final Timing handler; + + public CustomTimingsHandler(String name) { + Timing timing; + + Plugin plugin = null; + try { + plugin = TimingsManager.getPluginByClassloader(Reflection.getCallerClass()); + } catch (Exception ignored) {} + + new AuthorNagException("Deprecated use of CustomTimingsHandler. Please Switch to Timings.of ASAP").printStackTrace(); + if (plugin != null) { + timing = Timings.of(plugin, "(Deprecated API) " + name); + } else { + try { + final Method ofSafe = TimingsManager.class.getMethod("getHandler", String.class, String.class, Timing.class, boolean.class); + timing = (Timing) ofSafe.invoke("Minecraft", "(Deprecated API) " + name, null, true); + } catch (Exception e) { + Bukkit.getLogger().log(Level.SEVERE, "This handler could not be registered"); + timing = Timings.NULL_HANDLER; + } + } + handler = timing; + } + + public void startTiming() { handler.startTiming(); } + public void stopTiming() { handler.stopTiming(); } + +} +*/ \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java new file mode 100644 index 0000000..b35c7c1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java @@ -0,0 +1,55 @@ +package org.spigotmc.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; + +// PaperSpigot start +import org.bukkit.event.Cancellable; +// PaperSpigot end + +/** + * Called when an entity stops riding another entity. + * + */ +public class EntityDismountEvent extends EntityEvent implements Cancellable // PaperSpigot - implement Cancellable +{ + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Entity dismounted; + + public EntityDismountEvent(Entity what, Entity dismounted) + { + super( what ); + this.dismounted = dismounted; + } + + public Entity getDismounted() + { + return dismounted; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + // PaperSpigot start - implement Cancellable methods + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/entity/EntityMountEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/entity/EntityMountEvent.java new file mode 100644 index 0000000..16aa2a7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/entity/EntityMountEvent.java @@ -0,0 +1,52 @@ +package org.spigotmc.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; + +/** + * Called when an entity attempts to ride another entity. + * + */ +public class EntityMountEvent extends EntityEvent implements Cancellable +{ + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Entity mount; + + public EntityMountEvent(Entity what, Entity mount) + { + super( what ); + this.mount = mount; + } + + public Entity getMount() + { + return mount; + } + + @Override + public boolean isCancelled() + { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) + { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/player/PlayerSpawnLocationEvent.java b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/player/PlayerSpawnLocationEvent.java new file mode 100644 index 0000000..dd3f58c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/java/org/spigotmc/event/player/PlayerSpawnLocationEvent.java @@ -0,0 +1,50 @@ +package org.spigotmc.event.player; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +/** + * Called when player is about to spawn in a world after joining the server. + */ +public class PlayerSpawnLocationEvent extends PlayerEvent { + private static final HandlerList handlers = new HandlerList(); + private Location spawnLocation; + + public PlayerSpawnLocationEvent(final Player who, Location spawnLocation) { + super(who); + this.spawnLocation = spawnLocation; + } + + + /** + * Gets player's spawn location. + * If the player {@link Player#hasPlayedBefore()}, it's going to default to the location inside player.dat file. + * For new players, the default spawn location is spawn of the main Bukkit world. + * + * @return the spawn location + */ + public Location getSpawnLocation() { + return spawnLocation; + } + + /** + * Sets player's spawn location. + * + * @param location the spawn location + */ + public void setSpawnLocation(Location location) { + this.spawnLocation = location; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/block/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/block/package-info.java new file mode 100644 index 0000000..dc0f36a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/block/package-info.java @@ -0,0 +1,6 @@ +/** + * Classes used to manipulate the voxels in a {@link org.bukkit.World world}, + * including special states. + */ +package org.bukkit.block; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/command/defaults/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/command/defaults/package-info.java new file mode 100644 index 0000000..b67dfba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/command/defaults/package-info.java @@ -0,0 +1,6 @@ +/** + * Commands for emulating the Minecraft commands and other necessary ones for + * use by a Bukkit implementation. + */ +package org.bukkit.command.defaults; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/command/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/command/package-info.java new file mode 100644 index 0000000..6428f47 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/command/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes relating to handling specialized non-chat player input. + */ +package org.bukkit.command; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/file/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/file/package-info.java new file mode 100644 index 0000000..4973ffc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/file/package-info.java @@ -0,0 +1,7 @@ +/** + * Classes dedicated facilitating {@link + * org.bukkit.configuration.Configuration configurations} to be read and + * stored on the filesystem. + */ +package org.bukkit.configuration.file; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/package-info.java new file mode 100644 index 0000000..63a3965 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes dedicated to handling a plugin's runtime configuration. + */ +package org.bukkit.configuration; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/serialization/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/serialization/package-info.java new file mode 100644 index 0000000..529de2e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/configuration/serialization/package-info.java @@ -0,0 +1,7 @@ +/** + * Classes dedicated to being able to perform serialization specialized for + * the Bukkit {@link org.bukkit.configuration.Configuration configuration} + * implementation. + */ +package org.bukkit.configuration.serialization; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/conversations/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/conversations/package-info.java new file mode 100644 index 0000000..d49dafa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/conversations/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes dedicated to facilitate direct player-to-plugin communication. + */ +package org.bukkit.conversations; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/enchantments/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/enchantments/package-info.java new file mode 100644 index 0000000..fb67cc7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/enchantments/package-info.java @@ -0,0 +1,7 @@ +/** + * Classes relating to the specialized enhancements to {@link + * org.bukkit.inventory.ItemStack item stacks}, as part of the {@link + * org.bukkit.inventory.meta.ItemMeta meta data}. + */ +package org.bukkit.enchantments; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/entity/minecart/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/entity/minecart/package-info.java new file mode 100644 index 0000000..342f10b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/entity/minecart/package-info.java @@ -0,0 +1,5 @@ +/** + * Interfaces for various {@link org.bukkit.entity.Minecart} types. + */ +package org.bukkit.entity.minecart; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/entity/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/entity/package-info.java new file mode 100644 index 0000000..167a830 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/entity/package-info.java @@ -0,0 +1,6 @@ +/** + * Interfaces for non-voxel objects that can exist in a {@link + * org.bukkit.World world}, including all players, monsters, projectiles, etc. + */ +package org.bukkit.entity; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/block/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/block/package-info.java new file mode 100644 index 0000000..30aec21 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/block/package-info.java @@ -0,0 +1,7 @@ +/** + * {@link org.bukkit.event.Event Events} relating to when a {@link + * org.bukkit.block.Block block} is changed or interacts with the {@link + * org.bukkit.World world}. + */ +package org.bukkit.event.block; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/enchantment/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/enchantment/package-info.java new file mode 100644 index 0000000..e609c63 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/enchantment/package-info.java @@ -0,0 +1,6 @@ +/** + * {@link org.bukkit.event.Event Events} triggered from an {@link + * org.bukkit.inventory.EnchantingInventory enchantment table}. + */ +package org.bukkit.event.enchantment; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/entity/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/entity/package-info.java new file mode 100644 index 0000000..cddcd4e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/entity/package-info.java @@ -0,0 +1,7 @@ +/** + * {@link org.bukkit.event.Event Events} relating to {@link + * org.bukkit.entity.Entity entities}, excluding some directly referencing + * some more specific entity types. + */ +package org.bukkit.event.entity; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/hanging/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/hanging/package-info.java new file mode 100644 index 0000000..bf16382 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/hanging/package-info.java @@ -0,0 +1,6 @@ +/** + * {@link org.bukkit.event.Event Events} relating to {@link + * org.bukkit.entity.Hanging entities that hang}. + */ +package org.bukkit.event.hanging; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/inventory/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/inventory/package-info.java new file mode 100644 index 0000000..7dd5b69 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/inventory/package-info.java @@ -0,0 +1,6 @@ +/** + * {@link org.bukkit.event.Event Events} relating to {@link + * org.bukkit.inventory.Inventory inventory} manipulation. + */ +package org.bukkit.event.inventory; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/package-info.java new file mode 100644 index 0000000..dd8baa1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes dedicated to handling triggered code executions. + */ +package org.bukkit.event; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/painting/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/painting/package-info.java new file mode 100644 index 0000000..6c9a091 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/painting/package-info.java @@ -0,0 +1,7 @@ +/** + * {@link org.bukkit.event.Event Events} relating to {@link + * org.bukkit.entity.Painting paintings}, but deprecated for more general + * {@link org.bukkit.event.hanging hanging} events. + */ +package org.bukkit.event.painting; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/player/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/player/package-info.java new file mode 100644 index 0000000..fb645f3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/player/package-info.java @@ -0,0 +1,6 @@ +/** + * {@link org.bukkit.event.Event Events} relating to {@link + * org.bukkit.entity.Player players}. + */ +package org.bukkit.event.player; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/server/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/server/package-info.java new file mode 100644 index 0000000..b548270 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/server/package-info.java @@ -0,0 +1,6 @@ +/** + * {@link org.bukkit.event.Event Events} relating to programmatic state + * changes on the server. + */ +package org.bukkit.event.server; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/vehicle/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/vehicle/package-info.java new file mode 100644 index 0000000..b88cbcd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/vehicle/package-info.java @@ -0,0 +1,6 @@ +/** + * {@link org.bukkit.event.Event Events} relating to {@link + * org.bukkit.entity.Vehicle vehicular entities}. + */ +package org.bukkit.event.vehicle; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/weather/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/weather/package-info.java new file mode 100644 index 0000000..edaaf9f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/weather/package-info.java @@ -0,0 +1,5 @@ +/** + * {@link org.bukkit.event.Event Events} relating to weather. + */ +package org.bukkit.event.weather; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/world/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/world/package-info.java new file mode 100644 index 0000000..4cbb818 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/event/world/package-info.java @@ -0,0 +1,6 @@ +/** + * {@link org.bukkit.event.Event Events} triggered by various {@link + * org.bukkit.World world} states or changes. + */ +package org.bukkit.event.world; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/generator/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/generator/package-info.java new file mode 100644 index 0000000..2532add --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/generator/package-info.java @@ -0,0 +1,6 @@ +/** + * Classes to facilitate {@link org.bukkit.World world} generation + * implementation. + */ +package org.bukkit.generator; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/help/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/help/package-info.java new file mode 100644 index 0000000..66a4aac --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/help/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes used to manipulate the default command and topic assistance system. + */ +package org.bukkit.help; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/inventory/meta/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/inventory/meta/package-info.java new file mode 100644 index 0000000..b80eb88 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/inventory/meta/package-info.java @@ -0,0 +1,6 @@ +/** + * The interfaces used when manipulating extra data can can be stored inside + * {@link org.bukkit.inventory.ItemStack item stacks}. + */ +package org.bukkit.inventory.meta; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/inventory/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/inventory/package-info.java new file mode 100644 index 0000000..8881abc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/inventory/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes involved in manipulating player inventories and item interactions. + */ +package org.bukkit.inventory; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/map/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/map/package-info.java new file mode 100644 index 0000000..30de8b2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/map/package-info.java @@ -0,0 +1,6 @@ +/** + * Classes to facilitate plugin handling of {@link org.bukkit.Material#MAP + * map} displays. + */ +package org.bukkit.map; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/material/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/material/package-info.java new file mode 100644 index 0000000..f3be435 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/material/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes that represents various voxel types and states. + */ +package org.bukkit.material; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/metadata/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/metadata/package-info.java new file mode 100644 index 0000000..f8e0039 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/metadata/package-info.java @@ -0,0 +1,6 @@ +/** + * Classes dedicated to providing a layer of plugin specified data on various + * Minecraft concepts. + */ +package org.bukkit.metadata; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/package-info.java new file mode 100644 index 0000000..da7d9f1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/package-info.java @@ -0,0 +1,5 @@ +/** + * More generalized classes in the API. + */ +package org.bukkit; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/permissions/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/permissions/package-info.java new file mode 100644 index 0000000..860abc3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/permissions/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes dedicated to providing binary state properties to players. + */ +package org.bukkit.permissions; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/doc-files/permissions-example_plugin.yml b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/doc-files/permissions-example_plugin.yml new file mode 100644 index 0000000..34d0381 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/doc-files/permissions-example_plugin.yml @@ -0,0 +1,64 @@ +name: ScrapBukkit +main: com.dinnerbone.bukkit.scrap.ScrapBukkit +version: 1.0.0 +website: http://www.bukkit.org +author: The Bukkit Team +description: > + Miscellaneous administrative commands for Bukkit. + This plugin is one of the default plugins shipped with Bukkit. +# commands: snipped + +permissions: + scrapbukkit.*: + description: Gives all permissions for Scrapbukkit + default: op + children: + scrapbukkit.remove: + description: Allows the player to remove items from anyones inventory + children: + scrapbukkit.remove.self: + description: Allows the player to remove items from their own inventory + scrapbukkit.remove.other: + description: Allows the player to remove items from other peoples inventory + + scrapbukkit.time: + description: Allows the player to view and change the time + children: + scrapbukkit.time.view: + description: Allows the player to view the time + default: true + scrapbukkit.time.change: + description: Allows the player to change the time + + scrapbukkit.tp: + description: Allows the player to teleport anyone to anyone else + children: + scrapbukkit.tp.here: + description: Allows the player to teleport other players to themselves + scrapbukkit.tp.self: + description: Allows the player to teleport themselves to another player + scrapbukkit.tp.other: + description: Allows the player to teleport anyone to another player + + scrapbukkit.give: + description: Allows the player to give items + children: + scrapbukkit.give.self: + description: Allows the player to give themselves items + scrapbukkit.give.other: + description: Allows the player to give other players items + + scrapbukkit.clear: + description: Allows the player to clear inventories + children: + scrapbukkit.clear.self: + description: Allows the player to clear their own inventory + scrapbukkit.clear.other: + description: Allows the player to clear other players inventory + + scrapbukkit.some.standard.perm: {} + scrapbukkit.some.other.perm: true + scrapbukkit.some.bad.perm: false + # This is defined here individually, as simply giving it an association will not cause it to exist at runtime + scrapbukkit.some.bad.perm: {} + scrapbukkit.some.other.perm: {} diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/java/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/java/package-info.java new file mode 100644 index 0000000..c74e709 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/java/package-info.java @@ -0,0 +1,6 @@ +/** + * Classes for handling {@link org.bukkit.plugin.Plugin plugins} written in + * java. + */ +package org.bukkit.plugin.java; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/messaging/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/messaging/package-info.java new file mode 100644 index 0000000..04cb2b9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/messaging/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes dedicated to specialized plugin to client protocols. + */ +package org.bukkit.plugin.messaging; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/package-info.java new file mode 100644 index 0000000..76fbe6b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/plugin/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes specifically relating to loading software modules at runtime. + */ +package org.bukkit.plugin; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/potion/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/potion/package-info.java new file mode 100644 index 0000000..6dd3454 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/potion/package-info.java @@ -0,0 +1,6 @@ +/** + * Classes to represent various {@link org.bukkit.Material#POTION potion} + * properties and manipulation. + */ +package org.bukkit.potion; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/projectiles/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/projectiles/package-info.java new file mode 100644 index 0000000..5efe736 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/projectiles/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes to represent the source of a projectile + */ +package org.bukkit.projectiles; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/scheduler/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/scheduler/package-info.java new file mode 100644 index 0000000..c441df6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/scheduler/package-info.java @@ -0,0 +1,6 @@ +/** + * Classes dedicated to letting {@link org.bukkit.plugin.Plugin plugins} run + * code at specific time intervals, including thread safety. + */ +package org.bukkit.scheduler; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/scoreboard/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/scoreboard/package-info.java new file mode 100644 index 0000000..4d0b7e2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/scoreboard/package-info.java @@ -0,0 +1,5 @@ +/** + * Interfaces used to manage the client side score display system. + */ +package org.bukkit.scoreboard; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/io/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/io/package-info.java new file mode 100644 index 0000000..c4efffb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/io/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes used to facilitate stream processing for specific Bukkit concepts. + */ +package org.bukkit.util.io; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/noise/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/noise/package-info.java new file mode 100644 index 0000000..8dd1501 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/noise/package-info.java @@ -0,0 +1,5 @@ +/** + * Classes dedicated to facilitating deterministic noise. + */ +package org.bukkit.util.noise; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/package-info.java new file mode 100644 index 0000000..58176d0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/package-info.java @@ -0,0 +1,6 @@ +/** + * Multi and single purpose classes to facilitate various programmatic + * concepts. + */ +package org.bukkit.util; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/permissions/package-info.java b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/permissions/package-info.java new file mode 100644 index 0000000..0749811 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/org/bukkit/util/permissions/package-info.java @@ -0,0 +1,6 @@ +/** + * Static methods for miscellaneous {@link org.bukkit.permissions.Permission + * permission} functionality. + */ +package org.bukkit.util.permissions; + diff --git a/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/overview.html b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/overview.html new file mode 100644 index 0000000..e96bf35 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/main/javadoc/overview.html @@ -0,0 +1,17 @@ + +

Bukkit, the plugin development framework.

+ +

+ The documentation is for developing plugins and is split into the + respective packages for each subject matter. This documentation does not + cover running a server, contributing code back to the project, or setting + up a workspace. Working knowledge of the Java language is a prerequisite + for developing plugins. +

+ For basic plugin development, see the {@link org.bukkit.plugin plugin + package}. It covers the basic requirements of a plugin jar. +

+ For handling events and triggered code, see the {@link org.bukkit.event + event package}. +

+ diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/ConfigurationSectionTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/ConfigurationSectionTest.java new file mode 100644 index 0000000..6dab477 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/ConfigurationSectionTest.java @@ -0,0 +1,548 @@ +package org.bukkit.configuration; + +import org.bukkit.Material; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; +import org.junit.Test; +import static org.junit.Assert.*; + +public abstract class ConfigurationSectionTest { + public abstract ConfigurationSection getConfigurationSection(); + + @Test + public void testGetKeys() { + ConfigurationSection section = getConfigurationSection(); + + section.set("key", true); + section.set("subsection.subkey", true); + section.set("subsection.subkey2", true); + section.set("subsection.subsubsection.key", true); + section.set("key2", true); + section.set("42", true); + + assertArrayEquals(new String[] { "key", "subsection", "key2", "42" }, section.getKeys(false).toArray()); + assertArrayEquals(new String[] { "key", "subsection", "subsection.subkey", "subsection.subkey2", "subsection.subsubsection", "subsection.subsubsection.key", "key2", "42" }, section.getKeys(true).toArray()); + assertArrayEquals(new String[] { "subkey", "subkey2", "subsubsection", "subsubsection.key" }, section.getConfigurationSection("subsection").getKeys(true).toArray()); + } + + @Test + public void testGetKeysWithDefaults() { + ConfigurationSection section = getConfigurationSection(); + section.getRoot().options().copyDefaults(true); + + section.set("key", true); + section.addDefault("subsection.subkey", true); + section.addDefault("subsection.subkey2", true); + section.addDefault("subsection.subsubsection.key", true); + section.addDefault("key2", true); + + assertArrayEquals(new String[] { "subsection", "key2", "key" }, section.getKeys(false).toArray()); + assertArrayEquals(new String[] { "subsection", "subsection.subkey", "subsection.subkey2", "subsection.subsubsection", "subsection.subsubsection.key", "key2", "key" }, section.getKeys(true).toArray()); + assertArrayEquals(new String[] { "subkey", "subkey2", "subsubsection", "subsubsection.key" }, section.getConfigurationSection("subsection").getKeys(true).toArray()); + } + + @Test + public void testGetValues() { + ConfigurationSection section = getConfigurationSection(); + + section.set("bool", true); + section.set("subsection.string", "test"); + section.set("subsection.long", Long.MAX_VALUE); + section.set("int", 42); + + Map shallowValues = section.getValues(false); + assertArrayEquals(new String[] { "bool", "subsection", "int" }, shallowValues.keySet().toArray()); + assertArrayEquals(new Object[] { true, section.getConfigurationSection("subsection"), 42 }, shallowValues.values().toArray()); + + Map deepValues = section.getValues(true); + assertArrayEquals(new String[] { "bool", "subsection", "subsection.string", "subsection.long", "int" }, deepValues.keySet().toArray()); + assertArrayEquals(new Object[] { true, section.getConfigurationSection("subsection"), "test", Long.MAX_VALUE, 42 }, deepValues.values().toArray()); + } + + @Test + public void testGetValuesWithDefaults() { + ConfigurationSection section = getConfigurationSection(); + section.getRoot().options().copyDefaults(true); + + section.set("bool", true); + section.set("subsection.string", "test"); + section.addDefault("subsection.long", Long.MAX_VALUE); + section.addDefault("int", 42); + + Map shallowValues = section.getValues(false); + assertArrayEquals(new String[] { "subsection", "int", "bool" }, shallowValues.keySet().toArray()); + assertArrayEquals(new Object[] { section.getConfigurationSection("subsection"), 42, true }, shallowValues.values().toArray()); + + Map deepValues = section.getValues(true); + assertArrayEquals(new String[] { "subsection", "subsection.long", "int", "bool", "subsection.string" }, deepValues.keySet().toArray()); + assertArrayEquals(new Object[] { section.getConfigurationSection("subsection"), Long.MAX_VALUE, 42, true, "test" }, deepValues.values().toArray()); + } + + @Test + public void testContains() { + ConfigurationSection section = getConfigurationSection(); + + section.set("exists", true); + + assertTrue(section.contains("exists")); + assertFalse(section.contains("doesnt-exist")); + } + + @Test + public void testIsSet() { + ConfigurationSection section = getConfigurationSection(); + + section.set("notDefault", true); + section.getRoot().addDefault("default", true); + section.getRoot().addDefault("defaultAndSet", true); + section.set("defaultAndSet", true); + + assertTrue(section.isSet("notDefault")); + assertFalse(section.isSet("default")); + assertTrue(section.isSet("defaultAndSet")); + } + + @Test + public void testGetCurrentPath() { + ConfigurationSection section = getConfigurationSection(); + + assertEquals(section.getName(), section.getCurrentPath()); + } + + @Test + public void testGetName() { + ConfigurationSection section = getConfigurationSection().createSection("subsection"); + + assertEquals("subsection", section.getName()); + assertEquals("", section.getRoot().getName()); + } + + @Test + public void testGetRoot() { + ConfigurationSection section = getConfigurationSection(); + + assertNotNull(section.getRoot()); + assertTrue(section.getRoot().contains(section.getCurrentPath())); + } + + @Test + public void testGetParent() { + ConfigurationSection section = getConfigurationSection(); + ConfigurationSection subsection = section.createSection("subsection"); + + assertEquals(section.getRoot(), section.getParent()); + assertEquals(section, subsection.getParent()); + } + + @Test + public void testGet_String() { + ConfigurationSection section = getConfigurationSection(); + + section.set("exists", "hello world"); + + assertEquals("hello world", section.getString("exists")); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGet_String_Object() { + ConfigurationSection section = getConfigurationSection(); + + section.set("exists", "Set Value"); + + assertEquals("Set Value", section.get("exists", "Default Value")); + assertEquals("Default Value", section.get("doesntExist", "Default Value")); + } + + @Test + public void testSet() { + ConfigurationSection section = getConfigurationSection(); + + section.set("exists", "hello world"); + + assertTrue(section.contains("exists")); + assertTrue(section.isSet("exists")); + assertEquals("hello world", section.get("exists")); + + section.set("exists", null); + + assertFalse(section.contains("exists")); + assertFalse(section.isSet("exists")); + } + + @Test + public void testCreateSection() { + ConfigurationSection section = getConfigurationSection(); + ConfigurationSection subsection = section.createSection("subsection"); + + assertEquals("subsection", subsection.getName()); + } + + @Test + public void testSectionMap() { + ConfigurationSection config = getConfigurationSection(); + Map testMap = new LinkedHashMap(); + + testMap.put("string", "Hello World"); + testMap.put("integer", 15); + + config.createSection("test.path", testMap); + + assertEquals(testMap, config.getConfigurationSection("test.path").getValues(false)); + } + + @Test + public void testGetString_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + String value = "Hello World"; + + section.set(key, value); + + assertEquals(value, section.getString(key)); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetString_String_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + String value = "Hello World"; + String def = "Default Value"; + + section.set(key, value); + + assertEquals(value, section.getString(key, def)); + assertEquals(def, section.getString("doesntExist", def)); + } + + @Test + public void testIsString() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + String value = "Hello World"; + + section.set(key, value); + + assertTrue(section.isString(key)); + assertFalse(section.isString("doesntExist")); + } + + @Test + public void testGetInt_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + int value = Integer.MAX_VALUE; + + section.set(key, value); + + assertEquals(value, section.getInt(key)); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetInt_String_Int() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + int value = Integer.MAX_VALUE; + int def = Integer.MIN_VALUE; + + section.set(key, value); + + assertEquals(value, section.getInt(key, def)); + assertEquals(def, section.getInt("doesntExist", def)); + } + + @Test + public void testIsInt() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + int value = Integer.MAX_VALUE; + + section.set(key, value); + + assertTrue(section.isInt(key)); + assertFalse(section.isInt("doesntExist")); + } + + @Test + public void testGetBoolean_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + boolean value = true; + + section.set(key, value); + + assertEquals(value, section.getBoolean(key)); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetBoolean_String_Boolean() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + boolean value = true; + boolean def = false; + + section.set(key, value); + + assertEquals(value, section.getBoolean(key, def)); + assertEquals(def, section.getBoolean("doesntExist", def)); + } + + @Test + public void testIsBoolean() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + boolean value = true; + + section.set(key, value); + + assertTrue(section.isBoolean(key)); + assertFalse(section.isBoolean("doesntExist")); + } + + @Test + public void testGetDouble_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + double value = Double.MAX_VALUE; + + section.set(key, value); + + assertEquals(value, section.getDouble(key), 1); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetDoubleFromInt() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + double value = 123; + + section.set(key, (int) value); + + assertEquals(value, section.getDouble(key), 1); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetDouble_String_Double() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + double value = Double.MAX_VALUE; + double def = Double.MIN_VALUE; + + section.set(key, value); + + assertEquals(value, section.getDouble(key, def), 1); + assertEquals(def, section.getDouble("doesntExist", def), 1); + } + + @Test + public void testIsDouble() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + double value = Double.MAX_VALUE; + + section.set(key, value); + + assertTrue(section.isDouble(key)); + assertFalse(section.isDouble("doesntExist")); + } + + @Test + public void testGetLong_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + long value = Long.MAX_VALUE; + + section.set(key, value); + + assertEquals(value, section.getLong(key)); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetLong_String_Long() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + long value = Long.MAX_VALUE; + long def = Long.MIN_VALUE; + + section.set(key, value); + + assertEquals(value, section.getLong(key, def)); + assertEquals(def, section.getLong("doesntExist", def)); + } + + @Test + public void testIsLong() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + long value = Long.MAX_VALUE; + + section.set(key, value); + + assertTrue(section.isLong(key)); + assertFalse(section.isLong("doesntExist")); + } + + @Test + public void testGetList_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + Map map = new HashMap(); + + map.put("one", 1); + map.put("two", "two"); + map.put("three", 3.14); + + List value = Arrays.asList("One", "Two", "Three", 4, "5", 6.0, true, "false", map); + + section.set(key, value); + + assertEquals(value, section.getList(key)); + assertEquals(Arrays.asList((Object) "One", "Two", "Three", "4", "5", "6.0", "true", "false"), section.getStringList(key)); + assertEquals(Arrays.asList((Object) 4, 5, 6), section.getIntegerList(key)); + assertEquals(Arrays.asList((Object) true, false), section.getBooleanList(key)); + assertEquals(Arrays.asList((Object) 4.0, 5.0, 6.0), section.getDoubleList(key)); + assertEquals(Arrays.asList((Object) 4.0f, 5.0f, 6.0f), section.getFloatList(key)); + assertEquals(Arrays.asList((Object) 4l, 5l, 6l), section.getLongList(key)); + assertEquals(Arrays.asList((Object) (byte) 4, (byte) 5, (byte) 6), section.getByteList(key)); + assertEquals(Arrays.asList((Object) (short) 4, (short) 5, (short) 6), section.getShortList(key)); + assertEquals(map, section.getMapList(key).get(0)); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetList_String_List() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + List value = Arrays.asList("One", "Two", "Three"); + List def = Arrays.asList("A", "B", "C"); + + section.set(key, value); + + assertEquals(value, section.getList(key, def)); + assertEquals(def, section.getList("doesntExist", def)); + } + + @Test + public void testIsList() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + List value = Arrays.asList("One", "Two", "Three"); + + section.set(key, value); + + assertTrue(section.isList(key)); + assertFalse(section.isList("doesntExist")); + } + + @Test + public void testGetVector_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + Vector value = new Vector(Double.MIN_VALUE, Double.MAX_VALUE, 5); + + section.set(key, value); + + assertEquals(value, section.getVector(key)); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetVector_String_Vector() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + Vector value = new Vector(Double.MIN_VALUE, Double.MAX_VALUE, 5); + Vector def = new Vector(100, Double.MIN_VALUE, Double.MAX_VALUE); + + section.set(key, value); + + assertEquals(value, section.getVector(key, def)); + assertEquals(def, section.getVector("doesntExist", def)); + } + + @Test + public void testIsVector() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + Vector value = new Vector(Double.MIN_VALUE, Double.MAX_VALUE, 5); + + section.set(key, value); + + assertTrue(section.isVector(key)); + assertFalse(section.isVector("doesntExist")); + } + + @Test + public void testGetItemStack_String() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + ItemStack value = new ItemStack(Material.WOOD, 50, (short) 2); + + section.set(key, value); + + assertEquals(value, section.getItemStack(key)); + assertNull(section.getString("doesntExist")); + } + + @Test + public void testGetItemStack_String_ItemStack() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + ItemStack value = new ItemStack(Material.WOOD, 50, (short) 2); + ItemStack def = new ItemStack(Material.STONE, 1); + + section.set(key, value); + + assertEquals(value, section.getItemStack(key, def)); + assertEquals(def, section.getItemStack("doesntExist", def)); + } + + @Test + public void testIsItemStack() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + ItemStack value = new ItemStack(Material.WOOD, 50, (short) 2); + + section.set(key, value); + + assertTrue(section.isItemStack(key)); + assertFalse(section.isItemStack("doesntExist")); + } + + @Test + public void testGetConfigurationSection() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + + ConfigurationSection subsection = section.createSection(key); + + assertEquals(subsection, section.getConfigurationSection(key)); + } + + @Test + public void testIsConfigurationSection() { + ConfigurationSection section = getConfigurationSection(); + String key = "exists"; + + section.createSection(key); + + assertTrue(section.isConfigurationSection(key)); + assertFalse(section.isConfigurationSection("doesntExist")); + } + + public enum TestEnum { + HELLO, + WORLD, + BANANAS + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/ConfigurationTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/ConfigurationTest.java new file mode 100644 index 0000000..e187d15 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/ConfigurationTest.java @@ -0,0 +1,156 @@ +package org.bukkit.configuration; + +import java.util.LinkedHashMap; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.bukkit.util.Vector; +import org.junit.Test; +import static org.junit.Assert.*; + +public abstract class ConfigurationTest { + public abstract Configuration getConfig(); + + public Map getTestValues() { + HashMap result = new LinkedHashMap(); + + result.put("integer", Integer.MIN_VALUE); + result.put("string", "String Value"); + result.put("long", Long.MAX_VALUE); + result.put("true-boolean", true); + result.put("false-boolean", false); + result.put("vector", new Vector(12345.67, 64, -12345.6789)); + result.put("list", Arrays.asList(1, 2, 3, 4, 5)); + result.put("42", "The Answer"); + + return result; + } + + /** + * Test of addDefault method, of class Configuration. + */ + @Test + public void testAddDefault() { + Configuration config = getConfig(); + Map values = getTestValues(); + + for (Map.Entry entry : values.entrySet()) { + String path = entry.getKey(); + Object object = entry.getValue(); + + config.addDefault(path, object); + + assertEquals(object, config.get(path)); + assertTrue(config.contains(path)); + assertFalse(config.isSet(path)); + assertTrue(config.getDefaults().isSet(path)); + } + } + + /** + * Test of addDefaults method, of class Configuration. + */ + @Test + public void testAddDefaults_Map() { + Configuration config = getConfig(); + Map values = getTestValues(); + + config.addDefaults(values); + + for (Map.Entry entry : values.entrySet()) { + String path = entry.getKey(); + Object object = entry.getValue(); + + assertEquals(object, config.get(path)); + assertTrue(config.contains(path)); + assertFalse(config.isSet(path)); + assertTrue(config.getDefaults().isSet(path)); + } + } + + /** + * Test of addDefaults method, of class Configuration. + */ + @Test + public void testAddDefaults_Configuration() { + Configuration config = getConfig(); + Map values = getTestValues(); + Configuration defaults = getConfig(); + + for (Map.Entry entry : values.entrySet()) { + defaults.set(entry.getKey(), entry.getValue()); + } + + config.addDefaults(defaults); + + for (Map.Entry entry : values.entrySet()) { + String path = entry.getKey(); + Object object = entry.getValue(); + + assertEquals(object, config.get(path)); + assertTrue(config.contains(path)); + assertFalse(config.isSet(path)); + assertTrue(config.getDefaults().isSet(path)); + } + } + + /** + * Test of setDefaults method, of class Configuration. + */ + @Test + public void testSetDefaults() { + Configuration config = getConfig(); + Map values = getTestValues(); + Configuration defaults = getConfig(); + + for (Map.Entry entry : values.entrySet()) { + defaults.set(entry.getKey(), entry.getValue()); + } + + config.setDefaults(defaults); + + for (Map.Entry entry : values.entrySet()) { + String path = entry.getKey(); + Object object = entry.getValue(); + + assertEquals(object, config.get(path)); + assertTrue(config.contains(path)); + assertFalse(config.isSet(path)); + assertTrue(config.getDefaults().isSet(path)); + } + } + + /** + * Test creation of ConfigurationSection + */ + @Test + public void testCreateSection() { + Configuration config = getConfig(); + + Set set = new HashSet(); + set.add("this"); + set.add("this.test.sub"); + set.add("this.test"); + set.add("this.test.other"); + + config.createSection("this.test.sub"); + config.createSection("this.test.other"); + + assertEquals(set, config.getKeys(true)); + } + + /** + * Test of getDefaults method, of class Configuration. + */ + @Test + public void testGetDefaults() { + Configuration config = getConfig(); + Configuration defaults = getConfig(); + + config.setDefaults(defaults); + + assertEquals(defaults, config.getDefaults()); + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/MemoryConfigurationTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/MemoryConfigurationTest.java new file mode 100644 index 0000000..3de0ce9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/MemoryConfigurationTest.java @@ -0,0 +1,8 @@ +package org.bukkit.configuration; + +public class MemoryConfigurationTest extends ConfigurationTest { + @Override + public Configuration getConfig() { + return new MemoryConfiguration(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/MemorySectionTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/MemorySectionTest.java new file mode 100644 index 0000000..be7768a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/MemorySectionTest.java @@ -0,0 +1,8 @@ +package org.bukkit.configuration; + +public class MemorySectionTest extends ConfigurationSectionTest { + @Override + public ConfigurationSection getConfigurationSection() { + return new MemoryConfiguration().createSection("section"); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/file/FileConfigurationTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/file/FileConfigurationTest.java new file mode 100644 index 0000000..ce0c2e5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/file/FileConfigurationTest.java @@ -0,0 +1,209 @@ +package org.bukkit.configuration.file; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.Map; +import org.bukkit.configuration.MemoryConfigurationTest; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import static org.junit.Assert.*; + +public abstract class FileConfigurationTest extends MemoryConfigurationTest { + @Rule + public TemporaryFolder testFolder = new TemporaryFolder(); + + @Override + public abstract FileConfiguration getConfig(); + + public abstract String getTestValuesString(); + + public abstract String getTestHeaderInput(); + + public abstract String getTestHeaderResult(); + + @Test + public void testSave_File() throws Exception { + FileConfiguration config = getConfig(); + File file = testFolder.newFile("test.config"); + + for (Map.Entry entry : getTestValues().entrySet()) { + config.set(entry.getKey(), entry.getValue()); + } + + config.save(file); + + assertTrue(file.isFile()); + } + + @Test + public void testSave_String() throws Exception { + FileConfiguration config = getConfig(); + File file = testFolder.newFile("test.config"); + + for (Map.Entry entry : getTestValues().entrySet()) { + config.set(entry.getKey(), entry.getValue()); + } + + config.save(file.getAbsolutePath()); + + assertTrue(file.isFile()); + } + + @Test + public void testSaveToString() { + FileConfiguration config = getConfig(); + + for (Map.Entry entry : getTestValues().entrySet()) { + config.set(entry.getKey(), entry.getValue()); + } + + String result = config.saveToString(); + String expected = getTestValuesString(); + + assertEquals(expected, result); + } + + @Test + public void testLoad_File() throws Exception { + FileConfiguration config = getConfig(); + File file = testFolder.newFile("test.config"); + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + String saved = getTestValuesString(); + Map values = getTestValues(); + + try { + writer.write(saved); + } finally { + writer.close(); + } + + config.load(file); + + for (Map.Entry entry : values.entrySet()) { + assertEquals(entry.getValue(), config.get(entry.getKey())); + } + + assertEquals(values.keySet(), config.getKeys(true)); + } + + @Test + public void testLoad_String() throws Exception { + FileConfiguration config = getConfig(); + File file = testFolder.newFile("test.config"); + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + String saved = getTestValuesString(); + Map values = getTestValues(); + + try { + writer.write(saved); + } finally { + writer.close(); + } + + config.load(file.getAbsolutePath()); + + for (Map.Entry entry : values.entrySet()) { + assertEquals(entry.getValue(), config.get(entry.getKey())); + } + + assertEquals(values.keySet(), config.getKeys(true)); + } + + @Test + public void testLoadFromString() throws Exception { + FileConfiguration config = getConfig(); + Map values = getTestValues(); + String saved = getTestValuesString(); + + config.loadFromString(saved); + + for (Map.Entry entry : values.entrySet()) { + assertEquals(entry.getValue(), config.get(entry.getKey())); + } + + assertEquals(values.keySet(), config.getKeys(true)); + assertEquals(saved, config.saveToString()); + } + + @Test + public void testSaveToStringWithHeader() { + FileConfiguration config = getConfig(); + config.options().header(getTestHeaderInput()); + + for (Map.Entry entry : getTestValues().entrySet()) { + config.set(entry.getKey(), entry.getValue()); + } + + String result = config.saveToString(); + String expected = getTestHeaderResult() + "\n" + getTestValuesString(); + + assertEquals(expected, result); + } + + @Test + public void testParseHeader() throws Exception { + FileConfiguration config = getConfig(); + Map values = getTestValues(); + String saved = getTestValuesString(); + String header = getTestHeaderResult(); + String expected = getTestHeaderInput(); + + config.loadFromString(header + "\n" + saved); + + assertEquals(expected, config.options().header()); + + for (Map.Entry entry : values.entrySet()) { + assertEquals(entry.getValue(), config.get(entry.getKey())); + } + + assertEquals(values.keySet(), config.getKeys(true)); + assertEquals(header + "\n" + saved, config.saveToString()); + } + + @Test + public void testCopyHeader() throws Exception { + FileConfiguration config = getConfig(); + FileConfiguration defaults = getConfig(); + Map values = getTestValues(); + String saved = getTestValuesString(); + String header = getTestHeaderResult(); + String expected = getTestHeaderInput(); + + defaults.loadFromString(header); + config.loadFromString(saved); + config.setDefaults(defaults); + + assertNull(config.options().header()); + assertEquals(expected, defaults.options().header()); + + for (Map.Entry entry : values.entrySet()) { + assertEquals(entry.getValue(), config.get(entry.getKey())); + } + + assertEquals(values.keySet(), config.getKeys(true)); + assertEquals(header + "\n" + saved, config.saveToString()); + + config = getConfig(); + config.loadFromString(getTestHeaderResult() + saved); + assertEquals(getTestHeaderResult() + saved, config.saveToString()); + } + + @Test + public void testReloadEmptyConfig() throws Exception { + FileConfiguration config = getConfig(); + + assertEquals("", config.saveToString()); + + config = getConfig(); + config.loadFromString(""); + + assertEquals("", config.saveToString()); + + config = getConfig(); + config.loadFromString("\n\n"); // Should trim the first newlines of a header + + assertEquals("", config.saveToString()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/file/YamlConfigurationTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/file/YamlConfigurationTest.java new file mode 100644 index 0000000..aa83af3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/configuration/file/YamlConfigurationTest.java @@ -0,0 +1,56 @@ +package org.bukkit.configuration.file; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class YamlConfigurationTest extends FileConfigurationTest { + + @Override + public YamlConfiguration getConfig() { + return new YamlConfiguration(); + } + + @Override + public String getTestHeaderInput() { + return "This is a sample\nheader.\n\nNewline above should be commented.\n\n"; + } + + @Override + public String getTestHeaderResult() { + return "# This is a sample\n# header.\n# \n# Newline above should be commented.\n\n"; + } + + @Override + public String getTestValuesString() { + return "integer: -2147483648\n" + + "string: String Value\n" + + "long: 9223372036854775807\n" + + "true-boolean: true\n" + + "false-boolean: false\n" + + "vector:\n" + + " ==: Vector\n" + + " x: 12345.67\n" + + " y: 64.0\n" + + " z: -12345.6789\n" + + "list:\n" + + "- 1\n" + + "- 2\n" + + "- 3\n" + + "- 4\n" + + "- 5\n" + + "'42': The Answer\n"; + } + + @Test + public void testSaveToStringWithIndent() { + YamlConfiguration config = getConfig(); + config.options().indent(9); + + config.set("section.key", 1); + + String result = config.saveToString(); + String expected = "section:\n key: 1\n"; + + assertEquals(expected, result); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ConversationContextTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ConversationContextTest.java new file mode 100644 index 0000000..dfc462b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ConversationContextTest.java @@ -0,0 +1,34 @@ +package org.bukkit.conversations; + +import org.junit.Test; +import static org.junit.Assert.*; + +import java.util.HashMap; +import java.util.Map; + +/** + */ +public class ConversationContextTest { + @Test + public void TestFromWhom() { + Conversable conversable = new FakeConversable(); + ConversationContext context = new ConversationContext(null, conversable, new HashMap()); + assertEquals(conversable, context.getForWhom()); + } + + @Test + public void TestPlugin() { + Conversable conversable = new FakeConversable(); + ConversationContext context = new ConversationContext(null, conversable, new HashMap()); + assertEquals(null, context.getPlugin()); + } + + @Test + public void TestSessionData() { + Conversable conversable = new FakeConversable(); + Map session = new HashMap(); + session.put("key", "value"); + ConversationContext context = new ConversationContext(null, conversable, session); + assertEquals("value", context.getSessionData("key")); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ConversationTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ConversationTest.java new file mode 100644 index 0000000..732caab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ConversationTest.java @@ -0,0 +1,116 @@ +package org.bukkit.conversations; + +import org.junit.Test; +import static org.junit.Assert.*; + +/** + */ +public class ConversationTest { + + @Test + public void testBaseConversationFlow() { + FakeConversable forWhom = new FakeConversable(); + Conversation conversation = new Conversation(null, forWhom, new FirstPrompt()); + + // Conversation not yet begun + assertNull(forWhom.lastSentMessage); + assertEquals(conversation.getForWhom(), forWhom); + assertTrue(conversation.isModal()); + + // Begin the conversation + conversation.begin(); + assertEquals("FirstPrompt", forWhom.lastSentMessage); + assertEquals(conversation, forWhom.begunConversation); + + // Send the first input + conversation.acceptInput("FirstInput"); + assertEquals("SecondPrompt", forWhom.lastSentMessage); + assertEquals(conversation, forWhom.abandonedConverstion); + } + + @Test + public void testConversationFactory() { + FakeConversable forWhom = new FakeConversable(); + NullConversationPrefix prefix = new NullConversationPrefix(); + ConversationFactory factory = new ConversationFactory(null) + .withFirstPrompt(new FirstPrompt()) + .withModality(false) + .withPrefix(prefix); + Conversation conversation = factory.buildConversation(forWhom); + + // Conversation not yet begun + assertNull(forWhom.lastSentMessage); + assertEquals(conversation.getForWhom(), forWhom); + assertFalse(conversation.isModal()); + assertEquals(conversation.getPrefix(), prefix); + + // Begin the conversation + conversation.begin(); + assertEquals("FirstPrompt", forWhom.lastSentMessage); + assertEquals(conversation, forWhom.begunConversation); + + // Send the first input + conversation.acceptInput("FirstInput"); + assertEquals("SecondPrompt", forWhom.lastSentMessage); + assertEquals(conversation, forWhom.abandonedConverstion); + } + + @Test + public void testEscapeSequence() { + FakeConversable forWhom = new FakeConversable(); + Conversation conversation = new Conversation(null, forWhom, new FirstPrompt()); + conversation.addConversationCanceller(new ExactMatchConversationCanceller("bananas")); + + // Begin the conversation + conversation.begin(); + assertEquals("FirstPrompt", forWhom.lastSentMessage); + assertEquals(conversation, forWhom.begunConversation); + + // Send the first input + conversation.acceptInput("bananas"); + assertEquals("bananas", forWhom.lastSentMessage); + assertEquals(conversation, forWhom.abandonedConverstion); + } + + @Test + public void testNotPlayer() { + FakeConversable forWhom = new FakeConversable(); + NullConversationPrefix prefix = new NullConversationPrefix(); + ConversationFactory factory = new ConversationFactory(null) + .thatExcludesNonPlayersWithMessage("bye"); + Conversation conversation = factory.buildConversation(forWhom); + + // Begin the conversation + conversation.begin(); + assertEquals("bye", forWhom.lastSentMessage); + assertEquals(conversation, forWhom.begunConversation); + assertEquals(conversation, forWhom.abandonedConverstion); + } + + private class FirstPrompt extends StringPrompt { + + public String getPromptText(ConversationContext context) { + return "FirstPrompt"; + } + + public Prompt acceptInput(ConversationContext context, String input) { + assertEquals("FirstInput", input); + context.setSessionData("data", 10); + return new SecondPrompt(); + } + } + + private class SecondPrompt extends MessagePrompt { + + @Override + protected Prompt getNextPrompt(ConversationContext context) { + return Prompt.END_OF_CONVERSATION; + } + + public String getPromptText(ConversationContext context) { + // Assert that session data passes from one prompt to the next + assertEquals(context.getSessionData("data"), 10); + return "SecondPrompt"; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/FakeConversable.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/FakeConversable.java new file mode 100644 index 0000000..87fb311 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/FakeConversable.java @@ -0,0 +1,105 @@ +package org.bukkit.conversations; + +import org.bukkit.Server; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + +import java.util.Set; + +/** + */ +public class FakeConversable implements Conversable { + public String lastSentMessage; + public Conversation begunConversation; + public Conversation abandonedConverstion; + public ConversationAbandonedEvent abandonedConversationEvent; + + public boolean isConversing() { + return false; + } + + public void acceptConversationInput(String input) { + + } + + public boolean beginConversation(Conversation conversation) { + begunConversation = conversation; + conversation.outputNextPrompt(); + return true; + } + + public void abandonConversation(Conversation conversation) { + abandonedConverstion = conversation; + } + + public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) { + abandonedConverstion = conversation; + abandonedConversationEvent = details; + } + + public void sendRawMessage(String message) { + lastSentMessage = message; + } + + public Server getServer() { + return null; + } + + public String getName() { + return null; + } + + public boolean isPermissionSet(String name) { + return false; + } + + public boolean isPermissionSet(Permission perm) { + return false; + } + + public boolean hasPermission(String name) { + return false; + } + + public boolean hasPermission(Permission perm) { + return false; + } + + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + return null; + } + + public PermissionAttachment addAttachment(Plugin plugin) { + return null; + } + + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + return null; + } + + public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + return null; + } + + public void removeAttachment(PermissionAttachment attachment) { + + } + + public void recalculatePermissions() { + + } + + public Set getEffectivePermissions() { + return null; + } + + public boolean isOp() { + return false; + } + + public void setOp(boolean value) { + + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ValidatingPromptTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ValidatingPromptTest.java new file mode 100644 index 0000000..d1c0f42 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/conversations/ValidatingPromptTest.java @@ -0,0 +1,115 @@ +package org.bukkit.conversations; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + */ +public class ValidatingPromptTest { + + @Test + public void TestBooleanPrompt() { + TestBooleanPrompt prompt = new TestBooleanPrompt(); + assertTrue(prompt.isInputValid(null, "true")); + assertFalse(prompt.isInputValid(null, "bananas")); + prompt.acceptInput(null, "true"); + assertTrue(prompt.result); + prompt.acceptInput(null, "no"); + assertFalse(prompt.result); + } + + @Test + public void TestFixedSetPrompt() { + TestFixedSetPrompt prompt = new TestFixedSetPrompt("foo", "bar"); + assertTrue(prompt.isInputValid(null, "foo")); + assertFalse(prompt.isInputValid(null, "cheese")); + prompt.acceptInput(null, "foo"); + assertEquals("foo", prompt.result); + } + + @Test + public void TestNumericPrompt() { + TestNumericPrompt prompt = new TestNumericPrompt(); + assertTrue(prompt.isInputValid(null, "1010220")); + assertFalse(prompt.isInputValid(null, "tomato")); + prompt.acceptInput(null, "1010220"); + assertEquals(1010220, prompt.result); + } + + @Test + public void TestRegexPrompt() { + TestRegexPrompt prompt = new TestRegexPrompt("a.c"); + assertTrue(prompt.isInputValid(null, "abc")); + assertTrue(prompt.isInputValid(null, "axc")); + assertFalse(prompt.isInputValid(null, "xyz")); + prompt.acceptInput(null, "abc"); + assertEquals("abc", prompt.result); + } + + //TODO: TestPlayerNamePrompt() + + private class TestBooleanPrompt extends BooleanPrompt { + public boolean result; + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, boolean input) { + result = input; + return null; + } + + public String getPromptText(ConversationContext context) { + return null; + } + } + + private class TestFixedSetPrompt extends FixedSetPrompt { + public String result; + + public TestFixedSetPrompt(String... fixedSet) { + super(fixedSet); + } + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, String input) { + result = input; + return null; + } + + public String getPromptText(ConversationContext context) { + return null; + } + } + + private class TestNumericPrompt extends NumericPrompt { + public Number result; + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, Number input) { + result = input; + return null; + } + + public String getPromptText(ConversationContext context) { + return null; + } + } + + private class TestRegexPrompt extends RegexPrompt { + public String result; + + public TestRegexPrompt(String pattern) { + super(pattern); + } + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, String input) { + result = input; + return null; + } + + public String getPromptText(ConversationContext context) { + return null; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/event/TestEvent.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/event/TestEvent.java new file mode 100644 index 0000000..25904f5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/event/TestEvent.java @@ -0,0 +1,19 @@ +package org.bukkit.event; + + +public class TestEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + public TestEvent(boolean async) { + super(async); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/materials/MaterialDataTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/materials/MaterialDataTest.java new file mode 100644 index 0000000..e888381 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/materials/MaterialDataTest.java @@ -0,0 +1,61 @@ +package org.bukkit.materials; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.material.Door; +import org.junit.Test; + +public class MaterialDataTest { + + @Test + public void testDoor() + { + @SuppressWarnings("deprecation") + Door door = new Door(); + assertThat("Constructed with default door type",door.getItemType(),equalTo(Material.WOODEN_DOOR)); + assertThat("Constructed with default top or bottom",door.isTopHalf(),equalTo(false)); + assertThat("Constructed with default direction",door.getFacing(),equalTo(BlockFace.WEST)); + assertThat("Constructed with default open state",door.isOpen(),equalTo(false)); + + Material[] types = new Material[] { Material.WOODEN_DOOR, + Material.IRON_DOOR_BLOCK, Material.SPRUCE_DOOR, + Material.BIRCH_DOOR, Material.JUNGLE_DOOR, + Material.ACACIA_DOOR, Material.DARK_OAK_DOOR }; + BlockFace[] directions = new BlockFace[] { BlockFace.WEST, BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH }; + boolean[] openStates = new boolean[] {false, true}; + boolean[] hingeStates = new boolean[] {false, true}; + for(Material type : types) + { + // Test bottom half + for(BlockFace facing : directions) + { + door = new Door(type,facing); + assertThat("Constructed with correct door type",door.getItemType(),equalTo(type)); + assertThat("Constructed with default top or bottom",door.isTopHalf(),equalTo(false)); + assertThat("Constructed with correct direction",door.getFacing(),equalTo(facing)); + assertThat("Constructed with default open state",door.isOpen(),equalTo(false)); + + for(boolean openState : openStates) + { + door = new Door(type,facing,openState); + assertThat("Constructed with correct door type",door.getItemType(),equalTo(type)); + assertThat("Constructed with default top or bottom",door.isTopHalf(),equalTo(false)); + assertThat("Constructed with correct direction",door.getFacing(),equalTo(facing)); + assertThat("Constructed with correct open state",door.isOpen(),equalTo(openState)); + } + } + + // Test top half + for(boolean hingeState : hingeStates) + { + door = new Door(type,hingeState); + assertThat("Constructed with correct door type",door.getItemType(),equalTo(type)); + assertThat("Constructed with default top or bottom",door.isTopHalf(),equalTo(true)); + assertThat("Constructed with correct direction",door.getHinge(),equalTo(hingeState)); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/FixedMetadataValueTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/FixedMetadataValueTest.java new file mode 100644 index 0000000..5583b27 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/FixedMetadataValueTest.java @@ -0,0 +1,42 @@ +package org.bukkit.metadata; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.TestPlugin; +import org.junit.Test; + +public class FixedMetadataValueTest { + private Plugin plugin = new TestPlugin("X"); + private FixedMetadataValue subject; + + @Test + public void testBasic() { + subject = new FixedMetadataValue(plugin, new Integer(50)); + assertSame(plugin, subject.getOwningPlugin()); + assertEquals(new Integer(50), subject.value()); + } + + @Test + public void testNumberTypes() { + subject = new FixedMetadataValue(plugin, new Integer(5)); + assertEquals(new Integer(5), subject.value()); + assertEquals(5, subject.asInt()); + assertEquals(true, subject.asBoolean()); + assertEquals(5, subject.asByte()); + assertEquals(5.0, subject.asFloat(), 0.1e-8); + assertEquals(5.0D, subject.asDouble(), 0.1e-8D); + assertEquals(5L, subject.asLong()); + assertEquals(5, subject.asShort()); + assertEquals("5", subject.asString()); + } + + @Test + public void testInvalidateDoesNothing() { + Object o = new Object(); + subject = new FixedMetadataValue(plugin, o); + subject.invalidate(); + assertSame(o, subject.value()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/LazyMetadataValueTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/LazyMetadataValueTest.java new file mode 100644 index 0000000..a3172db --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/LazyMetadataValueTest.java @@ -0,0 +1,135 @@ +package org.bukkit.metadata; + +import org.bukkit.plugin.TestPlugin; +import org.junit.Test; + +import java.util.concurrent.Callable; + +import static org.junit.Assert.*; + +public class LazyMetadataValueTest { + private LazyMetadataValue subject; + private TestPlugin plugin = new TestPlugin("x"); + + @Test + public void testLazyInt() { + int value = 10; + subject = makeSimpleCallable(value); + + assertEquals(value, subject.value()); + } + + @Test + public void testLazyDouble() { + double value = 10.5; + subject = makeSimpleCallable(value); + + assertEquals(value, (Double)subject.value(), 0.01); + } + + @Test + public void testLazyString() { + String value = "TEN"; + subject = makeSimpleCallable(value); + + assertEquals(value, subject.value()); + } + + @Test + public void testLazyBoolean() { + boolean value = false; + subject = makeSimpleCallable(value); + + assertEquals(value, subject.value()); + } + + @Test(expected=MetadataEvaluationException.class) + public void testEvalException() { + subject = new LazyMetadataValue(plugin, LazyMetadataValue.CacheStrategy.CACHE_AFTER_FIRST_EVAL, new Callable() { + public Object call() throws Exception { + throw new RuntimeException("Gotcha!"); + } + }); + subject.value(); + } + + @Test + public void testCacheStrategyCacheAfterFirstEval() { + final Counter counter = new Counter(); + final int value = 10; + subject = new LazyMetadataValue(plugin, LazyMetadataValue.CacheStrategy.CACHE_AFTER_FIRST_EVAL, new Callable() { + public Object call() throws Exception { + counter.increment(); + return value; + } + }); + + subject.value(); + subject.value(); + assertEquals(value, subject.value()); + assertEquals(1, counter.value()); + + subject.invalidate(); + subject.value(); + assertEquals(2, counter.value()); + } + + @Test + public void testCacheStrategyNeverCache() { + final Counter counter = new Counter(); + final int value = 10; + subject = new LazyMetadataValue(plugin, LazyMetadataValue.CacheStrategy.NEVER_CACHE, new Callable() { + public Object call() throws Exception { + counter.increment(); + return value; + } + }); + + subject.value(); + subject.value(); + assertEquals(value, subject.value()); + assertEquals(3, counter.value()); + } + + @Test + public void testCacheStrategyEternally() { + final Counter counter = new Counter(); + final int value = 10; + subject = new LazyMetadataValue(plugin, LazyMetadataValue.CacheStrategy.CACHE_ETERNALLY, new Callable() { + public Object call() throws Exception { + counter.increment(); + return value; + } + }); + + subject.value(); + subject.value(); + assertEquals(value, subject.value()); + assertEquals(1, counter.value()); + + subject.invalidate(); + subject.value(); + assertEquals(value, subject.value()); + assertEquals(1, counter.value()); + } + + private LazyMetadataValue makeSimpleCallable(final Object value) { + return new LazyMetadataValue(plugin, new Callable() { + public Object call() throws Exception { + return value; + } + }); + } + + private class Counter { + private int c = 0; + + public void increment() { + c++; + } + + public int value() { + return c; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataConversionTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataConversionTest.java new file mode 100644 index 0000000..a595cc8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataConversionTest.java @@ -0,0 +1,103 @@ +// Copyright (C) 2011 Ryan Michela +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package org.bukkit.metadata; + +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.TestPlugin; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + */ +public class MetadataConversionTest { + private Plugin plugin = new TestPlugin("x"); + private FixedMetadataValue subject; + + private void setSubject(Object value) { + subject = new FixedMetadataValue(plugin, value); + } + + @Test + public void testFromInt() { + setSubject(10); + + assertEquals(10, subject.asInt()); + assertEquals(10, subject.asFloat(), 0.000001); + assertEquals(10, subject.asDouble(), 0.000001); + assertEquals(10, subject.asLong()); + assertEquals(10, subject.asShort()); + assertEquals(10, subject.asByte()); + assertEquals(true, subject.asBoolean()); + assertEquals("10", subject.asString()); + } + + @Test + public void testFromFloat() { + setSubject(10.5); + + assertEquals(10, subject.asInt()); + assertEquals(10.5, subject.asFloat(), 0.000001); + assertEquals(10.5, subject.asDouble(), 0.000001); + assertEquals(10, subject.asLong()); + assertEquals(10, subject.asShort()); + assertEquals(10, subject.asByte()); + assertEquals(true, subject.asBoolean()); + assertEquals("10.5", subject.asString()); + } + + @Test + public void testFromNumericString() { + setSubject("10"); + + assertEquals(10, subject.asInt()); + assertEquals(10, subject.asFloat(), 0.000001); + assertEquals(10, subject.asDouble(), 0.000001); + assertEquals(10, subject.asLong()); + assertEquals(10, subject.asShort()); + assertEquals(10, subject.asByte()); + assertEquals(false, subject.asBoolean()); + assertEquals("10", subject.asString()); + } + + @Test + public void testFromNonNumericString() { + setSubject("true"); + + assertEquals(0, subject.asInt()); + assertEquals(0, subject.asFloat(), 0.000001); + assertEquals(0, subject.asDouble(), 0.000001); + assertEquals(0, subject.asLong()); + assertEquals(0, subject.asShort()); + assertEquals(0, subject.asByte()); + assertEquals(true, subject.asBoolean()); + assertEquals("true", subject.asString()); + } + + @Test + public void testFromNull() { + setSubject(null); + + assertEquals(0, subject.asInt()); + assertEquals(0, subject.asFloat(), 0.000001); + assertEquals(0, subject.asDouble(), 0.000001); + assertEquals(0, subject.asLong()); + assertEquals(0, subject.asShort()); + assertEquals(0, subject.asByte()); + assertEquals(false, subject.asBoolean()); + assertEquals("", subject.asString()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataStoreTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataStoreTest.java new file mode 100644 index 0000000..30f0368 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataStoreTest.java @@ -0,0 +1,143 @@ +package org.bukkit.metadata; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.concurrent.Callable; + +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.TestPlugin; +import org.junit.Test; + +public class MetadataStoreTest { + private Plugin pluginX = new TestPlugin("x"); + private Plugin pluginY = new TestPlugin("y"); + + StringMetadataStore subject = new StringMetadataStore(); + + @Test + public void testMetadataStore() { + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginX, 10)); + + assertTrue(subject.hasMetadata("subject", "key")); + List values = subject.getMetadata("subject", "key"); + assertEquals(10, values.get(0).value()); + } + + @Test + public void testMetadataNotPresent() { + assertFalse(subject.hasMetadata("subject", "key")); + List values = subject.getMetadata("subject", "key"); + assertTrue(values.isEmpty()); + } + + @Test + public void testInvalidateAll() { + final Counter counter = new Counter(); + + subject.setMetadata("subject", "key", new LazyMetadataValue(pluginX, new Callable() { + public Object call() throws Exception { + counter.increment(); + return 10; + } + })); + + assertTrue(subject.hasMetadata("subject", "key")); + subject.getMetadata("subject", "key").get(0).value(); + subject.invalidateAll(pluginX); + subject.getMetadata("subject", "key").get(0).value(); + assertEquals(2, counter.value()); + } + + @Test + public void testInvalidateAllButActuallyNothing() { + final Counter counter = new Counter(); + + subject.setMetadata("subject", "key", new LazyMetadataValue(pluginX, new Callable() { + public Object call() throws Exception { + counter.increment(); + return 10; + } + })); + + assertTrue(subject.hasMetadata("subject", "key")); + subject.getMetadata("subject", "key").get(0).value(); + subject.invalidateAll(pluginY); + subject.getMetadata("subject", "key").get(0).value(); + assertEquals(1, counter.value()); + } + + @Test + public void testMetadataReplace() { + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginX, 10)); + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginY, 10)); + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginX, 20)); + + for (MetadataValue mv : subject.getMetadata("subject", "key")) { + if (mv.getOwningPlugin().equals(pluginX)) { + assertEquals(20, mv.value()); + } + if (mv.getOwningPlugin().equals(pluginY)) { + assertEquals(10, mv.value()); + } + } + } + + @Test + public void testMetadataRemove() { + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginX, 10)); + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginY, 20)); + subject.removeMetadata("subject", "key", pluginX); + + assertTrue(subject.hasMetadata("subject", "key")); + assertEquals(1, subject.getMetadata("subject", "key").size()); + assertEquals(20, subject.getMetadata("subject", "key").get(0).value()); + } + + @Test + public void testMetadataRemoveLast() { + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginX, 10)); + subject.removeMetadata("subject", "key", pluginX); + + assertFalse(subject.hasMetadata("subject", "key")); + assertEquals(0, subject.getMetadata("subject", "key").size()); + } + + @Test + public void testMetadataRemoveForNonExistingPlugin() { + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginX, 10)); + subject.removeMetadata("subject", "key", pluginY); + + assertTrue(subject.hasMetadata("subject", "key")); + assertEquals(1, subject.getMetadata("subject", "key").size()); + assertEquals(10, subject.getMetadata("subject", "key").get(0).value()); + } + + @Test + public void testHasMetadata() { + subject.setMetadata("subject", "key", new FixedMetadataValue(pluginX, 10)); + assertTrue(subject.hasMetadata("subject", "key")); + assertFalse(subject.hasMetadata("subject", "otherKey")); + } + + private class StringMetadataStore extends MetadataStoreBase implements MetadataStore { + @Override + protected String disambiguate(String subject, String metadataKey) { + return subject + ":" + metadataKey; + } + } + + private class Counter { + int c = 0; + + public void increment() { + c++; + } + + public int value() { + return c; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataValueAdapterTest.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataValueAdapterTest.java new file mode 100644 index 0000000..7d8a17f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/metadata/MetadataValueAdapterTest.java @@ -0,0 +1,97 @@ +package org.bukkit.metadata; + +import static org.junit.Assert.assertEquals; + +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.TestPlugin; +import org.junit.Test; + +public class MetadataValueAdapterTest { + private TestPlugin plugin = new TestPlugin("x"); + + @Test + public void testAdapterBasics() { + IncrementingMetaValue mv = new IncrementingMetaValue(plugin); + // check getOwningPlugin + assertEquals(mv.getOwningPlugin(), this.plugin); + + // Check value-getting and invalidation. + assertEquals(new Integer(1), mv.value()); + assertEquals(new Integer(2), mv.value()); + mv.invalidate(); + assertEquals(new Integer(1), mv.value()); + } + + @Test + public void testAdapterConversions() { + IncrementingMetaValue mv = new IncrementingMetaValue(plugin); + + assertEquals(1, mv.asInt()); + assertEquals(2L, mv.asLong()); + assertEquals(3.0, mv.asFloat(), 0.001); + assertEquals(4, mv.asByte()); + assertEquals(5.0, mv.asDouble(), 0.001); + assertEquals(6, mv.asShort()); + assertEquals("7", mv.asString()); + } + + /** Boolean conversion is non-trivial, we want to test it thoroughly. */ + @Test + public void testBooleanConversion() { + // null is False. + assertEquals(false, simpleValue(null).asBoolean()); + + // String to boolean. + assertEquals(true, simpleValue("True").asBoolean()); + assertEquals(true, simpleValue("TRUE").asBoolean()); + assertEquals(false, simpleValue("false").asBoolean()); + + // Number to boolean. + assertEquals(true, simpleValue(1).asBoolean()); + assertEquals(true, simpleValue(5.0).asBoolean()); + assertEquals(false, simpleValue(0).asBoolean()); + assertEquals(false, simpleValue(0.1).asBoolean()); + + // Boolean as boolean, of course. + assertEquals(true, simpleValue(Boolean.TRUE).asBoolean()); + assertEquals(false, simpleValue(Boolean.FALSE).asBoolean()); + + // any object that is not null and not a Boolean, String, or Number is true. + assertEquals(true, simpleValue(new Object()).asBoolean()); + } + + /** Test String conversions return an empty string when given null. */ + @Test + public void testStringConversionNull() { + assertEquals("", simpleValue(null).asString()); + } + + /** Get a fixed value MetadataValue. */ + private MetadataValue simpleValue(Object value) { + return new FixedMetadataValue(plugin, value); + } + + /** + * A sample non-trivial MetadataValueAdapter implementation. + * + * The rationale for implementing an incrementing value is to have a value + * which changes with every call to value(). This is important for testing + * because we want to make sure all the tested conversions are calling the + * value() method exactly once and no caching is going on. + */ + class IncrementingMetaValue extends MetadataValueAdapter { + private int internalValue = 0; + + protected IncrementingMetaValue(Plugin owningPlugin) { + super(owningPlugin); + } + + public Object value() { + return ++internalValue; + } + + public void invalidate() { + internalValue = 0; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/plugin/TestPlugin.java b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/plugin/TestPlugin.java new file mode 100644 index 0000000..7e09892 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-API/src/test/java/org/bukkit/plugin/TestPlugin.java @@ -0,0 +1,111 @@ +package org.bukkit.plugin; + +import java.io.File; +import java.io.InputStream; +import java.util.List; + +import org.bukkit.Server; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.generator.ChunkGenerator; + +import com.avaje.ebean.EbeanServer; + +public class TestPlugin extends PluginBase { + private boolean enabled = true; + + final private String pluginName; + + public TestPlugin(String pluginName) { + this.pluginName = pluginName; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public File getDataFolder() { + throw new UnsupportedOperationException("Not supported."); + } + + public PluginDescriptionFile getDescription() { + return new PluginDescriptionFile(pluginName, "1.0", "test.test"); + } + + public FileConfiguration getConfig() { + throw new UnsupportedOperationException("Not supported."); + } + + public InputStream getResource(String filename) { + throw new UnsupportedOperationException("Not supported."); + } + + public void saveConfig() { + throw new UnsupportedOperationException("Not supported."); + } + + public void saveDefaultConfig() { + throw new UnsupportedOperationException("Not supported."); + } + + public void saveResource(String resourcePath, boolean replace) { + throw new UnsupportedOperationException("Not supported."); + } + + public void reloadConfig() { + throw new UnsupportedOperationException("Not supported."); + } + + public PluginLogger getLogger() { + throw new UnsupportedOperationException("Not supported."); + } + + public PluginLoader getPluginLoader() { + throw new UnsupportedOperationException("Not supported."); + } + + public Server getServer() { + throw new UnsupportedOperationException("Not supported."); + } + + public boolean isEnabled() { + return enabled; + } + + public void onDisable() { + throw new UnsupportedOperationException("Not supported."); + } + + public void onLoad() { + throw new UnsupportedOperationException("Not supported."); + } + + public void onEnable() { + throw new UnsupportedOperationException("Not supported."); + } + + public boolean isNaggable() { + throw new UnsupportedOperationException("Not supported."); + } + + public void setNaggable(boolean canNag) { + throw new UnsupportedOperationException("Not supported."); + } + + public EbeanServer getDatabase() { + throw new UnsupportedOperationException("Not supported."); + } + + public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { + throw new UnsupportedOperationException("Not supported."); + } + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + throw new UnsupportedOperationException("Not supported."); + } + + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + throw new UnsupportedOperationException("Not supported."); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/LGPL.txt b/MythicSpigot-master/TacoSpigot-Server/LGPL.txt new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/LGPL.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/MythicSpigot-master/TacoSpigot-Server/LICENCE.txt b/MythicSpigot-master/TacoSpigot-Server/LICENCE.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/LICENCE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/MythicSpigot-master/TacoSpigot-Server/README.md b/MythicSpigot-master/TacoSpigot-Server/README.md new file mode 100644 index 0000000..810597a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/README.md @@ -0,0 +1,32 @@ +CraftBukkit +====== +An implemenation of the [Bukkit](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit) plugin API for [Minecraft](https://minecraft.net/) servers, currently maintained by [SpigotMC](http://www.spigotmc.org/). + +Bug Reporting +------------- +The development team is very open to both bug and feature requests / suggestions. You can submit these on the [JIRA Issue Tracker](http://hub.spigotmc.org/jira/). + +Compilation +----------- +CraftBukkit is a Java program which uses [Maven 3](http://maven.apache.org/) for compilation. To compile fresh from Git, simply perform the following steps: + +* Install Git using your preferred installation methods. +* Download and run [BuildTools](https://www.spigotmc.org/wiki/buildtools/) + +Some IDEs such as [NetBeans](https://netbeans.org/) can perform these steps for you. Any Maven capable Java IDE can be used to develop with CraftBukkit, however the current team's personal preference is to use NetBeans. + +Contributing +------------ +Contributions of all sorts are welcome. To manage community contributions, we use the pull request functionality of Stash. In to gain access to Stash and create a pull request, you will first need to perform the following steps: + +* Create an account on [JIRA](http://hub.spigotmc.org/jira/). +* Fill in the [SpigotMC CLA](http://www.spigotmc.org/go/cla) and wait up to 24 hours for your Stash account to be activated. Please ensure that your username and email addresses match. +* Log into Stash using your JIRA credentials. + +Once you have performed these steps you can create a fork, push your code changes, and then submit it for review. + +If you submit a PR involving both Bukkit and CraftBukkit, it's appreciated if each PR links the other. Additionally, every reference to an obfuscated field/method in NMS should be marked with `// PAIL: Rename` and optionally a suggested name, to make mapping creation easier. E.g.: +``` + entity.k.get(i).f(); // PAIL Rename pathfinders, navigateToHome +``` +Also, make sure to include `// Craftbukkit` comments to indicate modified NMS sources. diff --git a/MythicSpigot-master/TacoSpigot-Server/applyPatches.sh b/MythicSpigot-master/TacoSpigot-Server/applyPatches.sh new file mode 100644 index 0000000..0240113 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/applyPatches.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +if [ -z "$1" ] +then + echo "Please run this script again with the clean decompile sources as an argument. In most cases this will be ../work/decompile-XXXX" + exit +fi + +nms=$1/net/minecraft/server +cb=src/main/java/net/minecraft/server +#clean up and rebuild +rm -rf $cb +mkdir -p $cb +for file in $(/bin/ls nms-patches) +do + patchFile="nms-patches/$file" + file="$(echo $file | cut -d. -f1).java" + + echo "Patching $file < $patchFile" + sed -i 's/\r//' "$nms/$file" > /dev/null + + cp "$nms/$file" "$cb/$file" + patch -d src/main/java/ "net/minecraft/server/$file" < "$patchFile" +done diff --git a/MythicSpigot-master/TacoSpigot-Server/dependency-reduced-pom.xml b/MythicSpigot-master/TacoSpigot-Server/dependency-reduced-pom.xml new file mode 100644 index 0000000..8fba796 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/dependency-reduced-pom.xml @@ -0,0 +1,201 @@ + + + + parent + me.levansj01.mythicspigot + dev-SNAPSHOT + + 4.0.0 + me.levansj01.mythicspigot + server + MythicSpigot-Server + 1.8.8-R0.2-SNAPSHOT + verusdev.xyz + + install + + + com.lukegb.mojo + gitdescribe-maven-plugin + 1.3 + + + compile + + gitdescribe + + + + + git-TacoSpigot- + .. + + + + maven-jar-plugin + 2.5 + + true + + + org.bukkit.craftbukkit.Main + CraftBukkit + ${describe} + Bukkit Team + Bukkit + ${api.version} + Bukkit Team + + + + net/bukkit/ + + true + + + + com/bukkit/ + + true + + + + org/bukkit/ + + true + + + + + + + + maven-shade-plugin + 2.3 + + + package + + shade + + + + + joptsimple + org.bukkit.craftbukkit.libs.joptsimple + + + jline + org.bukkit.craftbukkit.libs.jline + + + org.ibex + org.bukkit.craftbukkit.libs.org.ibex + + + org.gjt + org.bukkit.craftbukkit.libs.org.gjt + + + org.bukkit.craftbukkit + org.bukkit.craftbukkit.v${minecraft_version} + + org.bukkit.craftbukkit.Main* + + + + net.minecraft.server + net.minecraft.server.v${minecraft_version} + + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.1 + + + package + + remap + + + ${project.basedir}/deprecation-mappings.csrg + ${project.basedir}/deprecation-mappings.at + + + + + + maven-compiler-plugin + 3.8.1 + + + org.codehaus.plexus + plexus-compiler-eclipse + 2.5.0-spigotmc + + + + true + 1.8 + 1.8 + + + + maven-surefire-plugin + 2.18 + + ${basedir}/target/test-server + + org/bukkit/craftbukkit/inventory/ItemStack*Test.java + + + + + + + + spigotmc-public + https://hub.spigotmc.org/nexus/content/groups/public/ + + + destroystokyo + https://ci.destroystokyo.com/plugin/repository/everything/ + + + + + junit + junit + 4.11 + test + + + org.hamcrest + hamcrest-library + 1.3 + test + + + org.projectlombok + lombok + 1.18.12 + provided + + + + 1.8.8 + 4.11 + unknown + 1_8_R3 + 1.8 + UTF-8 + git-Bukkit- + 1.8 + + + diff --git a/MythicSpigot-master/TacoSpigot-Server/deprecation-mappings.at b/MythicSpigot-master/TacoSpigot-Server/deprecation-mappings.at new file mode 100644 index 0000000..5858b48 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/deprecation-mappings.at @@ -0,0 +1,62 @@ +public+synthetic org/bukkit/Bukkit/getOnlinePlayers()[Lorg/bukkit/entity/Player; +public+synthetic org/bukkit/Server/getOnlinePlayers()[Lorg/bukkit/entity/Player; + +public+synthetic org/bukkit/entity/Damageable/damage(I)V +public+synthetic org/bukkit/entity/Damageable/damage(ILorg/bukkit/entity/Entity;)V +public+synthetic org/bukkit/entity/Damageable/getHealth()I +public+synthetic org/bukkit/entity/Damageable/getMaxHealth()I +public+synthetic org/bukkit/entity/Damageable/setHealth(I)V +public+synthetic org/bukkit/entity/Damageable/setMaxHealth(I)V + +public+synthetic org/bukkit/entity/LivingEntity/getLastDamage()I +public+synthetic org/bukkit/entity/LivingEntity/setLastDamage(I)V + +public+synthetic org/bukkit/entity/Minecart/getDamage()I +public+synthetic org/bukkit/entity/Minecart/setDamage(I)V + +public+synthetic org/bukkit/entity/Projectile/getShooter()Lorg/bukkit/entity/LivingEntity; +public+synthetic org/bukkit/entity/Projectile/setShooter(Lorg/bukkit/entity/LivingEntity;)V + +public+synthetic org/bukkit/event/entity/EntityDamageEvent/getDamage()I +public+synthetic org/bukkit/event/entity/EntityDamageEvent/setDamage(I)V + +public+synthetic org/bukkit/event/entity/EntityRegainHealthEvent/getAmount()I +public+synthetic org/bukkit/event/entity/EntityRegainHealthEvent/setAmount(I)V + +public+synthetic org/bukkit/event/vehicle/VehicleDamageEvent/getDamage()I +public+synthetic org/bukkit/event/vehicle/VehicleDamageEvent/setDamage(I)V + +# CraftBukkit +public+synthetic org/bukkit/craftbukkit/v1_8_R3/CraftServer/getOnlinePlayers()[Lorg/bukkit/entity/Player; + +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftArrow/getShooter()Lorg/bukkit/entity/LivingEntity; +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftArrow/setShooter(Lorg/bukkit/entity/LivingEntity;)V + +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftEnderDragonPart/damage(I)V +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftEnderDragonPart/damage(ILorg/bukkit/entity/Entity;)V +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftEnderDragonPart/getHealth()I +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftEnderDragonPart/getMaxHealth()I +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftEnderDragonPart/setHealth(I)V +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftEnderDragonPart/setMaxHealth(I)V + + +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftFireball/getShooter()Lorg/bukkit/entity/LivingEntity; +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftFireball/setShooter(Lorg/bukkit/entity/LivingEntity;)V + +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftFish/getShooter()Lorg/bukkit/entity/LivingEntity; +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftFish/setShooter(Lorg/bukkit/entity/LivingEntity;)V + +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftLivingEntity/damage(I)V +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftLivingEntity/damage(ILorg/bukkit/entity/Entity;)V +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftLivingEntity/getHealth()I +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftLivingEntity/getMaxHealth()I +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftLivingEntity/setHealth(I)V +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftLivingEntity/setMaxHealth(I)V +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftLivingEntity/getLastDamage()I +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftLivingEntity/setLastDamage(I)V + +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftMinecart/getDamage()I +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftMinecart/setDamage(I)V + +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftProjectile/getShooter()Lorg/bukkit/entity/LivingEntity; +public+synthetic org/bukkit/craftbukkit/v1_8_R3/entity/CraftProjectile/setShooter(Lorg/bukkit/entity/LivingEntity;)V diff --git a/MythicSpigot-master/TacoSpigot-Server/deprecation-mappings.csrg b/MythicSpigot-master/TacoSpigot-Server/deprecation-mappings.csrg new file mode 100644 index 0000000..48bc504 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/deprecation-mappings.csrg @@ -0,0 +1,27 @@ +org/bukkit/Bukkit _INVALID_getOnlinePlayers ()[Lorg/bukkit/entity/Player; getOnlinePlayers +org/bukkit/Server _INVALID_getOnlinePlayers ()[Lorg/bukkit/entity/Player; getOnlinePlayers + +org/bukkit/entity/Damageable _INVALID_damage (I)V damage +org/bukkit/entity/Damageable _INVALID_damage (ILorg/bukkit/entity/Entity;)V damage +org/bukkit/entity/Damageable _INVALID_getHealth ()I getHealth +org/bukkit/entity/Damageable _INVALID_getMaxHealth ()I getMaxHealth +org/bukkit/entity/Damageable _INVALID_setHealth (I)V setHealth +org/bukkit/entity/Damageable _INVALID_setMaxHealth (I)V setMaxHealth + +org/bukkit/entity/LivingEntity _INVALID_getLastDamage ()I getLastDamage +org/bukkit/entity/LivingEntity _INVALID_setLastDamage (I)V setLastDamage + +org/bukkit/entity/Minecart _INVALID_getDamage ()I getDamage +org/bukkit/entity/Minecart _INVALID_setDamage (I)V setDamage + +org/bukkit/entity/Projectile _INVALID_getShooter ()Lorg/bukkit/entity/LivingEntity; getShooter +org/bukkit/entity/Projectile _INVALID_setShooter (Lorg/bukkit/entity/LivingEntity;)V setShooter + +org/bukkit/event/entity/EntityDamageEvent _INVALID_getDamage ()I getDamage +org/bukkit/event/entity/EntityDamageEvent _INVALID_setDamage (I)V setDamage + +org/bukkit/event/entity/EntityRegainHealthEvent _INVALID_getAmount ()I getAmount +org/bukkit/event/entity/EntityRegainHealthEvent _INVALID_setAmount (I)V setAmount + +org/bukkit/event/vehicle/VehicleDamageEvent _INVALID_getDamage ()I getDamage +org/bukkit/event/vehicle/VehicleDamageEvent _INVALID_setDamage (I)V setDamage diff --git a/MythicSpigot-master/TacoSpigot-Server/makePatches.sh b/MythicSpigot-master/TacoSpigot-Server/makePatches.sh new file mode 100644 index 0000000..3400e7e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/makePatches.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +if [ -z "$1" ] +then + echo "Please run this script again with the clean decompile sources as an argument. In most cases this will be ../work/decompile-XXXX" + exit +fi +cb=src/main/java/net/minecraft/server +nms="$1/net/minecraft/server" + +for file in $(/bin/ls $cb) +do + echo "Diffing $file" + sed -i 's/\r//' "$nms/$file" + sed -i 's/\r//' "$cb/$file" + outName=$(echo nms-patches/"$(echo $file | cut -d. -f1)".patch) + patchNew=$(diff -u --label a/net/minecraft/server/$file "$nms/$file" --label b/net/minecraft/server/$file "$cb/$file") + if [ -f "$outName" ] + then + patchCut=$(echo "$patchNew" | tail -n +3) + patchOld=$(cat "$outName" | tail -n +3) + if [ "$patchCut" != "$patchOld" ] ; then + echo "$outName changed" + echo "$patchNew" > "$outName" + fi + else + echo "New patch $outName" + echo "$patchNew" > "$outName" + fi +done \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/mythicspigot.iml b/MythicSpigot-master/TacoSpigot-Server/mythicspigot.iml new file mode 100644 index 0000000..b236e97 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/mythicspigot.iml @@ -0,0 +1,50 @@ + + + + + + + MCP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BiomeTheEndDecorator.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BiomeTheEndDecorator.patch new file mode 100644 index 0000000..77ae887 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BiomeTheEndDecorator.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/BiomeTheEndDecorator.java ++++ b/net/minecraft/server/BiomeTheEndDecorator.java +@@ -21,7 +21,7 @@ + EntityEnderDragon entityenderdragon = new EntityEnderDragon(this.a); + + entityenderdragon.setPositionRotation(0.0D, 128.0D, 0.0D, this.b.nextFloat() * 360.0F, 0.0F); +- this.a.addEntity(entityenderdragon); ++ this.a.addEntity(entityenderdragon, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Block.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Block.patch new file mode 100644 index 0000000..360a2c0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Block.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/server/Block.java ++++ b/net/minecraft/server/Block.java +@@ -336,7 +336,8 @@ + int j = this.getDropCount(i, world.random); + + for (int k = 0; k < j; ++k) { +- if (world.random.nextFloat() <= f) { ++ // CraftBukkit - <= to < to allow for plugins to completely disable block drops from explosions ++ if (world.random.nextFloat() < f) { + Item item = this.getDropType(iblockdata, world.random, i); + + if (item != null) { +@@ -1002,4 +1003,10 @@ + return this.getBreakSound(); + } + } ++ ++ // CraftBukkit start ++ public int getExpDrop(World world, IBlockData data, int enchantmentLevel) { ++ return 0; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockBloodStone.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockBloodStone.patch new file mode 100644 index 0000000..250ed8a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockBloodStone.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/server/BlockBloodStone.java ++++ b/net/minecraft/server/BlockBloodStone.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockBloodStone extends Block { + + public BlockBloodStone() { +@@ -10,4 +12,17 @@ + public MaterialMapColor g(IBlockData iblockdata) { + return MaterialMapColor.K; + } ++ ++ // CraftBukkit start ++ @Override ++ public void doPhysics(World world, BlockPosition position, IBlockData iblockdata, Block block) { ++ if (block != null && block.isPowerSource()) { ++ org.bukkit.block.Block bl = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()); ++ int power = bl.getBlockPower(); ++ ++ BlockRedstoneEvent event = new BlockRedstoneEvent(bl, power, power); ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockButtonAbstract.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockButtonAbstract.patch new file mode 100644 index 0000000..408baab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockButtonAbstract.patch @@ -0,0 +1,110 @@ +--- a/net/minecraft/server/BlockButtonAbstract.java ++++ b/net/minecraft/server/BlockButtonAbstract.java +@@ -3,6 +3,11 @@ + import java.util.List; + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.event.block.BlockRedstoneEvent; ++import org.bukkit.event.entity.EntityInteractEvent; ++// CraftBukkit end ++ + public abstract class BlockButtonAbstract extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing"); +@@ -124,6 +129,19 @@ + if (((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue()) { + return true; + } else { ++ // CraftBukkit start ++ boolean powered = ((Boolean) iblockdata.get(POWERED)); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ int old = (powered) ? 15 : 0; ++ int current = (!powered) ? 15 : 0; ++ ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) { ++ return true; ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, iblockdata.set(BlockButtonAbstract.POWERED, Boolean.valueOf(true)), 3); + world.b(blockposition, blockposition); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, 0.6F); +@@ -161,6 +179,16 @@ + if (this.N) { + this.f(world, blockposition, iblockdata); + } else { ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() > 0) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeUpdate(blockposition, iblockdata.set(BlockButtonAbstract.POWERED, Boolean.valueOf(false))); + this.c(world, blockposition, (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, 0.5F); +@@ -195,7 +223,41 @@ + boolean flag = !list.isEmpty(); + boolean flag1 = ((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue(); + ++ // CraftBukkit start - Call interact event when arrows turn on wooden buttons ++ if (flag1 != flag && flag) { ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ boolean allowed = false; ++ ++ // If all of the events are cancelled block the button press, else allow ++ for (Object object : list) { ++ if (object != null) { ++ EntityInteractEvent event = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ allowed = true; ++ break; ++ } ++ } ++ } ++ ++ if (!allowed) { ++ return; ++ } ++ } ++ // CraftBukkit end ++ + if (flag && !flag1) { ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 0, 15); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() <= 0) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeUpdate(blockposition, iblockdata.set(BlockButtonAbstract.POWERED, Boolean.valueOf(true))); + this.c(world, blockposition, (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)); + world.b(blockposition, blockposition); +@@ -203,6 +265,16 @@ + } + + if (!flag && flag1) { ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() > 0) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeUpdate(blockposition, iblockdata.set(BlockButtonAbstract.POWERED, Boolean.valueOf(false))); + this.c(world, blockposition, (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)); + world.b(blockposition, blockposition); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCactus.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCactus.patch new file mode 100644 index 0000000..b8b99b8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCactus.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/server/BlockCactus.java ++++ b/net/minecraft/server/BlockCactus.java +@@ -3,6 +3,8 @@ + import java.util.Iterator; + import java.util.Random; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockCactus extends Block { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 15); +@@ -28,9 +30,10 @@ + int j = ((Integer) iblockdata.get(BlockCactus.AGE)).intValue(); + + if (j == 15) { +- world.setTypeUpdate(blockposition1, this.getBlockData()); ++ // world.setTypeUpdate(blockposition1, this.getBlockData()); // CraftBukkit + IBlockData iblockdata1 = iblockdata.set(BlockCactus.AGE, Integer.valueOf(0)); + ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), this, 0); // CraftBukkit + world.setTypeAndData(blockposition, iblockdata1, 4); + this.doPhysics(world, blockposition1, iblockdata1, this); + } else { +@@ -83,7 +86,9 @@ + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { ++ CraftEventFactory.blockDamage = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); // CraftBukkit + entity.damageEntity(DamageSource.CACTUS, 1.0F); ++ CraftEventFactory.blockDamage = null; // CraftBukkit + } + + public IBlockData fromLegacyData(int i) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCake.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCake.patch new file mode 100644 index 0000000..5545918 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCake.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/server/BlockCake.java ++++ b/net/minecraft/server/BlockCake.java +@@ -55,7 +55,18 @@ + private void b(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { + if (entityhuman.j(false)) { + entityhuman.b(StatisticList.H); +- entityhuman.getFoodData().eat(2, 0.1F); ++ // CraftBukkit start ++ // entityhuman.getFoodData().eat(2, 0.1F); ++ int oldFoodLevel = entityhuman.getFoodData().foodLevel; ++ ++ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, 2 + oldFoodLevel); ++ ++ if (!event.isCancelled()) { ++ entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 0.1F); ++ } ++ ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel)); ++ // CraftBukkit end + int i = ((Integer) iblockdata.get(BlockCake.BITES)).intValue(); + + if (i < 6) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCocoa.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCocoa.patch new file mode 100644 index 0000000..d7ba70e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCocoa.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/server/BlockCocoa.java ++++ b/net/minecraft/server/BlockCocoa.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockCocoa extends BlockDirectional implements IBlockFragilePlantElement { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 2); +@@ -19,7 +21,10 @@ + int i = ((Integer) iblockdata.get(BlockCocoa.AGE)).intValue(); + + if (i < 2) { +- world.setTypeAndData(blockposition, iblockdata.set(BlockCocoa.AGE, Integer.valueOf(i + 1)), 2); ++ // CraftBukkit start ++ IBlockData data = iblockdata.set(AGE, Integer.valueOf(i + 1)); ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data)); ++ // CraftBukkit end + } + } + +@@ -125,7 +130,10 @@ + } + + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { +- world.setTypeAndData(blockposition, iblockdata.set(BlockCocoa.AGE, Integer.valueOf(((Integer) iblockdata.get(BlockCocoa.AGE)).intValue() + 1)), 2); ++ // CraftBukkit start ++ IBlockData data = iblockdata.set(AGE, Integer.valueOf(((Integer) iblockdata.get(AGE)).intValue() + 1)); ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data)); ++ // CraftBukkit end + } + + public IBlockData fromLegacyData(int i) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCommand.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCommand.patch new file mode 100644 index 0000000..236e740 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCommand.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/server/BlockCommand.java ++++ b/net/minecraft/server/BlockCommand.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockCommand extends BlockContainer { + + public static final BlockStateBoolean TRIGGERED = BlockStateBoolean.of("triggered"); +@@ -20,10 +22,19 @@ + boolean flag = world.isBlockIndirectlyPowered(blockposition); + boolean flag1 = ((Boolean) iblockdata.get(BlockCommand.TRIGGERED)).booleanValue(); + +- if (flag && !flag1) { ++ // CraftBukkit start ++ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ int old = flag1 ? 15 : 0; ++ int current = flag ? 15 : 0; ++ ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, old, current); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ // CraftBukkit end ++ ++ if (eventRedstone.getNewCurrent() > 0 && !(eventRedstone.getOldCurrent() > 0)) { // CraftBukkit + world.setTypeAndData(blockposition, iblockdata.set(BlockCommand.TRIGGERED, Boolean.valueOf(true)), 4); + world.a(blockposition, (Block) this, this.a(world)); +- } else if (!flag && flag1) { ++ } else if (!(eventRedstone.getNewCurrent() > 0) && eventRedstone.getOldCurrent() > 0) { // CraftBukkit + world.setTypeAndData(blockposition, iblockdata.set(BlockCommand.TRIGGERED, Boolean.valueOf(false)), 4); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCrops.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCrops.patch new file mode 100644 index 0000000..bc89bbd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockCrops.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/server/BlockCrops.java ++++ b/net/minecraft/server/BlockCrops.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 7); +@@ -31,7 +33,10 @@ + float f = a((Block) this, world, blockposition); + + if (random.nextInt((int) (25.0F / f) + 1) == 0) { +- world.setTypeAndData(blockposition, iblockdata.set(BlockCrops.AGE, Integer.valueOf(i + 1)), 2); ++ // CraftBukkit start ++ IBlockData data = iblockdata.set(AGE, Integer.valueOf(i + 1)); ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data)); ++ // CraftBukkit end + } + } + } +@@ -45,7 +50,10 @@ + i = 7; + } + +- world.setTypeAndData(blockposition, iblockdata.set(BlockCrops.AGE, Integer.valueOf(i)), 2); ++ // CraftBukkit start ++ IBlockData data = iblockdata.set(AGE, Integer.valueOf(i)); ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data)); ++ // CraftBukkit end + } + + protected static float a(Block block, World world, BlockPosition blockposition) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDaylightDetector.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDaylightDetector.patch new file mode 100644 index 0000000..ba11108 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDaylightDetector.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/BlockDaylightDetector.java ++++ b/net/minecraft/server/BlockDaylightDetector.java +@@ -41,6 +41,7 @@ + } + + if (((Integer) iblockdata.get(BlockDaylightDetector.POWER)).intValue() != i) { ++ i = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), ((Integer) iblockdata.get(POWER)), i).getNewCurrent(); // CraftBukkit - Call BlockRedstoneEvent + world.setTypeAndData(blockposition, iblockdata.set(BlockDaylightDetector.POWER, Integer.valueOf(i)), 3); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDiodeAbstract.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDiodeAbstract.patch new file mode 100644 index 0000000..8144ad4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDiodeAbstract.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/server/BlockDiodeAbstract.java ++++ b/net/minecraft/server/BlockDiodeAbstract.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public abstract class BlockDiodeAbstract extends BlockDirectional { + + protected final boolean N; +@@ -31,8 +33,18 @@ + boolean flag = this.e(world, blockposition, iblockdata); + + if (this.N && !flag) { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 15, 0).getNewCurrent() != 0) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, this.k(iblockdata), 2); + } else if (!this.N) { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 0, 15).getNewCurrent() != 15) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, this.e(iblockdata), 2); + if (!flag) { + world.a(blockposition, this.e(iblockdata).getBlock(), this.m(iblockdata), -1); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDispenser.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDispenser.patch new file mode 100644 index 0000000..ff2bdb7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDispenser.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/server/BlockDispenser.java ++++ b/net/minecraft/server/BlockDispenser.java +@@ -8,6 +8,7 @@ + public static final BlockStateBoolean TRIGGERED = BlockStateBoolean.of("triggered"); + public static final RegistryDefault REGISTRY = new RegistryDefault(new DispenseBehaviorItem()); + protected Random O = new Random(); ++ public static boolean eventFired = false; // CraftBukkit + + protected BlockDispenser() { + super(Material.STONE); +@@ -83,6 +84,7 @@ + + if (idispensebehavior != IDispenseBehavior.NONE) { + ItemStack itemstack1 = idispensebehavior.a(sourceblock, itemstack); ++ eventFired = false; // CraftBukkit - reset event status + + tileentitydispenser.setItem(i, itemstack1.count <= 0 ? null : itemstack1); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDoor.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDoor.patch new file mode 100644 index 0000000..5f6752c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDoor.patch @@ -0,0 +1,44 @@ +--- a/net/minecraft/server/BlockDoor.java ++++ b/net/minecraft/server/BlockDoor.java +@@ -3,6 +3,8 @@ + import com.google.common.base.Predicate; + import java.util.Random; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockDoor extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirection.EnumDirectionLimit.HORIZONTAL); +@@ -155,9 +157,22 @@ + this.b(world, blockposition, iblockdata, 0); + } + } else { +- boolean flag1 = world.isBlockIndirectlyPowered(blockposition) || world.isBlockIndirectlyPowered(blockposition2); + +- if ((flag1 || block.isPowerSource()) && block != this && flag1 != ((Boolean) iblockdata2.get(BlockDoor.POWERED)).booleanValue()) { ++ // CraftBukkit start ++ org.bukkit.World bworld = world.getWorld(); ++ org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ org.bukkit.block.Block blockTop = bworld.getBlockAt(blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()); ++ ++ int power = bukkitBlock.getBlockPower(); ++ int powerTop = blockTop.getBlockPower(); ++ if (powerTop > power) power = powerTop; ++ int oldPower = (Boolean)iblockdata2.get(POWERED) ? 15 : 0; ++ ++ if (oldPower == 0 ^ power == 0) { ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, oldPower, power); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ boolean flag1 = eventRedstone.getNewCurrent() > 0; + world.setTypeAndData(blockposition2, iblockdata2.set(BlockDoor.POWERED, Boolean.valueOf(flag1)), 2); + if (flag1 != ((Boolean) iblockdata.get(BlockDoor.OPEN)).booleanValue()) { + world.setTypeAndData(blockposition, iblockdata.set(BlockDoor.OPEN, Boolean.valueOf(flag1)), 2); +@@ -165,6 +180,7 @@ + world.a((EntityHuman) null, flag1 ? 1003 : 1006, blockposition, 0); + } + } ++ // CraftBukkit end + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDragonEgg.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDragonEgg.patch new file mode 100644 index 0000000..e9860ee --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDragonEgg.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/server/BlockDragonEgg.java ++++ b/net/minecraft/server/BlockDragonEgg.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.event.block.BlockFromToEvent; // CraftBukkit ++ + public class BlockDragonEgg extends Block { + + public BlockDragonEgg() { +@@ -61,6 +63,18 @@ + BlockPosition blockposition1 = blockposition.a(world.random.nextInt(16) - world.random.nextInt(16), world.random.nextInt(8) - world.random.nextInt(8), world.random.nextInt(16) - world.random.nextInt(16)); + + if (world.getType(blockposition1).getBlock().material == Material.AIR) { ++ // CraftBukkit start ++ org.bukkit.block.Block from = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ org.bukkit.block.Block to = world.getWorld().getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); ++ BlockFromToEvent event = new BlockFromToEvent(from, to); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ blockposition1 = new BlockPosition(event.getToBlock().getX(), event.getToBlock().getY(), event.getToBlock().getZ()); ++ // CraftBukkit end + if (world.isClientSide) { + for (int j = 0; j < 128; ++j) { + double d0 = world.random.nextDouble(); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDropper.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDropper.patch new file mode 100644 index 0000000..9f4ff91 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockDropper.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/server/BlockDropper.java ++++ b/net/minecraft/server/BlockDropper.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.inventory.InventoryMoveItemEvent; ++// CraftBukkit end ++ + public class BlockDropper extends BlockDispenser { + + private final IDispenseBehavior P = new DispenseBehaviorItem(); +@@ -38,8 +43,25 @@ + itemstack1 = null; + } + } else { +- itemstack1 = TileEntityHopper.addItem(iinventory, itemstack.cloneItemStack().cloneAndSubtract(1), enumdirection.opposite()); +- if (itemstack1 == null) { ++ // CraftBukkit start - Fire event when pushing items into other inventories ++ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(itemstack.cloneItemStack().cloneAndSubtract(1)); ++ ++ org.bukkit.inventory.Inventory destinationInventory; ++ // Have to special case large chests as they work oddly ++ if (iinventory instanceof InventoryLargeChest) { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); ++ } else { ++ destinationInventory = iinventory.getOwner().getInventory(); ++ } ++ ++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(tileentitydispenser.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); ++ world.getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return; ++ } ++ itemstack1 = TileEntityHopper.addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), enumdirection.opposite()); ++ if (event.getItem().equals(oitemstack) && itemstack1 == null) { ++ // CraftBukkit end + itemstack1 = itemstack.cloneItemStack(); + if (--itemstack1.count <= 0) { + itemstack1 = null; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockEnderPortal.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockEnderPortal.patch new file mode 100644 index 0000000..8f130a9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockEnderPortal.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/server/BlockEnderPortal.java ++++ b/net/minecraft/server/BlockEnderPortal.java +@@ -3,6 +3,8 @@ + import java.util.List; + import java.util.Random; + ++import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit ++ + public class BlockEnderPortal extends BlockContainer { + + protected BlockEnderPortal(Material material) { +@@ -36,6 +38,10 @@ + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (entity.vehicle == null && entity.passenger == null && !world.isClientSide) { ++ // CraftBukkit start - Entity in portal ++ EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ())); ++ world.getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end + entity.c(1); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockFire.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockFire.patch new file mode 100644 index 0000000..db1a8fd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockFire.patch @@ -0,0 +1,136 @@ +--- a/net/minecraft/server/BlockFire.java ++++ b/net/minecraft/server/BlockFire.java +@@ -4,6 +4,12 @@ + import java.util.Map; + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.block.BlockBurnEvent; ++import org.bukkit.event.block.BlockSpreadEvent; ++// CraftBukkit end ++ + public class BlockFire extends Block { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 15); +@@ -109,7 +115,7 @@ + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (world.getGameRules().getBoolean("doFireTick")) { + if (!this.canPlace(world, blockposition)) { +- world.setAir(blockposition); ++ fireExtinguished(world, blockposition); // CraftBukkit - invalid place location + } + + Block block = world.getType(blockposition.down()).getBlock(); +@@ -120,7 +126,7 @@ + } + + if (!flag && world.S() && this.e(world, blockposition)) { +- world.setAir(blockposition); ++ fireExtinguished(world, blockposition); // CraftBukkit - extinguished by rain + } else { + int i = ((Integer) iblockdata.get(BlockFire.AGE)).intValue(); + +@@ -133,14 +139,14 @@ + if (!flag) { + if (!this.f(world, blockposition)) { + if (!World.a((IBlockAccess) world, blockposition.down()) || i > 3) { +- world.setAir(blockposition); ++ fireExtinguished(world, blockposition); // CraftBukkit + } + + return; + } + + if (!this.e((IBlockAccess) world, blockposition.down()) && i == 15 && random.nextInt(4) == 0) { +- world.setAir(blockposition); ++ fireExtinguished(world, blockposition); // CraftBukkit + return; + } + } +@@ -186,7 +192,26 @@ + l1 = 15; + } + +- world.setTypeAndData(blockposition1, iblockdata.set(BlockFire.AGE, Integer.valueOf(l1)), 3); ++ // CraftBukkit start - Call to stop spread of fire ++ if (world.getType(blockposition1) != Blocks.FIRE) { ++ if (CraftEventFactory.callBlockIgniteEvent(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), blockposition.getX(), blockposition.getY(), blockposition.getZ()).isCancelled()) { ++ continue; ++ } ++ ++ org.bukkit.Server server = world.getServer(); ++ org.bukkit.World bworld = world.getWorld(); ++ org.bukkit.block.BlockState blockState = bworld.getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()).getState(); ++ blockState.setTypeId(Block.getId(this)); ++ blockState.setData(new org.bukkit.material.MaterialData(Block.getId(this), (byte) l1)); ++ ++ BlockSpreadEvent spreadEvent = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), blockState); ++ server.getPluginManager().callEvent(spreadEvent); ++ ++ if (!spreadEvent.isCancelled()) { ++ blockState.update(true); ++ } ++ } ++ // CraftBukkit end + } + } + } +@@ -224,6 +249,17 @@ + if (random.nextInt(i) < k) { + IBlockData iblockdata = world.getType(blockposition); + ++ // CraftBukkit start ++ org.bukkit.block.Block theBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ BlockBurnEvent event = new BlockBurnEvent(theBlock); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ + if (random.nextInt(j + 10) < 5 && !world.isRainingAt(blockposition)) { + int l = j + random.nextInt(5) / 4; + +@@ -233,7 +269,7 @@ + + world.setTypeAndData(blockposition, this.getBlockData().set(BlockFire.AGE, Integer.valueOf(l)), 3); + } else { +- world.setAir(blockposition); ++ fireExtinguished(world, blockposition); // CraftBukkit + } + + if (iblockdata.getBlock() == Blocks.TNT) { +@@ -290,7 +326,7 @@ + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!World.a((IBlockAccess) world, blockposition.down()) && !this.f(world, blockposition)) { +- world.setAir(blockposition); ++ fireExtinguished(world, blockposition); // CraftBukkit - fuel block gone + } + + } +@@ -298,7 +334,7 @@ + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (world.worldProvider.getDimension() > 0 || !Blocks.PORTAL.e(world, blockposition)) { + if (!World.a((IBlockAccess) world, blockposition.down()) && !this.f(world, blockposition)) { +- world.setAir(blockposition); ++ fireExtinguished(world, blockposition); // CraftBukkit - fuel block broke + } else { + world.a(blockposition, (Block) this, this.a(world) + world.random.nextInt(10)); + } +@@ -320,4 +356,12 @@ + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockFire.AGE, BlockFire.NORTH, BlockFire.EAST, BlockFire.SOUTH, BlockFire.WEST, BlockFire.UPPER, BlockFire.FLIP, BlockFire.ALT}); + } ++ ++ // CraftBukkit start ++ private void fireExtinguished(World world, BlockPosition position) { ++ if (!CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), Blocks.AIR).isCancelled()) { ++ world.setAir(position); ++ } ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockFlowing.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockFlowing.patch new file mode 100644 index 0000000..38caee1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockFlowing.patch @@ -0,0 +1,74 @@ +--- a/net/minecraft/server/BlockFlowing.java ++++ b/net/minecraft/server/BlockFlowing.java +@@ -5,6 +5,11 @@ + import java.util.Random; + import java.util.Set; + ++// CraftBukkit start ++import org.bukkit.block.BlockFace; ++import org.bukkit.event.block.BlockFromToEvent; ++// CraftBukkit end ++ + public class BlockFlowing extends BlockFluids { + + int a; +@@ -18,6 +23,11 @@ + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { ++ // CraftBukkit start ++ org.bukkit.World bworld = world.getWorld(); ++ org.bukkit.Server server = world.getServer(); ++ org.bukkit.block.Block source = bworld == null ? null : bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ // CraftBukkit end + int i = ((Integer) iblockdata.get(BlockFlowing.LEVEL)).intValue(); + byte b0 = 1; + +@@ -88,6 +98,12 @@ + IBlockData iblockdata2 = world.getType(blockposition.down()); + + if (this.h(world, blockposition.down(), iblockdata2)) { ++ // CraftBukkit start - Send "down" to the server ++ BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN); ++ if (server != null) { ++ server.getPluginManager().callEvent(event); ++ } ++ if (!event.isCancelled()) { + if (this.material == Material.LAVA && world.getType(blockposition.down()).getBlock().getMaterial() == Material.WATER) { + world.setTypeUpdate(blockposition.down(), Blocks.STONE.getBlockData()); + this.fizz(world, blockposition.down()); +@@ -99,6 +115,8 @@ + } else { + this.flow(world, blockposition.down(), iblockdata2, i + 8); + } ++ } ++ // CraftBukkit end + } else if (i >= 0 && (i == 0 || this.g(world, blockposition.down(), iblockdata2))) { + Set set = this.f(world, blockposition); + +@@ -116,14 +134,23 @@ + while (iterator1.hasNext()) { + EnumDirection enumdirection1 = (EnumDirection) iterator1.next(); + +- this.flow(world, blockposition.shift(enumdirection1), world.getType(blockposition.shift(enumdirection1)), k); ++ // CraftBukkit start ++ BlockFromToEvent event = new BlockFromToEvent(source, org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection1)); ++ if (server != null) { ++ server.getPluginManager().callEvent(event); ++ } ++ ++ if (!event.isCancelled()) { ++ this.flow(world, blockposition.shift(enumdirection1), world.getType(blockposition.shift(enumdirection1)), k); ++ } ++ // CraftBukkit end + } + } + + } + + private void flow(World world, BlockPosition blockposition, IBlockData iblockdata, int i) { +- if (this.h(world, blockposition, iblockdata)) { ++ if (world.isLoaded(blockposition) && this.h(world, blockposition, iblockdata)) { // CraftBukkit - add isLoaded check + if (iblockdata.getBlock() != Blocks.AIR) { + if (this.material == Material.LAVA) { + this.fizz(world, blockposition); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockGrass.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockGrass.patch new file mode 100644 index 0000000..7014deb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockGrass.patch @@ -0,0 +1,77 @@ +--- a/net/minecraft/server/BlockGrass.java ++++ b/net/minecraft/server/BlockGrass.java +@@ -2,6 +2,14 @@ + + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.event.block.BlockSpreadEvent; ++import org.bukkit.event.block.BlockFadeEvent; ++// CraftBukkit end ++ + public class BlockGrass extends Block implements IBlockFragilePlantElement { + + public static final BlockStateBoolean SNOWY = BlockStateBoolean.of("snowy"); +@@ -22,7 +30,19 @@ + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (world.getLightLevel(blockposition.up()) < 4 && world.getType(blockposition.up()).getBlock().p() > 2) { +- world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); ++ // CraftBukkit start ++ // world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); ++ org.bukkit.World bworld = world.getWorld(); ++ BlockState blockState = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()).getState(); ++ blockState.setType(CraftMagicNumbers.getMaterial(Blocks.DIRT)); ++ ++ BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } else { + if (world.getLightLevel(blockposition.up()) >= 9) { + for (int i = 0; i < 4; ++i) { +@@ -31,7 +51,19 @@ + IBlockData iblockdata1 = world.getType(blockposition1); + + if (iblockdata1.getBlock() == Blocks.DIRT && iblockdata1.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.DIRT && world.getLightLevel(blockposition1.up()) >= 4 && block.p() <= 2) { +- world.setTypeUpdate(blockposition1, Blocks.GRASS.getBlockData()); ++ // CraftBukkit start ++ // world.setTypeUpdate(blockposition1, Blocks.GRASS.getBlockData()); ++ org.bukkit.World bworld = world.getWorld(); ++ BlockState blockState = bworld.getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()).getState(); ++ blockState.setType(CraftMagicNumbers.getMaterial(Blocks.GRASS)); ++ ++ BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), blockState); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } + } + } +@@ -74,13 +106,15 @@ + IBlockData iblockdata1 = blockflowers.getBlockData().set(blockflowers.n(), blockflowers_enumflowervarient); + + if (blockflowers.f(world, blockposition2, iblockdata1)) { +- world.setTypeAndData(blockposition2, iblockdata1, 3); ++ // world.setTypeAndData(blockposition2, iblockdata1, 3); // CraftBukkit ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition2.getX(), blockposition2.getY(), blockposition2.getZ(), iblockdata1.getBlock(), iblockdata1.getBlock().toLegacyData(iblockdata1)); // CraftBukkit + } + } else { + IBlockData iblockdata2 = Blocks.TALLGRASS.getBlockData().set(BlockLongGrass.TYPE, BlockLongGrass.EnumTallGrassType.GRASS); + + if (Blocks.TALLGRASS.f(world, blockposition2, iblockdata2)) { +- world.setTypeAndData(blockposition2, iblockdata2, 3); ++ // world.setTypeAndData(blockposition2, iblockdata2, 3); // CraftBukkit ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition2.getX(), blockposition2.getY(), blockposition2.getZ(), iblockdata2.getBlock(), iblockdata2.getBlock().toLegacyData(iblockdata2)); // CraftBukkit + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockIce.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockIce.patch new file mode 100644 index 0000000..05344a7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockIce.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/server/BlockIce.java ++++ b/net/minecraft/server/BlockIce.java +@@ -44,6 +44,12 @@ + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (world.b(EnumSkyBlock.BLOCK, blockposition) > 11 - this.p()) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), world.worldProvider.n() ? Blocks.AIR : Blocks.WATER).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ + if (world.worldProvider.n()) { + world.setAir(blockposition); + } else { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockJukeBox.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockJukeBox.patch new file mode 100644 index 0000000..080ba7e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockJukeBox.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/server/BlockJukeBox.java ++++ b/net/minecraft/server/BlockJukeBox.java +@@ -136,6 +136,11 @@ + } + + public void setRecord(ItemStack itemstack) { ++ // CraftBukkit start - There can only be one ++ if (itemstack != null) { ++ itemstack.count = 1; ++ } ++ // CraftBukkit end + this.record = itemstack; + this.update(); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockLeaves.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockLeaves.patch new file mode 100644 index 0000000..ffdc77a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockLeaves.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/server/BlockLeaves.java ++++ b/net/minecraft/server/BlockLeaves.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.event.block.LeavesDecayEvent; // CraftBukkit ++ + public abstract class BlockLeaves extends BlockTransparent { + + public static final BlockStateBoolean DECAYABLE = BlockStateBoolean.of("decayable"); +@@ -130,6 +132,14 @@ + } + + private void e(World world, BlockPosition blockposition) { ++ // CraftBukkit start ++ LeavesDecayEvent event = new LeavesDecayEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled() || world.getType(blockposition).getBlock() != this) { ++ return; ++ } ++ // CraftBukkit end + this.b(world, blockposition, world.getType(blockposition), 0); + world.setAir(blockposition); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockLever.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockLever.patch new file mode 100644 index 0000000..c150122 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockLever.patch @@ -0,0 +1,32 @@ +--- a/net/minecraft/server/BlockLever.java ++++ b/net/minecraft/server/BlockLever.java +@@ -2,6 +2,8 @@ + + import java.util.Iterator; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockLever extends Block { + + public static final BlockStateEnum FACING = BlockStateEnum.of("facing", BlockLever.EnumLeverPosition.class); +@@ -155,6 +157,20 @@ + if (world.isClientSide) { + return true; + } else { ++ // CraftBukkit start - Interact Lever ++ boolean powered = iblockdata.get(POWERED); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ int old = (powered) ? 15 : 0; ++ int current = (!powered) ? 15 : 0; ++ ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) { ++ return true; ++ } ++ // CraftBukkit end ++ + iblockdata = iblockdata.a(BlockLever.POWERED); + world.setTypeAndData(blockposition, iblockdata, 3); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, ((Boolean) iblockdata.get(BlockLever.POWERED)).booleanValue() ? 0.6F : 0.5F); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMinecartDetector.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMinecartDetector.patch new file mode 100644 index 0000000..625436f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMinecartDetector.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/server/BlockMinecartDetector.java ++++ b/net/minecraft/server/BlockMinecartDetector.java +@@ -4,6 +4,8 @@ + import java.util.List; + import java.util.Random; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockMinecartDetector extends BlockMinecartTrackAbstract { + + public static final BlockStateEnum SHAPE = BlockStateEnum.a("shape", BlockMinecartTrackAbstract.EnumTrackPosition.class, new Predicate() { +@@ -64,6 +66,17 @@ + flag1 = true; + } + ++ // CraftBukkit start ++ if (flag != flag1) { ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, flag ? 15 : 0, flag1 ? 15 : 0); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ flag1 = eventRedstone.getNewCurrent() > 0; ++ } ++ // CraftBukkit end ++ + if (flag1 && !flag) { + world.setTypeAndData(blockposition, iblockdata.set(BlockMinecartDetector.POWERED, Boolean.valueOf(true)), 3); + world.applyPhysics(blockposition, this); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMinecartTrackAbstract.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMinecartTrackAbstract.patch new file mode 100644 index 0000000..922347c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMinecartTrackAbstract.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/BlockMinecartTrackAbstract.java ++++ b/net/minecraft/server/BlockMinecartTrackAbstract.java +@@ -87,7 +87,7 @@ + flag = true; + } + +- if (flag) { ++ if (flag && !world.isEmpty(blockposition)) { // CraftBukkit - SPIGOT-424, MC-73474 + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } else { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMobSpawner.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMobSpawner.patch new file mode 100644 index 0000000..870a990 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMobSpawner.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/server/BlockMobSpawner.java ++++ b/net/minecraft/server/BlockMobSpawner.java +@@ -22,9 +22,19 @@ + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + super.dropNaturally(world, blockposition, iblockdata, f, i); ++ /* CraftBukkit start - Delegate to getExpDrop + int j = 15 + world.random.nextInt(15) + world.random.nextInt(15); + + this.dropExperience(world, blockposition, j); ++ */ ++ } ++ ++ @Override ++ public int getExpDrop(World world, IBlockData iblockdata, int enchantmentLevel) { ++ int j = 15 + world.random.nextInt(15) + world.random.nextInt(15); ++ ++ return j; ++ // CraftBukkit end + } + + public boolean c() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMonsterEggs.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMonsterEggs.patch new file mode 100644 index 0000000..1a4ae34 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMonsterEggs.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/BlockMonsterEggs.java ++++ b/net/minecraft/server/BlockMonsterEggs.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; // CraftBukkit ++ + public class BlockMonsterEggs extends Block { + + public static final BlockStateEnum VARIANT = BlockStateEnum.of("variant", BlockMonsterEggs.EnumMonsterEggVarient.class); +@@ -50,7 +52,7 @@ + EntitySilverfish entitysilverfish = new EntitySilverfish(world); + + entitysilverfish.setPositionRotation((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, 0.0F, 0.0F); +- world.addEntity(entitysilverfish); ++ world.addEntity(entitysilverfish, SpawnReason.SILVERFISH_BLOCK); // CraftBukkit - add SpawnReason + entitysilverfish.y(); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMushroom.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMushroom.patch new file mode 100644 index 0000000..20bdf91 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMushroom.patch @@ -0,0 +1,55 @@ +--- a/net/minecraft/server/BlockMushroom.java ++++ b/net/minecraft/server/BlockMushroom.java +@@ -3,6 +3,12 @@ + import java.util.Iterator; + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.TreeType; ++import org.bukkit.block.BlockState; ++import org.bukkit.event.block.BlockSpreadEvent; ++// CraftBukkit end ++ + public class BlockMushroom extends BlockPlant implements IBlockFragilePlantElement { + + protected BlockMushroom() { +@@ -13,6 +19,7 @@ + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { ++ final int sourceX = blockposition.getX(), sourceY = blockposition.getY(), sourceZ = blockposition.getZ(); // CraftBukkit + if (random.nextInt(25) == 0) { + int i = 5; + boolean flag = true; +@@ -40,7 +47,19 @@ + } + + if (world.isEmpty(blockposition2) && this.f(world, blockposition2, this.getBlockData())) { +- world.setTypeAndData(blockposition2, this.getBlockData(), 2); ++ // CraftBukkit start ++ // world.setTypeAndData(blockposition2, this.getBlockData(), 2); ++ org.bukkit.World bworld = world.getWorld(); ++ BlockState blockState = bworld.getBlockAt(blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()).getState(); ++ blockState.setType(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(this)); // nms: this.id, 0, 2 ++ ++ BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(sourceX, sourceY, sourceZ), blockState); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } + } + +@@ -69,8 +88,10 @@ + WorldGenHugeMushroom worldgenhugemushroom = null; + + if (this == Blocks.BROWN_MUSHROOM) { ++ BlockSapling.treeType = TreeType.BROWN_MUSHROOM; // CraftBukkit + worldgenhugemushroom = new WorldGenHugeMushroom(Blocks.BROWN_MUSHROOM_BLOCK); + } else if (this == Blocks.RED_MUSHROOM) { ++ BlockSapling.treeType = TreeType.RED_MUSHROOM; // CraftBukkit + worldgenhugemushroom = new WorldGenHugeMushroom(Blocks.RED_MUSHROOM_BLOCK); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMycel.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMycel.patch new file mode 100644 index 0000000..472975d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockMycel.patch @@ -0,0 +1,58 @@ +--- a/net/minecraft/server/BlockMycel.java ++++ b/net/minecraft/server/BlockMycel.java +@@ -2,6 +2,13 @@ + + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.event.block.BlockFadeEvent; ++import org.bukkit.event.block.BlockSpreadEvent; ++// CraftBukkit end ++ + public class BlockMycel extends Block { + + public static final BlockStateBoolean SNOWY = BlockStateBoolean.of("snowy"); +@@ -22,7 +29,19 @@ + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (world.getLightLevel(blockposition.up()) < 4 && world.getType(blockposition.up()).getBlock().p() > 2) { +- world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, BlockDirt.EnumDirtVariant.DIRT)); ++ // CraftBukkit start ++ // world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, EnumDirtVariant.DIRT)); ++ org.bukkit.World bworld = world.getWorld(); ++ BlockState blockState = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()).getState(); ++ blockState.setType(CraftMagicNumbers.getMaterial(Blocks.DIRT)); ++ ++ BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } else { + if (world.getLightLevel(blockposition.up()) >= 9) { + for (int i = 0; i < 4; ++i) { +@@ -31,7 +50,19 @@ + Block block = world.getType(blockposition1.up()).getBlock(); + + if (iblockdata1.getBlock() == Blocks.DIRT && iblockdata1.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.DIRT && world.getLightLevel(blockposition1.up()) >= 4 && block.p() <= 2) { +- world.setTypeUpdate(blockposition1, this.getBlockData()); ++ // CraftBukkit start ++ // world.setTypeUpdate(blockposition1, this.getBlockData()); ++ org.bukkit.World bworld = world.getWorld(); ++ BlockState blockState = bworld.getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()).getState(); ++ blockState.setType(CraftMagicNumbers.getMaterial(this)); ++ ++ BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), blockState); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockNetherWart.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockNetherWart.patch new file mode 100644 index 0000000..79e9888 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockNetherWart.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/server/BlockNetherWart.java ++++ b/net/minecraft/server/BlockNetherWart.java +@@ -29,7 +29,8 @@ + + if (i < 3 && random.nextInt(10) == 0) { + iblockdata = iblockdata.set(BlockNetherWart.AGE, Integer.valueOf(i + 1)); +- world.setTypeAndData(blockposition, iblockdata, 2); ++ // world.setTypeAndData(blockposition, iblockdata, 2); // CraftBukkit ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(iblockdata)); // CraftBukkit + } + + super.b(world, blockposition, iblockdata, random); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockOre.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockOre.patch new file mode 100644 index 0000000..4522722 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockOre.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/server/BlockOre.java ++++ b/net/minecraft/server/BlockOre.java +@@ -37,6 +37,7 @@ + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + super.dropNaturally(world, blockposition, iblockdata, f, i); ++ /* CraftBukkit start - Delegated to getExpDrop + if (this.getDropType(iblockdata, world.random, i) != Item.getItemOf(this)) { + int j = 0; + +@@ -54,9 +55,34 @@ + + this.dropExperience(world, blockposition, j); + } ++ // */ + + } + ++ @Override ++ public int getExpDrop(World world, IBlockData iblockdata, int i) { ++ if (this.getDropType(iblockdata, world.random, i) != Item.getItemOf(this)) { ++ int j = 0; ++ ++ if (this == Blocks.COAL_ORE) { ++ j = MathHelper.nextInt(world.random, 0, 2); ++ } else if (this == Blocks.DIAMOND_ORE) { ++ j = MathHelper.nextInt(world.random, 3, 7); ++ } else if (this == Blocks.EMERALD_ORE) { ++ j = MathHelper.nextInt(world.random, 3, 7); ++ } else if (this == Blocks.LAPIS_ORE) { ++ j = MathHelper.nextInt(world.random, 2, 5); ++ } else if (this == Blocks.QUARTZ_ORE) { ++ j = MathHelper.nextInt(world.random, 2, 5); ++ } ++ ++ return j; ++ } ++ ++ return 0; ++ // CraftBukkit end ++ } ++ + public int getDropData(World world, BlockPosition blockposition) { + return 0; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPiston.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPiston.patch new file mode 100644 index 0000000..b19bcf4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPiston.patch @@ -0,0 +1,102 @@ +--- a/net/minecraft/server/BlockPiston.java ++++ b/net/minecraft/server/BlockPiston.java +@@ -2,6 +2,18 @@ + + import java.util.List; + ++// CraftBukkit start ++import java.util.AbstractList; ++import java.util.Collection; ++import java.util.Iterator; ++import java.util.ListIterator; ++ ++import com.google.common.collect.ImmutableList; ++import org.bukkit.craftbukkit.block.CraftBlock; ++import org.bukkit.event.block.BlockPistonRetractEvent; ++import org.bukkit.event.block.BlockPistonExtendEvent; ++// CraftBukkit end ++ + public class BlockPiston extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing"); +@@ -56,6 +68,17 @@ + world.playBlockAction(blockposition, this, 0, enumdirection.a()); + } + } else if (!flag && ((Boolean) iblockdata.get(BlockPiston.EXTENDED)).booleanValue()) { ++ // CraftBukkit start ++ if (!this.sticky) { ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.of(), CraftBlock.notchToBlockFace(enumdirection)); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, iblockdata.set(BlockPiston.EXTENDED, Boolean.valueOf(false)), 2); + world.playBlockAction(blockposition, this, 1, enumdirection.a()); + } +@@ -146,7 +169,7 @@ + } + } + +- if (!flag1 && block.getMaterial() != Material.AIR && a(block, world, blockposition1, enumdirection.opposite(), false) && (block.k() == 0 || block == Blocks.PISTON || block == Blocks.STICKY_PISTON)) { ++ if (!flag1 && a(block, world, blockposition1, enumdirection.opposite(), false) && (block.k() == 0 || block == Blocks.PISTON || block == Blocks.STICKY_PISTON)) { // CraftBukkit - remove 'block.getMaterial() != Material.AIR' condition + this.a(world, blockposition, enumdirection, false); + } + } else { +@@ -286,10 +309,53 @@ + if (!pistonextendschecker.a()) { + return false; + } else { ++ // CraftBukkit start ++ final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ final List moved = pistonextendschecker.getMovedBlocks(); ++ final List broken = pistonextendschecker.getBrokenBlocks(); ++ ++ List blocks = new AbstractList() { ++ ++ @Override ++ public int size() { ++ return moved.size() + broken.size(); ++ } ++ ++ @Override ++ public org.bukkit.block.Block get(int index) { ++ if (index >= size() || index < 0) { ++ throw new ArrayIndexOutOfBoundsException(index); ++ } ++ BlockPosition pos = (BlockPosition) (index < moved.size() ? moved.get(index) : broken.get(index - moved.size())); ++ return bblock.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ } ++ }; ++ + int i = list.size() + list1.size(); + Block[] ablock = new Block[i]; + EnumDirection enumdirection1 = flag ? enumdirection : enumdirection.opposite(); + ++ org.bukkit.event.block.BlockPistonEvent event; ++ if (flag) { ++ event = new BlockPistonExtendEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1)); ++ } else { ++ event = new BlockPistonRetractEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1)); ++ } ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ for (BlockPosition b : broken) { ++ world.notify(b); ++ } ++ for (BlockPosition b : moved) { ++ world.notify(b); ++ world.notify(b.shift(enumdirection1)); ++ } ++ return false; ++ } ++ // CraftBukkit end ++ + int j; + BlockPosition blockposition1; + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPlant.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPlant.patch new file mode 100644 index 0000000..29fb3af --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPlant.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/server/BlockPlant.java ++++ b/net/minecraft/server/BlockPlant.java +@@ -1,6 +1,10 @@ + package net.minecraft.server; + + import java.util.Random; ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.event.block.BlockPhysicsEvent; ++// CraftBukkit end + + public class BlockPlant extends Block { + +@@ -40,6 +44,15 @@ + + protected void e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!this.f(world, blockposition, iblockdata)) { ++ // CraftBukkit Start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ BlockPhysicsEvent event = new BlockPhysicsEvent(block, block.getTypeId()); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + this.b(world, blockposition, iblockdata, 0); + world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPortal.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPortal.patch new file mode 100644 index 0000000..d3d3a65 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPortal.patch @@ -0,0 +1,144 @@ +--- a/net/minecraft/server/BlockPortal.java ++++ b/net/minecraft/server/BlockPortal.java +@@ -3,6 +3,9 @@ + import com.google.common.cache.LoadingCache; + import java.util.Random; + ++import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit ++import org.bukkit.event.world.PortalCreateEvent; // CraftBukkit ++ + public class BlockPortal extends BlockHalfTransparent { + + public static final BlockStateEnum AXIS = BlockStateEnum.of("axis", EnumDirection.EnumAxis.class, new EnumDirection.EnumAxis[] { EnumDirection.EnumAxis.X, EnumDirection.EnumAxis.Z}); +@@ -25,7 +28,8 @@ + } + + if (i > 0 && !world.getType(blockposition1.up()).getBlock().isOccluding()) { +- Entity entity = ItemMonsterEgg.a(world, 57, (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 1.1D, (double) blockposition1.getZ() + 0.5D); ++ // CraftBukkit - set spawn reason to NETHER_PORTAL ++ Entity entity = ItemMonsterEgg.spawnCreature(world, 57, (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 1.1D, (double) blockposition1.getZ() + 0.5D, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); + + if (entity != null) { + entity.portalCooldown = entity.aq(); +@@ -67,14 +71,16 @@ + BlockPortal.Shape blockportal_shape = new BlockPortal.Shape(world, blockposition, EnumDirection.EnumAxis.X); + + if (blockportal_shape.d() && blockportal_shape.e == 0) { +- blockportal_shape.createPortal(); +- return true; ++ // CraftBukkit start - return portalcreator ++ return blockportal_shape.createPortal(); ++ // return true; + } else { + BlockPortal.Shape blockportal_shape1 = new BlockPortal.Shape(world, blockposition, EnumDirection.EnumAxis.Z); + + if (blockportal_shape1.d() && blockportal_shape1.e == 0) { +- blockportal_shape1.createPortal(); +- return true; ++ return blockportal_shape1.createPortal(); ++ // return true; ++ // CraftBukkit end + } else { + return false; + } +@@ -105,6 +111,10 @@ + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (entity.vehicle == null && entity.passenger == null) { ++ // CraftBukkit start - Entity in portal ++ EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ())); ++ world.getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end + entity.d(blockposition); + } + +@@ -185,6 +195,7 @@ + private BlockPosition position; + private int height; + private int width; ++ java.util.Collection blocks = new java.util.HashSet(); // CraftBukkit - add field + + public Shape(World world, BlockPosition blockposition, EnumDirection.EnumAxis enumdirection_enumaxis) { + this.a = world; +@@ -243,6 +254,10 @@ + } + + protected int c() { ++ // CraftBukkit start ++ this.blocks.clear(); ++ org.bukkit.World bworld = this.a.getWorld(); ++ // CraftBukkit end + int i; + + label56: +@@ -263,11 +278,21 @@ + block = this.a.getType(blockposition.shift(this.d)).getBlock(); + if (block != Blocks.OBSIDIAN) { + break label56; ++ // CraftBukkit start - add the block to our list ++ } else { ++ BlockPosition pos = blockposition.shift(this.d); ++ blocks.add(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ // CraftBukkit end + } + } else if (i == this.width - 1) { + block = this.a.getType(blockposition.shift(this.c)).getBlock(); + if (block != Blocks.OBSIDIAN) { + break label56; ++ // CraftBukkit start - add the block to our list ++ } else { ++ BlockPosition pos = blockposition.shift(this.c); ++ blocks.add(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ // CraftBukkit end + } + } + } +@@ -277,6 +302,11 @@ + if (this.a.getType(this.position.shift(this.c, i).up(this.height)).getBlock() != Blocks.OBSIDIAN) { + this.height = 0; + break; ++ // CraftBukkit start - add the block to our list ++ } else { ++ BlockPosition pos = this.position.shift(this.c, i).up(this.height); ++ blocks.add(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ // CraftBukkit end + } + } + +@@ -298,7 +328,27 @@ + return this.position != null && this.width >= 2 && this.width <= 21 && this.height >= 3 && this.height <= 21; + } + +- public void createPortal() { ++ // CraftBukkit start - return boolean ++ public boolean createPortal() { ++ org.bukkit.World bworld = this.a.getWorld(); ++ ++ // Copy below for loop ++ for (int i = 0; i < this.width; ++i) { ++ BlockPosition blockposition = this.position.shift(this.c, i); ++ ++ for (int j = 0; j < this.height; ++j) { ++ BlockPosition pos = blockposition.up(j); ++ blocks.add(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ } ++ } ++ ++ PortalCreateEvent event = new PortalCreateEvent(blocks, bworld, PortalCreateEvent.CreateReason.FIRE); ++ this.a.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ // CraftBukkit end + for (int i = 0; i < this.width; ++i) { + BlockPosition blockposition = this.position.shift(this.c, i); + +@@ -307,6 +357,7 @@ + } + } + ++ return true; // CraftBukkit + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPoweredRail.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPoweredRail.patch new file mode 100644 index 0000000..61dcda6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPoweredRail.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/server/BlockPoweredRail.java ++++ b/net/minecraft/server/BlockPoweredRail.java +@@ -2,6 +2,8 @@ + + import com.google.common.base.Predicate; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockPoweredRail extends BlockMinecartTrackAbstract { + + public static final BlockStateEnum SHAPE = BlockStateEnum.a("shape", BlockMinecartTrackAbstract.EnumTrackPosition.class, new Predicate() { +@@ -116,6 +118,13 @@ + boolean flag1 = world.isBlockIndirectlyPowered(blockposition) || this.a(world, blockposition, iblockdata, true, 0) || this.a(world, blockposition, iblockdata, false, 0); + + if (flag1 != flag) { ++ // CraftBukkit start ++ int power = (Boolean)iblockdata.get(POWERED) ? 15 : 0; ++ int newPower = CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), power, 15 - power).getNewCurrent(); ++ if (newPower == power) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, iblockdata.set(BlockPoweredRail.POWERED, Boolean.valueOf(flag1)), 3); + world.applyPhysics(blockposition.down(), this); + if (((BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)).c()) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateAbstract.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateAbstract.patch new file mode 100644 index 0000000..1260c22 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateAbstract.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/server/BlockPressurePlateAbstract.java ++++ b/net/minecraft/server/BlockPressurePlateAbstract.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public abstract class BlockPressurePlateAbstract extends Block { + + protected BlockPressurePlateAbstract(Material material) { +@@ -99,6 +101,19 @@ + boolean flag = i > 0; + boolean flag1 = j > 0; + ++ // CraftBukkit start - Interact Pressure Plate ++ org.bukkit.World bworld = world.getWorld(); ++ org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); ++ ++ if (flag != flag1) { ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), i, j); ++ manager.callEvent(eventRedstone); ++ ++ flag1 = eventRedstone.getNewCurrent() > 0; ++ j = eventRedstone.getNewCurrent(); ++ } ++ // CraftBukkit end ++ + if (i != j) { + iblockdata = this.a(iblockdata, j); + world.setTypeAndData(blockposition, iblockdata, 2); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateBinary.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateBinary.patch new file mode 100644 index 0000000..37a87c1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateBinary.patch @@ -0,0 +1,38 @@ +--- a/net/minecraft/server/BlockPressurePlateBinary.java ++++ b/net/minecraft/server/BlockPressurePlateBinary.java +@@ -3,6 +3,8 @@ + import java.util.Iterator; + import java.util.List; + ++import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit ++ + public class BlockPressurePlateBinary extends BlockPressurePlateAbstract { + + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); +@@ -45,6 +47,26 @@ + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + ++ // CraftBukkit start - Call interact event when turning on a pressure plate ++ if (this.e(world.getType(blockposition)) == 0) { ++ org.bukkit.World bworld = world.getWorld(); ++ org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (entity instanceof EntityHuman) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); ++ } else { ++ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); ++ manager.callEvent((EntityInteractEvent) cancellable); ++ } ++ ++ // We only want to block turning the plate on if all events are cancelled ++ if (cancellable.isCancelled()) { ++ continue; ++ } ++ } ++ // CraftBukkit end ++ + if (!entity.aI()) { + return 15; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateWeighted.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateWeighted.patch new file mode 100644 index 0000000..4b1f6e2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPressurePlateWeighted.patch @@ -0,0 +1,43 @@ +--- a/net/minecraft/server/BlockPressurePlateWeighted.java ++++ b/net/minecraft/server/BlockPressurePlateWeighted.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit ++ + public class BlockPressurePlateWeighted extends BlockPressurePlateAbstract { + + public static final BlockStateInteger POWER = BlockStateInteger.of("power", 0, 15); +@@ -16,7 +18,31 @@ + } + + protected int f(World world, BlockPosition blockposition) { +- int i = Math.min(world.a(Entity.class, this.getBoundingBox(blockposition)).size(), this.weight); ++ // CraftBukkit start ++ //int i = Math.min(world.a(Entity.class, this.a(blockposition)).size(), this.b); ++ int i = 0; ++ java.util.Iterator iterator = world.a(Entity.class, this.getBoundingBox(blockposition)).iterator(); ++ ++ while (iterator.hasNext()) { ++ Entity entity = (Entity) iterator.next(); ++ ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (entity instanceof EntityHuman) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); ++ } else { ++ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); ++ world.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); ++ } ++ ++ // We only want to block turning the plate on if all events are cancelled ++ if (!cancellable.isCancelled()) { ++ i++; ++ } ++ } ++ ++ i = Math.min(i, this.weight); ++ // CraftBukkit end + + if (i > 0) { + float f = (float) Math.min(this.weight, i) / (float) this.weight; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPumpkin.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPumpkin.patch new file mode 100644 index 0000000..224b1e9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockPumpkin.patch @@ -0,0 +1,80 @@ +--- a/net/minecraft/server/BlockPumpkin.java ++++ b/net/minecraft/server/BlockPumpkin.java +@@ -2,6 +2,12 @@ + + import com.google.common.base.Predicate; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.BlockStateListPopulator; ++import org.bukkit.event.block.BlockRedstoneEvent; ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; ++// CraftBukkit end ++ + public class BlockPumpkin extends BlockDirectional { + + private ShapeDetector snowGolemPart; +@@ -40,17 +46,24 @@ + int j; + + if ((shapedetector_shapedetectorcollection = this.getDetectorSnowGolem().a(world, blockposition)) != null) { ++ BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld()); // CraftBukkit - Use BlockStateListPopulator + for (i = 0; i < this.getDetectorSnowGolem().b(); ++i) { + ShapeDetectorBlock shapedetectorblock = shapedetector_shapedetectorcollection.a(0, i, 0); + +- world.setTypeAndData(shapedetectorblock.getPosition(), Blocks.AIR.getBlockData(), 2); ++ // CraftBukkit start ++ // world.setTypeAndData(shapedetectorblock.d(), Blocks.AIR.getBlockData(), 2); ++ BlockPosition pos = shapedetectorblock.getPosition(); ++ blockList.setTypeId(pos.getX(), pos.getY(), pos.getZ(), 0); ++ // CraftBukkit end + } + + EntitySnowman entitysnowman = new EntitySnowman(world); + BlockPosition blockposition1 = shapedetector_shapedetectorcollection.a(0, 2, 0).getPosition(); + + entitysnowman.setPositionRotation((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.05D, (double) blockposition1.getZ() + 0.5D, 0.0F, 0.0F); +- world.addEntity(entitysnowman); ++ // CraftBukkit start ++ if (world.addEntity(entitysnowman, SpawnReason.BUILD_SNOWMAN)) { ++ 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]); +@@ -61,10 +74,16 @@ + + world.update(shapedetectorblock1.getPosition(), Blocks.AIR); + } ++ } // CraftBukkit end + } else if ((shapedetector_shapedetectorcollection = this.getDetectorIronGolem().a(world, blockposition)) != null) { ++ BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld()); // CraftBukkit - Use BlockStateListPopulator + for (i = 0; i < this.getDetectorIronGolem().c(); ++i) { + for (int k = 0; k < this.getDetectorIronGolem().b(); ++k) { +- world.setTypeAndData(shapedetector_shapedetectorcollection.a(i, k, 0).getPosition(), Blocks.AIR.getBlockData(), 2); ++ // CraftBukkit start ++ // world.setTypeAndData(shapedetectorcollection.a(i, k, 0).d(), Blocks.AIR.getBlockData(), 2); ++ BlockPosition pos = shapedetector_shapedetectorcollection.a(i, k, 0).getPosition(); ++ blockList.setTypeId(pos.getX(), pos.getY(), pos.getZ(), 0); ++ // CraftBukkit end + } + } + +@@ -73,7 +92,10 @@ + + entityirongolem.setPlayerCreated(true); + entityirongolem.setPositionRotation((double) blockposition2.getX() + 0.5D, (double) blockposition2.getY() + 0.05D, (double) blockposition2.getZ() + 0.5D, 0.0F, 0.0F); +- world.addEntity(entityirongolem); ++ ++ // CraftBukkit start ++ if (world.addEntity(entityirongolem, SpawnReason.BUILD_IRONGOLEM)) { ++ 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]); +@@ -86,6 +108,7 @@ + world.update(shapedetectorblock2.getPosition(), Blocks.AIR); + } + } ++ } // CraftBukkit end + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneLamp.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneLamp.patch new file mode 100644 index 0000000..1aec632 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneLamp.patch @@ -0,0 +1,47 @@ +--- a/net/minecraft/server/BlockRedstoneLamp.java ++++ b/net/minecraft/server/BlockRedstoneLamp.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockRedstoneLamp extends Block { + + private final boolean a; +@@ -20,6 +22,11 @@ + if (this.a && !world.isBlockIndirectlyPowered(blockposition)) { + world.setTypeAndData(blockposition, Blocks.REDSTONE_LAMP.getBlockData(), 2); + } else if (!this.a && world.isBlockIndirectlyPowered(blockposition)) { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 0, 15).getNewCurrent() != 15) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.LIT_REDSTONE_LAMP.getBlockData(), 2); + } + +@@ -31,6 +38,11 @@ + if (this.a && !world.isBlockIndirectlyPowered(blockposition)) { + world.a(blockposition, (Block) this, 4); + } else if (!this.a && world.isBlockIndirectlyPowered(blockposition)) { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 0, 15).getNewCurrent() != 15) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.LIT_REDSTONE_LAMP.getBlockData(), 2); + } + +@@ -40,6 +52,11 @@ + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (this.a && !world.isBlockIndirectlyPowered(blockposition)) { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 15, 0).getNewCurrent() != 0) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.REDSTONE_LAMP.getBlockData(), 2); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneOre.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneOre.patch new file mode 100644 index 0000000..f9614c7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneOre.patch @@ -0,0 +1,101 @@ +--- a/net/minecraft/server/BlockRedstoneOre.java ++++ b/net/minecraft/server/BlockRedstoneOre.java +@@ -2,6 +2,11 @@ + + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityInteractEvent; ++// CraftBukkit end ++ + public class BlockRedstoneOre extends Block { + + private final boolean a; +@@ -20,23 +25,44 @@ + } + + public void attack(World world, BlockPosition blockposition, EntityHuman entityhuman) { +- this.e(world, blockposition); ++ this.e(world, blockposition, entityhuman); // CraftBukkit - add entityhuman + super.attack(world, blockposition, entityhuman); + } + + public void a(World world, BlockPosition blockposition, Entity entity) { +- this.e(world, blockposition); +- super.a(world, blockposition, entity); ++ // CraftBukkit start ++ // this.e(world, blockposition); ++ // super.a(world, blockposition, entity); ++ if (entity instanceof EntityHuman) { ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); ++ if (!event.isCancelled()) { ++ this.e(world, blockposition, entity); // add entity ++ super.a(world, blockposition, entity); ++ } ++ } else { ++ EntityInteractEvent event = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); ++ world.getServer().getPluginManager().callEvent(event); ++ if (!event.isCancelled()) { ++ this.e(world, blockposition, entity); // add entity ++ super.a(world, blockposition, entity); ++ } ++ } ++ // CraftBukkit end + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { +- this.e(world, blockposition); ++ this.e(world, blockposition, entityhuman); // CraftBukkit - add entityhuman + return super.interact(world, blockposition, iblockdata, entityhuman, enumdirection, f, f1, f2); + } + +- private void e(World world, BlockPosition blockposition) { ++ private void e(World world, BlockPosition blockposition, Entity entity) { // CraftBukkit - add Entity + this.f(world, blockposition); + if (this == Blocks.REDSTONE_ORE) { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.LIT_REDSTONE_ORE, 0).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeUpdate(blockposition, Blocks.LIT_REDSTONE_ORE.getBlockData()); + } + +@@ -44,6 +70,11 @@ + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (this == Blocks.LIT_REDSTONE_ORE) { ++ // CraftBukkit start ++ if (CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), Blocks.REDSTONE_ORE).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeUpdate(blockposition, Blocks.REDSTONE_ORE.getBlockData()); + } + +@@ -63,12 +94,24 @@ + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + super.dropNaturally(world, blockposition, iblockdata, f, i); ++ /* CraftBukkit start - Delegated to getExpDrop + if (this.getDropType(iblockdata, world.random, i) != Item.getItemOf(this)) { + int j = 1 + world.random.nextInt(5); + + this.dropExperience(world, blockposition, j); + } ++ // */ ++ } + ++ @Override ++ public int getExpDrop(World world, IBlockData data, int i) { ++ if (this.getDropType(data, world.random, i) != Item.getItemOf(this)) { ++ int j = 1 + world.random.nextInt(5); ++ ++ return j; ++ } ++ return 0; ++ // CraftBukkit end + } + + private void f(World world, BlockPosition blockposition) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneTorch.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneTorch.patch new file mode 100644 index 0000000..2eea0e7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneTorch.patch @@ -0,0 +1,62 @@ +--- a/net/minecraft/server/BlockRedstoneTorch.java ++++ b/net/minecraft/server/BlockRedstoneTorch.java +@@ -6,6 +6,8 @@ + import java.util.Map; + import java.util.Random; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockRedstoneTorch extends BlockTorch { + + private static Map> b = Maps.newHashMap(); +@@ -13,7 +15,7 @@ + + private boolean a(World world, BlockPosition blockposition, boolean flag) { + if (!BlockRedstoneTorch.b.containsKey(world)) { +- BlockRedstoneTorch.b.put(world, Lists.newArrayList()); ++ BlockRedstoneTorch.b.put(world, Lists.newArrayList()); // CraftBukkit - fix decompile error + } + + List list = (List) BlockRedstoneTorch.b.get(world); +@@ -96,8 +98,25 @@ + list.remove(0); + } + ++ // CraftBukkit start ++ org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ int oldCurrent = this.isOn ? 15 : 0; ++ ++ BlockRedstoneEvent event = new BlockRedstoneEvent(block, oldCurrent, oldCurrent); ++ // CraftBukkit end ++ + if (this.isOn) { + if (flag) { ++ // CraftBukkit start ++ if (oldCurrent != 0) { ++ event.setNewCurrent(0); ++ manager.callEvent(event); ++ if (event.getNewCurrent() != 0) { ++ return; ++ } ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.UNLIT_REDSTONE_TORCH.getBlockData().set(BlockRedstoneTorch.FACING, iblockdata.get(BlockRedstoneTorch.FACING)), 3); + if (this.a(world, blockposition, true)) { + world.makeSound((double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), "random.fizz", 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); +@@ -114,6 +133,15 @@ + } + } + } else if (!flag && !this.a(world, blockposition, false)) { ++ // CraftBukkit start ++ if (oldCurrent != 15) { ++ event.setNewCurrent(15); ++ manager.callEvent(event); ++ if (event.getNewCurrent() != 15) { ++ return; ++ } ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.REDSTONE_TORCH.getBlockData().set(BlockRedstoneTorch.FACING, iblockdata.get(BlockRedstoneTorch.FACING)), 3); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneWire.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneWire.patch new file mode 100644 index 0000000..ffd86e1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockRedstoneWire.patch @@ -0,0 +1,27 @@ +--- a/net/minecraft/server/BlockRedstoneWire.java ++++ b/net/minecraft/server/BlockRedstoneWire.java +@@ -8,6 +8,8 @@ + import java.util.Random; + import java.util.Set; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockRedstoneWire extends Block { + + public static final BlockStateEnum NORTH = BlockStateEnum.of("north", BlockRedstoneWire.EnumRedstoneWireConnection.class); +@@ -124,6 +126,15 @@ + j = k; + } + ++ // CraftBukkit start ++ if (i != j) { ++ BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), i, j); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ j = event.getNewCurrent(); ++ } ++ // CraftBukkit end ++ + if (i != j) { + iblockdata = iblockdata.set(BlockRedstoneWire.POWER, Integer.valueOf(j)); + if (world.getType(blockposition) == iblockdata1) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockReed.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockReed.patch new file mode 100644 index 0000000..6b9939e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockReed.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/server/BlockReed.java ++++ b/net/minecraft/server/BlockReed.java +@@ -29,8 +29,12 @@ + int j = ((Integer) iblockdata.get(BlockReed.AGE)).intValue(); + + if (j == 15) { +- world.setTypeUpdate(blockposition.up(), this.getBlockData()); ++ // CraftBukkit start ++ // world.setTypeUpdate(blockposition.up(), this.getBlockData()); // CraftBukkit ++ BlockPosition upPos = blockposition.up(); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, upPos.getX(), upPos.getY(), upPos.getZ(), this, 0); + world.setTypeAndData(blockposition, iblockdata.set(BlockReed.AGE, Integer.valueOf(0)), 4); ++ // CraftBukkit end + } else { + world.setTypeAndData(blockposition, iblockdata.set(BlockReed.AGE, Integer.valueOf(j + 1)), 4); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSapling.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSapling.patch new file mode 100644 index 0000000..bdb4074 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSapling.patch @@ -0,0 +1,125 @@ +--- a/net/minecraft/server/BlockSapling.java ++++ b/net/minecraft/server/BlockSapling.java +@@ -2,10 +2,20 @@ + + import java.util.Random; + ++// CraftBukkit start ++import java.util.List; ++ ++import org.bukkit.Location; ++import org.bukkit.TreeType; ++import org.bukkit.block.BlockState; ++import org.bukkit.event.world.StructureGrowEvent; ++// CraftBukkit end ++ + public class BlockSapling extends BlockPlant implements IBlockFragilePlantElement { + + public static final BlockStateEnum TYPE = BlockStateEnum.of("type", BlockWood.EnumLogVariant.class); + public static final BlockStateInteger STAGE = BlockStateInteger.of("stage", 0, 1); ++ public static TreeType treeType; // CraftBukkit + + protected BlockSapling() { + this.j(this.blockStateList.getBlockData().set(BlockSapling.TYPE, BlockWood.EnumLogVariant.OAK).set(BlockSapling.STAGE, Integer.valueOf(0))); +@@ -23,7 +33,30 @@ + if (!world.isClientSide) { + super.b(world, blockposition, iblockdata, random); + if (world.getLightLevel(blockposition.up()) >= 9 && random.nextInt(7) == 0) { ++ // CraftBukkit start ++ world.captureTreeGeneration = true; ++ // CraftBukkit end + this.grow(world, blockposition, iblockdata, random); ++ // CraftBukkit start ++ world.captureTreeGeneration = false; ++ if (world.capturedBlockStates.size() > 0) { ++ TreeType treeType = BlockSapling.treeType; ++ BlockSapling.treeType = null; ++ Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ List blocks = (List) world.capturedBlockStates.clone(); ++ world.capturedBlockStates.clear(); ++ StructureGrowEvent event = null; ++ if (treeType != null) { ++ event = new StructureGrowEvent(location, treeType, false, null, blocks); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ } ++ if (event == null || !event.isCancelled()) { ++ for (BlockState blockstate : blocks) { ++ blockstate.update(true); ++ } ++ } ++ } ++ // CraftBukkit end + } + + } +@@ -39,7 +72,17 @@ + } + + public void e(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { +- Object object = random.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true); ++ // CraftBukkit start - Turn ternary operator into if statement to set treeType ++ // Object object = random.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true); ++ Object object; ++ if (random.nextInt(10) == 0) { ++ treeType = TreeType.BIG_TREE; ++ object = new WorldGenBigTree(true); ++ } else { ++ treeType = TreeType.TREE; ++ object = new WorldGenTrees(true); ++ } ++ // CraftBukkit end + int i = 0; + int j = 0; + boolean flag = false; +@@ -51,6 +94,7 @@ + for (i = 0; i >= -1; --i) { + for (j = 0; j >= -1; --j) { + if (this.a(world, blockposition, i, j, BlockWood.EnumLogVariant.SPRUCE)) { ++ treeType = TreeType.MEGA_REDWOOD; // CraftBukkit + object = new WorldGenMegaTree(false, random.nextBoolean()); + flag = true; + break label66; +@@ -61,11 +105,13 @@ + if (!flag) { + j = 0; + i = 0; ++ treeType = TreeType.REDWOOD; // CraftBukkit + object = new WorldGenTaiga2(true); + } + break; + + case 2: ++ treeType = TreeType.BIRCH; // CraftBukkit + object = new WorldGenForest(true, false); + break; + +@@ -77,6 +123,7 @@ + for (i = 0; i >= -1; --i) { + for (j = 0; j >= -1; --j) { + if (this.a(world, blockposition, i, j, BlockWood.EnumLogVariant.JUNGLE)) { ++ treeType = TreeType.JUNGLE; // CraftBukkit + object = new WorldGenJungleTree(true, 10, 20, iblockdata1, iblockdata2); + flag = true; + break label78; +@@ -87,11 +134,13 @@ + if (!flag) { + j = 0; + i = 0; ++ treeType = TreeType.SMALL_JUNGLE; // CraftBukkit + object = new WorldGenTrees(true, 4 + random.nextInt(7), iblockdata1, iblockdata2, false); + } + break; + + case 4: ++ treeType = TreeType.ACACIA; // CraftBukkit + object = new WorldGenAcaciaTree(true); + break; + +@@ -100,6 +149,7 @@ + for (i = 0; i >= -1; --i) { + for (j = 0; j >= -1; --j) { + if (this.a(world, blockposition, i, j, BlockWood.EnumLogVariant.DARK_OAK)) { ++ treeType = TreeType.DARK_OAK; // CraftBukkit + object = new WorldGenForestTree(true); + flag = true; + break label90; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSkull.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSkull.patch new file mode 100644 index 0000000..84c1dc2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSkull.patch @@ -0,0 +1,120 @@ +--- a/net/minecraft/server/BlockSkull.java ++++ b/net/minecraft/server/BlockSkull.java +@@ -4,6 +4,11 @@ + import java.util.Iterator; + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.BlockStateListPopulator; ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; ++// CraftBukkit end ++ + public class BlockSkull extends BlockContainer { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing"); +@@ -81,8 +86,26 @@ + + return tileentity instanceof TileEntitySkull ? ((TileEntitySkull) tileentity).getSkullType() : super.getDropData(world, blockposition); + } ++ ++ // CraftBukkit start - Special case dropping so we can get info from the tile entity ++ @Override ++ public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { ++ if (world.random.nextFloat() < f) { ++ ItemStack itemstack = new ItemStack(Items.SKULL, 1, this.getDropData(world, blockposition)); ++ TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(blockposition); ++ ++ if (tileentityskull.getSkullType() == 3 && tileentityskull.getGameProfile() != null) { ++ itemstack.setTag(new NBTTagCompound()); ++ NBTTagCompound nbttagcompound = new NBTTagCompound(); ++ ++ GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile()); ++ itemstack.getTag().set("SkullOwner", nbttagcompound); ++ } + +- public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) {} ++ a(world, blockposition, itemstack); ++ } ++ } ++ // CraftBukkit end + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { + if (entityhuman.abilities.canInstantlyBuild) { +@@ -95,7 +118,10 @@ + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!world.isClientSide) { +- if (!((Boolean) iblockdata.get(BlockSkull.NODROP)).booleanValue()) { ++ // CraftBukkit start - Drop item in code above, not here ++ // if (!((Boolean) iblockdata.get(BlockSkull.NODROP)).booleanValue()) { ++ if (false) { ++ // CraftBukkit end + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntitySkull) { +@@ -127,24 +153,36 @@ + } + + public void a(World world, BlockPosition blockposition, TileEntitySkull tileentityskull) { ++ if (world.captureBlockStates) return; // CraftBukkit + if (tileentityskull.getSkullType() == 1 && blockposition.getY() >= 2 && world.getDifficulty() != EnumDifficulty.PEACEFUL && !world.isClientSide) { + ShapeDetector shapedetector = this.n(); + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = shapedetector.a(world, blockposition); + + if (shapedetector_shapedetectorcollection != null) { ++ // CraftBukkit start - Use BlockStateListPopulator ++ BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld()); + int i; + + for (i = 0; i < 3; ++i) { + ShapeDetectorBlock shapedetectorblock = shapedetector_shapedetectorcollection.a(i, 0, 0); + +- world.setTypeAndData(shapedetectorblock.getPosition(), shapedetectorblock.a().set(BlockSkull.NODROP, Boolean.valueOf(true)), 2); ++ // CraftBukkit start ++ // world.setTypeAndData(shapedetectorblock.getPosition(), shapedetectorblock.a().set(BlockSkull.NODROP, Boolean.valueOf(true)), 2); ++ BlockPosition pos = shapedetectorblock.getPosition(); ++ IBlockData data = shapedetectorblock.a().set(BlockSkull.NODROP, Boolean.valueOf(true)); ++ blockList.setTypeAndData(pos.getX(), pos.getY(), pos.getZ(), data.getBlock(), data.getBlock().toLegacyData(data), 2); ++ // CraftBukkit end + } + + for (i = 0; i < shapedetector.c(); ++i) { + for (int j = 0; j < shapedetector.b(); ++j) { + ShapeDetectorBlock shapedetectorblock1 = shapedetector_shapedetectorcollection.a(i, j, 0); + +- world.setTypeAndData(shapedetectorblock1.getPosition(), Blocks.AIR.getBlockData(), 2); ++ // CraftBukkit start ++ // world.setTypeAndData(shapedetectorblock1.getPosition(), Blocks.AIR.getBlockData(), 2); ++ BlockPosition pos = shapedetectorblock1.getPosition(); ++ blockList.setTypeAndData(pos.getX(), pos.getY(), pos.getZ(), Blocks.AIR, 0, 2); ++ // CraftBukkit end + } + } + +@@ -157,14 +195,16 @@ + entitywither.n(); + Iterator iterator = world.a(EntityHuman.class, entitywither.getBoundingBox().grow(50.0D, 50.0D, 50.0D)).iterator(); + ++ // CraftBukkit start ++ if (world.addEntity(entitywither, SpawnReason.BUILD_WITHER)) { ++ blockList.updateList(); ++ + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + entityhuman.b((Statistic) AchievementList.I); + } + +- world.addEntity(entitywither); +- + int k; + + for (k = 0; k < 120; ++k) { +@@ -178,6 +218,7 @@ + world.update(shapedetectorblock2.getPosition(), Blocks.AIR); + } + } ++ } // CraftBukkit end + + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSnow.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSnow.patch new file mode 100644 index 0000000..19b864a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSnow.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/server/BlockSnow.java ++++ b/net/minecraft/server/BlockSnow.java +@@ -85,6 +85,11 @@ + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (world.b(EnumSkyBlock.BLOCK, blockposition) > 11) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), Blocks.AIR).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + this.b(world, blockposition, world.getType(blockposition), 0); + world.setAir(blockposition); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSoil.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSoil.patch new file mode 100644 index 0000000..6490edd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockSoil.patch @@ -0,0 +1,64 @@ +--- a/net/minecraft/server/BlockSoil.java ++++ b/net/minecraft/server/BlockSoil.java +@@ -3,6 +3,11 @@ + import java.util.Iterator; + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityInteractEvent; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++// CraftBukkit end ++ + public class BlockSoil extends Block { + + public static final BlockStateInteger MOISTURE = BlockStateInteger.of("moisture", 0, 7); +@@ -34,6 +39,12 @@ + if (i > 0) { + world.setTypeAndData(blockposition, iblockdata.set(BlockSoil.MOISTURE, Integer.valueOf(i - 1)), 2); + } else if (!this.e(world, blockposition)) { ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ if (CraftEventFactory.callBlockFadeEvent(block, Blocks.DIRT).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); + } + } else if (i < 7) { +@@ -43,16 +54,35 @@ + } + + public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { ++ super.fallOn(world, blockposition, entity, f); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. + if (entity instanceof EntityLiving) { + if (!world.isClientSide && world.random.nextFloat() < f - 0.5F) { + if (!(entity instanceof EntityHuman) && !world.getGameRules().getBoolean("mobGriefing")) { + return; + } + ++ // CraftBukkit start - Interact soil ++ org.bukkit.event.Cancellable cancellable; ++ if (entity instanceof EntityHuman) { ++ cancellable = CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); ++ } else { ++ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); ++ world.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); ++ } ++ ++ if (cancellable.isCancelled()) { ++ return; ++ } ++ ++ if (CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.DIRT, 0).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ + world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); + } + +- super.fallOn(world, blockposition, entity, f); ++ // super.fallOn(world, blockposition, entity, f); // CraftBukkit - moved up + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockStationary.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockStationary.patch new file mode 100644 index 0000000..f58767b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockStationary.patch @@ -0,0 +1,40 @@ +--- a/net/minecraft/server/BlockStationary.java ++++ b/net/minecraft/server/BlockStationary.java +@@ -2,6 +2,8 @@ + + import java.util.Random; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockStationary extends BlockFluids { + + protected BlockStationary(Material material) { +@@ -41,6 +43,13 @@ + + if (block.material == Material.AIR) { + if (this.f(world, blockposition1)) { ++ // CraftBukkit start - Prevent lava putting something on fire ++ if (world.getType(blockposition1) != Blocks.FIRE) { ++ if (CraftEventFactory.callBlockIgniteEvent(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), blockposition.getX(), blockposition.getY(), blockposition.getZ()).isCancelled()) { ++ continue; ++ } ++ } ++ // CraftBukkit end + world.setTypeUpdate(blockposition1, Blocks.FIRE.getBlockData()); + return; + } +@@ -53,6 +62,14 @@ + BlockPosition blockposition2 = blockposition.a(random.nextInt(3) - 1, 0, random.nextInt(3) - 1); + + if (world.isEmpty(blockposition2.up()) && this.m(world, blockposition2)) { ++ // CraftBukkit start - Prevent lava putting something on fire ++ BlockPosition up = blockposition2.up(); ++ if (world.getType(up) != Blocks.FIRE) { ++ if (CraftEventFactory.callBlockIgniteEvent(world, up.getX(), up.getY(), up.getZ(), blockposition.getX(), blockposition.getY(), blockposition.getZ()).isCancelled()) { ++ continue; ++ } ++ } ++ // CraftBukkit end + world.setTypeUpdate(blockposition2.up(), Blocks.FIRE.getBlockData()); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockStem.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockStem.patch new file mode 100644 index 0000000..df06ccf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockStem.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/server/BlockStem.java ++++ b/net/minecraft/server/BlockStem.java +@@ -4,6 +4,8 @@ + import java.util.Iterator; + import java.util.Random; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockStem extends BlockPlant implements IBlockFragilePlantElement { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 7); +@@ -58,7 +60,8 @@ + + if (i < 7) { + iblockdata = iblockdata.set(BlockStem.AGE, Integer.valueOf(i + 1)); +- world.setTypeAndData(blockposition, iblockdata, 2); ++ // world.setTypeAndData(blockposition, iblockdata, 2); // CraftBukkit ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(iblockdata)); // CraftBukkit + } else { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + +@@ -74,7 +77,8 @@ + Block block = world.getType(blockposition.down()).getBlock(); + + if (world.getType(blockposition).getBlock().material == Material.AIR && (block == Blocks.FARMLAND || block == Blocks.DIRT || block == Blocks.GRASS)) { +- world.setTypeUpdate(blockposition, this.blockFruit.getBlockData()); ++ // world.setTypeUpdate(blockposition, this.blockFruit.getBlockData()); // CraftBukkit ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.blockFruit, 0); // CraftBukkit + } + } + } +@@ -85,7 +89,8 @@ + public void g(World world, BlockPosition blockposition, IBlockData iblockdata) { + int i = ((Integer) iblockdata.get(BlockStem.AGE)).intValue() + MathHelper.nextInt(world.random, 2, 5); + +- world.setTypeAndData(blockposition, iblockdata.set(BlockStem.AGE, Integer.valueOf(Math.min(7, i))), 2); ++ // world.setTypeAndData(blockposition, iblockdata.set(BlockStem.AGE, Integer.valueOf(Math.min(7, i))), 2); ++ CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, Math.min(7, i)); // CraftBukkit + } + + public void j() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTrapdoor.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTrapdoor.patch new file mode 100644 index 0000000..595644f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTrapdoor.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/server/BlockTrapdoor.java ++++ b/net/minecraft/server/BlockTrapdoor.java +@@ -2,6 +2,8 @@ + + import com.google.common.base.Predicate; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockTrapdoor extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirection.EnumDirectionLimit.HORIZONTAL); +@@ -101,6 +103,19 @@ + boolean flag = world.isBlockIndirectlyPowered(blockposition); + + if (flag || block.isPowerSource()) { ++ // CraftBukkit start ++ org.bukkit.World bworld = world.getWorld(); ++ org.bukkit.block.Block bblock = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ int power = bblock.getBlockPower(); ++ int oldPower = (Boolean) iblockdata.get(OPEN) ? 15 : 0; ++ ++ if (oldPower == 0 ^ power == 0 || block.isPowerSource()) { ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bblock, oldPower, power); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ flag = eventRedstone.getNewCurrent() > 0; ++ } ++ // CraftBukkit end + boolean flag1 = ((Boolean) iblockdata.get(BlockTrapdoor.OPEN)).booleanValue(); + + if (flag1 != flag) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTripwire.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTripwire.patch new file mode 100644 index 0000000..524e1a7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTripwire.patch @@ -0,0 +1,52 @@ +--- a/net/minecraft/server/BlockTripwire.java ++++ b/net/minecraft/server/BlockTripwire.java +@@ -4,6 +4,8 @@ + import java.util.List; + import java.util.Random; + ++import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit ++ + public class BlockTripwire extends Block { + + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); +@@ -155,6 +157,40 @@ + } + } + ++ // CraftBukkit start - Call interact even when triggering connected tripwire ++ if (flag != flag1 && flag1 && (Boolean)iblockdata.get(ATTACHED)) { ++ org.bukkit.World bworld = world.getWorld(); ++ org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); ++ org.bukkit.block.Block block = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ boolean allowed = false; ++ ++ // If all of the events are cancelled block the tripwire trigger, else allow ++ for (Object object : list) { ++ if (object != null) { ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (object instanceof EntityHuman) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) object, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); ++ } else if (object instanceof Entity) { ++ cancellable = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block); ++ manager.callEvent((EntityInteractEvent) cancellable); ++ } else { ++ continue; ++ } ++ ++ if (!cancellable.isCancelled()) { ++ allowed = true; ++ break; ++ } ++ } ++ } ++ ++ if (!allowed) { ++ return; ++ } ++ } ++ // CraftBukkit end ++ + if (flag1 != flag) { + iblockdata = iblockdata.set(BlockTripwire.POWERED, Boolean.valueOf(flag1)); + world.setTypeAndData(blockposition, iblockdata, 3); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTripwireHook.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTripwireHook.patch new file mode 100644 index 0000000..d67644a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockTripwireHook.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/server/BlockTripwireHook.java ++++ b/net/minecraft/server/BlockTripwireHook.java +@@ -5,6 +5,8 @@ + import java.util.Iterator; + import java.util.Random; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockTripwireHook extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirection.EnumDirectionLimit.HORIZONTAL); +@@ -141,6 +143,17 @@ + this.a(world, blockposition1, flag5, flag6, flag2, flag3); + } + ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() > 0) { ++ return; ++ } ++ // CraftBukkit end ++ + this.a(world, blockposition, flag5, flag6, flag2, flag3); + if (!flag) { + world.setTypeAndData(blockposition, iblockdata3.set(BlockTripwireHook.FACING, enumdirection), 3); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockVine.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockVine.patch new file mode 100644 index 0000000..e377c24 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/BlockVine.patch @@ -0,0 +1,75 @@ +--- a/net/minecraft/server/BlockVine.java ++++ b/net/minecraft/server/BlockVine.java +@@ -3,6 +3,8 @@ + import java.util.Iterator; + import java.util.Random; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockVine extends Block { + + public static final BlockStateBoolean UP = BlockStateBoolean.of("up"); +@@ -200,7 +202,13 @@ + } + + if (((Boolean) iblockdata1.get(BlockVine.NORTH)).booleanValue() || ((Boolean) iblockdata1.get(BlockVine.EAST)).booleanValue() || ((Boolean) iblockdata1.get(BlockVine.SOUTH)).booleanValue() || ((Boolean) iblockdata1.get(BlockVine.WEST)).booleanValue()) { +- world.setTypeAndData(blockposition1, iblockdata1, 2); ++ // CraftBukkit start - Call BlockSpreadEvent ++ // world.setTypeAndData(blockposition1, iblockdata1, 2); ++ BlockPosition target = blockposition1; ++ org.bukkit.block.Block source = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(target.getX(), target.getY(), target.getZ()); ++ CraftEventFactory.handleBlockSpreadEvent(block, source, this, toLegacyData(iblockdata1)); ++ // CraftBukkit end + } + + } +@@ -220,17 +228,29 @@ + BlockPosition blockposition3 = blockposition2.shift(enumdirection1); + BlockPosition blockposition4 = blockposition2.shift(enumdirection2); + ++ // CraftBukkit start - Call BlockSpreadEvent ++ org.bukkit.block.Block source = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()); ++ + if (flag1 && this.c(world.getType(blockposition3).getBlock())) { +- world.setTypeAndData(blockposition2, this.getBlockData().set(getDirection(enumdirection1), Boolean.valueOf(true)), 2); ++ // world.setTypeAndData(blockposition2, this.getBlockData().set(a(enumdirection1), Boolean.valueOf(true)), 2); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData().set(getDirection(enumdirection1), Boolean.valueOf(true)))); + } else if (flag2 && this.c(world.getType(blockposition4).getBlock())) { +- world.setTypeAndData(blockposition2, this.getBlockData().set(getDirection(enumdirection2), Boolean.valueOf(true)), 2); ++ // world.setTypeAndData(blockposition2, this.getBlockData().set(a(enumdirection2), Boolean.valueOf(true)), 2); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData().set(getDirection(enumdirection2), Boolean.valueOf(true)))); + } else if (flag1 && world.isEmpty(blockposition3) && this.c(world.getType(blockposition.shift(enumdirection1)).getBlock())) { +- world.setTypeAndData(blockposition3, this.getBlockData().set(getDirection(enumdirection.opposite()), Boolean.valueOf(true)), 2); ++ // world.setTypeAndData(blockposition3, this.getBlockData().set(a(enumdirection.opposite()), Boolean.valueOf(true)), 2); ++ bukkitBlock = world.getWorld().getBlockAt(blockposition3.getX(), blockposition3.getY(), blockposition3.getZ()); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData().set(getDirection(enumdirection.opposite()), Boolean.valueOf(true)))); + } else if (flag2 && world.isEmpty(blockposition4) && this.c(world.getType(blockposition.shift(enumdirection2)).getBlock())) { +- world.setTypeAndData(blockposition4, this.getBlockData().set(getDirection(enumdirection.opposite()), Boolean.valueOf(true)), 2); ++ // world.setTypeAndData(blockposition4, this.getBlockData().set(a(enumdirection.opposite()), Boolean.valueOf(true)), 2); ++ bukkitBlock = world.getWorld().getBlockAt(blockposition4.getX(), blockposition4.getY(), blockposition4.getZ()); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData().set(getDirection(enumdirection.opposite()), Boolean.valueOf(true)))); + } else if (this.c(world.getType(blockposition2.up()).getBlock())) { +- world.setTypeAndData(blockposition2, this.getBlockData(), 2); ++ // world.setTypeAndData(blockposition2, this.getBlockData(), 2); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData())); + } ++ // CraftBukkit end + } else if (block.material.k() && block.d()) { + world.setTypeAndData(blockposition, iblockdata.set(getDirection(enumdirection), Boolean.valueOf(true)), 2); + } +@@ -257,7 +277,12 @@ + } + + if (((Boolean) iblockdata3.get(BlockVine.NORTH)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.EAST)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.SOUTH)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.WEST)).booleanValue()) { +- world.setTypeAndData(blockposition2, iblockdata3, 2); ++ // CraftBukkit start - Call BlockSpreadEvent ++ // world.setTypeAndData(blockposition2, iblockdata3, 2); ++ org.bukkit.block.Block source = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(iblockdata3)); ++ // CraftBukkit end + } + } else if (block1 == this) { + iblockdata3 = iblockdata2; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChatBaseComponent.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChatBaseComponent.patch new file mode 100644 index 0000000..308ddf9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChatBaseComponent.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/ChatBaseComponent.java ++++ b/net/minecraft/server/ChatBaseComponent.java +@@ -111,7 +111,7 @@ + } + + public int hashCode() { +- return 31 * this.b.hashCode() + this.a.hashCode(); ++ return 31 * this.getChatModifier().hashCode() + this.a.hashCode(); // CraftBukkit - fix null pointer + } + + public String toString() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChatModifier.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChatModifier.patch new file mode 100644 index 0000000..a91ca87 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChatModifier.patch @@ -0,0 +1,44 @@ +--- a/net/minecraft/server/ChatModifier.java ++++ b/net/minecraft/server/ChatModifier.java +@@ -254,16 +254,18 @@ + } + + public int hashCode() { +- int i = this.b.hashCode(); ++ // CraftBukkit start - fix npe ++ int i = b == null ? 0 : this.b.hashCode(); + +- i = 31 * i + this.c.hashCode(); +- i = 31 * i + this.d.hashCode(); +- i = 31 * i + this.e.hashCode(); +- i = 31 * i + this.f.hashCode(); +- i = 31 * i + this.g.hashCode(); +- i = 31 * i + this.h.hashCode(); +- i = 31 * i + this.i.hashCode(); +- i = 31 * i + this.j.hashCode(); ++ i = 31 * i + (c == null ? 0 : this.c.hashCode()); ++ i = 31 * i + (d == null ? 0 : this.d.hashCode()); ++ i = 31 * i + (e == null ? 0 : this.e.hashCode()); ++ i = 31 * i + (f == null ? 0 : this.f.hashCode()); ++ i = 31 * i + (g == null ? 0 : this.g.hashCode()); ++ i = 31 * i + (h == null ? 0 : this.h.hashCode()); ++ i = 31 * i + (this.i == null ? 0 : this.i.hashCode()); ++ i = 31 * i + (j == null ? 0 : this.j.hashCode()); ++ // CraftBukkit end + return i; + } + +@@ -429,11 +431,11 @@ + } + } + +- public JsonElement serialize(Object object, Type type, JsonSerializationContext jsonserializationcontext) { ++ public JsonElement serialize(ChatModifier object, Type type, JsonSerializationContext jsonserializationcontext) { // CraftBukkit - fix decompile error + return this.a((ChatModifier) object, type, jsonserializationcontext); + } + +- public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { ++ public ChatModifier deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { // CraftBukkit - fix decompile error + return this.a(jsonelement, type, jsondeserializationcontext); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Chunk.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Chunk.patch new file mode 100644 index 0000000..9ccf30c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Chunk.patch @@ -0,0 +1,153 @@ +--- a/net/minecraft/server/Chunk.java ++++ b/net/minecraft/server/Chunk.java +@@ -14,6 +14,9 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import com.google.common.collect.Lists; // CraftBukkit ++import org.bukkit.Bukkit; // CraftBukkit ++ + public class Chunk { + + private static final Logger c = LogManager.getLogger(); +@@ -40,6 +43,34 @@ + private int v; + private ConcurrentLinkedQueue w; + ++ // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking ++ private int neighbors = 0x1 << 12; ++ ++ public boolean areNeighborsLoaded(final int radius) { ++ switch (radius) { ++ case 2: ++ return this.neighbors == Integer.MAX_VALUE >> 6; ++ case 1: ++ final int mask = ++ // x z offset x z offset x z offset ++ (0x1 << (1 * 5 + 1 + 12)) | (0x1 << (0 * 5 + 1 + 12)) | (0x1 << (-1 * 5 + 1 + 12)) | ++ (0x1 << (1 * 5 + 0 + 12)) | (0x1 << (0 * 5 + 0 + 12)) | (0x1 << (-1 * 5 + 0 + 12)) | ++ (0x1 << (1 * 5 + -1 + 12)) | (0x1 << (0 * 5 + -1 + 12)) | (0x1 << (-1 * 5 + -1 + 12)); ++ return (this.neighbors & mask) == mask; ++ default: ++ throw new UnsupportedOperationException(String.valueOf(radius)); ++ } ++ } ++ ++ public void setNeighborLoaded(final int x, final int z) { ++ this.neighbors |= 0x1 << (x * 5 + 12 + z); ++ } ++ ++ public void setNeighborUnloaded(final int x, final int z) { ++ this.neighbors &= ~(0x1 << (x * 5 + 12 + z)); ++ } ++ // CraftBukkit end ++ + public Chunk(World world, int i, int j) { + this.sections = new ChunkSection[16]; + this.e = new byte[256]; +@@ -60,8 +91,17 @@ + + Arrays.fill(this.f, -999); + Arrays.fill(this.e, (byte) -1); ++ ++ // CraftBukkit start ++ if (!(this instanceof EmptyChunk)) { ++ this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); ++ } + } + ++ public org.bukkit.Chunk bukkitChunk; ++ public boolean mustSave; ++ // CraftBukkit end ++ + public Chunk(World world, ChunkSnapshot chunksnapshot, int i, int j) { + this(world, i, j); + short short0 = 256; +@@ -529,7 +569,8 @@ + } + } + +- if (!this.world.isClientSide && block1 != block) { ++ // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. ++ if (!this.world.isClientSide && block1 != block && (!this.world.captureBlockStates || block instanceof BlockContainer)) { + block.onPlace(this.world, blockposition, iblockdata); + } + +@@ -610,7 +651,11 @@ + int j = MathHelper.floor(entity.locZ / 16.0D); + + if (i != this.locX || j != this.locZ) { +- Chunk.c.warn("Wrong location! (" + i + ", " + j + ") should be (" + this.locX + ", " + this.locZ + "), " + entity, new Object[] { entity}); ++ // CraftBukkit start ++ Bukkit.getLogger().warning("Wrong location for " + entity + " in world '" + world.getWorld().getName() + "'!"); ++ // Chunk.c.warn("Wrong location! (" + i + ", " + j + ") should be (" + this.locX + ", " + this.locZ + "), " + entity, new Object[] { entity}); ++ Bukkit.getLogger().warning("Entity is at " + entity.locX + "," + entity.locZ + " (chunk " + i + "," + j + ") but was stored in chunk " + this.locX + "," + this.locZ); ++ // CraftBukkit end + entity.die(); + } + +@@ -662,7 +707,15 @@ + } + + public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) { +- TileEntity tileentity = (TileEntity) this.tileEntities.get(blockposition); ++ // CraftBukkit start ++ TileEntity tileentity = null; ++ if (world.captureBlockStates) { ++ tileentity = world.capturedTileEntities.get(blockposition); ++ } ++ if (tileentity == null) { ++ tileentity = (TileEntity) this.tileEntities.get(blockposition); ++ } ++ // CraftBukkit end + + if (tileentity == null) { + if (chunk_enumtileentitystate == Chunk.EnumTileEntityState.IMMEDIATE) { +@@ -697,6 +750,13 @@ + + tileentity.D(); + this.tileEntities.put(blockposition, tileentity); ++ // CraftBukkit start ++ } else { ++ System.out.println("Attempted to place a tile entity (" + tileentity + ") at " + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ() ++ + " (" + org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(getType(blockposition)) + ") where there was no entity tile!"); ++ System.out.println("Chunk coordinates: " + (this.locX * 16) + "," + (this.locZ * 16)); ++ new Exception().printStackTrace(); ++ // CraftBukkit end + } + } + +@@ -740,7 +800,21 @@ + } + + for (int i = 0; i < this.entitySlices.length; ++i) { +- this.world.c((Collection) this.entitySlices[i]); ++ // CraftBukkit start ++ List newList = Lists.newArrayList(this.entitySlices[i]); ++ java.util.Iterator iter = newList.iterator(); ++ while (iter.hasNext()) { ++ Entity entity = iter.next(); ++ ++ // Do not pass along players, as doing so can get them stuck outside of time. ++ // (which for example disables inventory icon updates and prevents block breaking) ++ if (entity instanceof EntityPlayer) { ++ iter.remove(); ++ } ++ } ++ ++ this.world.c((Collection) newList); ++ // CraftBukkit end + } + + } +@@ -798,8 +872,8 @@ + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + +- if (entity.getBoundingBox().b(axisalignedbb) && (predicate == null || predicate.apply(entity))) { +- list.add(entity); ++ if (entity.getBoundingBox().b(axisalignedbb) && (predicate == null || predicate.apply((T) entity))) { // CraftBukkit - fix decompile error ++ list.add((T) entity); // Fix decompile error + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkProviderServer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkProviderServer.patch new file mode 100644 index 0000000..65c2167 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkProviderServer.patch @@ -0,0 +1,327 @@ +--- a/net/minecraft/server/ChunkProviderServer.java ++++ b/net/minecraft/server/ChunkProviderServer.java +@@ -11,16 +11,27 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.util.Random; ++import java.util.logging.Level; ++ ++import org.bukkit.Server; ++import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; ++import org.bukkit.craftbukkit.util.LongHash; ++import org.bukkit.craftbukkit.util.LongHashSet; ++import org.bukkit.craftbukkit.util.LongObjectHashMap; ++import org.bukkit.event.world.ChunkUnloadEvent; ++// CraftBukkit end ++ + public class ChunkProviderServer implements IChunkProvider { + + private static final Logger b = LogManager.getLogger(); +- private Set unloadQueue = Collections.newSetFromMap(new ConcurrentHashMap()); ++ public LongHashSet unloadQueue = new LongHashSet(); // CraftBukkit - LongHashSet + public Chunk emptyChunk; + public IChunkProvider chunkProvider; + private IChunkLoader chunkLoader; +- public boolean forceChunkLoad = true; +- private LongHashMap chunks = new LongHashMap(); +- private List chunkList = Lists.newArrayList(); ++ public boolean forceChunkLoad = false; // CraftBukkit - true -> false ++ public LongObjectHashMap chunks = new LongObjectHashMap(); + public WorldServer world; + + public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, IChunkProvider ichunkprovider) { +@@ -31,26 +42,43 @@ + } + + public boolean isChunkLoaded(int i, int j) { +- return this.chunks.contains(ChunkCoordIntPair.a(i, j)); ++ return this.chunks.containsKey(LongHash.toLong(i, j)); // CraftBukkit + } + +- public List a() { +- return this.chunkList; ++ // CraftBukkit start - Change return type to Collection and return the values of our chunk map ++ public java.util.Collection a() { ++ // return this.chunkList; ++ return this.chunks.values(); ++ // CraftBukkit end + } + + public void queueUnload(int i, int j) { + if (this.world.worldProvider.e()) { + if (!this.world.c(i, j)) { +- this.unloadQueue.add(Long.valueOf(ChunkCoordIntPair.a(i, j))); ++ // CraftBukkit start ++ this.unloadQueue.add(i, j); ++ ++ Chunk c = chunks.get(LongHash.toLong(i, j)); ++ if (c != null) { ++ c.mustSave = true; ++ } ++ // CraftBukkit end + } + } else { +- this.unloadQueue.add(Long.valueOf(ChunkCoordIntPair.a(i, j))); ++ // CraftBukkit start ++ this.unloadQueue.add(i, j); ++ ++ Chunk c = chunks.get(LongHash.toLong(i, j)); ++ if (c != null) { ++ c.mustSave = true; ++ } ++ // CraftBukkit end + } + + } + + public void b() { +- Iterator iterator = this.chunkList.iterator(); ++ Iterator iterator = this.chunks.values().iterator(); + + while (iterator.hasNext()) { + Chunk chunk = (Chunk) iterator.next(); +@@ -60,11 +88,48 @@ + + } + ++ // CraftBukkit start - Add async variant, provide compatibility ++ public Chunk getChunkIfLoaded(int x, int z) { ++ return chunks.get(LongHash.toLong(x, z)); ++ } ++ + public Chunk getChunkAt(int i, int j) { +- long k = ChunkCoordIntPair.a(i, j); ++ return getChunkAt(i, j, null); ++ } ++ ++ public Chunk getChunkAt(int i, int j, Runnable runnable) { ++ unloadQueue.remove(i, j); ++ Chunk chunk = chunks.get(LongHash.toLong(i, j)); ++ ChunkRegionLoader loader = null; ++ ++ if (this.chunkLoader instanceof ChunkRegionLoader) { ++ loader = (ChunkRegionLoader) this.chunkLoader; + +- this.unloadQueue.remove(Long.valueOf(k)); +- Chunk chunk = (Chunk) this.chunks.getEntry(k); ++ } ++ // We can only use the queue for already generated chunks ++ if (chunk == null && loader != null && loader.chunkExists(world, i, j)) { ++ if (runnable != null) { ++ ChunkIOExecutor.queueChunkLoad(world, loader, this, i, j, runnable); ++ return null; ++ } else { ++ chunk = ChunkIOExecutor.syncChunkLoad(world, loader, this, i, j); ++ } ++ } else if (chunk == null) { ++ chunk = originalGetChunkAt(i, j); ++ } ++ ++ // If we didn't load the chunk async and have a callback run it now ++ if (runnable != null) { ++ runnable.run(); ++ } ++ ++ return chunk; ++ } ++ public Chunk originalGetChunkAt(int i, int j) { ++ this.unloadQueue.remove(i, j); ++ Chunk chunk = (Chunk) this.chunks.get(LongHash.toLong(i, j)); ++ boolean newChunk = false; ++ // CraftBukkit end + + if (chunk == null) { + chunk = this.loadChunk(i, j); +@@ -79,16 +144,44 @@ + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Chunk to be generated"); + + crashreportsystemdetails.a("Location", (Object) String.format("%d,%d", new Object[] { Integer.valueOf(i), Integer.valueOf(j)})); +- crashreportsystemdetails.a("Position hash", (Object) Long.valueOf(k)); ++ crashreportsystemdetails.a("Position hash", (Object) Long.valueOf(LongHash.toLong(i, j))); // CraftBukkit - Use LongHash + crashreportsystemdetails.a("Generator", (Object) this.chunkProvider.getName()); + throw new ReportedException(crashreport); + } + } ++ newChunk = true; // CraftBukkit + } + +- this.chunks.put(k, chunk); +- this.chunkList.add(chunk); ++ this.chunks.put(LongHash.toLong(i, j), chunk); ++ + chunk.addEntities(); ++ ++ // CraftBukkit start ++ Server server = world.getServer(); ++ if (server != null) { ++ /* ++ * If it's a new world, the first few chunks are generated inside ++ * the World constructor. We can't reliably alter that, so we have ++ * no way of creating a CraftWorld/CraftServer at that point. ++ */ ++ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, newChunk)); ++ } ++ ++ // Update neighbor counts ++ for (int x = -2; x < 3; x++) { ++ for (int z = -2; z < 3; z++) { ++ if (x == 0 && z == 0) { ++ continue; ++ } ++ ++ Chunk neighbor = this.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z); ++ if (neighbor != null) { ++ neighbor.setNeighborLoaded(-x, -z); ++ chunk.setNeighborLoaded(x, z); ++ } ++ } ++ } ++ // CraftBukkit end + chunk.loadNearby(this, this, i, j); + } + +@@ -96,9 +189,22 @@ + } + + public Chunk getOrCreateChunk(int i, int j) { +- Chunk chunk = (Chunk) this.chunks.getEntry(ChunkCoordIntPair.a(i, j)); ++ // CraftBukkit start ++ Chunk chunk = (Chunk) this.chunks.get(LongHash.toLong(i, j)); ++ ++ chunk = chunk == null ? (!this.world.ad() && !this.forceChunkLoad ? this.emptyChunk : this.getChunkAt(i, j)) : chunk; ++ ++ if (chunk == emptyChunk) return chunk; ++ if (i != chunk.locX || j != chunk.locZ) { ++ b.error("Chunk (" + chunk.locX + ", " + chunk.locZ + ") stored at (" + i + ", " + j + ") in world '" + world.getWorld().getName() + "'"); ++ b.error(chunk.getClass().getName()); ++ Throwable ex = new Throwable(); ++ ex.fillInStackTrace(); ++ ex.printStackTrace(); ++ } + +- return chunk == null ? (!this.world.ad() && !this.forceChunkLoad ? this.emptyChunk : this.getChunkAt(i, j)) : chunk; ++ return chunk; ++ // CraftBukkit end + } + + public Chunk loadChunk(int i, int j) { +@@ -155,6 +261,30 @@ + chunk.n(); + if (this.chunkProvider != null) { + this.chunkProvider.getChunkAt(ichunkprovider, i, j); ++ ++ // CraftBukkit start ++ BlockSand.instaFall = true; ++ Random random = new Random(); ++ random.setSeed(world.getSeed()); ++ long xRand = random.nextLong() / 2L * 2L + 1L; ++ long zRand = random.nextLong() / 2L * 2L + 1L; ++ random.setSeed((long) i * xRand + (long) j * zRand ^ world.getSeed()); ++ ++ org.bukkit.World world = this.world.getWorld(); ++ if (world != null) { ++ this.world.populating = true; ++ try { ++ for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) { ++ populator.populate(world, random, chunk.bukkitChunk); ++ } ++ } finally { ++ this.world.populating = false; ++ } ++ } ++ BlockSand.instaFall = false; ++ this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(chunk.bukkitChunk)); ++ // CraftBukkit end ++ + chunk.e(); + } + } +@@ -174,10 +304,12 @@ + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) { + int i = 0; +- ArrayList arraylist = Lists.newArrayList(this.chunkList); + +- for (int j = 0; j < arraylist.size(); ++j) { +- Chunk chunk = (Chunk) arraylist.get(j); ++ // CraftBukkit start ++ Iterator iterator = this.chunks.values().iterator(); ++ while (iterator.hasNext()) { ++ Chunk chunk = (Chunk) iterator.next(); ++ // CraftBukkit end + + if (flag) { + this.saveChunkNOP(chunk); +@@ -205,22 +337,43 @@ + + public boolean unloadChunks() { + if (!this.world.savingDisabled) { +- for (int i = 0; i < 100; ++i) { +- if (!this.unloadQueue.isEmpty()) { +- Long olong = (Long) this.unloadQueue.iterator().next(); +- Chunk chunk = (Chunk) this.chunks.getEntry(olong.longValue()); ++ // CraftBukkit start ++ Server server = this.world.getServer(); ++ for (int i = 0; i < 100 && !this.unloadQueue.isEmpty(); ++i) { ++ long chunkcoordinates = this.unloadQueue.popFirst(); ++ Chunk chunk = this.chunks.get(chunkcoordinates); ++ if (chunk == null) continue; ++ ++ ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk); ++ server.getPluginManager().callEvent(event); ++ if (!event.isCancelled()) { + + if (chunk != null) { + chunk.removeEntities(); + this.saveChunk(chunk); + this.saveChunkNOP(chunk); +- this.chunks.remove(olong.longValue()); +- this.chunkList.remove(chunk); ++ this.chunks.remove(chunkcoordinates); // CraftBukkit + } + +- this.unloadQueue.remove(olong); ++ // this.unloadQueue.remove(olong); ++ ++ // Update neighbor counts ++ for (int x = -2; x < 3; x++) { ++ for (int z = -2; z < 3; z++) { ++ if (x == 0 && z == 0) { ++ continue; ++ } ++ ++ Chunk neighbor = this.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z); ++ if (neighbor != null) { ++ neighbor.setNeighborUnloaded(-x, -z); ++ chunk.setNeighborUnloaded(x, z); ++ } ++ } ++ } + } + } ++ // CraftBukkit end + + if (this.chunkLoader != null) { + this.chunkLoader.a(); +@@ -235,7 +388,8 @@ + } + + public String getName() { +- return "ServerChunkCache: " + this.chunks.count() + " Drop: " + this.unloadQueue.size(); ++ // CraftBukkit - this.chunks.count() -> .size() ++ return "ServerChunkCache: " + this.chunks.size() + " Drop: " + this.unloadQueue.size(); + } + + public List getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { +@@ -247,7 +401,8 @@ + } + + public int getLoadedChunks() { +- return this.chunks.count(); ++ // CraftBukkit - this.chunks.count() -> this.chunks.size() ++ return this.chunks.size(); + } + + public void recreateStructures(Chunk chunk, int i, int j) {} diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkRegionLoader.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkRegionLoader.patch new file mode 100644 index 0000000..47a5014 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkRegionLoader.patch @@ -0,0 +1,127 @@ +--- a/net/minecraft/server/ChunkRegionLoader.java ++++ b/net/minecraft/server/ChunkRegionLoader.java +@@ -26,7 +26,35 @@ + this.d = file; + } + ++ // CraftBukkit start ++ public boolean chunkExists(World world, int i, int j) { ++ ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); ++ ++ if (this.c.contains(chunkcoordintpair)) { ++ if (this.b.containsKey(chunkcoordintpair)) { ++ return true; ++ } ++ } ++ ++ return RegionFileCache.a(this.d, i, j).chunkExists(i & 31, j & 31); ++ } ++ // CraftBukkit end ++ ++ // CraftBukkit start - Add async variant, provide compatibility + public Chunk a(World world, int i, int j) throws IOException { ++ Object[] data = loadChunk(world, i, j); ++ if (data != null) { ++ Chunk chunk = (Chunk) data[0]; ++ NBTTagCompound nbttagcompound = (NBTTagCompound) data[1]; ++ loadEntities(chunk, nbttagcompound.getCompound("Level"), world); ++ return chunk; ++ } ++ ++ return null; ++ } ++ ++ public Object[] loadChunk(World world, int i, int j) throws IOException { ++ // CraftBukkit end + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.get(chunkcoordintpair); + +@@ -43,7 +71,7 @@ + return this.a(world, i, j, nbttagcompound); + } + +- protected Chunk a(World world, int i, int j, NBTTagCompound nbttagcompound) { ++ protected Object[] a(World world, int i, int j, NBTTagCompound nbttagcompound) { // CraftBukkit - return Chunk -> Object[] + if (!nbttagcompound.hasKeyOfType("Level", 10)) { + ChunkRegionLoader.a.error("Chunk file at " + i + "," + j + " is missing level data, skipping"); + return null; +@@ -60,10 +88,28 @@ + ChunkRegionLoader.a.error("Chunk file at " + i + "," + j + " is in the wrong location; relocating. (Expected " + i + ", " + j + ", got " + chunk.locX + ", " + chunk.locZ + ")"); + nbttagcompound1.setInt("xPos", i); + nbttagcompound1.setInt("zPos", j); ++ ++ // CraftBukkit start - Have to move tile entities since we don't load them at this stage ++ NBTTagList tileEntities = nbttagcompound.getCompound("Level").getList("TileEntities", 10); ++ if (tileEntities != null) { ++ for (int te = 0; te < tileEntities.size(); te++) { ++ NBTTagCompound tileEntity = (NBTTagCompound) tileEntities.get(te); ++ int x = tileEntity.getInt("x") - chunk.locX * 16; ++ int z = tileEntity.getInt("z") - chunk.locZ * 16; ++ tileEntity.setInt("x", i * 16 + x); ++ tileEntity.setInt("z", j * 16 + z); ++ } ++ } ++ // CraftBukkit end + chunk = this.a(world, nbttagcompound1); + } + +- return chunk; ++ // CraftBukkit start ++ Object[] data = new Object[2]; ++ data[0] = chunk; ++ data[1] = nbttagcompound; ++ return data; ++ // CraftBukkit end + } + } + } +@@ -303,7 +349,26 @@ + int k1 = l >> 4 & 15; + int l1 = nibblearray1 != null ? nibblearray1.a(i1, j1, k1) : 0; + +- achar[l] = (char) (l1 << 12 | (abyte[l] & 255) << 4 | nibblearray.a(i1, j1, k1)); ++ // CraftBukkit start - fix broken blocks ++ // achar[l] = (char) (l1 << 12 | (abyte[l] & 255) << 4 | nibblearray.a(i1, j1, k1)); ++ ++ int ex = l1; ++ int id = (abyte[l] & 255); ++ int data = nibblearray.a(i1, j1, k1); ++ int packed = ex << 12 | id << 4 | data; ++ if (Block.d.a(packed) == null) { ++ Block block = Block.getById(ex << 8 | id); ++ if (block != null) { ++ try { ++ data = block.toLegacyData(block.fromLegacyData(data)); ++ } catch (Exception ignored) { ++ data = block.toLegacyData(block.getBlockData()); ++ } ++ packed = ex << 12 | id << 4 | data; ++ } ++ } ++ achar[l] = (char) packed; ++ // CraftBukkit end + } + + chunksection.a(achar); +@@ -321,6 +386,13 @@ + chunk.a(nbttagcompound.getByteArray("Biomes")); + } + ++ // CraftBukkit start - End this method here and split off entity loading to another method ++ return chunk; ++ } ++ ++ public void loadEntities(Chunk chunk, NBTTagCompound nbttagcompound, World world) { ++ // CraftBukkit end ++ + NBTTagList nbttaglist1 = nbttagcompound.getList("Entities", 10); + + if (nbttaglist1 != null) { +@@ -379,6 +451,6 @@ + } + } + +- return chunk; ++ // return chunk; // CraftBukkit + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkSection.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkSection.patch new file mode 100644 index 0000000..6a96a99 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ChunkSection.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/server/ChunkSection.java ++++ b/net/minecraft/server/ChunkSection.java +@@ -19,6 +19,18 @@ + + } + ++ // CraftBukkit start ++ public ChunkSection(int y, boolean flag, char[] blockIds) { ++ this.yPos = y; ++ this.blockIds = blockIds; ++ this.emittedLight = new NibbleArray(); ++ if (flag) { ++ this.skyLight = new NibbleArray(); ++ } ++ recalcBlockCounts(); ++ } ++ // CraftBukkit end ++ + public IBlockData getType(int i, int j, int k) { + IBlockData iblockdata = (IBlockData) Block.d.a(this.blockIds[j << 8 | k << 4 | i]); + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandBlockListenerAbstract.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandBlockListenerAbstract.patch new file mode 100644 index 0000000..c7dec98 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandBlockListenerAbstract.patch @@ -0,0 +1,167 @@ +--- a/net/minecraft/server/CommandBlockListenerAbstract.java ++++ b/net/minecraft/server/CommandBlockListenerAbstract.java +@@ -4,6 +4,13 @@ + import java.util.Date; + import java.util.concurrent.Callable; + ++// CraftBukkit start ++import java.util.ArrayList; ++import org.bukkit.craftbukkit.command.VanillaCommandWrapper; ++import com.google.common.base.Joiner; ++import java.util.logging.Level; ++// CraftBukkit end ++ + public abstract class CommandBlockListenerAbstract implements ICommandListener { + + private static final SimpleDateFormat a = new SimpleDateFormat("HH:mm:ss"); +@@ -13,6 +20,7 @@ + private String e = ""; + private String f = "@"; + private final CommandObjectiveExecutor g = new CommandObjectiveExecutor(); ++ protected org.bukkit.command.CommandSender sender; // CraftBukkit - add sender + + public CommandBlockListenerAbstract() {} + +@@ -79,7 +87,10 @@ + + try { + this.d = null; +- this.b = icommandhandler.a(this, this.e); ++ // this.b = icommandhandler.a(this, this.e); ++ // CraftBukkit start - Handle command block commands using Bukkit dispatcher ++ this.b = executeCommand(this, sender, this.e); ++ // CraftBukkit end + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Executing command block"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Command to be executed"); +@@ -110,6 +121,130 @@ + + } + ++ // CraftBukkit start ++ public static int executeCommand(ICommandListener sender, org.bukkit.command.CommandSender bSender, String command) { ++ org.bukkit.command.SimpleCommandMap commandMap = sender.getWorld().getServer().getCommandMap(); ++ Joiner joiner = Joiner.on(" "); ++ if (command.startsWith("/")) { ++ command = command.substring(1); ++ } ++ String[] args = command.split(" "); ++ ArrayList commands = new ArrayList(); ++ ++ String cmd = args[0]; ++ if (cmd.startsWith("minecraft:")) cmd = cmd.substring("minecraft:".length()); ++ if (cmd.startsWith("bukkit:")) cmd = cmd.substring("bukkit:".length()); ++ ++ // Block disallowed commands ++ if (cmd.equalsIgnoreCase("stop") || cmd.equalsIgnoreCase("kick") || cmd.equalsIgnoreCase("op") ++ || cmd.equalsIgnoreCase("deop") || cmd.equalsIgnoreCase("ban") || cmd.equalsIgnoreCase("ban-ip") ++ || cmd.equalsIgnoreCase("pardon") || cmd.equalsIgnoreCase("pardon-ip") || cmd.equalsIgnoreCase("reload")) { ++ return 0; ++ } ++ ++ // If the world has no players don't run ++ if (sender.getWorld().players.isEmpty()) { ++ return 0; ++ } ++ ++ // Handle vanilla commands; ++ org.bukkit.command.Command commandBlockCommand = commandMap.getCommand(args[0]); ++ if (sender.getWorld().getServer().getCommandBlockOverride(args[0])) { ++ commandBlockCommand = commandMap.getCommand("minecraft:" + args[0]); ++ } ++ if (commandBlockCommand instanceof VanillaCommandWrapper) { ++ command = command.trim(); ++ if (command.startsWith("/")) { ++ command = command.substring(1); ++ } ++ String as[] = command.split(" "); ++ as = VanillaCommandWrapper.dropFirstArgument(as); ++ if (!((VanillaCommandWrapper) commandBlockCommand).testPermission(bSender)) { ++ return 0; ++ } ++ return ((VanillaCommandWrapper) commandBlockCommand).dispatchVanillaCommand(bSender, sender, as); ++ } ++ ++ // Make sure this is a valid command ++ if (commandMap.getCommand(args[0]) == null) { ++ return 0; ++ } ++ ++ commands.add(args); ++ ++ // Find positions of command block syntax, if any ++ WorldServer[] prev = MinecraftServer.getServer().worldServer; ++ MinecraftServer server = MinecraftServer.getServer(); ++ server.worldServer = new WorldServer[server.worlds.size()]; ++ server.worldServer[0] = (WorldServer) sender.getWorld(); ++ int bpos = 0; ++ for (int pos = 1; pos < server.worldServer.length; pos++) { ++ WorldServer world = server.worlds.get(bpos++); ++ if (server.worldServer[0] == world) { ++ pos--; ++ continue; ++ } ++ server.worldServer[pos] = world; ++ } ++ try { ++ ArrayList newCommands = new ArrayList(); ++ for (int i = 0; i < args.length; i++) { ++ if (PlayerSelector.isPattern(args[i])) { ++ for (int j = 0; j < commands.size(); j++) { ++ newCommands.addAll(buildCommands(sender, commands.get(j), i)); ++ } ++ ArrayList temp = commands; ++ commands = newCommands; ++ newCommands = temp; ++ newCommands.clear(); ++ } ++ } ++ } finally { ++ MinecraftServer.getServer().worldServer = prev; ++ } ++ ++ int completed = 0; ++ ++ // Now dispatch all of the commands we ended up with ++ for (int i = 0; i < commands.size(); i++) { ++ try { ++ if (commandMap.dispatch(bSender, joiner.join(java.util.Arrays.asList(commands.get(i))))) { ++ completed++; ++ } ++ } catch (Throwable exception) { ++ if (sender.f() instanceof EntityMinecartCommandBlock) { ++ MinecraftServer.getServer().server.getLogger().log(Level.WARNING, String.format("MinecartCommandBlock at (%d,%d,%d) failed to handle command", sender.getChunkCoordinates().getX(), sender.getChunkCoordinates().getY(), sender.getChunkCoordinates().getZ()), exception); ++ } else if (sender instanceof CommandBlockListenerAbstract) { ++ CommandBlockListenerAbstract listener = (CommandBlockListenerAbstract) sender; ++ MinecraftServer.getServer().server.getLogger().log(Level.WARNING, String.format("CommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().getX(), listener.getChunkCoordinates().getY(), listener.getChunkCoordinates().getZ()), exception); ++ } else { ++ MinecraftServer.getServer().server.getLogger().log(Level.WARNING, String.format("Unknown CommandBlock failed to handle command"), exception); ++ } ++ } ++ } ++ ++ return completed; ++ } ++ ++ private static ArrayList buildCommands(ICommandListener sender, String[] args, int pos) { ++ ArrayList commands = new ArrayList(); ++ java.util.List players = (java.util.List)PlayerSelector.getPlayers(sender, args[pos], EntityPlayer.class); ++ ++ if (players != null) { ++ for (EntityPlayer player : players) { ++ if (player.world != sender.getWorld()) { ++ continue; ++ } ++ String[] command = args.clone(); ++ command[pos] = player.getName(); ++ commands.add(command); ++ } ++ } ++ ++ return commands; ++ } ++ // CraftBukkit end ++ + public String getName() { + return this.f; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandExecute.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandExecute.patch new file mode 100644 index 0000000..9f93796 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandExecute.patch @@ -0,0 +1,58 @@ +--- a/net/minecraft/server/CommandExecute.java ++++ b/net/minecraft/server/CommandExecute.java +@@ -2,6 +2,10 @@ + + import java.util.Collection; + import java.util.List; ++// CraftBukkit start ++import org.bukkit.craftbukkit.command.ProxiedNativeCommandSender; ++import org.bukkit.craftbukkit.command.VanillaCommandWrapper; ++// CraftBukkit end + + public class CommandExecute extends CommandAbstract { + +@@ -94,12 +98,31 @@ + ICommandHandler icommandhandler = MinecraftServer.getServer().getCommandHandler(); + + try { +- int j = icommandhandler.a(icommandlistener1, s); ++ // CraftBukkit start ++ org.bukkit.command.CommandSender sender = null; ++ if (icommandlistener instanceof DedicatedServer) { ++ sender = MinecraftServer.getServer().server.getConsoleSender(); ++ } else if (icommandlistener instanceof CommandBlockListenerAbstract) { ++ sender = ((CommandBlockListenerAbstract) icommandlistener).sender; ++ } else if (VanillaCommandWrapper.lastSender != null) { ++ sender = VanillaCommandWrapper.lastSender; ++ }else if (icommandlistener.f() != null) { ++ sender = icommandlistener.f().getBukkitEntity(); ++ } else { ++ throw new CommandException("Unhandled executor " + icommandlistener.getClass().getSimpleName(), new Object[0]); ++ } ++ int j = CommandBlockListenerAbstract.executeCommand(icommandlistener1, new ProxiedNativeCommandSender(icommandlistener1, sender, entity.getBukkitEntity()), s); ++ // CraftBukkit end + + if (j < 1) { + throw new CommandException("commands.execute.allInvocationsFailed", new Object[] { s}); + } + } catch (Throwable throwable) { ++ // CraftBukkit start ++ if (throwable instanceof CommandException) { ++ throw (CommandException) throwable; ++ } ++ // CraftBukkit end + throw new CommandException("commands.execute.failed", new Object[] { s, entity.getName()}); + } + } +@@ -112,4 +135,11 @@ + public boolean isListStart(String[] astring, int i) { + return i == 0; + } ++ ++ // CraftBukkit start - fix decompiler error ++ @Override ++ public int compareTo(ICommand o) { ++ return a((ICommand) o); ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandGamemode.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandGamemode.patch new file mode 100644 index 0000000..6280a4b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandGamemode.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/server/CommandGamemode.java ++++ b/net/minecraft/server/CommandGamemode.java +@@ -26,6 +26,13 @@ + EntityPlayer entityplayer = astring.length >= 2 ? a(icommandlistener, astring[1]) : b(icommandlistener); + + entityplayer.a(worldsettings_enumgamemode); ++ // CraftBukkit start - handle event cancelling the change ++ if (entityplayer.playerInteractManager.getGameMode() != worldsettings_enumgamemode) { ++ icommandlistener.sendMessage(new ChatComponentText("Failed to set the gamemode of '" + entityplayer.getName() + "'")); ++ return; ++ } ++ // CraftBukkit end ++ + entityplayer.fallDistance = 0.0F; + if (icommandlistener.getWorld().getGameRules().getBoolean("sendCommandFeedback")) { + entityplayer.sendMessage(new ChatMessage("gameMode.changed", new Object[0])); +@@ -57,4 +64,11 @@ + public boolean isListStart(String[] astring, int i) { + return i == 1; + } ++ ++ // CraftBukkit start - fix decompiler error ++ @Override ++ public int compareTo(ICommand o) { ++ return a((ICommand) o); ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandGamerule.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandGamerule.patch new file mode 100644 index 0000000..c619010 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandGamerule.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/server/CommandGamerule.java ++++ b/net/minecraft/server/CommandGamerule.java +@@ -20,7 +20,7 @@ + } + + public void execute(ICommandListener icommandlistener, String[] astring) throws CommandException { +- GameRules gamerules = this.d(); ++ GameRules gamerules = icommandlistener.getWorld().getGameRules(); // CraftBukkit - Use current world + String s = astring.length > 0 ? astring[0] : ""; + String s1 = astring.length > 1 ? a(astring, 1) : ""; + +@@ -85,4 +85,11 @@ + private GameRules d() { + return MinecraftServer.getServer().getWorldServer(0).getGameRules(); + } ++ ++ // CraftBukkit start - fix decompile error ++ @Override ++ public int compareTo(ICommand o) { ++ return a((ICommand) o); ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandSpreadPlayers.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandSpreadPlayers.patch new file mode 100644 index 0000000..7f7a938 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandSpreadPlayers.patch @@ -0,0 +1,47 @@ +--- a/net/minecraft/server/CommandSpreadPlayers.java ++++ b/net/minecraft/server/CommandSpreadPlayers.java +@@ -237,6 +237,13 @@ + return astring.length >= 1 && astring.length <= 2 ? b(astring, 0, blockposition) : null; + } + ++ // CraftBukkit start - fix decompile error ++ @Override ++ public int compareTo(ICommand o) { ++ return a(o); ++ } ++ // CraftBukkit end ++ + static class Location2D { + + double a; +@@ -303,7 +310,7 @@ + } + + blockposition = blockposition.down(); +- } while (world.getType(blockposition).getBlock().getMaterial() == Material.AIR); ++ } while (getType(world, blockposition).getBlock().getMaterial() == Material.AIR); // CraftBukkit + + return blockposition.getY() + 1; + } +@@ -319,7 +326,7 @@ + } + + blockposition = blockposition.down(); +- material = world.getType(blockposition).getBlock().getMaterial(); ++ material = getType(world, blockposition).getBlock().getMaterial(); // CraftBukkit + } while (material == Material.AIR); + + return !material.isLiquid() && material != Material.FIRE; +@@ -329,5 +336,12 @@ + this.a = MathHelper.a(random, d0, d2); + this.b = MathHelper.a(random, d1, d3); + } ++ ++ // CraftBukkit start - add a version of getType which force loads chunks ++ private static IBlockData getType(World world, BlockPosition position) { ++ ((ChunkProviderServer) world.chunkProvider).getChunkAt(position.getX() >> 4, position.getZ() >> 4); ++ return world.getType(position); ++ } ++ // CraftBukkit end + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandTp.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandTp.patch new file mode 100644 index 0000000..13912dd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CommandTp.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/server/CommandTp.java ++++ b/net/minecraft/server/CommandTp.java +@@ -105,17 +105,11 @@ + } else { + Entity entity = b(icommandlistener, astring[astring.length - 1]); + +- if (entity.world != ((Entity) object).world) { +- throw new CommandException("commands.tp.notSameDimension", new Object[0]); +- } else { +- ((Entity) object).mount((Entity) null); +- if (object instanceof EntityPlayer) { +- ((EntityPlayer) object).playerConnection.a(entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch); +- } else { +- ((Entity) object).setPositionRotation(entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch); +- } +- +- a(icommandlistener, this, "commands.tp.success", new Object[] { ((Entity) object).getName(), entity.getName()}); ++ // CraftBukkit Start ++ // Use Bukkit teleport method in all cases. It has cross dimensional handling, events ++ if (((Entity) object).getBukkitEntity().teleport(entity.getBukkitEntity(), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.COMMAND)) { ++ a(icommandlistener, this, "commands.tp.success", new Object[]{((Entity) object).getName(), entity.getName()}); ++ // CraftBukkit End + } + } + } +@@ -128,4 +122,11 @@ + public boolean isListStart(String[] astring, int i) { + return i == 0; + } ++ ++ // CraftBukkit start - fix decompile error ++ @Override ++ public int compareTo(ICommand o) { ++ return a((ICommand) o); ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Container.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Container.patch new file mode 100644 index 0000000..55fe26c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Container.patch @@ -0,0 +1,210 @@ +--- a/net/minecraft/server/Container.java ++++ b/net/minecraft/server/Container.java +@@ -7,6 +7,17 @@ + import java.util.List; + import java.util.Set; + ++// CraftBukkit start ++import java.util.HashMap; ++import java.util.Map; ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.Event.Result; ++import org.bukkit.event.inventory.InventoryDragEvent; ++import org.bukkit.event.inventory.InventoryType; ++import org.bukkit.inventory.InventoryView; ++// CraftBukkit end ++ + public abstract class Container { + + public List b = Lists.newArrayList(); +@@ -18,12 +29,24 @@ + protected List listeners = Lists.newArrayList(); + private Set i = Sets.newHashSet(); + ++ // CraftBukkit start ++ public boolean checkReachable = true; ++ public abstract InventoryView getBukkitView(); ++ public void transferTo(Container other, org.bukkit.craftbukkit.entity.CraftHumanEntity player) { ++ InventoryView source = this.getBukkitView(), destination = other.getBukkitView(); ++ ((CraftInventory) source.getTopInventory()).getInventory().onClose(player); ++ ((CraftInventory) source.getBottomInventory()).getInventory().onClose(player); ++ ((CraftInventory) destination.getTopInventory()).getInventory().onOpen(player); ++ ((CraftInventory) destination.getBottomInventory()).getInventory().onOpen(player); ++ } ++ // CraftBukkit end ++ + public Container() {} + + protected Slot a(Slot slot) { + slot.rawSlotIndex = this.c.size(); + this.c.add(slot); +- this.b.add((Object) null); ++ this.b.add(null); // CraftBukkit - fix decompile error + return slot; + } + +@@ -124,6 +147,7 @@ + l = playerinventory.getCarried().count; + Iterator iterator = this.h.iterator(); + ++ Map draggedSlots = new HashMap(); // CraftBukkit - Store slots from drag in map (raw slot id -> new stack) + while (iterator.hasNext()) { + Slot slot1 = (Slot) iterator.next(); + +@@ -141,16 +165,48 @@ + } + + l -= itemstack2.count - j1; +- slot1.set(itemstack2); ++ // slot1.set(itemstack2); ++ draggedSlots.put(slot1.rawSlotIndex, itemstack2); // CraftBukkit - Put in map instead of setting + } + } + +- itemstack1.count = l; +- if (itemstack1.count <= 0) { +- itemstack1 = null; ++ // CraftBukkit start - InventoryDragEvent ++ InventoryView view = getBukkitView(); ++ org.bukkit.inventory.ItemStack newcursor = CraftItemStack.asCraftMirror(itemstack1); ++ newcursor.setAmount(l); ++ Map eventmap = new HashMap(); ++ for (Map.Entry ditem : draggedSlots.entrySet()) { ++ eventmap.put(ditem.getKey(), CraftItemStack.asBukkitCopy(ditem.getValue())); ++ } ++ ++ // It's essential that we set the cursor to the new value here to prevent item duplication if a plugin closes the inventory. ++ ItemStack oldCursor = playerinventory.getCarried(); ++ playerinventory.setCarried(CraftItemStack.asNMSCopy(newcursor)); ++ ++ InventoryDragEvent event = new InventoryDragEvent(view, (newcursor.getType() != org.bukkit.Material.AIR ? newcursor : null), CraftItemStack.asBukkitCopy(oldCursor), this.dragType == 1, eventmap); ++ entityhuman.world.getServer().getPluginManager().callEvent(event); ++ ++ // Whether or not a change was made to the inventory that requires an update. ++ boolean needsUpdate = event.getResult() != Result.DEFAULT; ++ ++ if (event.getResult() != Result.DENY) { ++ for (Map.Entry dslot : draggedSlots.entrySet()) { ++ view.setItem(dslot.getKey(), CraftItemStack.asBukkitCopy(dslot.getValue())); ++ } ++ // The only time the carried item will be set to null is if the inventory is closed by the server. ++ // If the inventory is closed by the server, then the cursor items are dropped. This is why we change the cursor early. ++ if (playerinventory.getCarried() != null) { ++ playerinventory.setCarried(CraftItemStack.asNMSCopy(event.getCursor())); ++ needsUpdate = true; ++ } ++ } else { ++ playerinventory.setCarried(oldCursor); + } + +- playerinventory.setCarried(itemstack1); ++ if (needsUpdate && entityhuman instanceof EntityPlayer) { ++ ((EntityPlayer) entityhuman).updateInventory(this); ++ } ++ // CraftBukkit end + } + + this.d(); +@@ -173,8 +229,14 @@ + } + + if (j == 1) { +- entityhuman.drop(playerinventory.getCarried().cloneAndSubtract(1), true); +- if (playerinventory.getCarried().count == 0) { ++ // CraftBukkit start - Store a reference ++ ItemStack itemstack4 = playerinventory.getCarried(); ++ if (itemstack4.count > 0) { ++ entityhuman.drop(itemstack4.cloneAndSubtract(1), true); ++ } ++ ++ if (itemstack4.count == 0) { ++ // CraftBukkit end + playerinventory.setCarried((ItemStack) null); + } + } +@@ -223,7 +285,11 @@ + + if (itemstack4.count == 0) { + playerinventory.setCarried((ItemStack) null); ++ // CraftBukkit start - Update client cursor if we didn't empty it ++ } else if (entityhuman instanceof EntityPlayer) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried())); + } ++ // CraftBukkit end + } + } else if (slot2.isAllowed(entityhuman)) { + if (itemstack4 == null) { +@@ -249,7 +315,11 @@ + itemstack4.cloneAndSubtract(k1); + if (itemstack4.count == 0) { + playerinventory.setCarried((ItemStack) null); ++ // CraftBukkit start - Update client cursor if we didn't empty it ++ } else if (entityhuman instanceof EntityPlayer) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried())); + } ++ // CraftBukkit end + + itemstack1.count += k1; + } else if (itemstack4.count <= slot2.getMaxStackSize(itemstack4)) { +@@ -258,7 +328,9 @@ + } + } else if (itemstack1.getItem() == itemstack4.getItem() && itemstack4.getMaxStackSize() > 1 && (!itemstack1.usesData() || itemstack1.getData() == itemstack4.getData()) && ItemStack.equals(itemstack1, itemstack4)) { + k1 = itemstack1.count; +- if (k1 > 0 && k1 + itemstack4.count <= itemstack4.getMaxStackSize()) { ++ // CraftBukkit start - itemstack4.getMaxStackSize() -> maxStack ++ int maxStack = Math.min(itemstack4.getMaxStackSize(), slot2.getMaxStackSize()); ++ if (k1 > 0 && k1 + itemstack4.count <= maxStack) { + itemstack4.count += k1; + itemstack1 = slot2.a(k1); + if (itemstack1.count == 0) { +@@ -266,11 +338,24 @@ + } + + slot2.a(entityhuman, playerinventory.getCarried()); ++ // CraftBukkit start - Update client cursor if we didn't empty it ++ } else if (entityhuman instanceof EntityPlayer) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried())); + } ++ // CraftBukkit end + } + } + + slot2.f(); ++ // CraftBukkit start - Make sure the client has the right slot contents ++ if (entityhuman instanceof EntityPlayer && slot2.getMaxStackSize() != 64) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, slot2.rawSlotIndex, slot2.getItem())); ++ // Updating a crafting inventory makes the client reset the result slot, have to send it again ++ if (this.getBukkitView().getType() == InventoryType.WORKBENCH || this.getBukkitView().getType() == InventoryType.CRAFTING) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, 0, this.getSlot(0).getItem())); ++ } ++ } ++ // CraftBukkit end + } + } + } else if (k == 2 && j >= 0 && j < 9) { +@@ -411,17 +496,20 @@ + if (itemstack1 != null && itemstack1.getItem() == itemstack.getItem() && (!itemstack.usesData() || itemstack.getData() == itemstack1.getData()) && ItemStack.equals(itemstack, itemstack1)) { + int l = itemstack1.count + itemstack.count; + +- if (l <= itemstack.getMaxStackSize()) { ++ // CraftBukkit start - itemstack.getMaxStackSize() -> maxStack ++ int maxStack = Math.min(itemstack.getMaxStackSize(), slot.getMaxStackSize()); ++ if (l <= maxStack) { + itemstack.count = 0; + itemstack1.count = l; + slot.f(); + flag1 = true; +- } else if (itemstack1.count < itemstack.getMaxStackSize()) { +- itemstack.count -= itemstack.getMaxStackSize() - itemstack1.count; +- itemstack1.count = itemstack.getMaxStackSize(); ++ } else if (itemstack1.count < maxStack) { ++ itemstack.count -= maxStack - itemstack1.count; ++ itemstack1.count = maxStack; + slot.f(); + flag1 = true; + } ++ // CraftBukkit end + } + + if (flag) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerAnvil.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerAnvil.patch new file mode 100644 index 0000000..003cc50 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerAnvil.patch @@ -0,0 +1,51 @@ +--- a/net/minecraft/server/ContainerAnvil.java ++++ b/net/minecraft/server/ContainerAnvil.java +@@ -6,6 +6,8 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit ++ + public class ContainerAnvil extends Container { + + private static final Logger f = LogManager.getLogger(); +@@ -22,8 +24,13 @@ + private int k; + private String l; + private final EntityHuman m; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ // CraftBukkit end + + public ContainerAnvil(PlayerInventory playerinventory, final World world, final BlockPosition blockposition, EntityHuman entityhuman) { ++ this.player = playerinventory; // CraftBukkit + this.j = blockposition; + this.i = world; + this.m = entityhuman; +@@ -317,6 +324,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.i.getType(this.j).getBlock() != Blocks.ANVIL ? false : entityhuman.e((double) this.j.getX() + 0.5D, (double) this.j.getY() + 0.5D, (double) this.j.getZ() + 0.5D) <= 64.0D; + } + +@@ -372,4 +380,17 @@ + + this.e(); + } ++ ++ // CraftBukkit start ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryAnvil(this.h, this.g); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerBeacon.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerBeacon.patch new file mode 100644 index 0000000..332ab07 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerBeacon.patch @@ -0,0 +1,47 @@ +--- a/net/minecraft/server/ContainerBeacon.java ++++ b/net/minecraft/server/ContainerBeacon.java +@@ -1,11 +1,18 @@ + package net.minecraft.server; + ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit ++ + public class ContainerBeacon extends Container { + + private IInventory beacon; + private final ContainerBeacon.SlotBeacon f; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ // CraftBukkit end + + public ContainerBeacon(IInventory iinventory, IInventory iinventory1) { ++ player = (PlayerInventory) iinventory; // CraftBukkit - TODO: check this + this.beacon = iinventory1; + this.a((Slot) (this.f = new ContainerBeacon.SlotBeacon(iinventory1, 0, 136, 110))); + byte b0 = 36; +@@ -47,6 +54,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.beacon.a(entityhuman); + } + +@@ -110,4 +118,17 @@ + return 1; + } + } ++ ++ // CraftBukkit start ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryBeacon((TileEntityBeacon) this.beacon); // TODO - check this ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerBrewingStand.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerBrewingStand.patch new file mode 100644 index 0000000..3de4d47 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerBrewingStand.patch @@ -0,0 +1,52 @@ +--- a/net/minecraft/server/ContainerBrewingStand.java ++++ b/net/minecraft/server/ContainerBrewingStand.java +@@ -1,12 +1,23 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerBrewingStand extends Container { + + private IInventory brewingStand; + private final Slot f; + private int g; + ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ // CraftBukkit end ++ + public ContainerBrewingStand(PlayerInventory playerinventory, IInventory iinventory) { ++ player = playerinventory; // CraftBukkit + this.brewingStand = iinventory; + this.a((Slot) (new ContainerBrewingStand.SlotPotionBottle(playerinventory.player, iinventory, 0, 56, 46))); + this.a((Slot) (new ContainerBrewingStand.SlotPotionBottle(playerinventory.player, iinventory, 1, 79, 53))); +@@ -47,6 +58,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.brewingStand.a(entityhuman); + } + +@@ -146,4 +158,17 @@ + return itemstack != null && (itemstack.getItem() == Items.POTION || itemstack.getItem() == Items.GLASS_BOTTLE); + } + } ++ ++ // CraftBukkit start ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryBrewer inventory = new CraftInventoryBrewer(this.brewingStand); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerChest.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerChest.patch new file mode 100644 index 0000000..e28d0dc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerChest.patch @@ -0,0 +1,60 @@ +--- a/net/minecraft/server/ContainerChest.java ++++ b/net/minecraft/server/ContainerChest.java +@@ -1,9 +1,37 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerChest extends Container { + + private IInventory container; + private int f; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventory inventory; ++ if (this.container instanceof PlayerInventory) { ++ inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryPlayer((PlayerInventory) this.container); ++ } else if (this.container instanceof InventoryLargeChest) { ++ inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) this.container); ++ } else { ++ inventory = new CraftInventory(this.container); ++ } ++ ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + + public ContainerChest(IInventory iinventory, IInventory iinventory1, EntityHuman entityhuman) { + this.container = iinventory1; +@@ -11,6 +39,11 @@ + iinventory1.startOpen(entityhuman); + int i = (this.f - 4) * 18; + ++ // CraftBukkit start - Save player ++ // TODO: Should we check to make sure it really is an InventoryPlayer? ++ this.player = (PlayerInventory) iinventory; ++ // CraftBukkit end ++ + int j; + int k; + +@@ -33,6 +66,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.container.a(entityhuman); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerDispenser.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerDispenser.patch new file mode 100644 index 0000000..44e157e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerDispenser.patch @@ -0,0 +1,53 @@ +--- a/net/minecraft/server/ContainerDispenser.java ++++ b/net/minecraft/server/ContainerDispenser.java +@@ -1,11 +1,24 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerDispenser extends Container { + + public IInventory items; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ // CraftBukkit end + + public ContainerDispenser(IInventory iinventory, IInventory iinventory1) { + this.items = iinventory1; ++ // CraftBukkit start - Save player ++ // TODO: Should we check to make sure it really is an InventoryPlayer? ++ this.player = (PlayerInventory)iinventory; ++ // CraftBukkit end + + int i; + int j; +@@ -29,6 +42,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.items.a(entityhuman); + } + +@@ -63,4 +77,17 @@ + + return itemstack; + } ++ ++ // CraftBukkit start ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventory inventory = new CraftInventory(this.items); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerEnchantTable.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerEnchantTable.patch new file mode 100644 index 0000000..5e436ed --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerEnchantTable.patch @@ -0,0 +1,177 @@ +--- a/net/minecraft/server/ContainerEnchantTable.java ++++ b/net/minecraft/server/ContainerEnchantTable.java +@@ -3,9 +3,21 @@ + import java.util.List; + import java.util.Random; + ++// CraftBukkit start ++import java.util.Map; ++ ++import org.bukkit.craftbukkit.inventory.CraftInventoryEnchanting; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.enchantment.EnchantItemEvent; ++import org.bukkit.event.enchantment.PrepareItemEnchantEvent; ++import org.bukkit.entity.Player; ++// CraftBukkit end ++ + public class ContainerEnchantTable extends Container { + +- public IInventory enchantSlots = new InventorySubcontainer("Enchant", true, 2) { ++ // CraftBukkit - make type specific (changed from IInventory) ++ public InventorySubcontainer enchantSlots = new InventorySubcontainer("Enchant", true, 2) { + public int getMaxStackSize() { + return 64; + } +@@ -21,6 +33,10 @@ + public int f; + public int[] costs = new int[3]; + public int[] h = new int[] { -1, -1, -1}; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private Player player; ++ // CraftBukkit end + + public ContainerEnchantTable(PlayerInventory playerinventory, World world, BlockPosition blockposition) { + this.world = world; +@@ -53,6 +69,9 @@ + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + ++ // CraftBukkit start ++ player = (Player) playerinventory.player.getBukkitEntity(); ++ // CraftBukkit end + } + + public void addSlotListener(ICrafting icrafting) { +@@ -88,7 +107,7 @@ + ItemStack itemstack = iinventory.getItem(0); + int i; + +- if (itemstack != null && itemstack.v()) { ++ if (itemstack != null) { // CraftBukkit - relax condition + if (!this.world.isClientSide) { + i = 0; + +@@ -136,6 +155,20 @@ + } + } + ++ // CraftBukkit start ++ CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); ++ PrepareItemEnchantEvent event = new PrepareItemEnchantEvent(player, this.getBukkitView(), this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), item, this.costs, i); ++ event.setCancelled(!itemstack.v()); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ for (i = 0; i < 3; ++i) { ++ this.costs[i] = 0; ++ } ++ return; ++ } ++ // CraftBukkit end ++ + for (j = 0; j < 3; ++j) { + if (this.costs[j] > 0) { + List list = this.a(itemstack, j, this.costs[j]); +@@ -170,24 +203,55 @@ + } else if (this.costs[i] > 0 && itemstack != null && (entityhuman.expLevel >= j && entityhuman.expLevel >= this.costs[i] || entityhuman.abilities.canInstantlyBuild)) { + if (!this.world.isClientSide) { + List list = this.a(itemstack, i, this.costs[i]); ++ // CraftBukkit start - Provide an empty enchantment list ++ if (list == null) { ++ list = new java.util.ArrayList(); ++ } ++ // CraftBukkit end + boolean flag = itemstack.getItem() == Items.BOOK; + + if (list != null) { +- entityhuman.enchantDone(j); ++ // CraftBukkit start ++ Map enchants = new java.util.HashMap(); ++ for (Object obj : list) { ++ WeightedRandomEnchant instance = (WeightedRandomEnchant) obj; ++ enchants.put(org.bukkit.enchantments.Enchantment.getById(instance.enchantment.id), instance.level); ++ } ++ CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); ++ ++ EnchantItemEvent event = new EnchantItemEvent((Player) entityhuman.getBukkitEntity(), this.getBukkitView(), this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), item, this.costs[i], enchants, i); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ int level = event.getExpLevelCost(); ++ if (event.isCancelled() || (level > entityhuman.expLevel && !entityhuman.abilities.canInstantlyBuild) || event.getEnchantsToAdd().isEmpty()) { ++ return false; ++ } + if (flag) { + itemstack.setItem(Items.ENCHANTED_BOOK); + } + +- for (int k = 0; k < list.size(); ++k) { +- WeightedRandomEnchant weightedrandomenchant = (WeightedRandomEnchant) list.get(k); ++ for (Map.Entry entry : event.getEnchantsToAdd().entrySet()) { ++ try { ++ if (flag) { ++ int enchantId = entry.getKey().getId(); ++ if (Enchantment.getById(enchantId) == null) { ++ continue; ++ } + +- if (flag) { +- Items.ENCHANTED_BOOK.a(itemstack, weightedrandomenchant); +- } else { +- itemstack.addEnchantment(weightedrandomenchant.enchantment, weightedrandomenchant.level); ++ WeightedRandomEnchant enchantment = new WeightedRandomEnchant(Enchantment.getById(enchantId), entry.getValue()); ++ Items.ENCHANTED_BOOK.a(itemstack, enchantment); ++ } else { ++ item.addUnsafeEnchantment(entry.getKey(), entry.getValue()); ++ } ++ } catch (IllegalArgumentException e) { ++ /* Just swallow invalid enchantments */ + } + } + ++ entityhuman.enchantDone(j); ++ // CraftBukkit end ++ ++ // CraftBukkit - TODO: let plugins change this + if (!entityhuman.abilities.canInstantlyBuild) { + itemstack1.count -= j; + if (itemstack1.count <= 0) { +@@ -221,6 +285,11 @@ + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); ++ // CraftBukkit Start - If an enchantable was opened from a null location, set the world to the player's world, preventing a crash ++ if(this.world == null) { ++ this.world = entityhuman.getWorld(); ++ } ++ // CraftBukkit end + if (!this.world.isClientSide) { + for (int i = 0; i < this.enchantSlots.getSize(); ++i) { + ItemStack itemstack = this.enchantSlots.splitWithoutUpdate(i); +@@ -234,6 +303,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.world.getType(this.position).getBlock() != Blocks.ENCHANTING_TABLE ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + +@@ -286,4 +356,17 @@ + + return itemstack; + } ++ ++ // CraftBukkit start ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryEnchanting inventory = new CraftInventoryEnchanting(this.enchantSlots); ++ bukkitEntity = new CraftInventoryView(this.player, inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerFurnace.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerFurnace.patch new file mode 100644 index 0000000..e64b781 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerFurnace.patch @@ -0,0 +1,50 @@ +--- a/net/minecraft/server/ContainerFurnace.java ++++ b/net/minecraft/server/ContainerFurnace.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerFurnace extends Container { + + private final IInventory furnace; +@@ -8,11 +13,28 @@ + private int h; + private int i; + ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryFurnace inventory = new CraftInventoryFurnace((TileEntityFurnace) this.furnace); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end ++ + public ContainerFurnace(PlayerInventory playerinventory, IInventory iinventory) { + this.furnace = iinventory; + this.a(new Slot(iinventory, 0, 56, 17)); + this.a((Slot) (new SlotFurnaceFuel(iinventory, 1, 56, 53))); + this.a((Slot) (new SlotFurnaceResult(playerinventory.player, iinventory, 2, 116, 35))); ++ this.player = playerinventory; // CraftBukkit - save player + + int i; + +@@ -63,6 +85,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.furnace.a(entityhuman); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerHopper.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerHopper.patch new file mode 100644 index 0000000..a78872c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerHopper.patch @@ -0,0 +1,44 @@ +--- a/net/minecraft/server/ContainerHopper.java ++++ b/net/minecraft/server/ContainerHopper.java +@@ -1,11 +1,33 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerHopper extends Container { + + private final IInventory hopper; + ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventory inventory = new CraftInventory(this.hopper); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end ++ + public ContainerHopper(PlayerInventory playerinventory, IInventory iinventory, EntityHuman entityhuman) { + this.hopper = iinventory; ++ this.player = playerinventory; // CraftBukkit - save player + iinventory.startOpen(entityhuman); + byte b0 = 51; + +@@ -28,6 +50,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.hopper.a(entityhuman); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerHorse.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerHorse.patch new file mode 100644 index 0000000..845da06 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerHorse.patch @@ -0,0 +1,36 @@ +--- a/net/minecraft/server/ContainerHorse.java ++++ b/net/minecraft/server/ContainerHorse.java +@@ -1,11 +1,33 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++import org.bukkit.inventory.InventoryView; ++// CraftBukkit end ++ + public class ContainerHorse extends Container { + + private IInventory a; + private EntityHorse f; + ++ // CraftBukkit start ++ org.bukkit.craftbukkit.inventory.CraftInventoryView bukkitEntity; ++ PlayerInventory player; ++ ++ @Override ++ public InventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryHorse(this.a); ++ return bukkitEntity = new CraftInventoryView(player.player.getBukkitEntity(), inventory, this); ++ } ++ + public ContainerHorse(IInventory iinventory, final IInventory iinventory1, final EntityHorse entityhorse, EntityHuman entityhuman) { ++ player = (PlayerInventory) iinventory; ++ // CraftBukkit end + this.a = iinventory1; + this.f = entityhorse; + byte b0 = 3; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerMerchant.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerMerchant.patch new file mode 100644 index 0000000..362f8d7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerMerchant.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/server/ContainerMerchant.java ++++ b/net/minecraft/server/ContainerMerchant.java +@@ -1,11 +1,26 @@ + package net.minecraft.server; + ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit ++ + public class ContainerMerchant extends Container { + + private IMerchant merchant; + private InventoryMerchant f; + private final World g; + ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity == null) { ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), new org.bukkit.craftbukkit.inventory.CraftInventoryMerchant((InventoryMerchant) f), this); ++ } ++ return bukkitEntity; ++ } ++ // CraftBukkit end ++ + public ContainerMerchant(PlayerInventory playerinventory, IMerchant imerchant, World world) { + this.merchant = imerchant; + this.g = world; +@@ -13,6 +28,7 @@ + this.a(new Slot(this.f, 0, 36, 53)); + this.a(new Slot(this.f, 1, 62, 53)); + this.a((Slot) (new SlotMerchantResult(playerinventory.player, imerchant, this.f, 2, 120, 53))); ++ this.player = playerinventory; // CraftBukkit - save player + + int i; + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerPlayer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerPlayer.patch new file mode 100644 index 0000000..482d838 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerPlayer.patch @@ -0,0 +1,104 @@ +--- a/net/minecraft/server/ContainerPlayer.java ++++ b/net/minecraft/server/ContainerPlayer.java +@@ -1,28 +1,42 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerPlayer extends Container { + + public InventoryCrafting craftInventory = new InventoryCrafting(this, 2, 2); + public IInventory resultInventory = new InventoryCraftResult(); + public boolean g; + private final EntityHuman h; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ // CraftBukkit end + + public ContainerPlayer(final PlayerInventory playerinventory, boolean flag, EntityHuman entityhuman) { + this.g = flag; + this.h = entityhuman; ++ this.resultInventory = new InventoryCraftResult(); // CraftBukkit - moved to before InventoryCrafting construction ++ this.craftInventory = new InventoryCrafting(this, 2, 2, playerinventory.player); // CraftBukkit - pass player ++ this.craftInventory.resultInventory = this.resultInventory; // CraftBukkit - let InventoryCrafting know about its result slot ++ this.player = playerinventory; // CraftBukkit - save player + this.a((Slot) (new SlotResult(playerinventory.player, this.craftInventory, this.resultInventory, 0, 144, 36))); + +- final int i; ++ // CraftBukkit - fixed multiple decompiler errors below, good luck + int j; + +- for (i = 0; i < 2; ++i) { ++ for (int i = 0; i < 2; ++i) { + for (j = 0; j < 2; ++j) { + this.a(new Slot(this.craftInventory, j + i * 2, 88 + j * 18, 26 + i * 18)); + } + } + +- for (i = 0; i < 4; ++i) { +- this.a(new Slot(playerinventory, playerinventory.getSize() - 1 - i, 8, 8 + i * 18) { ++ for (int ii = 0; ii < 4; ++ii) { ++ final int i = ii; ++ this.a(new Slot(playerinventory, playerinventory.getSize() - 1 - ii, 8, 8 + ii * 18) { + public int getMaxStackSize() { + return 1; + } +@@ -33,21 +47,32 @@ + }); + } + +- for (i = 0; i < 3; ++i) { ++ for (int i = 0; i < 3; ++i) { + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + (i + 1) * 9, 8 + j * 18, 84 + i * 18)); + } + } + +- for (i = 0; i < 9; ++i) { ++ for (int i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + +- this.a((IInventory) this.craftInventory); ++ // this.a((IInventory) this.craftInventory); // CraftBukkit - unneeded since it just sets result slot to empty + } + + public void a(IInventory iinventory) { +- this.resultInventory.setItem(0, CraftingManager.getInstance().craft(this.craftInventory, this.h.world)); ++ // this.resultInventory.setItem(0, CraftingManager.getInstance().craft(this.craftInventory, this.h.world)); ++ // CraftBukkit start (Note: the following line would cause an error if called during construction) ++ CraftingManager.getInstance().lastCraftView = getBukkitView(); ++ ItemStack craftResult = CraftingManager.getInstance().craft(this.craftInventory, this.h.world); ++ this.resultInventory.setItem(0, craftResult); ++ if (super.listeners.size() < 1) { ++ return; ++ } ++ ++ EntityPlayer player = (EntityPlayer) super.listeners.get(0); // TODO: Is this _always_ correct? Seems like it. ++ player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.activeContainer.windowId, 0, craftResult)); ++ // CraftBukkit end + } + + public void b(EntityHuman entityhuman) { +@@ -127,4 +152,17 @@ + public boolean a(ItemStack itemstack, Slot slot) { + return slot.inventory != this.resultInventory && super.a(itemstack, slot); + } ++ ++ // CraftBukkit start ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftInventory, this.resultInventory); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerWorkbench.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerWorkbench.patch new file mode 100644 index 0000000..850e440 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ContainerWorkbench.patch @@ -0,0 +1,82 @@ +--- a/net/minecraft/server/ContainerWorkbench.java ++++ b/net/minecraft/server/ContainerWorkbench.java +@@ -1,13 +1,28 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerWorkbench extends Container { + +- public InventoryCrafting craftInventory = new InventoryCrafting(this, 3, 3); +- public IInventory resultInventory = new InventoryCraftResult(); ++ public InventoryCrafting craftInventory; // CraftBukkit - move initialization into constructor ++ public IInventory resultInventory; // CraftBukkit - move initialization into constructor + private World g; + private BlockPosition h; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private PlayerInventory player; ++ // CraftBukkit end + + public ContainerWorkbench(PlayerInventory playerinventory, World world, BlockPosition blockposition) { ++ // CraftBukkit start - Switched order of IInventory construction and stored player ++ this.resultInventory = new InventoryCraftResult(); ++ this.craftInventory = new InventoryCrafting(this, 3, 3, playerinventory.player); // CraftBukkit - pass player ++ this.craftInventory.resultInventory = this.resultInventory; ++ this.player = playerinventory; ++ // CraftBukkit end + this.g = world; + this.h = blockposition; + this.a((Slot) (new SlotResult(playerinventory.player, this.craftInventory, this.resultInventory, 0, 124, 35))); +@@ -35,7 +50,21 @@ + } + + public void a(IInventory iinventory) { +- this.resultInventory.setItem(0, CraftingManager.getInstance().craft(this.craftInventory, this.g)); ++ // this.resultInventory.setItem(0, CraftingManager.getInstance().craft(this.craftInventory, this.g)); ++ // CraftBukkit start ++ CraftingManager.getInstance().lastCraftView = getBukkitView(); ++ ItemStack craftResult = CraftingManager.getInstance().craft(this.craftInventory, this.g); ++ this.resultInventory.setItem(0, craftResult); ++ if (super.listeners.size() < 1) { ++ return; ++ } ++ // See CraftBukkit PR #39 ++ if (craftResult != null && craftResult.getItem() == Items.FILLED_MAP) { ++ return; ++ } ++ EntityPlayer player = (EntityPlayer) super.listeners.get(0); // TODO: Is this _always_ correct? Seems like it. ++ player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.activeContainer.windowId, 0, craftResult)); ++ // CraftBukkit end + } + + public void b(EntityHuman entityhuman) { +@@ -53,6 +82,7 @@ + } + + public boolean a(EntityHuman entityhuman) { ++ if (!this.checkReachable) return true; // CraftBukkit + return this.g.getType(this.h).getBlock() != Blocks.CRAFTING_TABLE ? false : entityhuman.e((double) this.h.getX() + 0.5D, (double) this.h.getY() + 0.5D, (double) this.h.getZ() + 0.5D) <= 64.0D; + } + +@@ -101,4 +131,17 @@ + public boolean a(ItemStack itemstack, Slot slot) { + return slot.inventory != this.resultInventory && super.a(itemstack, slot); + } ++ ++ // CraftBukkit start ++ @Override ++ public CraftInventoryView getBukkitView() { ++ if (bukkitEntity != null) { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftInventory, this.resultInventory); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/CraftingManager.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CraftingManager.patch new file mode 100644 index 0000000..3a7c82e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CraftingManager.patch @@ -0,0 +1,53 @@ +--- a/net/minecraft/server/CraftingManager.java ++++ b/net/minecraft/server/CraftingManager.java +@@ -9,10 +9,16 @@ + import java.util.Iterator; + import java.util.List; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class CraftingManager { + + private static final CraftingManager a = new CraftingManager(); + public List recipes = Lists.newArrayList(); ++ // CraftBukkit start ++ public IRecipe lastRecipe; ++ public org.bukkit.inventory.InventoryView lastCraftView; ++ // CraftBukkit end + + public static CraftingManager getInstance() { + return CraftingManager.a; +@@ -167,7 +173,12 @@ + this.registerShapedRecipe(new ItemStack(Blocks.DAYLIGHT_DETECTOR), new Object[] { "GGG", "QQQ", "WWW", Character.valueOf('G'), Blocks.GLASS, Character.valueOf('Q'), Items.QUARTZ, Character.valueOf('W'), Blocks.WOODEN_SLAB}); + this.registerShapedRecipe(new ItemStack(Blocks.HOPPER), new Object[] { "I I", "ICI", " I ", Character.valueOf('I'), Items.IRON_INGOT, Character.valueOf('C'), Blocks.CHEST}); + this.registerShapedRecipe(new ItemStack(Items.ARMOR_STAND, 1), new Object[] { "///", " / ", "/_/", Character.valueOf('/'), Items.STICK, Character.valueOf('_'), new ItemStack(Blocks.STONE_SLAB, 1, BlockDoubleStepAbstract.EnumStoneSlabVariant.STONE.a())}); +- Collections.sort(this.recipes, new Comparator() { ++ sort(); ++ } ++ ++ // CraftBukkit start ++ public void sort() { ++ Collections.sort(this.recipes, new Comparator() { + public int a(IRecipe irecipe, IRecipe irecipe1) { + return irecipe instanceof ShapelessRecipes && irecipe1 instanceof ShapedRecipes ? 1 : (irecipe1 instanceof ShapelessRecipes && irecipe instanceof ShapedRecipes ? -1 : (irecipe1.a() < irecipe.a() ? -1 : (irecipe1.a() > irecipe.a() ? 1 : 0))); + } +@@ -274,13 +285,18 @@ + + do { + if (!iterator.hasNext()) { ++ inventorycrafting.currentRecipe = null; // CraftBukkit - Clear recipe when no recipe is found + return null; + } + + irecipe = (IRecipe) iterator.next(); + } while (!irecipe.a(inventorycrafting, world)); + +- return irecipe.craftItem(inventorycrafting); ++ // CraftBukkit start - INVENTORY_PRE_CRAFT event ++ inventorycrafting.currentRecipe = irecipe; ++ ItemStack result = irecipe.craftItem(inventorycrafting); ++ return CraftEventFactory.callPreCraftEvent(inventorycrafting, result, lastCraftView, false); ++ // CraftBukkit end + } + + public ItemStack[] b(InventoryCrafting inventorycrafting, World world) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/CrashReport.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CrashReport.patch new file mode 100644 index 0000000..f0dc064 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/CrashReport.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/CrashReport.java ++++ b/net/minecraft/server/CrashReport.java +@@ -124,6 +124,7 @@ + return this.a(); + } + }); ++ this.d.a("CraftBukkit Information", (Callable) (new org.bukkit.craftbukkit.CraftCrashReport())); // CraftBukkit + } + + public String a() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/DedicatedServer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/DedicatedServer.patch new file mode 100644 index 0000000..e1210d2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/DedicatedServer.patch @@ -0,0 +1,248 @@ +--- a/net/minecraft/server/DedicatedServer.java ++++ b/net/minecraft/server/DedicatedServer.java +@@ -15,10 +15,20 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.io.PrintStream; ++import org.apache.logging.log4j.Level; ++ ++import org.bukkit.craftbukkit.LoggerOutputStream; ++import org.bukkit.event.server.ServerCommandEvent; ++import org.bukkit.craftbukkit.util.Waitable; ++import org.bukkit.event.server.RemoteServerCommandEvent; ++// CraftBukkit end ++ + public class DedicatedServer extends MinecraftServer implements IMinecraftServer { + + private static final Logger LOGGER = LogManager.getLogger(); +- private final List l = Collections.synchronizedList(Lists.newArrayList()); ++ private final List l = Collections.synchronizedList(Lists.newArrayList()); // CraftBukkit - fix decompile error + private RemoteStatusListener m; + private RemoteControlListener n; + public PropertyManager propertyManager; +@@ -27,8 +37,10 @@ + private WorldSettings.EnumGamemode r; + private boolean s; + +- public DedicatedServer(File file) { +- super(file, Proxy.NO_PROXY, DedicatedServer.a); ++ // CraftBukkit start - Signature changed ++ public DedicatedServer(joptsimple.OptionSet options) { ++ super(options, Proxy.NO_PROXY, DedicatedServer.a); ++ // CraftBukkit end + Thread thread = new Thread("Server Infinisleeper") { + { + this.setDaemon(true); +@@ -50,13 +62,27 @@ + protected boolean init() throws IOException { + Thread thread = new Thread("Server console handler") { + public void run() { +- BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in)); ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.Main.useConsole) { ++ return; ++ } ++ // CraftBukkit end + ++ jline.console.ConsoleReader bufferedreader = reader; // CraftBukkit + String s; + + try { +- while (!DedicatedServer.this.isStopped() && DedicatedServer.this.isRunning() && (s = bufferedreader.readLine()) != null) { +- DedicatedServer.this.issueCommand(s, DedicatedServer.this); ++ // CraftBukkit start - JLine disabling compatibility ++ while (!isStopped() && isRunning()) { ++ if (org.bukkit.craftbukkit.Main.useJline) { ++ s = bufferedreader.readLine(">", null); ++ } else { ++ s = bufferedreader.readLine(); ++ } ++ if (s != null && s.trim().length() > 0) { // Trim to filter lines which are just spaces ++ issueCommand(s, DedicatedServer.this); ++ } ++ // CraftBukkit end + } + } catch (IOException ioexception) { + DedicatedServer.LOGGER.error("Exception handling console input", ioexception); +@@ -65,6 +91,27 @@ + } + }; + ++ // CraftBukkit start - TODO: handle command-line logging arguments ++ java.util.logging.Logger global = java.util.logging.Logger.getLogger(""); ++ global.setUseParentHandlers(false); ++ for (java.util.logging.Handler handler : global.getHandlers()) { ++ global.removeHandler(handler); ++ } ++ global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler()); ++ ++ final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()); ++ for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) { ++ if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) { ++ logger.removeAppender(appender); ++ } ++ } ++ ++ new Thread(new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader)).start(); ++ ++ System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true)); ++ System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true)); ++ // CraftBukkit end ++ + thread.setDaemon(true); + thread.start(); + DedicatedServer.LOGGER.info("Starting minecraft server version 1.8.8"); +@@ -73,7 +120,7 @@ + } + + DedicatedServer.LOGGER.info("Loading properties"); +- this.propertyManager = new PropertyManager(new File("server.properties")); ++ this.propertyManager = new PropertyManager(this.options); // CraftBukkit - CLI argument support + this.p = new EULA(new File("eula.txt")); + if (!this.p.a()) { + DedicatedServer.LOGGER.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info."); +@@ -129,6 +176,8 @@ + return false; + } + ++ this.a((PlayerList) (new DedicatedPlayerList(this))); // CraftBukkit ++ + if (!this.getOnlineMode()) { + DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); + DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); +@@ -143,7 +192,7 @@ + if (!NameReferencingFileConverter.a(this.propertyManager)) { + return false; + } else { +- this.a((PlayerList) (new DedicatedPlayerList(this))); ++ this.convertable = new WorldLoaderServer(server.getWorldContainer()); // CraftBukkit - moved from MinecraftServer constructor + long j = System.nanoTime(); + + if (this.U() == null) { +@@ -198,7 +247,18 @@ + DedicatedServer.LOGGER.info("Starting remote control listener"); + this.n = new RemoteControlListener(this); + this.n.a(); ++ 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 (this.aS() > 0L) { + Thread thread1 = new Thread(new ThreadWatchdog(this)); +@@ -213,6 +273,12 @@ + } + } + ++ // CraftBukkit start ++ public PropertyManager getPropertyManager() { ++ return this.propertyManager; ++ } ++ // CraftBukkit end ++ + public void setGamemode(WorldSettings.EnumGamemode worldsettings_enumgamemode) { + super.setGamemode(worldsettings_enumgamemode); + this.r = worldsettings_enumgamemode; +@@ -265,7 +331,7 @@ + System.exit(0); + } + +- protected void B() { ++ public void B() { // CraftBukkit - fix decompile error + super.B(); + this.aO(); + } +@@ -296,7 +362,15 @@ + while (!this.l.isEmpty()) { + ServerCommand servercommand = (ServerCommand) this.l.remove(0); + +- this.getCommandHandler().a(servercommand.source, servercommand.command); ++ // CraftBukkit start - ServerCommand for preprocessing ++ ServerCommandEvent event = new ServerCommandEvent(console, servercommand.command); ++ server.getPluginManager().callEvent(event); ++ if (event.isCancelled()) continue; ++ servercommand = new ServerCommand(event.getCommand(), servercommand.source); ++ ++ // this.getCommandHandler().a(servercommand.source, servercommand.command); // Called in dispatchServerCommand ++ server.dispatchServerCommand(console, servercommand); ++ // CraftBukkit end + } + + } +@@ -491,13 +565,60 @@ + } + + public String getPlugins() { +- return ""; +- } ++ // CraftBukkit start - Whole method ++ StringBuilder result = new StringBuilder(); ++ org.bukkit.plugin.Plugin[] plugins = server.getPluginManager().getPlugins(); ++ ++ result.append(server.getName()); ++ result.append(" on Bukkit "); ++ result.append(server.getBukkitVersion()); ++ ++ if (plugins.length > 0 && server.getQueryPlugins()) { ++ result.append(": "); ++ ++ for (int i = 0; i < plugins.length; i++) { ++ if (i > 0) { ++ result.append("; "); ++ } + +- public String executeRemoteCommand(String s) { +- RemoteControlCommandListener.getInstance().i(); +- this.b.a(RemoteControlCommandListener.getInstance(), s); +- return RemoteControlCommandListener.getInstance().j(); ++ result.append(plugins[i].getDescription().getName()); ++ result.append(" "); ++ result.append(plugins[i].getDescription().getVersion().replaceAll(";", ",")); ++ } ++ } ++ ++ return result.toString(); ++ // CraftBukkit end ++ } ++ ++ // CraftBukkit start - fire RemoteServerCommandEvent ++ public String executeRemoteCommand(final String s) { ++ Waitable waitable = new Waitable() { ++ @Override ++ protected String evaluate() { ++ RemoteControlCommandListener.getInstance().i(); ++ // Event changes start ++ RemoteServerCommandEvent event = new RemoteServerCommandEvent(remoteConsole, s); ++ server.getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return ""; ++ } ++ // Event change end ++ ServerCommand serverCommand = new ServerCommand(event.getCommand(), RemoteControlCommandListener.getInstance()); ++ server.dispatchServerCommand(remoteConsole, serverCommand); ++ return RemoteControlCommandListener.getInstance().j(); ++ } ++ }; ++ processQueue.add(waitable); ++ try { ++ return waitable.get(); ++ } catch (java.util.concurrent.ExecutionException e) { ++ throw new RuntimeException("Exception processing rcon command " + s, e.getCause()); ++ } catch (InterruptedException e) { ++ Thread.currentThread().interrupt(); // Maintain interrupted state ++ throw new RuntimeException("Interrupted processing rcon command " + s, e); ++ } ++ // CraftBukkit end + } + + public PlayerList getPlayerList() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenseBehaviorItem.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenseBehaviorItem.patch new file mode 100644 index 0000000..61fe049 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenseBehaviorItem.patch @@ -0,0 +1,76 @@ +--- a/net/minecraft/server/DispenseBehaviorItem.java ++++ b/net/minecraft/server/DispenseBehaviorItem.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end ++ + public class DispenseBehaviorItem implements IDispenseBehavior { + + public DispenseBehaviorItem() {} +@@ -17,11 +22,18 @@ + IPosition iposition = BlockDispenser.a(isourceblock); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + +- a(isourceblock.getWorld(), itemstack1, 6, enumdirection, iposition); ++ // CraftBukkit start ++ if (!a(isourceblock.getWorld(), itemstack1, 6, enumdirection, isourceblock)) { ++ itemstack.count++; ++ } ++ // CraftBukkit end + return itemstack; + } + +- public static void a(World world, ItemStack itemstack, int i, EnumDirection enumdirection, IPosition iposition) { ++ // CraftBukkit start - void -> boolean return, IPosition -> ISourceBlock last argument ++ public static boolean a(World world, ItemStack itemstack, int i, EnumDirection enumdirection, ISourceBlock isourceblock) { ++ IPosition iposition = BlockDispenser.a(isourceblock); ++ // CraftBukkit end + double d0 = iposition.getX(); + double d1 = iposition.getY(); + double d2 = iposition.getZ(); +@@ -41,7 +53,41 @@ + entityitem.motX += world.random.nextGaussian() * 0.007499999832361937D * (double) i; + entityitem.motY += world.random.nextGaussian() * 0.007499999832361937D * (double) i; + entityitem.motZ += world.random.nextGaussian() * 0.007499999832361937D * (double) i; ++ ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(entityitem.motX, entityitem.motY, entityitem.motZ)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ ++ entityitem.setItemStack(CraftItemStack.asNMSCopy(event.getItem())); ++ entityitem.motX = event.getVelocity().getX(); ++ entityitem.motY = event.getVelocity().getY(); ++ entityitem.motZ = event.getVelocity().getZ(); ++ ++ if (!event.getItem().getType().equals(craftItem.getType())) { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior.getClass() != DispenseBehaviorItem.class) { ++ idispensebehavior.a(isourceblock, eventStack); ++ } else { ++ world.addEntity(entityitem); ++ } ++ return false; ++ } ++ + world.addEntity(entityitem); ++ ++ return true; ++ // CraftBukkit end + } + + protected void a(ISourceBlock isourceblock) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenseBehaviorProjectile.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenseBehaviorProjectile.patch new file mode 100644 index 0000000..5cf558a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenseBehaviorProjectile.patch @@ -0,0 +1,54 @@ +--- a/net/minecraft/server/DispenseBehaviorProjectile.java ++++ b/net/minecraft/server/DispenseBehaviorProjectile.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end ++ + public abstract class DispenseBehaviorProjectile extends DispenseBehaviorItem { + + public DispenseBehaviorProjectile() {} +@@ -10,9 +15,38 @@ + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + IProjectile iprojectile = this.a(world, iposition); + +- iprojectile.shoot((double) enumdirection.getAdjacentX(), (double) ((float) enumdirection.getAdjacentY() + 0.1F), (double) enumdirection.getAdjacentZ(), this.getPower(), this.a()); ++ // iprojectile.shoot((double) enumdirection.getAdjacentX(), (double) ((float) enumdirection.getAdjacentY() + 0.1F), (double) enumdirection.getAdjacentZ(), this.b(), this.a()); ++ // CraftBukkit start ++ ItemStack itemstack1 = itemstack.cloneAndSubtract(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) enumdirection.getAdjacentX(), (double) ((float) enumdirection.getAdjacentY() + 0.1F), (double) enumdirection.getAdjacentZ())); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.count++; ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.count++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ iprojectile.shoot(event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.getPower(), this.a()); ++ ((Entity) iprojectile).projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) isourceblock.getTileEntity()); ++ // CraftBukkit end + world.addEntity((Entity) iprojectile); +- itemstack.cloneAndSubtract(1); ++ // itemstack.a(1); // CraftBukkit - Handled during event processing + return itemstack; + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenserRegistry.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenserRegistry.patch new file mode 100644 index 0000000..ba9e6a2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/DispenserRegistry.patch @@ -0,0 +1,385 @@ +--- a/net/minecraft/server/DispenserRegistry.java ++++ b/net/minecraft/server/DispenserRegistry.java +@@ -7,6 +7,11 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end ++ + public class DispenserRegistry { + + private static final PrintStream a = System.out; +@@ -74,13 +79,45 @@ + double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); + double d1 = (double) ((float) isourceblock.getBlockPosition().getY() + 0.2F); + double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); +- Entity entity = ItemMonsterEgg.a(isourceblock.getWorld(), itemstack.getData(), d0, d1, d2); ++ // Entity entity = ItemMonsterEgg.a(isourceblock.getWorld(), itemstack.getData(), d0, d1, d2); ++ ++ // CraftBukkit start ++ World world = isourceblock.getWorld(); ++ ItemStack itemstack1 = itemstack.cloneAndSubtract(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.count++; ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.count++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); ++ ++ Entity entity = ItemMonsterEgg.spawnCreature(isourceblock.getWorld(), itemstack.getData(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG); + + if (entity instanceof EntityLiving && itemstack.hasName()) { + ((EntityInsentient) entity).setCustomName(itemstack.getName()); + } + +- itemstack.cloneAndSubtract(1); ++ // itemstack.a(1); // Handled during event processing ++ // CraftBukkit end + return itemstack; + } + }); +@@ -90,10 +127,39 @@ + double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); + double d1 = (double) ((float) isourceblock.getBlockPosition().getY() + 0.2F); + double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); +- EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), d0, d1, d2, itemstack); ++ // CraftBukkit start ++ World world = isourceblock.getWorld(); ++ ItemStack itemstack1 = itemstack.cloneAndSubtract(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.count++; ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.count++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); ++ EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1); + + isourceblock.getWorld().addEntity(entityfireworks); +- itemstack.cloneAndSubtract(1); ++ // itemstack.a(1); // Handled during event processing ++ // CraftBukkit end + return itemstack; + } + +@@ -114,8 +180,38 @@ + double d4 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentY(); + double d5 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentZ(); + +- world.addEntity(new EntitySmallFireball(world, d0, d1, d2, d3, d4, d5)); +- itemstack.cloneAndSubtract(1); ++ // CraftBukkit start ++ ItemStack itemstack1 = itemstack.cloneAndSubtract(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d3, d4, d5)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.count++; ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.count++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ EntitySmallFireball entitysmallfireball = new EntitySmallFireball(world, d0, d1, d2, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); ++ entitysmallfireball.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) isourceblock.getTileEntity()); ++ ++ world.addEntity(entitysmallfireball); ++ // itemstack.a(1); // Handled during event processing ++ // CraftBukkit end + return itemstack; + } + +@@ -146,10 +242,38 @@ + d3 = 0.0D; + } + +- EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); ++ // EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); ++ // CraftBukkit start ++ ItemStack itemstack1 = itemstack.cloneAndSubtract(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.count++; ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.count++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ EntityBoat entityboat = new EntityBoat(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); ++ // CraftBukkit end + + world.addEntity(entityboat); +- itemstack.cloneAndSubtract(1); ++ // itemstack.a(1); // CraftBukkit - handled during event processing + return itemstack; + } + +@@ -164,9 +288,48 @@ + ItemBucket itembucket = (ItemBucket) itemstack.getItem(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + ++ // CraftBukkit start ++ World world = isourceblock.getWorld(); ++ int x = blockposition.getX(); ++ int y = blockposition.getY(); ++ int z = blockposition.getZ(); ++ if (world.isEmpty(blockposition) || !world.getType(blockposition).getBlock().getMaterial().isBuildable()) { ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); ++ } ++ // CraftBukkit end ++ + if (itembucket.a(isourceblock.getWorld(), blockposition)) { +- itemstack.setItem(Items.BUCKET); +- itemstack.count = 1; ++ // CraftBukkit start - Handle stacked buckets ++ Item item = Items.BUCKET; ++ if (--itemstack.count == 0) { ++ itemstack.setItem(Items.BUCKET); ++ itemstack.count = 1; ++ } else if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { ++ this.b.a(isourceblock, new ItemStack(item)); ++ } ++ // CraftBukkit end + return itemstack; + } else { + return this.b.a(isourceblock, itemstack); +@@ -197,6 +360,30 @@ + item = Items.LAVA_BUCKET; + } + ++ // CraftBukkit start ++ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ // CraftBukkit end ++ + world.setAir(blockposition); + if (--itemstack.count == 0) { + itemstack.setItem(item); +@@ -215,11 +402,39 @@ + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ // CraftBukkit end ++ + if (world.isEmpty(blockposition)) { +- world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); +- if (itemstack.isDamaged(1, world.random)) { +- itemstack.count = 0; ++ // CraftBukkit start - Ignition by dispensing flint and steel ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()).isCancelled()) { ++ world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ if (itemstack.isDamaged(1, world.random)) { ++ itemstack.count = 0; ++ } + } ++ // CraftBukkit end + } else if (world.getType(blockposition).getBlock() == Blocks.TNT) { + Blocks.TNT.postBreak(world, blockposition, Blocks.TNT.getBlockData().set(BlockTNT.EXPLODE, Boolean.valueOf(true))); + world.setAir(blockposition); +@@ -247,6 +462,30 @@ + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asNewCraftStack(itemstack.getItem()); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ // CraftBukkit end ++ + if (ItemDye.a(itemstack, world, blockposition)) { + if (!world.isClientSide) { + world.triggerEffect(2005, blockposition, 0); +@@ -274,11 +513,40 @@ + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); +- EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); ++ // EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); ++ ++ // CraftBukkit start ++ ItemStack itemstack1 = itemstack.cloneAndSubtract(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX() + 0.5, blockposition.getY() + 0.5, blockposition.getZ() + 0.5)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.count++; ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.count++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLiving) null); ++ // CraftBukkit end + + world.addEntity(entitytntprimed); + world.makeSound(entitytntprimed, "game.tnt.primed", 1.0F, 1.0F); +- --itemstack.count; ++ // --itemstack.count; // CraftBukkit - handled above + return itemstack; + } + }); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Enchantment.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Enchantment.patch new file mode 100644 index 0000000..5e419c5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Enchantment.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/server/Enchantment.java ++++ b/net/minecraft/server/Enchantment.java +@@ -8,6 +8,7 @@ + + public abstract class Enchantment { + ++ // CraftBukkit - update CraftEnchant.getName(i) if this changes + private static final Enchantment[] byId = new Enchantment[256]; + public static final Enchantment[] b; + private static final Map E = Maps.newHashMap(); +@@ -55,6 +56,8 @@ + Enchantment.byId[i] = this; + Enchantment.E.put(minecraftkey, this); + } ++ ++ org.bukkit.enchantments.Enchantment.registerEnchantment(new org.bukkit.craftbukkit.enchantments.CraftEnchantment(this)); // CraftBukkit + } + + public static Enchantment getByName(String s) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EnchantmentThorns.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EnchantmentThorns.patch new file mode 100644 index 0000000..1329a10 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EnchantmentThorns.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/EnchantmentThorns.java ++++ b/net/minecraft/server/EnchantmentThorns.java +@@ -29,7 +29,7 @@ + Random random = entityliving.bc(); + ItemStack itemstack = EnchantmentManager.a(Enchantment.THORNS, entityliving); + +- if (a(i, random)) { ++ if (entity != null && a(i, random)) { // CraftBukkit + if (entity != null) { + entity.damageEntity(DamageSource.a(entityliving), (float) b(i, random)); + entity.makeSound("damage.thorns", 0.5F, 1.0F); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Entity.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Entity.patch new file mode 100644 index 0000000..6e7195e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Entity.patch @@ -0,0 +1,617 @@ +--- a/net/minecraft/server/Entity.java ++++ b/net/minecraft/server/Entity.java +@@ -6,8 +6,40 @@ + import java.util.UUID; + import java.util.concurrent.Callable; + ++// CraftBukkit start ++import org.bukkit.Bukkit; ++import org.bukkit.Location; ++import org.bukkit.Server; ++import org.bukkit.TravelAgent; ++import org.bukkit.block.BlockFace; ++import org.bukkit.entity.Hanging; ++import org.bukkit.entity.LivingEntity; ++import org.bukkit.entity.Painting; ++import org.bukkit.entity.Vehicle; ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.hanging.HangingBreakByEntityEvent; ++import org.bukkit.event.painting.PaintingBreakByEntityEvent; ++import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; ++import org.bukkit.event.vehicle.VehicleEnterEvent; ++import org.bukkit.event.vehicle.VehicleExitEvent; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.entity.CraftEntity; ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityCombustEvent; ++import org.bukkit.event.entity.EntityPortalEvent; ++import org.bukkit.plugin.PluginManager; ++// CraftBukkit end ++ + public abstract class Entity implements ICommandListener { + ++ // CraftBukkit start ++ private static final int CURRENT_LEVEL = 2; ++ static boolean isLevelAtLeast(NBTTagCompound tag, int level) { ++ return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; ++ } ++ // CraftBukikt end ++ + private static final AxisAlignedBB a = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + private static int entityCount; + private int id; +@@ -79,6 +111,9 @@ + private boolean invulnerable; + protected UUID uniqueID; + private final CommandObjectiveExecutor au; ++ public boolean valid; // CraftBukkit ++ public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only ++ public boolean forceExplosionKnockback; // CraftBukkit - SPIGOT-949 + + public int getId() { + return this.id; +@@ -152,6 +187,33 @@ + } + + protected void setYawPitch(float f, float f1) { ++ // CraftBukkit start - yaw was sometimes set to NaN, so we need to set it back to 0 ++ if (Float.isNaN(f)) { ++ f = 0; ++ } ++ ++ if (f == Float.POSITIVE_INFINITY || f == Float.NEGATIVE_INFINITY) { ++ if (this instanceof EntityPlayer) { ++ this.world.getServer().getLogger().warning(this.getName() + " was caught trying to crash the server with an invalid yaw"); ++ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope"); ++ } ++ f = 0; ++ } ++ ++ // pitch was sometimes set to NaN, so we need to set it back to 0 ++ if (Float.isNaN(f1)) { ++ f1 = 0; ++ } ++ ++ if (f1 == Float.POSITIVE_INFINITY || f1 == Float.NEGATIVE_INFINITY) { ++ if (this instanceof EntityPlayer) { ++ this.world.getServer().getLogger().warning(this.getName() + " was caught trying to crash the server with an invalid pitch"); ++ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope"); ++ } ++ f1 = 0; ++ } ++ // CraftBukkit end ++ + this.yaw = f % 360.0F; + this.pitch = f1 % 360.0F; + } +@@ -188,7 +250,7 @@ + int i = this.L(); + + if (this.ak) { +- if (minecraftserver.getAllowNether()) { ++ if (true || minecraftserver.getAllowNether()) { // CraftBukkit + if (this.vehicle == null && this.al++ >= i) { + this.al = i; + this.portalCooldown = this.aq(); +@@ -265,6 +327,27 @@ + protected void burnFromLava() { + if (!this.fireProof) { + this.damageEntity(DamageSource.LAVA, 4.0F); ++ ++ // CraftBukkit start - Fallen in lava TODO: this event spams! ++ if (this instanceof EntityLiving) { ++ if (fireTicks <= 0) { ++ // not on fire yet ++ // TODO: shouldn't be sending null for the block ++ org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k); ++ org.bukkit.entity.Entity damagee = this.getBukkitEntity(); ++ EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15); ++ this.world.getServer().getPluginManager().callEvent(combustEvent); ++ ++ if (!combustEvent.isCancelled()) { ++ this.setOnFire(combustEvent.getDuration()); ++ } ++ } else { ++ // This will be called every single tick the entity is in lava, so don't throw an event ++ this.setOnFire(15); ++ } ++ return; ++ } ++ // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls + this.setOnFire(15); + } + } +@@ -302,6 +385,22 @@ + this.a(this.getBoundingBox().c(d0, d1, d2)); + this.recalcPosition(); + } else { ++ // CraftBukkit start - Don't do anything if we aren't moving ++ // We need to do this regardless of whether or not we are moving thanks to portals ++ try { ++ this.checkBlockCollisions(); ++ } catch (Throwable throwable) { ++ CrashReport crashreport = CrashReport.a(throwable, "Checking entity block collision"); ++ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being checked for collision"); ++ ++ this.appendEntityCrashDetails(crashreportsystemdetails); ++ throw new ReportedException(crashreport); ++ } ++ // Check if we're moving ++ if (d0 == 0 && d1 == 0 && d2 == 0 && this.vehicle == null && this.passenger == null) { ++ return; ++ } ++ // CraftBukkit end + this.world.methodProfiler.a("move"); + double d3 = this.locX; + double d4 = this.locY; +@@ -522,6 +621,26 @@ + block.a(this.world, this); + } + ++ // CraftBukkit start ++ if (positionChanged && getBukkitEntity() instanceof Vehicle) { ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.block.Block bl = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)); ++ ++ if (d6 > d0) { ++ bl = bl.getRelative(BlockFace.EAST); ++ } else if (d6 < d0) { ++ bl = bl.getRelative(BlockFace.WEST); ++ } else if (d8 > d2) { ++ bl = bl.getRelative(BlockFace.SOUTH); ++ } else if (d8 < d2) { ++ bl = bl.getRelative(BlockFace.NORTH); ++ } ++ ++ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl); ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ // CraftBukkit end ++ + if (this.s_() && !flag && this.vehicle == null) { + double d21 = this.locX - d3; + double d22 = this.locY - d4; +@@ -532,7 +651,7 @@ + } + + if (block != null && this.onGround) { +- block.a(this.world, blockposition, this); ++ // block.a(this.world, blockposition, this); // CraftBukkit moved down + } + + this.M = (float) ((double) this.M + (double) MathHelper.sqrt(d21 * d21 + d23 * d23) * 0.6D); +@@ -550,9 +669,12 @@ + } + + this.a(blockposition, block); ++ block.a(this.world, blockposition, this); // CraftBukkit moved from above + } + } + ++ // CraftBukkit start - Move to the top of the method ++ /* + try { + this.checkBlockCollisions(); + } catch (Throwable throwable) { +@@ -562,6 +684,8 @@ + this.appendEntityCrashDetails(crashreportsystemdetails); + throw new ReportedException(crashreport); + } ++ */ ++ // CraftBukkit end + + boolean flag2 = this.U(); + +@@ -569,7 +693,16 @@ + this.burn(1); + if (!flag2) { + ++this.fireTicks; +- if (this.fireTicks == 0) { ++ // CraftBukkit start - Not on fire yet ++ if (this.fireTicks <= 0) { // Only throw events on the first combust, otherwise it spams ++ EntityCombustEvent event = new EntityCombustEvent(getBukkitEntity(), 8); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ setOnFire(event.getDuration()); ++ } ++ } else { ++ // CraftBukkit end + this.setOnFire(8); + } + } +@@ -675,7 +808,7 @@ + return null; + } + +- protected void burn(int i) { ++ protected void burn(float i) { // CraftBukkit - int -> float + if (!this.fireProof) { + this.damageEntity(DamageSource.FIRE, (float) i); + } +@@ -818,6 +951,13 @@ + } + + public void spawnIn(World world) { ++ // CraftBukkit start ++ if (world == null) { ++ die(); ++ this.world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(); ++ return; ++ } ++ // CraftBukkit end + this.world = world; + } + +@@ -1010,6 +1150,18 @@ + try { + nbttagcompound.set("Pos", this.a(new double[] { this.locX, this.locY, this.locZ})); + nbttagcompound.set("Motion", this.a(new double[] { this.motX, this.motY, this.motZ})); ++ ++ // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero ++ // TODO: make sure this is the best way to address this. ++ if (Float.isNaN(this.yaw)) { ++ this.yaw = 0; ++ } ++ ++ if (Float.isNaN(this.pitch)) { ++ this.pitch = 0; ++ } ++ // CraftBukkit end ++ + nbttagcompound.set("Rotation", this.a(new float[] { this.yaw, this.pitch})); + nbttagcompound.setFloat("FallDistance", this.fallDistance); + nbttagcompound.setShort("Fire", (short) this.fireTicks); +@@ -1020,6 +1172,11 @@ + nbttagcompound.setInt("PortalCooldown", this.portalCooldown); + nbttagcompound.setLong("UUIDMost", this.getUniqueID().getMostSignificantBits()); + nbttagcompound.setLong("UUIDLeast", this.getUniqueID().getLeastSignificantBits()); ++ // CraftBukkit start ++ nbttagcompound.setLong("WorldUUIDLeast", this.world.getDataManager().getUUID().getLeastSignificantBits()); ++ nbttagcompound.setLong("WorldUUIDMost", this.world.getDataManager().getUUID().getMostSignificantBits()); ++ nbttagcompound.setInt("Bukkit.updateLevel", CURRENT_LEVEL); ++ // CraftBukkit end + if (this.getCustomName() != null && this.getCustomName().length() > 0) { + nbttagcompound.setString("CustomName", this.getCustomName()); + nbttagcompound.setBoolean("CustomNameVisible", this.getCustomNameVisible()); +@@ -1057,6 +1214,8 @@ + this.motX = nbttaglist1.d(0); + this.motY = nbttaglist1.d(1); + this.motZ = nbttaglist1.d(2); ++ ++ /* CraftBukkit start - Moved section down + if (Math.abs(this.motX) > 10.0D) { + this.motX = 0.0D; + } +@@ -1068,6 +1227,7 @@ + if (Math.abs(this.motZ) > 10.0D) { + this.motZ = 0.0D; + } ++ // CraftBukkit end */ + + this.lastX = this.P = this.locX = nbttaglist.d(0); + this.lastY = this.Q = this.locY = nbttaglist.d(1); +@@ -1103,6 +1263,58 @@ + this.setPosition(this.locX, this.locY, this.locZ); + } + ++ // CraftBukkit start ++ if (this instanceof EntityLiving) { ++ EntityLiving entity = (EntityLiving) this; ++ ++ // Reset the persistence for tamed animals ++ if (entity instanceof EntityTameableAnimal && !isLevelAtLeast(nbttagcompound, 2) && !nbttagcompound.getBoolean("PersistenceRequired")) { ++ EntityInsentient entityinsentient = (EntityInsentient) entity; ++ entityinsentient.persistent = !entityinsentient.isTypeNotPersistent(); ++ } ++ } ++ // CraftBukkit end ++ ++ // CraftBukkit start - Exempt Vehicles from notch's sanity check ++ if (!(getBukkitEntity() instanceof Vehicle)) { ++ if (Math.abs(this.motX) > 10.0D) { ++ this.motX = 0.0D; ++ } ++ ++ if (Math.abs(this.motY) > 10.0D) { ++ this.motY = 0.0D; ++ } ++ ++ if (Math.abs(this.motZ) > 10.0D) { ++ this.motZ = 0.0D; ++ } ++ } ++ // CraftBukkit end ++ ++ // CraftBukkit start - Reset world ++ if (this instanceof EntityPlayer) { ++ Server server = Bukkit.getServer(); ++ org.bukkit.World bworld = null; ++ ++ // TODO: Remove World related checks, replaced with WorldUID ++ String worldName = nbttagcompound.getString("world"); ++ ++ if (nbttagcompound.hasKey("WorldUUIDMost") && nbttagcompound.hasKey("WorldUUIDLeast")) { ++ UUID uid = new UUID(nbttagcompound.getLong("WorldUUIDMost"), nbttagcompound.getLong("WorldUUIDLeast")); ++ bworld = server.getWorld(uid); ++ } else { ++ bworld = server.getWorld(worldName); ++ } ++ ++ if (bworld == null) { ++ EntityPlayer entityPlayer = (EntityPlayer) this; ++ bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(entityPlayer.dimension).getWorld(); ++ } ++ ++ spawnIn(bworld == null? null : ((CraftWorld) bworld).getHandle()); ++ } ++ // CraftBukkit end ++ + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Loading entity NBT"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded"); +@@ -1164,6 +1376,12 @@ + + public EntityItem a(ItemStack itemstack, float f) { + if (itemstack.count != 0 && itemstack.getItem() != null) { ++ // CraftBukkit start - Capture drops for death event ++ if (this instanceof EntityLiving && ((EntityLiving) this).drops != null) { ++ ((EntityLiving) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); ++ return null; ++ } ++ // CraftBukkit end + EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY + (double) f, this.locZ, itemstack); + + entityitem.p(); +@@ -1277,17 +1495,70 @@ + return (double) this.length * 0.75D; + } + ++ // CraftBukkit start ++ protected CraftEntity bukkitEntity; ++ ++ public CraftEntity getBukkitEntity() { ++ if (bukkitEntity == null) { ++ bukkitEntity = CraftEntity.getEntity(world.getServer(), this); ++ } ++ return bukkitEntity; ++ } ++ + public void mount(Entity entity) { ++ Entity originalVehicle = this.vehicle; ++ Entity originalPassenger = this.vehicle == null ? null : this.vehicle.passenger; ++ PluginManager pluginManager = Bukkit.getPluginManager(); ++ getBukkitEntity(); // make sure bukkitEntity is initialised ++ // CraftBukkit end + this.ar = 0.0D; + this.as = 0.0D; + if (entity == null) { + if (this.vehicle != null) { ++ // CraftBukkit start ++ if ((this.bukkitEntity instanceof LivingEntity) && (this.vehicle.getBukkitEntity() instanceof Vehicle)) { ++ VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.bukkitEntity); ++ pluginManager.callEvent(event); ++ ++ if (event.isCancelled() || vehicle != originalVehicle) { ++ return; ++ } ++ } ++ // CraftBukkit end + this.setPositionRotation(this.vehicle.locX, this.vehicle.getBoundingBox().b + (double) this.vehicle.length, this.vehicle.locZ, this.yaw, this.pitch); + this.vehicle.passenger = null; + } + + this.vehicle = null; + } else { ++ // CraftBukkit start ++ if ((this.bukkitEntity instanceof LivingEntity) && (entity.getBukkitEntity() instanceof Vehicle) && entity.world.isChunkLoaded((int) entity.locX >> 4, (int) entity.locZ >> 4, true)) { ++ // It's possible to move from one vehicle to another. We need to check if they're already in a vehicle, and fire an exit event if they are. ++ VehicleExitEvent exitEvent = null; ++ if (this.vehicle != null && this.vehicle.getBukkitEntity() instanceof Vehicle) { ++ exitEvent = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.bukkitEntity); ++ pluginManager.callEvent(exitEvent); ++ ++ if (exitEvent.isCancelled() || this.vehicle != originalVehicle || (this.vehicle != null && this.vehicle.passenger != originalPassenger)) { ++ return; ++ } ++ } ++ ++ VehicleEnterEvent event = new VehicleEnterEvent((Vehicle) entity.getBukkitEntity(), this.bukkitEntity); ++ pluginManager.callEvent(event); ++ ++ // If a plugin messes with the vehicle or the vehicle's passenger ++ if (event.isCancelled() || this.vehicle != originalVehicle || (this.vehicle != null && this.vehicle.passenger != originalPassenger)) { ++ // If we only cancelled the enterevent then we need to put the player in a decent position. ++ if (exitEvent != null && this.vehicle == originalVehicle && this.vehicle != null && this.vehicle.passenger == originalPassenger) { ++ this.setPositionRotation(this.vehicle.locX, this.vehicle.getBoundingBox().b + (double) this.vehicle.length, this.vehicle.locZ, this.yaw, this.pitch); ++ this.vehicle.passenger = null; ++ this.vehicle = null; ++ } ++ return; ++ } ++ } ++ // CraftBukkit end + if (this.vehicle != null) { + this.vehicle.passenger = null; + } +@@ -1406,10 +1677,49 @@ + } + + public void onLightningStrike(EntityLightning entitylightning) { +- this.damageEntity(DamageSource.LIGHTNING, 5.0F); ++ // CraftBukkit start ++ final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity(); ++ final org.bukkit.entity.Entity stormBukkitEntity = entitylightning.getBukkitEntity(); ++ final PluginManager pluginManager = Bukkit.getPluginManager(); ++ ++ if (thisBukkitEntity instanceof Hanging) { ++ HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity); ++ PaintingBreakByEntityEvent paintingEvent = null; ++ ++ if (thisBukkitEntity instanceof Painting) { ++ paintingEvent = new PaintingBreakByEntityEvent((Painting) thisBukkitEntity, stormBukkitEntity); ++ } ++ ++ pluginManager.callEvent(hangingEvent); ++ ++ if (paintingEvent != null) { ++ paintingEvent.setCancelled(hangingEvent.isCancelled()); ++ pluginManager.callEvent(paintingEvent); ++ } ++ ++ if (hangingEvent.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { ++ return; ++ } ++ } ++ ++ if (this.fireProof) { ++ return; ++ } ++ CraftEventFactory.entityDamage = entitylightning; ++ if (!this.damageEntity(DamageSource.LIGHTNING, 5.0F)) { ++ CraftEventFactory.entityDamage = null; ++ return; ++ } ++ // CraftBukkit end + ++this.fireTicks; + if (this.fireTicks == 0) { +- this.setOnFire(8); ++ // CraftBukkit start - Call a combust event when lightning strikes ++ EntityCombustByEntityEvent entityCombustEvent = new EntityCombustByEntityEvent(stormBukkitEntity, thisBukkitEntity, 8); ++ pluginManager.callEvent(entityCombustEvent); ++ if (!entityCombustEvent.isCancelled()) { ++ this.setOnFire(entityCombustEvent.getDuration()); ++ } ++ // CraftBukkit end + } + + } +@@ -1550,32 +1860,83 @@ + if (!this.world.isClientSide && !this.dead) { + this.world.methodProfiler.a("changeDimension"); + MinecraftServer minecraftserver = MinecraftServer.getServer(); +- int j = this.dimension; +- WorldServer worldserver = minecraftserver.getWorldServer(j); +- WorldServer worldserver1 = minecraftserver.getWorldServer(i); ++ // CraftBukkit start - Move logic into new function "teleportToLocation" ++ // int j = this.dimension; ++ // WorldServer worldserver = minecraftserver.getWorldServer(j); ++ // WorldServer worldserver1 = minecraftserver.getWorldServer(i); ++ WorldServer exitWorld = null; ++ if (this.dimension < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // Plugins must specify exit from custom Bukkit worlds ++ // Only target existing worlds (compensate for allow-nether/allow-end as false) ++ for (WorldServer world : minecraftserver.worlds) { ++ if (world.dimension == i) { ++ exitWorld = world; ++ } ++ } ++ } ++ ++ Location enter = this.getBukkitEntity().getLocation(); ++ Location exit = exitWorld != null ? minecraftserver.getPlayerList().calculateTarget(enter, minecraftserver.getWorldServer(i)) : null; ++ boolean useTravelAgent = exitWorld != null && !(this.dimension == 1 && exitWorld.dimension == 1); // don't use agent for custom worlds or return from THE_END ++ ++ TravelAgent agent = exit != null ? (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().getTravelAgent() : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins ++ EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit, agent); ++ event.useTravelAgent(useTravelAgent); ++ event.getEntity().getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !this.isAlive()) { ++ return; ++ } ++ exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo(); ++ this.teleportTo(exit, true); ++ } ++ } ++ ++ public void teleportTo(Location exit, boolean portal) { ++ if (true) { ++ WorldServer worldserver = ((CraftWorld) getBukkitEntity().getLocation().getWorld()).getHandle(); ++ WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); ++ int i = worldserver1.dimension; ++ // CraftBukkit end + + this.dimension = i; ++ /* CraftBukkit start - TODO: Check if we need this + if (j == 1 && i == 1) { + worldserver1 = minecraftserver.getWorldServer(0); + this.dimension = 0; + } ++ // CraftBukkit end */ + + this.world.kill(this); + this.dead = false; + this.world.methodProfiler.a("reposition"); +- minecraftserver.getPlayerList().changeWorld(this, j, worldserver, worldserver1); ++ // CraftBukkit start - Ensure chunks are loaded in case TravelAgent is not used which would initially cause chunks to load during find/create ++ // minecraftserver.getPlayerList().changeWorld(this, j, worldserver, worldserver1); ++ boolean before = worldserver1.chunkProviderServer.forceChunkLoad; ++ worldserver1.chunkProviderServer.forceChunkLoad = true; ++ worldserver1.getMinecraftServer().getPlayerList().repositionEntity(this, exit, portal); ++ worldserver1.chunkProviderServer.forceChunkLoad = before; ++ // CraftBukkit end + this.world.methodProfiler.c("reloading"); + Entity entity = EntityTypes.createEntityByName(EntityTypes.b(this), worldserver1); + + if (entity != null) { + entity.n(this); ++ /* CraftBukkit start - We need to do this... + if (j == 1 && i == 1) { + BlockPosition blockposition = this.world.r(worldserver1.getSpawn()); + + entity.setPositionRotation(blockposition, entity.yaw, entity.pitch); + } ++ // CraftBukkit end */ + + worldserver1.addEntity(entity); ++ // CraftBukkit start - Forward the CraftEntity to the new entity ++ this.getBukkitEntity().setHandle(entity); ++ entity.bukkitEntity = this.getBukkitEntity(); ++ ++ if (this instanceof EntityInsentient) { ++ ((EntityInsentient)this).unleash(true, false); // Unleash to prevent duping of leads. ++ } ++ // CraftBukkit end + } + + this.dead = true; +@@ -1670,6 +2031,11 @@ + } + + public void setCustomName(String s) { ++ // CraftBukkit start - Add a sane limit for name length ++ if (s.length() > 256) { ++ s = s.substring(0, 256); ++ } ++ // CraftBukkit end + this.datawatcher.watch(2, s); + } + +@@ -1721,7 +2087,26 @@ + } + + public void a(AxisAlignedBB axisalignedbb) { +- this.boundingBox = axisalignedbb; ++ // CraftBukkit start - block invalid bounding boxes ++ double a = axisalignedbb.a, ++ b = axisalignedbb.b, ++ c = axisalignedbb.c, ++ d = axisalignedbb.d, ++ e = axisalignedbb.e, ++ f = axisalignedbb.f; ++ double len = axisalignedbb.d - axisalignedbb.a; ++ if (len < 0) d = a; ++ if (len > 64) d = a + 64.0; ++ ++ len = axisalignedbb.e - axisalignedbb.b; ++ if (len < 0) e = b; ++ if (len > 64) e = b + 64.0; ++ ++ len = axisalignedbb.f - axisalignedbb.c; ++ if (len < 0) f = c; ++ if (len > 64) f = c + 64.0; ++ this.boundingBox = new AxisAlignedBB(a, b, c, d, e, f); ++ // CraftBukkit end + } + + public float getHeadHeight() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityAgeable.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityAgeable.patch new file mode 100644 index 0000000..deef0f2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityAgeable.patch @@ -0,0 +1,57 @@ +--- a/net/minecraft/server/EntityAgeable.java ++++ b/net/minecraft/server/EntityAgeable.java +@@ -7,6 +7,7 @@ + protected int c; + private float bm = -1.0F; + private float bn; ++ public boolean ageLocked = false; // CraftBukkit + + public EntityAgeable(World world) { + super(world); +@@ -27,14 +28,14 @@ + if (entityageable != null) { + entityageable.setAgeRaw(-24000); + entityageable.setPositionRotation(this.locX, this.locY, this.locZ, 0.0F, 0.0F); +- this.world.addEntity(entityageable); ++ this.world.addEntity(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit + if (itemstack.hasName()) { + entityageable.setCustomName(itemstack.getName()); + } + + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; +- if (itemstack.count <= 0) { ++ if (itemstack.count == 0) { // CraftBukkit - allow less than 0 stacks as "infinite" + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + } +@@ -99,17 +100,19 @@ + super.b(nbttagcompound); + nbttagcompound.setInt("Age", this.getAge()); + nbttagcompound.setInt("ForcedAge", this.b); ++ nbttagcompound.setBoolean("AgeLocked", this.ageLocked); // CraftBukkit + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setAgeRaw(nbttagcompound.getInt("Age")); + this.b = nbttagcompound.getInt("ForcedAge"); ++ this.ageLocked = nbttagcompound.getBoolean("AgeLocked"); // CraftBukkit + } + + public void m() { + super.m(); +- if (this.world.isClientSide) { ++ 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]); +@@ -146,7 +149,7 @@ + this.a(flag ? 0.5F : 1.0F); + } + +- protected final void setSize(float f, float f1) { ++ public final void setSize(float f, float f1) { // CraftBukkit - protected to public + boolean flag = this.bm > 0.0F; + + this.bm = f; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityAnimal.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityAnimal.patch new file mode 100644 index 0000000..ee03038 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityAnimal.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/EntityAnimal.java ++++ b/net/minecraft/server/EntityAnimal.java +@@ -38,6 +38,9 @@ + + } + ++ /* CraftBukkit start ++ // Function disabled as it has no special function anymore after ++ // setSitting is disabled. + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; +@@ -46,6 +49,7 @@ + return super.damageEntity(damagesource, f); + } + } ++ // CraftBukkit end */ + + public float a(BlockPosition blockposition) { + return this.world.getType(blockposition.down()).getBlock() == Blocks.GRASS ? 10.0F : this.world.o(blockposition) - 0.5F; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityArmorStand.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityArmorStand.patch new file mode 100644 index 0000000..d7b6f74 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityArmorStand.patch @@ -0,0 +1,71 @@ +--- a/net/minecraft/server/EntityArmorStand.java ++++ b/net/minecraft/server/EntityArmorStand.java +@@ -2,6 +2,15 @@ + + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.inventory.EquipmentSlot; ++import org.bukkit.craftbukkit.CraftEquipmentSlot; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.entity.ArmorStand; ++import org.bukkit.entity.Player; ++import org.bukkit.event.player.PlayerArmorStandManipulateEvent; ++// CraftBukkit end ++ + public class EntityArmorStand extends EntityLiving { + + private static final Vector3f a = new Vector3f(0.0F, 0.0F, 0.0F); +@@ -332,6 +341,22 @@ + ItemStack itemstack1 = entityhuman.inventory.getItem(j); + ItemStack itemstack2; + ++ // CraftBukkit start ++ org.bukkit.inventory.ItemStack armorStandItem = CraftItemStack.asCraftMirror(itemstack); ++ org.bukkit.inventory.ItemStack playerHeldItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ Player player = (Player) entityhuman.getBukkitEntity(); ++ ArmorStand self = (ArmorStand) this.getBukkitEntity(); ++ ++ EquipmentSlot slot = CraftEquipmentSlot.getSlot(i); ++ PlayerArmorStandManipulateEvent armorStandManipulateEvent = new PlayerArmorStandManipulateEvent(player,self,playerHeldItem,armorStandItem,slot); ++ this.world.getServer().getPluginManager().callEvent(armorStandManipulateEvent); ++ ++ if (armorStandManipulateEvent.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ + if (entityhuman.abilities.canInstantlyBuild && (itemstack == null || itemstack.getItem() == Item.getItemOf(Blocks.AIR)) && itemstack1 != null) { + itemstack2 = itemstack1.cloneItemStack(); + itemstack2.count = 1; +@@ -352,6 +377,11 @@ + } + + public boolean damageEntity(DamageSource damagesource, float f) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { ++ return false; ++ } ++ // CraftBukkit end + if (this.world.isClientSide) { + return false; + } else if (DamageSource.OUT_OF_WORLD.equals(damagesource)) { +@@ -616,7 +646,8 @@ + return (this.datawatcher.getByte(10) & 8) != 0; + } + +- private void n(boolean flag) { ++ // PAIL ++ public void n(boolean flag) { // CraftBukkit - public + byte b0 = this.datawatcher.getByte(10); + + if (flag) { +@@ -628,6 +659,7 @@ + this.datawatcher.watch(10, Byte.valueOf(b0)); + } + ++ // PAIL + public boolean s() { + return (this.datawatcher.getByte(10) & 16) != 0; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityArrow.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityArrow.patch new file mode 100644 index 0000000..de6af82 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityArrow.patch @@ -0,0 +1,93 @@ +--- a/net/minecraft/server/EntityArrow.java ++++ b/net/minecraft/server/EntityArrow.java +@@ -2,6 +2,12 @@ + + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.entity.LivingEntity; ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.player.PlayerPickupItemEvent; ++// CraftBukkit end ++ + public class EntityArrow extends Entity implements IProjectile { + + private int d = -1; +@@ -35,6 +41,7 @@ + super(world); + this.j = 10.0D; + this.shooter = entityliving; ++ this.projectileSource = (LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit + if (entityliving instanceof EntityHuman) { + this.fromPlayer = 1; + } +@@ -62,6 +69,7 @@ + super(world); + this.j = 10.0D; + this.shooter = entityliving; ++ this.projectileSource = (LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit + if (entityliving instanceof EntityHuman) { + this.fromPlayer = 1; + } +@@ -201,6 +209,7 @@ + float f3; + + if (movingobjectposition != null) { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); // CraftBukkit - Call event + if (movingobjectposition.entity != null) { + f2 = MathHelper.sqrt(this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ); + int k = MathHelper.f((double) f2 * this.damage); +@@ -217,11 +226,18 @@ + damagesource = DamageSource.arrow(this, this.shooter); + } + +- if (this.isBurning() && !(movingobjectposition.entity instanceof EntityEnderman)) { +- movingobjectposition.entity.setOnFire(5); ++ // CraftBukkit start - Moved damage call ++ if (movingobjectposition.entity.damageEntity(damagesource, (float) k)) { ++ if (this.isBurning() && !(movingobjectposition.entity instanceof EntityEnderman) && (!(movingobjectposition.entity instanceof EntityPlayer) || !(this.shooter instanceof EntityPlayer) || this.world.pvpMode)) { // CraftBukkit - abide by pvp setting if destination is a player ++ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 5); ++ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); ++ if (!combustEvent.isCancelled()) { ++ movingobjectposition.entity.setOnFire(combustEvent.getDuration()); ++ } ++ // CraftBukkit end + } + +- if (movingobjectposition.entity.damageEntity(damagesource, (float) k)) { ++ // if (movingobjectposition.entity.damageEntity(damagesource, (float) k)) { // CraftBukkit - moved up + if (movingobjectposition.entity instanceof EntityLiving) { + EntityLiving entityliving = (EntityLiving) movingobjectposition.entity; + +@@ -383,6 +399,20 @@ + + public void d(EntityHuman entityhuman) { + if (!this.world.isClientSide && this.inGround && this.shake <= 0) { ++ // CraftBukkit start ++ ItemStack itemstack = new ItemStack(Items.ARROW); ++ if (this.fromPlayer == 1 && entityhuman.inventory.canHold(itemstack) > 0) { ++ EntityItem item = new EntityItem(this.world, this.locX, this.locY, this.locZ, itemstack); ++ ++ PlayerPickupItemEvent event = new PlayerPickupItemEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), new org.bukkit.craftbukkit.entity.CraftItem(this.world.getServer(), this, item), 0); ++ // event.setCancelled(!entityhuman.canPickUpLoot); TODO ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ } ++ // CraftBukkit end + boolean flag = this.fromPlayer == 1 || this.fromPlayer == 2 && entityhuman.abilities.canInstantlyBuild; + + if (this.fromPlayer == 1 && !entityhuman.inventory.pickup(new ItemStack(Items.ARROW, 1))) { +@@ -438,4 +468,10 @@ + + return (b0 & 1) != 0; + } ++ ++ // CraftBukkit start ++ public boolean isInGround() { ++ return inGround; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityBoat.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityBoat.patch new file mode 100644 index 0000000..8545c28 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityBoat.patch @@ -0,0 +1,225 @@ +--- a/net/minecraft/server/EntityBoat.java ++++ b/net/minecraft/server/EntityBoat.java +@@ -2,6 +2,16 @@ + + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.entity.Vehicle; ++import org.bukkit.event.vehicle.VehicleDamageEvent; ++import org.bukkit.event.vehicle.VehicleDestroyEvent; ++import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; ++import org.bukkit.event.vehicle.VehicleMoveEvent; ++// CraftBukkit end ++ + public class EntityBoat extends Entity { + + private boolean a; +@@ -13,6 +23,27 @@ + private double g; + private double h; + ++ // CraftBukkit start ++ public double maxSpeed = 0.4D; ++ public double occupiedDeceleration = 0.2D; ++ public double unoccupiedDeceleration = -1; ++ public boolean landBoats = false; ++ ++ @Override ++ public void collide(Entity entity) { ++ org.bukkit.entity.Entity hitEntity = (entity == null) ? null : entity.getBukkitEntity(); ++ ++ VehicleEntityCollisionEvent event = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), hitEntity); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ super.collide(entity); ++ } ++ // CraftBukkit end ++ + public EntityBoat(World world) { + super(world); + this.a = true; +@@ -52,6 +83,8 @@ + this.lastX = d0; + this.lastY = d1; + this.lastZ = d2; ++ ++ this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleCreateEvent((Vehicle) this.getBukkitEntity())); // CraftBukkit + } + + public double an() { +@@ -65,6 +98,19 @@ + if (this.passenger != null && this.passenger == damagesource.getEntity() && damagesource instanceof EntityDamageSourceIndirect) { + return false; + } else { ++ // CraftBukkit start ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.entity.Entity attacker = (damagesource.getEntity() == null) ? null : damagesource.getEntity().getBukkitEntity(); ++ ++ VehicleDamageEvent event = new VehicleDamageEvent(vehicle, attacker, (double) f); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return true; ++ } ++ // f = event.getDamage(); // TODO Why don't we do this? ++ // CraftBukkit end ++ + this.b(-this.m()); + this.a(10); + this.setDamage(this.j() + f * 10.0F); +@@ -72,6 +118,15 @@ + boolean flag = damagesource.getEntity() instanceof EntityHuman && ((EntityHuman) damagesource.getEntity()).abilities.canInstantlyBuild; + + if (flag || this.j() > 40.0F) { ++ // CraftBukkit start ++ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker); ++ this.world.getServer().getPluginManager().callEvent(destroyEvent); ++ ++ if (destroyEvent.isCancelled()) { ++ this.setDamage(40F); // Maximize damage so this doesn't get triggered again right away ++ return true; ++ } ++ // CraftBukkit end + if (this.passenger != null) { + this.passenger.mount(this); + } +@@ -95,6 +150,13 @@ + } + + public void t_() { ++ // CraftBukkit start ++ double prevX = this.locX; ++ double prevY = this.locY; ++ double prevZ = this.locZ; ++ float prevYaw = this.yaw; ++ float prevPitch = this.pitch; ++ // CraftBukkit end + super.t_(); + if (this.l() > 0) { + this.a(this.l() - 1); +@@ -196,6 +258,19 @@ + this.motX += -Math.sin((double) (f * 3.1415927F / 180.0F)) * this.b * (double) entityliving.ba * 0.05000000074505806D; + this.motZ += Math.cos((double) (f * 3.1415927F / 180.0F)) * this.b * (double) entityliving.ba * 0.05000000074505806D; + } ++ // CraftBukkit start - Support unoccupied deceleration ++ else if (unoccupiedDeceleration >= 0) { ++ this.motX *= unoccupiedDeceleration; ++ this.motZ *= unoccupiedDeceleration; ++ // Kill lingering speed ++ if (motX <= 0.00001) { ++ motX = 0; ++ } ++ if (motZ <= 0.00001) { ++ motZ = 0; ++ } ++ } ++ // CraftBukkit end + + d4 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + if (d4 > 0.35D) { +@@ -230,16 +305,26 @@ + Block block = this.world.getType(blockposition).getBlock(); + + if (block == Blocks.SNOW_LAYER) { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, l, j1, j, Blocks.AIR, 0).isCancelled()) { ++ continue; ++ } ++ // CraftBukkit end + this.world.setAir(blockposition); + this.positionChanged = false; + } else if (block == Blocks.WATERLILY) { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, l, j1, j, Blocks.AIR, 0).isCancelled()) { ++ continue; ++ } ++ // CraftBukkit end + this.world.setAir(blockposition, true); + this.positionChanged = false; + } + } + } + +- if (this.onGround) { ++ if (this.onGround && !this.landBoats) { // CraftBukkit + this.motX *= 0.5D; + this.motY *= 0.5D; + this.motZ *= 0.5D; +@@ -248,6 +333,11 @@ + this.move(this.motX, this.motY, this.motZ); + if (this.positionChanged && d3 > 0.2975D) { + if (!this.world.isClientSide && !this.dead) { ++ // CraftBukkit start ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, null); ++ this.world.getServer().getPluginManager().callEvent(destroyEvent); ++ if (!destroyEvent.isCancelled()) { + this.die(); + if (this.world.getGameRules().getBoolean("doEntityDrops")) { + for (k = 0; k < 3; ++k) { +@@ -258,6 +348,7 @@ + this.a(Items.STICK, 1, 0.0F); + } + } ++ } // CraftBukkit end + } + } else { + this.motX *= 0.9900000095367432D; +@@ -285,6 +376,22 @@ + + this.yaw = (float) ((double) this.yaw + d12); + this.setYawPitch(this.yaw, this.pitch); ++ ++ // CraftBukkit start ++ org.bukkit.Server server = this.world.getServer(); ++ org.bukkit.World bworld = this.world.getWorld(); ++ ++ Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); ++ Location to = new Location(bworld, this.locX, this.locY, this.locZ, this.yaw, this.pitch); ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ ++ server.getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle)); ++ ++ if (!from.equals(to)) { ++ VehicleMoveEvent event = new VehicleMoveEvent(vehicle, from, to); ++ server.getPluginManager().callEvent(event); ++ } ++ // CraftBukkit end + if (!this.world.isClientSide) { + List list = this.world.getEntities(this, this.getBoundingBox().grow(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + +@@ -299,6 +406,7 @@ + } + + if (this.passenger != null && this.passenger.dead) { ++ this.passenger.vehicle = null; // CraftBukkit + this.passenger = null; + } + +@@ -336,6 +444,11 @@ + if (this.fallDistance > 3.0F) { + this.e(this.fallDistance, 1.0F); + if (!this.world.isClientSide && !this.dead) { ++ // CraftBukkit start ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, null); ++ this.world.getServer().getPluginManager().callEvent(destroyEvent); ++ if (!destroyEvent.isCancelled()) { + this.die(); + if (this.world.getGameRules().getBoolean("doEntityDrops")) { + int i; +@@ -348,6 +461,7 @@ + this.a(Items.STICK, 1, 0.0F); + } + } ++ } // CraftBukkit end + } + + this.fallDistance = 0.0F; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityChicken.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityChicken.patch new file mode 100644 index 0000000..190c725 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityChicken.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/server/EntityChicken.java ++++ b/net/minecraft/server/EntityChicken.java +@@ -35,6 +35,11 @@ + } + + public void m() { ++ // CraftBukkit start ++ if (this.isChickenJockey()) { ++ this.persistent = !this.isTypeNotPersistent(); ++ } ++ // CraftBukkit end + super.m(); + this.bq = this.bm; + this.bp = this.bo; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCow.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCow.patch new file mode 100644 index 0000000..af9721a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCow.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/server/EntityCow.java ++++ b/net/minecraft/server/EntityCow.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++// CraftBukkit end ++ + public class EntityCow extends EntityAnimal { + + public EntityCow(World world) { +@@ -71,11 +76,21 @@ + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.BUCKET && !entityhuman.abilities.canInstantlyBuild && !this.isBaby()) { +- if (itemstack.count-- == 1) { +- entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, new ItemStack(Items.MILK_BUCKET)); +- } else if (!entityhuman.inventory.pickup(new ItemStack(Items.MILK_BUCKET))) { +- entityhuman.drop(new ItemStack(Items.MILK_BUCKET, 1, 0), false); ++ // CraftBukkit start - Got milk? ++ org.bukkit.Location loc = this.getBukkitEntity().getLocation(); ++ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), null, itemstack, Items.MILK_BUCKET); ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ ++ ItemStack result = CraftItemStack.asNMSCopy(event.getItemStack()); ++ if (--itemstack.count <= 0) { ++ entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, result); ++ } else if (!entityhuman.inventory.pickup(result)) { ++ entityhuman.drop(result, false); + } ++ // CraftBukkit end + + return true; + } else { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCreature.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCreature.patch new file mode 100644 index 0000000..5101551 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCreature.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/server/EntityCreature.java ++++ b/net/minecraft/server/EntityCreature.java +@@ -2,6 +2,10 @@ + + import java.util.UUID; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityUnleashEvent; ++// CraftBukkit end ++ + public abstract class EntityCreature extends EntityInsentient { + + public static final UUID bk = UUID.fromString("E199AD21-BA8A-4C53-8D13-6182D5C69D3A"); +@@ -69,6 +73,7 @@ + + if (this instanceof EntityTameableAnimal && ((EntityTameableAnimal) this).isSitting()) { + if (f > 10.0F) { ++ this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit + this.unleash(true, true); + } + +@@ -100,6 +105,7 @@ + } + + if (f > 10.0F) { ++ this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit + this.unleash(true, true); + } + } else if (!this.cc() && this.bm) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCreeper.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCreeper.patch new file mode 100644 index 0000000..3b023cb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityCreeper.patch @@ -0,0 +1,105 @@ +--- a/net/minecraft/server/EntityCreeper.java ++++ b/net/minecraft/server/EntityCreeper.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.ExplosionPrimeEvent; ++// CraftBukkit end ++ + public class EntityCreeper extends EntityMonster { + + private int a; +@@ -7,6 +12,7 @@ + private int maxFuseTicks = 30; + private int explosionRadius = 3; + private int bn = 0; ++ private int record = -1; // CraftBukkit + + public EntityCreeper(World world) { + super(world); +@@ -110,19 +116,39 @@ + } + + public void die(DamageSource damagesource) { +- super.die(damagesource); ++ // super.die(damagesource); // CraftBukkit - Moved to end + if (damagesource.getEntity() instanceof EntitySkeleton) { + int i = Item.getId(Items.RECORD_13); + int j = Item.getId(Items.RECORD_WAIT); + int k = i + this.random.nextInt(j - i + 1); + +- this.a(Item.getById(k), 1); ++ // CraftBukkit start - Store record for now, drop in dropDeathLoot ++ // this.a(Item.getById(k), 1); ++ this.record = k; ++ // CraftBukkit end + } else if (damagesource.getEntity() instanceof EntityCreeper && damagesource.getEntity() != this && ((EntityCreeper) damagesource.getEntity()).isPowered() && ((EntityCreeper) damagesource.getEntity()).cp()) { + ((EntityCreeper) damagesource.getEntity()).cq(); +- this.a(new ItemStack(Items.SKULL, 1, 4), 0.0F); ++ // CraftBukkit start ++ // this.a(new ItemStack(Items.SKULL, 1, 4), 0.0F); ++ headDrop = new ItemStack(Items.SKULL, 1, 4); ++ // CraftBukkit end + } ++ ++ super.die(damagesource); // CraftBukkit - Moved from above ++ } ++ ++ // CraftBukkit start - Whole method ++ @Override ++ protected void dropDeathLoot(boolean flag, int i) { ++ super.dropDeathLoot(flag, i); + ++ // Drop a music disc? ++ if (this.record != -1) { ++ this.a(Item.getById(this.record), 1); ++ this.record = -1; ++ } + } ++ // CraftBukkit end + + public boolean r(Entity entity) { + return true; +@@ -146,7 +172,21 @@ + + public void onLightningStrike(EntityLightning entitylightning) { + super.onLightningStrike(entitylightning); +- this.datawatcher.watch(17, Byte.valueOf((byte) 1)); ++ // CraftBukkit start ++ if (CraftEventFactory.callCreeperPowerEvent(this, entitylightning, org.bukkit.event.entity.CreeperPowerEvent.PowerCause.LIGHTNING).isCancelled()) { ++ return; ++ } ++ ++ this.setPowered(true); ++ } ++ ++ public void setPowered(boolean powered) { ++ if (!powered) { ++ this.datawatcher.watch(17, Byte.valueOf((byte) 0)); ++ } else { ++ this.datawatcher.watch(17, Byte.valueOf((byte) 1)); ++ } ++ // CraftBukkit end + } + + protected boolean a(EntityHuman entityhuman) { +@@ -170,8 +210,15 @@ + boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); + float f = this.isPowered() ? 2.0F : 1.0F; + +- this.world.explode(this, this.locX, this.locY, this.locZ, (float) this.explosionRadius * f, flag); +- this.die(); ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), this.explosionRadius * f, false); ++ this.world.getServer().getPluginManager().callEvent(event); ++ if (!event.isCancelled()) { ++ this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), flag); ++ this.die(); ++ } else { ++ fuseTicks = 0; ++ } ++ // CraftBukkit end + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityDamageSourceIndirect.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityDamageSourceIndirect.patch new file mode 100644 index 0000000..6896c49 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityDamageSourceIndirect.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/server/EntityDamageSourceIndirect.java ++++ b/net/minecraft/server/EntityDamageSourceIndirect.java +@@ -25,4 +25,10 @@ + + return itemstack != null && itemstack.hasName() && LocaleI18n.c(s1) ? new ChatMessage(s1, new Object[] { entityliving.getScoreboardDisplayName(), ichatbasecomponent, itemstack.C()}) : new ChatMessage(s, new Object[] { entityliving.getScoreboardDisplayName(), ichatbasecomponent}); + } ++ ++ // CraftBukkit start ++ public Entity getProximateDamageSource() { ++ return super.getEntity(); ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEgg.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEgg.patch new file mode 100644 index 0000000..9b33c18 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEgg.patch @@ -0,0 +1,66 @@ +--- a/net/minecraft/server/EntityEgg.java ++++ b/net/minecraft/server/EntityEgg.java +@@ -1,5 +1,12 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.entity.Ageable; ++import org.bukkit.entity.EntityType; ++import org.bukkit.entity.Player; ++import org.bukkit.event.player.PlayerEggThrowEvent; ++// CraftBukkit end ++ + public class EntityEgg extends EntityProjectile { + + public EntityEgg(World world) { +@@ -19,21 +26,37 @@ + movingobjectposition.entity.damageEntity(DamageSource.projectile(this, this.getShooter()), 0.0F); + } + +- if (!this.world.isClientSide && this.random.nextInt(8) == 0) { +- byte b0 = 1; ++ // CraftBukkit start - Fire PlayerEggThrowEvent ++ boolean hatching = !this.world.isClientSide && this.random.nextInt(8) == 0; ++ int numHatching = (this.random.nextInt(32) == 0) ? 4 : 1; ++ if (!hatching) { ++ numHatching = 0; ++ } ++ ++ EntityType hatchingType = EntityType.CHICKEN; ++ ++ Entity shooter = this.getShooter(); ++ if (shooter instanceof EntityPlayer) { ++ Player player = (shooter == null) ? null : (Player) shooter.getBukkitEntity(); ++ ++ PlayerEggThrowEvent event = new PlayerEggThrowEvent(player, (org.bukkit.entity.Egg) this.getBukkitEntity(), hatching, (byte) numHatching, hatchingType); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ hatching = event.isHatching(); ++ numHatching = event.getNumHatches(); ++ hatchingType = event.getHatchingType(); ++ } + +- if (this.random.nextInt(32) == 0) { +- b0 = 4; +- } +- +- for (int i = 0; i < b0; ++i) { +- EntityChicken entitychicken = new EntityChicken(this.world); +- +- entitychicken.setAgeRaw(-24000); +- entitychicken.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); +- this.world.addEntity(entitychicken); +- } ++ if (hatching) { ++ for (int k = 0; k < numHatching; k++) { ++ Entity entity = world.getWorld().createEntity(new org.bukkit.Location(world.getWorld(), this.locX, this.locY, this.locZ, this.yaw, 0.0F), hatchingType.getEntityClass()); ++ if (entity.getBukkitEntity() instanceof Ageable) { ++ ((Ageable) entity.getBukkitEntity()).setBaby(); ++ } ++ world.getWorld().addEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); ++ } + } ++ // CraftBukkit end + + double d0 = 0.08D; + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderCrystal.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderCrystal.patch new file mode 100644 index 0000000..3e39d77 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderCrystal.patch @@ -0,0 +1,52 @@ +--- a/net/minecraft/server/EntityEnderCrystal.java ++++ b/net/minecraft/server/EntityEnderCrystal.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.ExplosionPrimeEvent; ++// CraftBukkit end ++ + public class EntityEnderCrystal extends Entity { + + public int a; +@@ -32,7 +37,11 @@ + int k = MathHelper.floor(this.locZ); + + if (this.world.worldProvider instanceof WorldProviderTheEnd && this.world.getType(new BlockPosition(i, j, k)).getBlock() != Blocks.FIRE) { +- this.world.setTypeUpdate(new BlockPosition(i, j, k), Blocks.FIRE.getBlockData()); ++ // CraftBukkit start ++ if (!CraftEventFactory.callBlockIgniteEvent(this.world, i, j, k, this).isCancelled()) { ++ this.world.setTypeUpdate(new BlockPosition(i, j, k), Blocks.FIRE.getBlockData()); ++ } ++ // CraftBukkit end + } + + } +@@ -50,11 +59,24 @@ + return false; + } else { + if (!this.dead && !this.world.isClientSide) { ++ // CraftBukkit start - All non-living entities need this ++ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { ++ return false; ++ } ++ // CraftBukkit end + this.b = 0; + if (this.b <= 0) { + this.die(); + if (!this.world.isClientSide) { +- this.world.explode((Entity) null, this.locX, this.locY, this.locZ, 6.0F, true); ++ // CraftBukkit start ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 6.0F, false); ++ this.world.getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ this.dead = false; ++ return false; ++ } ++ this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), true); ++ // CraftBukkit end + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderDragon.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderDragon.patch new file mode 100644 index 0000000..9572a00 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderDragon.patch @@ -0,0 +1,277 @@ +--- a/net/minecraft/server/EntityEnderDragon.java ++++ b/net/minecraft/server/EntityEnderDragon.java +@@ -5,6 +5,17 @@ + import java.util.Iterator; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.util.BlockStateListPopulator; ++import org.bukkit.event.entity.EntityCreatePortalEvent; ++import org.bukkit.event.entity.EntityExplodeEvent; ++import org.bukkit.event.entity.EntityRegainHealthEvent; ++import org.bukkit.event.entity.EntityTargetEvent; ++import org.bukkit.Bukkit; ++// CraftBukkit end ++ + public class EntityEnderDragon extends EntityInsentient implements IComplex, IMonster { + + public double a; +@@ -27,6 +38,7 @@ + public Entity target; + public int by; + public EntityEnderCrystal bz; ++ private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, true); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() + + public EntityEnderDragon(World world) { + super(world); +@@ -294,12 +306,21 @@ + if (this.bz != null) { + if (this.bz.dead) { + if (!this.world.isClientSide) { ++ CraftEventFactory.entityDamage = this.bz; // CraftBukkit + this.a(this.bn, DamageSource.explosion((Explosion) null), 10.0F); ++ CraftEventFactory.entityDamage = null; // CraftBukkit + } + + this.bz = null; + } else if (this.ticksLived % 10 == 0 && this.getHealth() < this.getMaxHealth()) { +- this.setHealth(this.getHealth() + 1.0F); ++ // CraftBukkit start ++ EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), 1.0D, EntityRegainHealthEvent.RegainReason.ENDER_CRYSTAL); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ this.setHealth((float) (this.getHealth() + event.getAmount())); ++ } ++ // CraftBukkit end + } + } + +@@ -368,7 +389,19 @@ + } + + if (this.random.nextInt(2) == 0 && !arraylist.isEmpty()) { +- this.target = (Entity) arraylist.get(this.random.nextInt(arraylist.size())); ++ // CraftBukkit start ++ Entity target = (Entity) this.world.players.get(this.random.nextInt(this.world.players.size())); ++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), target.getBukkitEntity(), EntityTargetEvent.TargetReason.RANDOM_TARGET); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ if (event.getTarget() == null) { ++ this.target = null; ++ } else { ++ this.target = ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); ++ } ++ } ++ // CraftBukkit end + } else { + boolean flag; + +@@ -404,6 +437,11 @@ + boolean flag = false; + boolean flag1 = false; + ++ // CraftBukkit start - Create a list to hold all the destroyed blocks ++ List destroyedBlocks = new java.util.ArrayList(); ++ org.bukkit.craftbukkit.CraftWorld craftWorld = this.world.getWorld(); ++ // CraftBukkit end ++ + for (int k1 = i; k1 <= l; ++k1) { + for (int l1 = j; l1 <= i1; ++l1) { + for (int i2 = k; i2 <= j1; ++i2) { +@@ -412,7 +450,11 @@ + + if (block.getMaterial() != Material.AIR) { + if (block != Blocks.BARRIER && block != Blocks.OBSIDIAN && block != Blocks.END_STONE && block != Blocks.BEDROCK && block != Blocks.COMMAND_BLOCK && this.world.getGameRules().getBoolean("mobGriefing")) { +- flag1 = this.world.setAir(blockposition) || flag1; ++ // CraftBukkit start - Add blocks to list rather than destroying them ++ // flag1 = this.world.setAir(new BlockPosition(blockposition)) || flag1; ++ flag1 = true; ++ destroyedBlocks.add(craftWorld.getBlockAt(k1, l1, i2)); ++ // CraftBukkit end + } else { + flag = true; + } +@@ -422,6 +464,40 @@ + } + + if (flag1) { ++ // CraftBukkit start - Set off an EntityExplodeEvent for the dragon exploding all these blocks ++ org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity(); ++ EntityExplodeEvent event = new EntityExplodeEvent(bukkitEntity, bukkitEntity.getLocation(), destroyedBlocks, 0F); ++ Bukkit.getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ // This flag literally means 'Dragon hit something hard' (Obsidian, White Stone or Bedrock) and will cause the dragon to slow down. ++ // We should consider adding an event extension for it, or perhaps returning true if the event is cancelled. ++ return flag; ++ } else if (event.getYield() == 0F) { ++ // Yield zero ==> no drops ++ for (org.bukkit.block.Block block : event.blockList()) { ++ this.world.setAir(new BlockPosition(block.getX(), block.getY(), block.getZ())); ++ } ++ } else { ++ for (org.bukkit.block.Block block : event.blockList()) { ++ org.bukkit.Material blockId = block.getType(); ++ if (blockId == org.bukkit.Material.AIR) { ++ continue; ++ } ++ ++ int blockX = block.getX(); ++ int blockY = block.getY(); ++ int blockZ = block.getZ(); ++ ++ Block nmsBlock = org.bukkit.craftbukkit.util.CraftMagicNumbers.getBlock(blockId); ++ if (nmsBlock.a(explosionSource)) { ++ nmsBlock.dropNaturally(this.world, new BlockPosition(blockX, blockY, blockZ), nmsBlock.fromLegacyData(block.getData()), event.getYield(), 0); ++ } ++ nmsBlock.wasExploded(world, new BlockPosition(blockX, blockY, blockZ), explosionSource); ++ ++ this.world.setAir(new BlockPosition(blockX, blockY, blockZ)); ++ } ++ } ++ // CraftBukkit end + double d0 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) this.random.nextFloat(); + double d1 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) this.random.nextFloat(); + double d2 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) this.random.nextFloat(); +@@ -469,6 +545,7 @@ + } + + protected void aZ() { ++ if (this.dead) return; // CraftBukkit - can't kill what's already dead + ++this.by; + if (this.by >= 180 && this.by <= 200) { + float f = (this.random.nextFloat() - 0.5F) * 8.0F; +@@ -484,7 +561,7 @@ + + if (!this.world.isClientSide) { + if (this.by > 150 && this.by % 5 == 0 && flag) { +- i = 1000; ++ i = this.expToDrop / 12; // CraftBukkit - drop experience as dragon falls from sky. use experience drop from death event. This is now set in getExpReward() + + while (i > 0) { + j = EntityExperienceOrb.getOrbValue(i); +@@ -494,7 +571,23 @@ + } + + if (this.by == 1) { +- this.world.a(1018, new BlockPosition(this), 0); ++ // CraftBukkit start - Use relative location for far away sounds ++ // this.world.a(1018, new BlockPosition(this), 0); ++ int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; ++ for (EntityPlayer player : (List) MinecraftServer.getServer().getPlayerList().players) { ++ double deltaX = this.locX - player.locX; ++ double deltaZ = this.locZ - player.locZ; ++ double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; ++ if (distanceSquared > viewDistance * viewDistance) { ++ double deltaLength = Math.sqrt(distanceSquared); ++ double relativeX = player.locX + (deltaX / deltaLength) * viewDistance; ++ double relativeZ = player.locZ + (deltaZ / deltaLength) * viewDistance; ++ player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1018, new BlockPosition((int) relativeX, (int) this.locY, (int) relativeZ), 0, true)); ++ } else { ++ player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1018, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0, true)); ++ } ++ } ++ // CraftBukkit end + } + } + +@@ -502,7 +595,7 @@ + this.aI = this.yaw += 20.0F; + if (this.by == 200 && !this.world.isClientSide) { + if (flag) { +- i = 2000; ++ i = this.expToDrop - (10 * this.expToDrop / 12); // CraftBukkit - drop the remaining experience + + while (i > 0) { + j = EntityExperienceOrb.getOrbValue(i); +@@ -522,6 +615,9 @@ + double d0 = 12.25D; + double d1 = 6.25D; + ++ // CraftBukkit start - Replace any "this.world" in the following with just "world"! ++ BlockStateListPopulator world = new BlockStateListPopulator(this.world.getWorld()); ++ + for (int i = -1; i <= 32; ++i) { + for (int j = -4; j <= 4; ++j) { + for (int k = -4; k <= 4; ++k) { +@@ -532,31 +628,51 @@ + + if (i < 0) { + if (d2 <= 6.25D) { +- this.world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData()); ++ world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData()); + } + } else if (i > 0) { +- this.world.setTypeUpdate(blockposition1, Blocks.AIR.getBlockData()); ++ world.setTypeUpdate(blockposition1, Blocks.AIR.getBlockData()); + } else if (d2 > 6.25D) { +- this.world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData()); ++ world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData()); + } else { +- this.world.setTypeUpdate(blockposition1, Blocks.END_PORTAL.getBlockData()); ++ world.setTypeUpdate(blockposition1, Blocks.END_PORTAL.getBlockData()); + } + } + } + } + } + +- this.world.setTypeUpdate(blockposition, Blocks.BEDROCK.getBlockData()); +- this.world.setTypeUpdate(blockposition.up(), Blocks.BEDROCK.getBlockData()); ++ world.setTypeUpdate(blockposition, Blocks.BEDROCK.getBlockData()); ++ world.setTypeUpdate(blockposition.up(), Blocks.BEDROCK.getBlockData()); + BlockPosition blockposition2 = blockposition.up(2); + +- this.world.setTypeUpdate(blockposition2, Blocks.BEDROCK.getBlockData()); +- this.world.setTypeUpdate(blockposition2.west(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.EAST)); +- this.world.setTypeUpdate(blockposition2.east(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.WEST)); +- this.world.setTypeUpdate(blockposition2.north(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.SOUTH)); +- this.world.setTypeUpdate(blockposition2.south(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.NORTH)); +- this.world.setTypeUpdate(blockposition.up(3), Blocks.BEDROCK.getBlockData()); +- this.world.setTypeUpdate(blockposition.up(4), Blocks.DRAGON_EGG.getBlockData()); ++ world.setTypeUpdate(blockposition2, Blocks.BEDROCK.getBlockData()); ++ world.setTypeUpdate(blockposition2.west(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.EAST)); ++ world.setTypeUpdate(blockposition2.east(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.WEST)); ++ world.setTypeUpdate(blockposition2.north(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.SOUTH)); ++ world.setTypeUpdate(blockposition2.south(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.NORTH)); ++ world.setTypeUpdate(blockposition.up(3), Blocks.BEDROCK.getBlockData()); ++ world.setTypeUpdate(blockposition.up(4), Blocks.DRAGON_EGG.getBlockData()); ++ ++ EntityCreatePortalEvent event = new EntityCreatePortalEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), java.util.Collections.unmodifiableList(world.getList()), org.bukkit.PortalType.ENDER); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ for (BlockState state : event.getBlocks()) { ++ state.update(true); ++ } ++ } else { ++ for (BlockState state : event.getBlocks()) { ++ PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, new BlockPosition(state.getX(), state.getY(), state.getZ())); ++ for (Iterator it = this.world.players.iterator(); it.hasNext();) { ++ EntityHuman entity = (EntityHuman) it.next(); ++ if (entity instanceof EntityPlayer) { ++ ((EntityPlayer) entity).playerConnection.sendPacket(packet); ++ } ++ } ++ } ++ } ++ // CraftBukkit end + } + + protected void D() {} +@@ -584,4 +700,12 @@ + protected float bB() { + return 5.0F; + } ++ ++ // CraftBukkit start ++ public int getExpReward() { ++ // This value is equal to the amount of experience dropped while falling from the sky (10 * 1000) ++ // plus what is dropped when the dragon hits the ground (2000) ++ return 12000; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderPearl.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderPearl.patch new file mode 100644 index 0000000..760fad2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderPearl.patch @@ -0,0 +1,64 @@ +--- a/net/minecraft/server/EntityEnderPearl.java ++++ b/net/minecraft/server/EntityEnderPearl.java +@@ -1,5 +1,11 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.Bukkit; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.player.PlayerTeleportEvent; ++// CraftBukkit end ++ + public class EntityEnderPearl extends EntityProjectile { + + private EntityLiving c; +@@ -33,21 +39,35 @@ + EntityPlayer entityplayer = (EntityPlayer) entityliving; + + if (entityplayer.playerConnection.a().g() && entityplayer.world == this.world && !entityplayer.isSleeping()) { +- if (this.random.nextFloat() < 0.05F && this.world.getGameRules().getBoolean("doMobSpawning")) { +- EntityEndermite entityendermite = new EntityEndermite(this.world); +- +- entityendermite.a(true); +- entityendermite.setPositionRotation(entityliving.locX, entityliving.locY, entityliving.locZ, entityliving.yaw, entityliving.pitch); +- this.world.addEntity(entityendermite); ++ // CraftBukkit start - Fire PlayerTeleportEvent ++ org.bukkit.craftbukkit.entity.CraftPlayer player = entityplayer.getBukkitEntity(); ++ org.bukkit.Location location = getBukkitEntity().getLocation(); ++ location.setPitch(player.getLocation().getPitch()); ++ location.setYaw(player.getLocation().getYaw()); ++ ++ PlayerTeleportEvent teleEvent = new PlayerTeleportEvent(player, player.getLocation(), location, PlayerTeleportEvent.TeleportCause.ENDER_PEARL); ++ Bukkit.getPluginManager().callEvent(teleEvent); ++ ++ if (!teleEvent.isCancelled() && !entityplayer.playerConnection.isDisconnected()) { ++ if (this.random.nextFloat() < 0.05F && this.world.getGameRules().getBoolean("doMobSpawning")) { ++ EntityEndermite entityendermite = new EntityEndermite(this.world); ++ ++ entityendermite.a(true); ++ entityendermite.setPositionRotation(entityliving.locX, entityliving.locY, entityliving.locZ, entityliving.yaw, entityliving.pitch); ++ this.world.addEntity(entityendermite); ++ } ++ ++ if (entityliving.au()) { ++ entityliving.mount((Entity) null); ++ } ++ ++ entityplayer.playerConnection.teleport(teleEvent.getTo()); ++ entityliving.fallDistance = 0.0F; ++ CraftEventFactory.entityDamage = this; ++ entityliving.damageEntity(DamageSource.FALL, 5.0F); ++ CraftEventFactory.entityDamage = null; + } +- +- if (entityliving.au()) { +- entityliving.mount((Entity) null); +- } +- +- entityliving.enderTeleportTo(this.locX, this.locY, this.locZ); +- entityliving.fallDistance = 0.0F; +- entityliving.damageEntity(DamageSource.FALL, 5.0F); ++ // CraftBukkit end + } + } else if (entityliving != null) { + entityliving.enderTeleportTo(this.locX, this.locY, this.locZ); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderman.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderman.patch new file mode 100644 index 0000000..b14daaa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityEnderman.patch @@ -0,0 +1,62 @@ +--- a/net/minecraft/server/EntityEnderman.java ++++ b/net/minecraft/server/EntityEnderman.java +@@ -8,6 +8,12 @@ + import java.util.Set; + import java.util.UUID; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityTeleportEvent; ++// CraftBukkit end ++ + public class EntityEnderman extends EntityMonster { + + private static final UUID a = UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0"); +@@ -177,7 +183,17 @@ + } + + if (flag1) { +- super.enderTeleportTo(this.locX, this.locY, this.locZ); ++ // CraftBukkit start - Teleport event ++ // super.enderTeleportTo(this.locX, this.locY, this.locZ); ++ EntityTeleportEvent teleport = new EntityTeleportEvent(this.getBukkitEntity(), new Location(this.world.getWorld(), d3, d4, d5), new Location(this.world.getWorld(), this.locX, this.locY, this.locZ)); ++ this.world.getServer().getPluginManager().callEvent(teleport); ++ if (teleport.isCancelled()) { ++ return false; ++ } ++ ++ Location to = teleport.getTo(); ++ this.enderTeleportTo(to.getX(), to.getY(), to.getZ()); ++ // CraftBukkit end + if (this.world.getCubes(this, this.getBoundingBox()).isEmpty() && !this.world.containsLiquid(this.getBoundingBox())) { + flag = true; + } +@@ -333,8 +349,12 @@ + Block block = iblockdata.getBlock(); + + if (EntityEnderman.c.contains(block)) { +- this.enderman.setCarried(iblockdata); +- world.setTypeUpdate(blockposition, Blocks.AIR.getBlockData()); ++ // CraftBukkit start - Pickup event ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.enderman, this.enderman.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), org.bukkit.Material.AIR).isCancelled()) { ++ this.enderman.setCarried(iblockdata); ++ world.setTypeUpdate(blockposition, Blocks.AIR.getBlockData()); ++ } ++ // CraftBukkit end + } + + } +@@ -363,8 +383,12 @@ + Block block1 = world.getType(blockposition.down()).getBlock(); + + if (this.a(world, blockposition, this.a.getCarried().getBlock(), block, block1)) { ++ // CraftBukkit start - Place event ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.a, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.a.getCarried().getBlock(), this.a.getCarried().getBlock().toLegacyData(this.a.getCarried())).isCancelled()) { + world.setTypeAndData(blockposition, this.a.getCarried(), 3); + this.a.setCarried(Blocks.AIR.getBlockData()); ++ } ++ // CraftBukkit end + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityExperienceOrb.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityExperienceOrb.patch new file mode 100644 index 0000000..b01b0c7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityExperienceOrb.patch @@ -0,0 +1,82 @@ +--- a/net/minecraft/server/EntityExperienceOrb.java ++++ b/net/minecraft/server/EntityExperienceOrb.java +@@ -1,5 +1,11 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityTargetLivingEntityEvent; ++import org.bukkit.event.entity.EntityTargetEvent; ++// CraftBukkit end ++ + public class EntityExperienceOrb extends Entity { + + public int a; +@@ -34,6 +40,7 @@ + + public void t_() { + super.t_(); ++ EntityHuman prevTarget = this.targetPlayer;// CraftBukkit - store old target + if (this.c > 0) { + --this.c; + } +@@ -65,6 +72,16 @@ + } + + if (this.targetPlayer != null) { ++ // CraftBukkit start ++ boolean cancelled = false; ++ if (this.targetPlayer != prevTarget) { ++ EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(this, targetPlayer, EntityTargetEvent.TargetReason.CLOSEST_PLAYER); ++ EntityLiving target = event.getTarget() == null ? null : ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); ++ targetPlayer = target instanceof EntityHuman ? (EntityHuman) target : null; ++ cancelled = event.isCancelled(); ++ } ++ ++ if (!cancelled && targetPlayer != null) { + double d1 = (this.targetPlayer.locX - this.locX) / d0; + double d2 = (this.targetPlayer.locY + (double) this.targetPlayer.getHeadHeight() - this.locY) / d0; + double d3 = (this.targetPlayer.locZ - this.locZ) / d0; +@@ -77,6 +94,8 @@ + this.motY += d2 / d4 * d5 * 0.1D; + this.motZ += d3 / d4 * d5 * 0.1D; + } ++ } ++ // CraftBukkit end + } + + this.move(this.motX, this.motY, this.motZ); +@@ -141,7 +160,7 @@ + entityhuman.bp = 2; + this.world.makeSound(entityhuman, "random.orb", 0.1F, 0.5F * ((this.random.nextFloat() - this.random.nextFloat()) * 0.7F + 1.8F)); + entityhuman.receive(this, 1); +- entityhuman.giveExp(this.value); ++ entityhuman.giveExp(CraftEventFactory.callPlayerExpChangeEvent(entityhuman, this.value).getAmount()); // CraftBukkit - this.value -> event.getAmount() + this.die(); + } + +@@ -153,6 +172,24 @@ + } + + public static int getOrbValue(int i) { ++ // CraftBukkit start ++ if (i > 162670129) return i - 100000; ++ if (i > 81335063) return 81335063; ++ if (i > 40667527) return 40667527; ++ if (i > 20333759) return 20333759; ++ if (i > 10166857) return 10166857; ++ if (i > 5083423) return 5083423; ++ if (i > 2541701) return 2541701; ++ if (i > 1270849) return 1270849; ++ if (i > 635413) return 635413; ++ if (i > 317701) return 317701; ++ if (i > 158849) return 158849; ++ if (i > 79423) return 79423; ++ if (i > 39709) return 39709; ++ if (i > 19853) return 19853; ++ if (i > 9923) return 9923; ++ if (i > 4957) return 4957; ++ // CraftBukkit end + return i >= 2477 ? 2477 : (i >= 1237 ? 1237 : (i >= 617 ? 617 : (i >= 307 ? 307 : (i >= 149 ? 149 : (i >= 73 ? 73 : (i >= 37 ? 37 : (i >= 17 ? 17 : (i >= 7 ? 7 : (i >= 3 ? 3 : 1))))))))); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFallingBlock.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFallingBlock.patch new file mode 100644 index 0000000..a0ffb88 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFallingBlock.patch @@ -0,0 +1,52 @@ +--- a/net/minecraft/server/EntityFallingBlock.java ++++ b/net/minecraft/server/EntityFallingBlock.java +@@ -4,13 +4,15 @@ + import java.util.ArrayList; + import java.util.Iterator; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntityFallingBlock extends Entity { + + private IBlockData block; + public int ticksLived; + public boolean dropItem = true; + private boolean e; +- private boolean hurtEntities; ++ public boolean hurtEntities; // PAIL: private -> public + private int fallHurtMax = 40; + private float fallHurtAmount = 2.0F; + public NBTTagCompound tileEntityData; +@@ -56,7 +58,7 @@ + + if (this.ticksLived++ == 0) { + blockposition = new BlockPosition(this); +- if (this.world.getType(blockposition).getBlock() == block) { ++ if (this.world.getType(blockposition).getBlock() == block && !CraftEventFactory.callEntityChangeBlockEvent(this, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.AIR, 0).isCancelled()) { + this.world.setAir(blockposition); + } else if (!this.world.isClientSide) { + this.die(); +@@ -78,7 +80,12 @@ + if (this.world.getType(blockposition).getBlock() != Blocks.PISTON_EXTENSION) { + this.die(); + if (!this.e) { +- if (this.world.a(block, blockposition, true, EnumDirection.UP, (Entity) null, (ItemStack) null) && !BlockFalling.canFall(this.world, blockposition.down()) && this.world.setTypeAndData(blockposition, this.block, 3)) { ++ if (this.world.a(block, blockposition, true, EnumDirection.UP, (Entity) null, (ItemStack) 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() < 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; ++ } ++ this.world.setTypeAndData(blockposition, this.block, 3); ++ // CraftBukkit end + if (block instanceof BlockFalling) { + ((BlockFalling) block).a_(this.world, blockposition); + } +@@ -137,7 +144,9 @@ + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + ++ CraftEventFactory.entityDamage = this; // CraftBukkit + entity.damageEntity(damagesource, (float) Math.min(MathHelper.d((float) i * this.fallHurtAmount), this.fallHurtMax)); ++ CraftEventFactory.entityDamage = null; // CraftBukkit + } + + if (flag && (double) this.random.nextFloat() < 0.05000000074505806D + (double) i * 0.05D) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFireball.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFireball.patch new file mode 100644 index 0000000..416b8eb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFireball.patch @@ -0,0 +1,102 @@ +--- a/net/minecraft/server/EntityFireball.java ++++ b/net/minecraft/server/EntityFireball.java +@@ -2,6 +2,8 @@ + + import java.util.List; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public abstract class EntityFireball extends Entity { + + private int e = -1; +@@ -15,6 +17,8 @@ + public double dirX; + public double dirY; + public double dirZ; ++ public float bukkitYield = 1; // CraftBukkit ++ public boolean isIncendiary = true; // CraftBukkit + + public EntityFireball(World world) { + super(world); +@@ -38,10 +42,17 @@ + public EntityFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) { + super(world); + this.shooter = entityliving; ++ this.projectileSource = (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit + this.setSize(1.0F, 1.0F); + this.setPositionRotation(entityliving.locX, entityliving.locY, entityliving.locZ, entityliving.yaw, entityliving.pitch); + this.setPosition(this.locX, this.locY, this.locZ); + this.motX = this.motY = this.motZ = 0.0D; ++ // CraftBukkit start - Added setDirection method ++ this.setDirection(d0, d1, d2); ++ } ++ ++ public void setDirection(double d0, double d1, double d2) { ++ // CraftBukkit end + d0 += this.random.nextGaussian() * 0.4D; + d1 += this.random.nextGaussian() * 0.4D; + d2 += this.random.nextGaussian() * 0.4D; +@@ -117,6 +128,12 @@ + + if (movingobjectposition != null) { + this.a(movingobjectposition); ++ ++ // CraftBukkit start - Fire ProjectileHitEvent ++ if (this.dead) { ++ CraftEventFactory.callProjectileHitEvent(this); ++ } ++ // CraftBukkit end + } + + this.locX += this.motX; +@@ -181,6 +198,8 @@ + + nbttagcompound.setString("inTile", minecraftkey == null ? "" : minecraftkey.toString()); + nbttagcompound.setByte("inGround", (byte) (this.i ? 1 : 0)); ++ // CraftBukkit - Fix direction being mismapped to invalid variables ++ nbttagcompound.set("power", this.a(new double[] { this.dirX, this.dirY, this.dirZ})); + nbttagcompound.set("direction", this.a(new double[] { this.motX, this.motY, this.motZ})); + } + +@@ -195,12 +214,20 @@ + } + + this.i = nbttagcompound.getByte("inGround") == 1; +- if (nbttagcompound.hasKeyOfType("direction", 9)) { ++ // CraftBukkit start - direction -> power ++ if (nbttagcompound.hasKeyOfType("power", 9)) { ++ NBTTagList nbttaglist = nbttagcompound.getList("power", 6); ++ ++ this.dirX = nbttaglist.d(0); ++ this.dirY = nbttaglist.d(1); ++ this.dirZ = nbttaglist.d(2); ++ } else if (nbttagcompound.hasKeyOfType("direction", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("direction", 6); + + this.motX = nbttaglist.d(0); + this.motY = nbttaglist.d(1); + this.motZ = nbttaglist.d(2); ++ // CraftBukkit end + } else { + this.die(); + } +@@ -221,6 +248,11 @@ + } else { + this.ac(); + if (damagesource.getEntity() != null) { ++ // CraftBukkit start ++ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { ++ return false; ++ } ++ // CraftBukkit end + Vec3D vec3d = damagesource.getEntity().ap(); + + if (vec3d != null) { +@@ -234,6 +266,7 @@ + + if (damagesource.getEntity() instanceof EntityLiving) { + this.shooter = (EntityLiving) damagesource.getEntity(); ++ this.projectileSource = (org.bukkit.projectiles.ProjectileSource) this.shooter.getBukkitEntity(); + } + + return true; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFireworks.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFireworks.patch new file mode 100644 index 0000000..4da644d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFireworks.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/EntityFireworks.java ++++ b/net/minecraft/server/EntityFireworks.java +@@ -78,7 +78,7 @@ + } + + if (!this.world.isClientSide && this.ticksFlown > this.expectedLifespan) { +- this.world.broadcastEntityEffect(this, (byte) 17); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) this.world.broadcastEntityEffect(this, (byte) 17); + this.die(); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFishingHook.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFishingHook.patch new file mode 100644 index 0000000..899b0f4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityFishingHook.patch @@ -0,0 +1,92 @@ +--- a/net/minecraft/server/EntityFishingHook.java ++++ b/net/minecraft/server/EntityFishingHook.java +@@ -3,6 +3,12 @@ + import java.util.Arrays; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.entity.Fish; ++import org.bukkit.event.player.PlayerFishEvent; ++// CraftBukkit end ++ + public class EntityFishingHook extends Entity { + + private static final List d = Arrays.asList(new PossibleFishingResult[] { (new PossibleFishingResult(new ItemStack(Items.LEATHER_BOOTS), 10)).a(0.9F), new PossibleFishingResult(new ItemStack(Items.LEATHER), 10), new PossibleFishingResult(new ItemStack(Items.BONE), 10), new PossibleFishingResult(new ItemStack(Items.POTION), 10), new PossibleFishingResult(new ItemStack(Items.STRING), 5), (new PossibleFishingResult(new ItemStack(Items.FISHING_ROD), 2)).a(0.9F), new PossibleFishingResult(new ItemStack(Items.BOWL), 10), new PossibleFishingResult(new ItemStack(Items.STICK), 5), new PossibleFishingResult(new ItemStack(Items.DYE, 10, EnumColor.BLACK.getInvColorIndex()), 1), new PossibleFishingResult(new ItemStack(Blocks.TRIPWIRE_HOOK), 10), new PossibleFishingResult(new ItemStack(Items.ROTTEN_FLESH), 10)}); +@@ -182,6 +188,7 @@ + } + + if (movingobjectposition != null) { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); // Craftbukkit - Call event + if (movingobjectposition.entity != null) { + if (movingobjectposition.entity.damageEntity(DamageSource.projectile(this, this.owner), 0.0F)) { + this.hooked = movingobjectposition.entity; +@@ -381,6 +388,15 @@ + byte b0 = 0; + + if (this.hooked != null) { ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), this.hooked.getBukkitEntity(), (Fish) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_ENTITY); ++ this.world.getServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ return 0; ++ } ++ // CraftBukkit end ++ + double d0 = this.owner.locX - this.locX; + double d1 = this.owner.locY - this.locY; + double d2 = this.owner.locZ - this.locZ; +@@ -393,6 +409,15 @@ + b0 = 3; + } else if (this.av > 0) { + EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY, this.locZ, this.m()); ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), entityitem.getBukkitEntity(), (Fish) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); ++ playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1); ++ this.world.getServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ return 0; ++ } ++ // CraftBukkit end + double d5 = this.owner.locX - this.locX; + double d6 = this.owner.locY - this.locY; + double d7 = this.owner.locZ - this.locZ; +@@ -403,14 +428,35 @@ + entityitem.motY = d6 * d9 + (double) MathHelper.sqrt(d8) * 0.08D; + entityitem.motZ = d7 * d9; + this.world.addEntity(entityitem); +- this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX, this.owner.locY + 0.5D, this.owner.locZ + 0.5D, this.random.nextInt(6) + 1)); ++ // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop() ++ if (playerFishEvent.getExpToDrop() > 0) { ++ this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX, this.owner.locY + 0.5D, this.owner.locZ + 0.5D, playerFishEvent.getExpToDrop())); ++ } // CraftBukkit end + b0 = 1; + } + + if (this.as) { ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), null, (Fish) this.getBukkitEntity(), PlayerFishEvent.State.IN_GROUND); ++ this.world.getServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ return 0; ++ } ++ // CraftBukkit end + b0 = 2; + } + ++ // CraftBukkit start ++ if (b0 == 0) { ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), null, (Fish) this.getBukkitEntity(), PlayerFishEvent.State.FAILED_ATTEMPT); ++ this.world.getServer().getPluginManager().callEvent(playerFishEvent); ++ if (playerFishEvent.isCancelled()) { ++ return 0; ++ } ++ } ++ // CraftBukkit end ++ + this.die(); + this.owner.hookedFish = null; + return b0; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityGhast.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityGhast.patch new file mode 100644 index 0000000..681d72e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityGhast.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/server/EntityGhast.java ++++ b/net/minecraft/server/EntityGhast.java +@@ -162,7 +162,9 @@ + world.a((EntityHuman) null, 1008, new BlockPosition(this.b), 0); + EntityLargeFireball entitylargefireball = new EntityLargeFireball(world, this.b, d2, d3, d4); + +- entitylargefireball.yield = this.b.cf(); ++ ++ // CraftBukkit - set bukkitYield when setting explosionpower ++ entitylargefireball.bukkitYield = entitylargefireball.yield = this.b.cf(); + entitylargefireball.locX = this.b.locX + vec3d.a * d1; + entitylargefireball.locY = this.b.locY + (double) (this.b.length / 2.0F) + 0.5D; + entitylargefireball.locZ = this.b.locZ + vec3d.c * d1; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHanging.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHanging.patch new file mode 100644 index 0000000..aee058d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHanging.patch @@ -0,0 +1,182 @@ +--- a/net/minecraft/server/EntityHanging.java ++++ b/net/minecraft/server/EntityHanging.java +@@ -4,6 +4,13 @@ + import java.util.List; + import org.apache.commons.lang3.Validate; + ++// CraftBukkit start ++import org.bukkit.entity.Hanging; ++import org.bukkit.entity.Painting; ++import org.bukkit.event.hanging.HangingBreakEvent; ++import org.bukkit.event.painting.PaintingBreakEvent; ++// CraftBukkit end ++ + public abstract class EntityHanging extends Entity { + + private int c; +@@ -30,30 +37,34 @@ + this.updateBoundingBox(); + } + +- private void updateBoundingBox() { +- if (this.direction != null) { +- double d0 = (double) this.blockPosition.getX() + 0.5D; +- double d1 = (double) this.blockPosition.getY() + 0.5D; +- double d2 = (double) this.blockPosition.getZ() + 0.5D; ++ /* CraftBukkit start - bounding box calculation made static (for spawn usage) ++ ++ l is from function l() ++ m is from function m() ++ ++ Placing here as it's more likely to be noticed as something which needs to be updated ++ then something in a CraftBukkit file. ++ */ ++ public static AxisAlignedBB calculateBoundingBox(BlockPosition blockPosition, EnumDirection direction, int width, int height) { ++ double d0 = (double) blockPosition.getX() + 0.5D; ++ double d1 = (double) blockPosition.getY() + 0.5D; ++ double d2 = (double) blockPosition.getZ() + 0.5D; + double d3 = 0.46875D; +- double d4 = this.a(this.l()); +- double d5 = this.a(this.m()); ++ double d4 = width % 32 == 0 ? 0.5D : 0.0D; ++ double d5 = height % 32 == 0 ? 0.5D : 0.0D; + +- d0 -= (double) this.direction.getAdjacentX() * 0.46875D; +- d2 -= (double) this.direction.getAdjacentZ() * 0.46875D; ++ d0 -= (double) direction.getAdjacentX() * 0.46875D; ++ d2 -= (double) direction.getAdjacentZ() * 0.46875D; + d1 += d5; +- EnumDirection enumdirection = this.direction.f(); ++ EnumDirection enumdirection = direction.f(); + + d0 += d4 * (double) enumdirection.getAdjacentX(); + d2 += d4 * (double) enumdirection.getAdjacentZ(); +- this.locX = d0; +- this.locY = d1; +- this.locZ = d2; +- double d6 = (double) this.l(); +- double d7 = (double) this.m(); +- double d8 = (double) this.l(); ++ double d6 = (double) width; ++ double d7 = (double) height; ++ double d8 = (double) width; + +- if (this.direction.k() == EnumDirection.EnumAxis.Z) { ++ if (direction.k() == EnumDirection.EnumAxis.Z) { + d8 = 1.0D; + } else { + d6 = 1.0D; +@@ -62,7 +73,18 @@ + d6 /= 32.0D; + d7 /= 32.0D; + d8 /= 32.0D; +- this.a(new AxisAlignedBB(d0 - d6, d1 - d7, d2 - d8, d0 + d6, d1 + d7, d2 + d8)); ++ return new AxisAlignedBB(d0 - d6, d1 - d7, d2 - d8, d0 + d6, d1 + d7, d2 + d8); ++ } ++ ++ private void updateBoundingBox() { ++ if (this.direction != null) { ++ // CraftBukkit start code moved in to calculateBoundingBox ++ AxisAlignedBB bb = calculateBoundingBox(this.blockPosition, this.direction, this.l(), this.m()); ++ this.locX = (bb.a + bb.d) / 2.0D; ++ this.locY = (bb.b + bb.e) / 2.0D; ++ this.locZ = (bb.c + bb.f) / 2.0D; ++ this.a(bb); ++ // CraftBukkit end + } + } + +@@ -77,6 +99,32 @@ + if (this.c++ == 100 && !this.world.isClientSide) { + this.c = 0; + if (!this.dead && !this.survives()) { ++ // CraftBukkit start - fire break events ++ Material material = this.world.getType(new BlockPosition(this)).getBlock().getMaterial(); ++ HangingBreakEvent.RemoveCause cause; ++ ++ if (!material.equals(Material.AIR)) { ++ // TODO: This feels insufficient to catch 100% of suffocation cases ++ cause = HangingBreakEvent.RemoveCause.OBSTRUCTION; ++ } else { ++ cause = HangingBreakEvent.RemoveCause.PHYSICS; ++ } ++ ++ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), cause); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ PaintingBreakEvent paintingEvent = null; ++ if (this instanceof EntityPainting) { ++ // Fire old painting event until it can be removed ++ paintingEvent = new PaintingBreakEvent((Painting) this.getBukkitEntity(), PaintingBreakEvent.RemoveCause.valueOf(cause.name())); ++ paintingEvent.setCancelled(event.isCancelled()); ++ this.world.getServer().getPluginManager().callEvent(paintingEvent); ++ } ++ ++ if (dead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { ++ return; ++ } ++ // CraftBukkit end + this.die(); + this.b((Entity) null); + } +@@ -138,6 +186,32 @@ + return false; + } else { + if (!this.dead && !this.world.isClientSide) { ++ // CraftBukkit start - fire break events ++ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.DEFAULT); ++ PaintingBreakEvent paintingEvent = null; ++ if (damagesource.getEntity() != null) { ++ event = new org.bukkit.event.hanging.HangingBreakByEntityEvent((Hanging) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity()); ++ ++ if (this instanceof EntityPainting) { ++ // Fire old painting event until it can be removed ++ paintingEvent = new org.bukkit.event.painting.PaintingBreakByEntityEvent((Painting) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity()); ++ } ++ } else if (damagesource.isExplosion()) { ++ event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.EXPLOSION); ++ } ++ ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (paintingEvent != null) { ++ paintingEvent.setCancelled(event.isCancelled()); ++ this.world.getServer().getPluginManager().callEvent(paintingEvent); ++ } ++ ++ if (this.dead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { ++ return true; ++ } ++ // CraftBukkit end ++ + this.die(); + this.ac(); + this.b(damagesource.getEntity()); +@@ -149,6 +223,18 @@ + + public void move(double d0, double d1, double d2) { + if (!this.world.isClientSide && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { ++ if (this.dead) return; // CraftBukkit ++ ++ // CraftBukkit start - fire break events ++ // TODO - Does this need its own cause? Seems to only be triggered by pistons ++ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.PHYSICS); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (this.dead || event.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ + this.die(); + this.b((Entity) null); + } +@@ -156,7 +242,7 @@ + } + + public void g(double d0, double d1, double d2) { +- if (!this.world.isClientSide && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { ++ if (false && !this.world.isClientSide && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { // CraftBukkit - not needed + this.die(); + this.b((Entity) null); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHorse.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHorse.patch new file mode 100644 index 0000000..06eece5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHorse.patch @@ -0,0 +1,139 @@ +--- a/net/minecraft/server/EntityHorse.java ++++ b/net/minecraft/server/EntityHorse.java +@@ -4,6 +4,8 @@ + import java.util.Iterator; + import java.util.List; + ++import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; // CraftBukkit ++ + public class EntityHorse extends EntityAnimal implements IInventoryListener { + + private static final Predicate bs = new Predicate() { +@@ -44,6 +46,7 @@ + private String bO; + private String[] bP = new String[3]; + private boolean bQ = false; ++ public int maxDomestication = 100; // CraftBukkit - store max domestication value + + public EntityHorse(World world) { + super(world); +@@ -320,13 +323,13 @@ + private int cZ() { + int i = this.getType(); + +- return this.hasChest() && (i == 1 || i == 2) ? 17 : 2; ++ return this.hasChest() /* && (i == 1 || i == 2) */ ? 17 : 2; // CraftBukkit - Remove type check + } + + public void loadChest() { + InventoryHorseChest inventoryhorsechest = this.inventoryChest; + +- this.inventoryChest = new InventoryHorseChest("HorseChest", this.cZ()); ++ this.inventoryChest = new InventoryHorseChest("HorseChest", this.cZ(), this); // CraftBukkit - add this horse + this.inventoryChest.a(this.getName()); + if (inventoryhorsechest != null) { + inventoryhorsechest.b(this); +@@ -491,7 +494,7 @@ + } + + public int getMaxDomestication() { +- return 100; ++ return this.maxDomestication; // CraftBukkit - return stored max domestication instead of 100 + } + + protected float bB() { +@@ -591,7 +594,7 @@ + } + + if (this.getHealth() < this.getMaxHealth() && f > 0.0F) { +- this.heal(f); ++ this.heal(f, RegainReason.EATING); // CraftBukkit + flag = true; + } + +@@ -698,11 +701,24 @@ + + public void die(DamageSource damagesource) { + super.die(damagesource); ++ /* CraftBukkit start - Handle chest dropping in dropDeathLoot below + if (!this.world.isClientSide) { + this.dropChest(); + } ++ // CraftBukkit end */ ++ } + ++ // CraftBukkit start - Add method ++ @Override ++ protected void dropDeathLoot(boolean flag, int i) { ++ super.dropDeathLoot(flag, i); ++ ++ // Moved from die method above ++ if (!this.world.isClientSide) { ++ this.dropChest(); ++ } + } ++ // CraftBukkit end + + public void m() { + if (this.random.nextInt(200) == 0) { +@@ -712,7 +728,7 @@ + super.m(); + if (!this.world.isClientSide) { + if (this.random.nextInt(900) == 0 && this.deathTicks == 0) { +- this.heal(1.0F); ++ this.heal(1.0F, RegainReason.REGEN); // CraftBukkit + } + + if (!this.cy() && this.passenger == null && this.random.nextInt(300) == 0 && this.world.getType(new BlockPosition(MathHelper.floor(this.locX), MathHelper.floor(this.locY) - 1, MathHelper.floor(this.locZ))).getBlock() == Blocks.GRASS) { +@@ -955,6 +971,7 @@ + nbttagcompound.setInt("Temper", this.getTemper()); + nbttagcompound.setBoolean("Tame", this.isTame()); + nbttagcompound.setString("OwnerUUID", this.getOwnerUUID()); ++ nbttagcompound.setInt("Bukkit.MaxDomestication", this.maxDomestication); // CraftBukkit + if (this.hasChest()) { + NBTTagList nbttaglist = new NBTTagList(); + +@@ -1007,6 +1024,12 @@ + this.setOwnerUUID(s); + } + ++ // CraftBukkit start ++ if (nbttagcompound.hasKey("Bukkit.MaxDomestication")) { ++ this.maxDomestication = nbttagcompound.getInt("Bukkit.MaxDomestication"); ++ } ++ // CraftBukkit end ++ + AttributeInstance attributeinstance = this.getAttributeMap().a("Speed"); + + if (attributeinstance != null) { +@@ -1172,18 +1195,25 @@ + + public void v(int i) { + if (this.cG()) { ++ // CraftBukkit start - fire HorseJumpEvent, use event power + if (i < 0) { + i = 0; +- } else { +- this.bG = true; +- this.dh(); + } + ++ float power; + if (i >= 90) { +- this.br = 1.0F; ++ power = 1.0F; + } else { +- this.br = 0.4F + 0.4F * (float) i / 90.0F; ++ power = 0.4F + 0.4F * (float) i / 90.0F; ++ } ++ ++ org.bukkit.event.entity.HorseJumpEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callHorseJumpEvent(this, power); ++ if (!event.isCancelled()) { ++ this.bG = true; ++ this.dh(); ++ this.br = power; + } ++ // CraftBukkit end + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHuman.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHuman.patch new file mode 100644 index 0000000..fad8853 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityHuman.patch @@ -0,0 +1,430 @@ +--- a/net/minecraft/server/EntityHuman.java ++++ b/net/minecraft/server/EntityHuman.java +@@ -8,13 +8,27 @@ + import java.util.List; + import java.util.UUID; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.craftbukkit.entity.CraftItem; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.entity.Player; ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.player.PlayerBedEnterEvent; ++import org.bukkit.event.player.PlayerBedLeaveEvent; ++import org.bukkit.event.player.PlayerDropItemEvent; ++import org.bukkit.event.player.PlayerItemConsumeEvent; ++import org.bukkit.event.player.PlayerVelocityEvent; ++import org.bukkit.util.Vector; ++// CraftBukkit end ++ + public abstract class EntityHuman extends EntityLiving { + + public PlayerInventory inventory = new PlayerInventory(this); + private InventoryEnderChest enderChest = new InventoryEnderChest(); + public Container defaultContainer; + public Container activeContainer; +- protected FoodMetaData foodData = new FoodMetaData(); ++ protected FoodMetaData foodData = new FoodMetaData(this); // CraftBukkit - add "this" to constructor + protected int bm; + public float bn; + public float bo; +@@ -47,6 +61,17 @@ + private boolean bI = false; + public EntityFishingHook hookedFish; + ++ // CraftBukkit start ++ public boolean fauxSleeping; ++ public String spawnWorld = ""; ++ public int oldLevel = -1; ++ ++ @Override ++ public CraftHumanEntity getBukkitEntity() { ++ return (CraftHumanEntity) super.getBukkitEntity(); ++ } ++ // CraftBukkit end ++ + public EntityHuman(World world, GameProfile gameprofile) { + super(world); + this.uniqueID = a(gameprofile); +@@ -265,6 +290,32 @@ + if (this.g != null) { + this.b(this.g, 16); + int i = this.g.count; ++ ++ // CraftBukkit start - fire PlayerItemConsumeEvent ++ org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(this.g); ++ PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ // Update client ++ if (this instanceof EntityPlayer) { ++ ((EntityPlayer) this).playerConnection.sendPacket(new PacketPlayOutSetSlot((byte) 0, activeContainer.getSlot((IInventory) this.inventory, this.inventory.itemInHandIndex).index, this.g)); ++ } ++ return; ++ } ++ ++ // Plugin modified the item, process it but don't remove it ++ if (!craftItem.equals(event.getItem())) { ++ CraftItemStack.asNMSCopy(event.getItem()).b(this.world, this); ++ ++ // Update client ++ if (this instanceof EntityPlayer) { ++ ((EntityPlayer) this).playerConnection.sendPacket(new PacketPlayOutSetSlot((byte) 0, activeContainer.getSlot((IInventory) this.inventory, this.inventory.itemInHandIndex).index, this.g)); ++ } ++ return; ++ } ++ // CraftBukkit end ++ + ItemStack itemstack = this.g.b(this.world, this); + + if (itemstack != this.g || itemstack != null && itemstack.count != i) { +@@ -324,7 +375,8 @@ + + if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.world.getGameRules().getBoolean("naturalRegeneration")) { + if (this.getHealth() < this.getMaxHealth() && this.ticksLived % 20 == 0) { +- this.heal(1.0F); ++ // CraftBukkit - added regain reason of "REGEN" for filtering purposes. ++ this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); + } + + if (this.foodData.c() && this.ticksLived % 10 == 0) { +@@ -348,7 +400,7 @@ + + this.k((float) attributeinstance.getValue()); + float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); +- float f1 = (float) (Math.atan(-this.motY * 0.20000000298023224D) * 15.0D); ++ float f1 = (float) ( org.bukkit.craftbukkit.TrigMath.atan(-this.motY * 0.20000000298023224D) * 15.0D); // CraftBukkit + + if (f > 0.1F) { + f = 0.1F; +@@ -438,11 +490,13 @@ + + public void b(Entity entity, int i) { + this.addScore(i); +- Collection collection = this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.f); ++ // CraftBukkit - Get our scores instead ++ Collection collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.f, this.getName(), new java.util.ArrayList()); + + if (entity instanceof EntityHuman) { + this.b(StatisticList.B); +- collection.addAll(this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.e)); ++ // CraftBukkit - Get our scores instead ++ this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.e, this.getName(), collection); + collection.addAll(this.e(entity)); + } else { + this.b(StatisticList.z); +@@ -451,15 +505,14 @@ + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { +- ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); +- ScoreboardScore scoreboardscore = this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective); ++ ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); // CraftBukkit - Use our scores instead + + scoreboardscore.incrementScore(); + } + + } + +- private Collection e(Entity entity) { ++ private Collection e(Entity entity) { // CraftBukkit - TODO: Check me? + ScoreboardTeam scoreboardteam = this.getScoreboard().getPlayerTeam(this.getName()); + + if (scoreboardteam != null) { +@@ -491,6 +544,7 @@ + } + + public EntityItem a(boolean flag) { ++ // Called only when dropped by Q or CTRL-Q + return this.a(this.inventory.splitStack(this.inventory.itemInHandIndex, flag && this.inventory.getItemInHand() != null ? this.inventory.getItemInHand().count : 1), false, true); + } + +@@ -533,6 +587,30 @@ + entityitem.motZ += Math.sin((double) f1) * (double) f; + } + ++ // CraftBukkit start - fire PlayerDropItemEvent ++ Player player = (Player) this.getBukkitEntity(); ++ CraftItem drop = new CraftItem(this.world.getServer(), entityitem); ++ ++ PlayerDropItemEvent event = new PlayerDropItemEvent(player, drop); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ org.bukkit.inventory.ItemStack cur = player.getInventory().getItemInHand(); ++ if (flag1 && (cur == null || cur.getAmount() == 0)) { ++ // The complete stack was dropped ++ player.getInventory().setItemInHand(drop.getItemStack()); ++ } else if (flag1 && cur.isSimilar(drop.getItemStack()) && drop.getItemStack().getAmount() == 1) { ++ // Only one item is dropped ++ cur.setAmount(cur.getAmount() + 1); ++ player.getInventory().setItemInHand(cur); ++ } else { ++ // Fallback ++ player.getInventory().addItem(drop.getItemStack()); ++ } ++ return null; ++ } ++ // CraftBukkit end ++ + this.a(entityitem); + if (flag1) { + this.b(StatisticList.v); +@@ -624,6 +702,13 @@ + this.a(true, true, false); + } + ++ // CraftBukkit start ++ this.spawnWorld = nbttagcompound.getString("SpawnWorld"); ++ if ("".equals(spawnWorld)) { ++ this.spawnWorld = this.world.getServer().getWorlds().get(0).getName(); ++ } ++ // CraftBukkit end ++ + if (nbttagcompound.hasKeyOfType("SpawnX", 99) && nbttagcompound.hasKeyOfType("SpawnY", 99) && nbttagcompound.hasKeyOfType("SpawnZ", 99)) { + this.c = new BlockPosition(nbttagcompound.getInt("SpawnX"), nbttagcompound.getInt("SpawnY"), nbttagcompound.getInt("SpawnZ")); + this.d = nbttagcompound.getBoolean("SpawnForced"); +@@ -665,6 +750,7 @@ + if (itemstack != null && itemstack.getItem() != null) { + nbttagcompound.set("SelectedItem", itemstack.save(new NBTTagCompound())); + } ++ nbttagcompound.setString("SpawnWorld", spawnWorld); // CraftBukkit - fixes bed spawns for multiworld worlds + + } + +@@ -684,7 +770,7 @@ + + if (damagesource.r()) { + if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { +- f = 0.0F; ++ return false; // CraftBukkit - f = 0.0f -> return false + } + + if (this.world.getDifficulty() == EnumDifficulty.EASY) { +@@ -696,7 +782,7 @@ + } + } + +- if (f == 0.0F) { ++ if (false && f == 0.0F) { // CraftBukkit - Don't filter out 0 damage + return false; + } else { + Entity entity = damagesource.getEntity(); +@@ -712,10 +798,29 @@ + } + + public boolean a(EntityHuman entityhuman) { +- ScoreboardTeamBase scoreboardteambase = this.getScoreboardTeam(); +- ScoreboardTeamBase scoreboardteambase1 = entityhuman.getScoreboardTeam(); ++ // CraftBukkit start - Change to check OTHER player's scoreboard team according to API ++ // To summarize this method's logic, it's "Can parameter hurt this" ++ org.bukkit.scoreboard.Team team; ++ if (entityhuman instanceof EntityPlayer) { ++ EntityPlayer thatPlayer = (EntityPlayer) entityhuman; ++ team = thatPlayer.getBukkitEntity().getScoreboard().getPlayerTeam(thatPlayer.getBukkitEntity()); ++ if (team == null || team.allowFriendlyFire()) { ++ return true; ++ } ++ } else { ++ // This should never be called, but is implemented anyway ++ org.bukkit.OfflinePlayer thisPlayer = entityhuman.world.getServer().getOfflinePlayer(entityhuman.getName()); ++ team = entityhuman.world.getServer().getScoreboardManager().getMainScoreboard().getPlayerTeam(thisPlayer); ++ if (team == null || team.allowFriendlyFire()) { ++ return true; ++ } ++ } + +- return scoreboardteambase == null ? true : (!scoreboardteambase.isAlly(scoreboardteambase1) ? true : scoreboardteambase.allowFriendlyFire()); ++ if (this instanceof EntityPlayer) { ++ return !team.hasPlayer(((EntityPlayer) this).getBukkitEntity()); ++ } ++ return !team.hasPlayer(this.world.getServer().getOfflinePlayer(this.getName())); ++ // CraftBukkit end + } + + protected void damageArmor(float f) { +@@ -742,7 +847,12 @@ + return (float) i / (float) this.inventory.armor.length; + } + +- protected void d(DamageSource damagesource, float f) { ++ // CraftBukkit start ++ protected boolean d(DamageSource damagesource, float f) { // void -> boolean ++ if (true) { ++ return super.d(damagesource, f); ++ } ++ // CraftBukkit end + if (!this.isInvulnerable(damagesource)) { + if (!damagesource.ignoresArmor() && this.isBlocking() && f > 0.0F) { + f = (1.0F + f) * 0.5F; +@@ -766,6 +876,7 @@ + + } + } ++ return false; // CraftBukkit + } + + public void openSign(TileEntitySign tileentitysign) {} +@@ -800,7 +911,8 @@ + } + + if (itemstack.a(this, (EntityLiving) entity)) { +- if (itemstack.count <= 0 && !this.abilities.canInstantlyBuild) { ++ // CraftBukkit - bypass infinite items; <= 0 -> == 0 ++ if (itemstack.count == 0 && !this.abilities.canInstantlyBuild) { + this.ca(); + } + +@@ -866,8 +978,15 @@ + int j = EnchantmentManager.getFireAspectEnchantmentLevel(this); + + if (entity instanceof EntityLiving && j > 0 && !entity.isBurning()) { +- flag1 = true; +- entity.setOnFire(1); ++ // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item ++ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 1); ++ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); ++ ++ if (!combustEvent.isCancelled()) { ++ flag1 = true; ++ entity.setOnFire(combustEvent.getDuration()); ++ } ++ // CraftBukkit end + } + + double d0 = entity.motX; +@@ -884,11 +1003,28 @@ + } + + if (entity instanceof EntityPlayer && entity.velocityChanged) { +- ((EntityPlayer) entity).playerConnection.sendPacket(new PacketPlayOutEntityVelocity(entity)); +- entity.velocityChanged = false; +- entity.motX = d0; +- entity.motY = d1; +- entity.motZ = d2; ++ // CraftBukkit start - Add Velocity Event ++ boolean cancelled = false; ++ Player player = (Player) entity.getBukkitEntity(); ++ org.bukkit.util.Vector velocity = new Vector( d0, d1, d2 ); ++ ++ PlayerVelocityEvent event = new PlayerVelocityEvent(player, velocity.clone()); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ cancelled = true; ++ } else if (!velocity.equals(event.getVelocity())) { ++ player.setVelocity(event.getVelocity()); ++ } ++ ++ if (!cancelled) { ++ ( (EntityPlayer) entity ).playerConnection.sendPacket( new PacketPlayOutEntityVelocity( entity ) ); ++ entity.velocityChanged = false; ++ entity.motX = d0; ++ entity.motY = d1; ++ entity.motZ = d2; ++ } ++ // CraftBukkit end + } + + if (flag) { +@@ -922,7 +1058,8 @@ + + if (itemstack != null && object instanceof EntityLiving) { + itemstack.a((EntityLiving) object, this); +- if (itemstack.count <= 0) { ++ // CraftBukkit - bypass infinite items; <= 0 -> == 0 ++ if (itemstack.count == 0) { + this.ca(); + } + } +@@ -930,7 +1067,14 @@ + if (entity instanceof EntityLiving) { + this.a(StatisticList.w, Math.round(f * 10.0F)); + if (j > 0) { +- entity.setOnFire(j * 4); ++ // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item ++ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), j * 4); ++ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); ++ ++ if (!combustEvent.isCancelled()) { ++ entity.setOnFire(combustEvent.getDuration()); ++ } ++ // CraftBukkit end + } + } + +@@ -996,6 +1140,20 @@ + this.mount((Entity) null); + } + ++ // CraftBukkit start - fire PlayerBedEnterEvent ++ if (this.getBukkitEntity() instanceof Player) { ++ Player player = (Player) this.getBukkitEntity(); ++ org.bukkit.block.Block bed = this.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ PlayerBedEnterEvent event = new PlayerBedEnterEvent(player, bed); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return EnumBedResult.OTHER_PROBLEM; ++ } ++ } ++ // CraftBukkit end ++ + this.setSize(0.2F, 0.2F); + if (this.world.isLoaded(blockposition)) { + EnumDirection enumdirection = (EnumDirection) this.world.getType(blockposition).get(BlockDirectional.FACING); +@@ -1078,6 +1236,23 @@ + this.world.everyoneSleeping(); + } + ++ // CraftBukkit start - fire PlayerBedLeaveEvent ++ if (this.getBukkitEntity() instanceof Player) { ++ Player player = (Player) this.getBukkitEntity(); ++ ++ org.bukkit.block.Block bed; ++ BlockPosition blockposition = this.bx; ++ if (blockposition != null) { ++ bed = this.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ } else { ++ bed = this.world.getWorld().getBlockAt(player.getLocation()); ++ } ++ ++ PlayerBedLeaveEvent event = new PlayerBedLeaveEvent(player, bed); ++ this.world.getServer().getPluginManager().callEvent(event); ++ } ++ // CraftBukkit end ++ + this.sleepTicks = flag ? 0 : 100; + if (flag2) { + this.setRespawnPosition(this.bx, false); +@@ -1090,6 +1265,7 @@ + } + + public static BlockPosition getBed(World world, BlockPosition blockposition, boolean flag) { ++ ((ChunkProviderServer) world.chunkProvider).getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); // CraftBukkit + Block block = world.getType(blockposition).getBlock(); + + if (block != Blocks.BED) { +@@ -1128,9 +1304,11 @@ + if (blockposition != null) { + this.c = blockposition; + this.d = flag; ++ this.spawnWorld = this.world.worldData.getName(); // CraftBukkit + } else { + this.c = null; + this.d = false; ++ this.spawnWorld = ""; // CraftBukkit + } + + } +@@ -1480,6 +1658,7 @@ + } + + public IChatBaseComponent getScoreboardDisplayName() { ++ // CraftBukkit - todo: fun + ChatComponentText chatcomponenttext = new ChatComponentText(ScoreboardTeam.getPlayerDisplayName(this.getScoreboardTeam(), this.getName())); + + chatcomponenttext.getChatModifier().setChatClickable(new ChatClickable(ChatClickable.EnumClickAction.SUGGEST_COMMAND, "/msg " + this.getName() + " ")); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityInsentient.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityInsentient.patch new file mode 100644 index 0000000..955ebec --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityInsentient.patch @@ -0,0 +1,183 @@ +--- a/net/minecraft/server/EntityInsentient.java ++++ b/net/minecraft/server/EntityInsentient.java +@@ -4,6 +4,15 @@ + import java.util.List; + import java.util.UUID; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.entity.CraftLivingEntity; ++import org.bukkit.event.entity.EntityTargetLivingEntityEvent; ++import org.bukkit.event.entity.EntityTargetEvent; ++import org.bukkit.event.entity.EntityUnleashEvent; ++import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason; ++// CraftBukkit end ++ + public abstract class EntityInsentient extends EntityLiving { + + public int a_; +@@ -40,6 +49,9 @@ + this.dropChances[i] = 0.085F; + } + ++ // CraftBukkit start - default persistance to type's persistance value ++ this.persistent = !isTypeNotPersistent(); ++ // CraftBukkit end + } + + protected void initAttributes() { +@@ -76,7 +88,37 @@ + } + + public void setGoalTarget(EntityLiving entityliving) { ++ // CraftBukkit start - fire event ++ setGoalTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true); ++ } ++ ++ public void setGoalTarget(EntityLiving entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) { ++ if (getGoalTarget() == entityliving) return; ++ if (fireEvent) { ++ if (reason == EntityTargetEvent.TargetReason.UNKNOWN && getGoalTarget() != null && entityliving == null) { ++ reason = getGoalTarget().isAlive() ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED; ++ } ++ if (reason == EntityTargetEvent.TargetReason.UNKNOWN) { ++ world.getServer().getLogger().log(java.util.logging.Level.WARNING, "Unknown target reason, please report on the issue tracker", new Exception()); ++ } ++ CraftLivingEntity ctarget = null; ++ if (entityliving != null) { ++ ctarget = (CraftLivingEntity) entityliving.getBukkitEntity(); ++ } ++ EntityTargetLivingEntityEvent event = new EntityTargetLivingEntityEvent(this.getBukkitEntity(), ctarget, reason); ++ world.getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ if (event.getTarget() != null) { ++ entityliving = ((CraftLivingEntity) event.getTarget()).getHandle(); ++ } else { ++ entityliving = null; ++ } ++ } + this.goalTarget = entityliving; ++ // CraftBukkit end + } + + public boolean a(Class oclass) { +@@ -168,6 +210,7 @@ + return null; + } + ++ protected ItemStack headDrop = null; // CraftBukkit + protected void dropDeathLoot(boolean flag, int i) { + Item item = this.getLoot(); + +@@ -183,6 +226,12 @@ + } + } + ++ // CraftBukkit start ++ if (headDrop != null) { ++ this.a(headDrop, 0.0F); ++ headDrop = null; ++ } ++ // CraftBukkit end + } + + public void b(NBTTagCompound nbttagcompound) { +@@ -235,11 +284,20 @@ + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); ++ ++ // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it + if (nbttagcompound.hasKeyOfType("CanPickUpLoot", 1)) { +- this.j(nbttagcompound.getBoolean("CanPickUpLoot")); ++ boolean data = nbttagcompound.getBoolean("CanPickUpLoot"); ++ if (isLevelAtLeast(nbttagcompound, 1) || data) { ++ this.j(data); ++ } + } + +- this.persistent = nbttagcompound.getBoolean("PersistenceRequired"); ++ boolean data = nbttagcompound.getBoolean("PersistenceRequired"); ++ if (isLevelAtLeast(nbttagcompound, 1) || data) { ++ this.persistent = data; ++ } ++ // CraftBukkit end + NBTTagList nbttaglist; + int i; + +@@ -380,11 +438,11 @@ + double d2 = entityhuman.locZ - this.locZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + +- if (this.isTypeNotPersistent() && d3 > 16384.0D) { ++ if (d3 > 16384.0D) { // CraftBukkit - remove isTypeNotPersistent() check + this.die(); + } + +- if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d3 > 1024.0D && this.isTypeNotPersistent()) { ++ if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d3 > 1024.0D) { // CraftBukkit - remove isTypeNotPersistent() check + this.die(); + } else if (d3 < 1024.0D) { + this.ticksFarFromPlayer = 0; +@@ -707,6 +765,12 @@ + + public final boolean e(EntityHuman entityhuman) { + if (this.cc() && this.getLeashHolder() == entityhuman) { ++ // CraftBukkit start - fire PlayerUnleashEntityEvent ++ if (CraftEventFactory.callPlayerUnleashEntityEvent(this, entityhuman).isCancelled()) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder())); ++ return false; ++ } ++ // CraftBukkit end + this.unleash(true, !entityhuman.abilities.canInstantlyBuild); + return true; + } else { +@@ -714,12 +778,24 @@ + + if (itemstack != null && itemstack.getItem() == Items.LEAD && this.cb()) { + if (!(this instanceof EntityTameableAnimal) || !((EntityTameableAnimal) this).isTamed()) { ++ // CraftBukkit start - fire PlayerLeashEntityEvent ++ if (CraftEventFactory.callPlayerLeashEntityEvent(this, entityhuman, entityhuman).isCancelled()) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder())); ++ return false; ++ } ++ // CraftBukkit end + this.setLeashHolder(entityhuman, true); + --itemstack.count; + return true; + } + + if (((EntityTameableAnimal) this).e((EntityLiving) entityhuman)) { ++ // CraftBukkit start - fire PlayerLeashEntityEvent ++ if (CraftEventFactory.callPlayerLeashEntityEvent(this, entityhuman, entityhuman).isCancelled()) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder())); ++ return false; ++ } ++ // CraftBukkit end + this.setLeashHolder(entityhuman, true); + --itemstack.count; + return true; +@@ -741,10 +817,12 @@ + + if (this.bo) { + if (!this.isAlive()) { ++ this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.PLAYER_UNLEASH)); // CraftBukkit + this.unleash(true, true); + } + + if (this.bp == null || this.bp.dead) { ++ this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.HOLDER_GONE)); // CraftBukkit + this.unleash(true, true); + } + } +@@ -811,6 +889,7 @@ + + this.bp = entityleash; + } else { ++ this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit + this.unleash(false, true); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityIronGolem.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityIronGolem.patch new file mode 100644 index 0000000..f05036e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityIronGolem.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/EntityIronGolem.java ++++ b/net/minecraft/server/EntityIronGolem.java +@@ -59,7 +59,7 @@ + + protected void s(Entity entity) { + if (entity instanceof IMonster && !(entity instanceof EntityCreeper) && this.bc().nextInt(20) == 0) { +- this.setGoalTarget((EntityLiving) entity); ++ this.setGoalTarget((EntityLiving) entity, org.bukkit.event.entity.EntityTargetLivingEntityEvent.TargetReason.COLLISION, true); // CraftBukkit - set reason + } + + super.s(entity); +@@ -220,7 +220,7 @@ + } + + public boolean apply(Object object) { +- return this.a((EntityLiving) object); ++ return this.a((T) object); // CraftBukkit - fix decompiler error + } + }; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityItem.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityItem.patch new file mode 100644 index 0000000..dc98445 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityItem.patch @@ -0,0 +1,135 @@ +--- a/net/minecraft/server/EntityItem.java ++++ b/net/minecraft/server/EntityItem.java +@@ -3,6 +3,7 @@ + import java.util.Iterator; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; ++import org.bukkit.event.player.PlayerPickupItemEvent; // CraftBukkit + + public class EntityItem extends Entity { + +@@ -13,6 +14,7 @@ + private String f; + private String g; + public float a; ++ private int lastTick = MinecraftServer.currentTick; // CraftBukkit + + public EntityItem(World world, double d0, double d1, double d2) { + super(world); +@@ -28,6 +30,11 @@ + + public EntityItem(World world, double d0, double d1, double d2, ItemStack itemstack) { + this(world, d0, d1, d2); ++ // CraftBukkit start - Can't set null items in the datawatcher ++ if (itemstack == null || itemstack.getItem() == null) { ++ return; ++ } ++ // CraftBukkit end + this.setItemStack(itemstack); + } + +@@ -52,9 +59,12 @@ + this.die(); + } else { + super.t_(); +- if (this.pickupDelay > 0 && this.pickupDelay != 32767) { +- --this.pickupDelay; +- } ++ // CraftBukkit start - Use wall time for pickup and despawn timers ++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick; ++ if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; ++ if (this.age != -32768) this.age += elapsedTicks; ++ this.lastTick = MinecraftServer.currentTick; ++ // CraftBukkit end + + this.lastX = this.locX; + this.lastY = this.locY; +@@ -90,12 +100,21 @@ + this.motY *= -0.5D; + } + ++ /* Craftbukkit start - moved up + if (this.age != -32768) { + ++this.age; + } ++ // Craftbukkit end */ ++ + + this.W(); + if (!this.world.isClientSide && this.age >= 6000) { ++ // CraftBukkit start - fire ItemDespawnEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { ++ this.age = 0; ++ return; ++ } ++ // CraftBukkit end + this.die(); + } + +@@ -137,6 +156,7 @@ + } else if (itemstack1.count + itemstack.count > itemstack1.getMaxStackSize()) { + return false; + } else { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemMergeEvent(this, entityitem).isCancelled()) return false; // CraftBukkit + itemstack1.count += itemstack.count; + entityitem.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay); + entityitem.age = Math.min(entityitem.age, this.age); +@@ -183,6 +203,11 @@ + } else if (this.getItemStack() != null && this.getItemStack().getItem() == Items.NETHER_STAR && damagesource.isExplosion()) { + return false; + } else { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { ++ return false; ++ } ++ // CraftBukkit end + this.ac(); + this.e = (int) ((float) this.e - f); + if (this.e <= 0) { +@@ -228,7 +253,18 @@ + + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Item"); + +- this.setItemStack(ItemStack.createStack(nbttagcompound1)); ++ // CraftBukkit start - Handle missing "Item" compounds ++ if (nbttagcompound1 != null) { ++ ItemStack itemstack = ItemStack.createStack(nbttagcompound1); ++ if (itemstack != null) { ++ this.setItemStack(itemstack); ++ } else { ++ this.die(); ++ } ++ } else { ++ this.die(); ++ } ++ // CraftBukkit end + if (this.getItemStack() == null) { + this.die(); + } +@@ -240,6 +276,26 @@ + ItemStack itemstack = this.getItemStack(); + int i = itemstack.count; + ++ // CraftBukkit start - fire PlayerPickupItemEvent ++ int canHold = entityhuman.inventory.canHold(itemstack); ++ int remaining = itemstack.count - canHold; ++ ++ if (this.pickupDelay <= 0 && canHold > 0) { ++ itemstack.count = canHold; ++ PlayerPickupItemEvent event = new PlayerPickupItemEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); ++ // event.setCancelled(!entityhuman.canPickUpLoot); TODO ++ this.world.getServer().getPluginManager().callEvent(event); ++ itemstack.count = canHold + remaining; ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ // Possibly < 0; fix here so we do not have to modify code below ++ this.pickupDelay = 0; ++ } ++ // CraftBukkit end ++ + if (this.pickupDelay == 0 && (this.g == null || 6000 - this.age <= 200 || this.g.equals(entityhuman.getName())) && entityhuman.inventory.pickup(itemstack)) { + if (itemstack.getItem() == Item.getItemOf(Blocks.LOG)) { + entityhuman.b((Statistic) AchievementList.g); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityItemFrame.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityItemFrame.patch new file mode 100644 index 0000000..1859a97 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityItemFrame.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/server/EntityItemFrame.java ++++ b/net/minecraft/server/EntityItemFrame.java +@@ -27,6 +27,11 @@ + return false; + } else if (!damagesource.isExplosion() && this.getItem() != null) { + if (!this.world.isClientSide) { ++ // CraftBukkit start - fire EntityDamageEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f, false) || this.dead) { ++ return true; ++ } ++ // CraftBukkit end + this.a(damagesource.getEntity(), false); + this.setItem((ItemStack) null); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLargeFireball.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLargeFireball.patch new file mode 100644 index 0000000..09d2680 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLargeFireball.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/server/EntityLargeFireball.java ++++ b/net/minecraft/server/EntityLargeFireball.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit ++ + public class EntityLargeFireball extends EntityFireball { + + public int yield = 1; +@@ -21,7 +23,15 @@ + + boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); + +- this.world.createExplosion((Entity) null, this.locX, this.locY, this.locZ, (float) this.yield, flag, flag); ++ // CraftBukkit start - fire ExplosionPrimeEvent ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) org.bukkit.craftbukkit.entity.CraftEntity.getEntity(this.world.getServer(), this)); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ // give 'this' instead of (Entity) null so we know what causes the damage ++ this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), flag); ++ } ++ // CraftBukkit end + this.die(); + } + +@@ -35,7 +45,8 @@ + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("ExplosionPower", 99)) { +- this.yield = nbttagcompound.getInt("ExplosionPower"); ++ // CraftBukkit - set bukkitYield when setting explosionpower ++ bukkitYield = this.yield = nbttagcompound.getInt("ExplosionPower"); + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLeash.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLeash.patch new file mode 100644 index 0000000..0496ad2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLeash.patch @@ -0,0 +1,61 @@ +--- a/net/minecraft/server/EntityLeash.java ++++ b/net/minecraft/server/EntityLeash.java +@@ -3,6 +3,8 @@ + import java.util.Iterator; + import java.util.List; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntityLeash extends EntityHanging { + + public EntityLeash(World world) { +@@ -63,6 +65,12 @@ + while (iterator.hasNext()) { + entityinsentient = (EntityInsentient) iterator.next(); + if (entityinsentient.cc() && entityinsentient.getLeashHolder() == entityhuman) { ++ // CraftBukkit start ++ if (CraftEventFactory.callPlayerLeashEntityEvent(entityinsentient, this, entityhuman).isCancelled()) { ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, entityinsentient, entityinsentient.getLeashHolder())); ++ continue; ++ } ++ // CraftBukkit end + entityinsentient.setLeashHolder(this, true); + flag = true; + } +@@ -70,8 +78,11 @@ + } + + if (!this.world.isClientSide && !flag) { +- this.die(); +- if (entityhuman.abilities.canInstantlyBuild) { ++ // CraftBukkit start - Move below ++ // this.die(); ++ boolean die = true; ++ // CraftBukkit end ++ if (true || entityhuman.abilities.canInstantlyBuild) { // CraftBukkit - Process for non-creative as well + d0 = 7.0D; + list = this.world.a(EntityInsentient.class, new AxisAlignedBB(this.locX - d0, this.locY - d0, this.locZ - d0, this.locX + d0, this.locY + d0, this.locZ + d0)); + iterator = list.iterator(); +@@ -79,10 +90,21 @@ + while (iterator.hasNext()) { + entityinsentient = (EntityInsentient) iterator.next(); + if (entityinsentient.cc() && entityinsentient.getLeashHolder() == this) { +- entityinsentient.unleash(true, false); ++ // CraftBukkit start ++ if (CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, entityhuman).isCancelled()) { ++ die = false; ++ continue; ++ } ++ entityinsentient.unleash(true, !entityhuman.abilities.canInstantlyBuild); // false -> survival mode boolean ++ // CraftBukkit end + } + } + } ++ // CraftBukkit start ++ if (die) { ++ this.die(); ++ } ++ // CraftBukkit end + } + + return true; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLightning.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLightning.patch new file mode 100644 index 0000000..61a2854 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLightning.patch @@ -0,0 +1,106 @@ +--- a/net/minecraft/server/EntityLightning.java ++++ b/net/minecraft/server/EntityLightning.java +@@ -2,30 +2,53 @@ + + import java.util.List; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntityLightning extends EntityWeather { + + private int lifeTicks; + public long a; + private int c; + ++ // CraftBukkit start ++ public boolean isEffect = false; ++ + public EntityLightning(World world, double d0, double d1, double d2) { ++ this(world, d0, d1, d2, false); ++ } ++ ++ public EntityLightning(World world, double d0, double d1, double d2, boolean isEffect) { ++ // CraftBukkit end + super(world); ++ ++ // CraftBukkit - Set isEffect ++ this.isEffect = isEffect; ++ + this.setPositionRotation(d0, d1, d2, 0.0F, 0.0F); + this.lifeTicks = 2; + this.a = this.random.nextLong(); + this.c = this.random.nextInt(3) + 1; + BlockPosition blockposition = new BlockPosition(this); + +- if (!world.isClientSide && world.getGameRules().getBoolean("doFireTick") && (world.getDifficulty() == EnumDifficulty.NORMAL || world.getDifficulty() == EnumDifficulty.HARD) && world.areChunksLoaded(blockposition, 10)) { ++ // CraftBukkit - add "!isEffect" ++ if (!isEffect && !world.isClientSide && world.getGameRules().getBoolean("doFireTick") && (world.getDifficulty() == EnumDifficulty.NORMAL || world.getDifficulty() == EnumDifficulty.HARD) && world.areChunksLoaded(blockposition, 10)) { + if (world.getType(blockposition).getBlock().getMaterial() == Material.AIR && Blocks.FIRE.canPlace(world, blockposition)) { +- world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ // CraftBukkit start ++ if (!CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { ++ world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ } ++ // CraftBukkit end + } + + for (int i = 0; i < 4; ++i) { + BlockPosition blockposition1 = blockposition.a(this.random.nextInt(3) - 1, this.random.nextInt(3) - 1, this.random.nextInt(3) - 1); + + if (world.getType(blockposition1).getBlock().getMaterial() == Material.AIR && Blocks.FIRE.canPlace(world, blockposition1)) { +- world.setTypeUpdate(blockposition1, Blocks.FIRE.getBlockData()); ++ // CraftBukkit start ++ if (!CraftEventFactory.callBlockIgniteEvent(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), this).isCancelled()) { ++ world.setTypeUpdate(blockposition1, Blocks.FIRE.getBlockData()); ++ } ++ // CraftBukkit end + } + } + } +@@ -35,7 +58,24 @@ + public void t_() { + super.t_(); + if (this.lifeTicks == 2) { +- this.world.makeSound(this.locX, this.locY, this.locZ, "ambient.weather.thunder", 10000.0F, 0.8F + this.random.nextFloat() * 0.2F); ++ // CraftBukkit start - Use relative location for far away sounds ++ //this.world.makeSound(this.locX, this.locY, this.locZ, "ambient.weather.thunder", 10000.0F, 0.8F + this.random.nextFloat() * 0.2F); ++ float pitch = 0.8F + this.random.nextFloat() * 0.2F; ++ int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; ++ for (EntityPlayer player : (List) (List) this.world.players) { ++ double deltaX = this.locX - player.locX; ++ double deltaZ = this.locZ - player.locZ; ++ double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; ++ if (distanceSquared > viewDistance * viewDistance) { ++ double deltaLength = Math.sqrt(distanceSquared); ++ double relativeX = player.locX + (deltaX / deltaLength) * viewDistance; ++ double relativeZ = player.locZ + (deltaZ / deltaLength) * viewDistance; ++ player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("ambient.weather.thunder", relativeX, this.locY, relativeZ, 10000.0F, pitch)); ++ } else { ++ player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("ambient.weather.thunder", this.locX, this.locY, this.locZ, 10000.0F, pitch)); ++ } ++ } ++ // CraftBukkit end + this.world.makeSound(this.locX, this.locY, this.locZ, "random.explode", 2.0F, 0.5F + this.random.nextFloat() * 0.2F); + } + +@@ -49,13 +89,18 @@ + this.a = this.random.nextLong(); + BlockPosition blockposition = new BlockPosition(this); + ++ // CraftBukkit - add "!isEffect" + if (!this.world.isClientSide && this.world.getGameRules().getBoolean("doFireTick") && this.world.areChunksLoaded(blockposition, 10) && this.world.getType(blockposition).getBlock().getMaterial() == Material.AIR && Blocks.FIRE.canPlace(this.world, blockposition)) { +- this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ // CraftBukkit start ++ if (!isEffect && !CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { ++ this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ } ++ // CraftBukkit end + } + } + } + +- if (this.lifeTicks >= 0) { ++ if (this.lifeTicks >= 0 && !this.isEffect) { // CraftBukkit - add !this.isEffect + if (this.world.isClientSide) { + this.world.d(2); + } else { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLiving.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLiving.patch new file mode 100644 index 0000000..c6c9491 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityLiving.patch @@ -0,0 +1,546 @@ +--- a/net/minecraft/server/EntityLiving.java ++++ b/net/minecraft/server/EntityLiving.java +@@ -10,12 +10,25 @@ + import java.util.Random; + import java.util.UUID; + ++// CraftBukkit start ++import java.util.ArrayList; ++import com.google.common.base.Function; ++import com.google.common.collect.Lists; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.entity.LivingEntity; ++import org.bukkit.entity.Vehicle; ++import org.bukkit.event.entity.EntityDamageEvent; ++import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; ++import org.bukkit.event.entity.EntityRegainHealthEvent; ++import org.bukkit.event.vehicle.VehicleExitEvent; ++// CraftBukkit end ++ + public abstract class EntityLiving extends Entity { + + private static final UUID a = UUID.fromString("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 final CombatTracker combatTracker = new CombatTracker(this); ++ public CombatTracker combatTracker = new CombatTracker(this); + public final Map effects = Maps.newHashMap(); + private final ItemStack[] h = new ItemStack[5]; + public boolean ar; +@@ -69,6 +82,11 @@ + private float bm; + private int bn; + private float bo; ++ // CraftBukkit start ++ public int expToDrop; ++ public int maxAirTicks = 300; ++ ArrayList drops = null; ++ // CraftBukkit end + + public void G() { + this.damageEntity(DamageSource.OUT_OF_WORLD, Float.MAX_VALUE); +@@ -77,7 +95,8 @@ + public EntityLiving(World world) { + super(world); + this.initAttributes(); +- this.setHealth(this.getMaxHealth()); ++ // CraftBukkit - setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor ++ this.datawatcher.watch(6, (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue()); + this.k = true; + this.aH = (float) ((Math.random() + 1.0D) * 0.009999999776482582D); + this.setPosition(this.locX, this.locY, this.locZ); +@@ -119,7 +138,13 @@ + + int i = (int) (150.0D * d1); + +- ((WorldServer) this.world).a(EnumParticle.BLOCK_DUST, this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, new int[] { Block.getCombinedId(iblockdata)}); ++ // CraftBukkit start - visiblity api ++ if (this instanceof EntityPlayer) { ++ ((WorldServer) this.world).sendParticles((EntityPlayer) this, EnumParticle.BLOCK_DUST, false, this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, new int[] { Block.getCombinedId(iblockdata)}); ++ } else { ++ ((WorldServer) this.world).a(EnumParticle.BLOCK_DUST, this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, new int[] { Block.getCombinedId(iblockdata)}); ++ } ++ // CraftBukkit end + } + } + +@@ -177,7 +202,11 @@ + this.mount((Entity) null); + } + } else { +- this.setAirTicks(300); ++ // CraftBukkit start - Only set if needed to work around a DataWatcher inefficiency ++ if (this.getAirTicks() != 300) { ++ this.setAirTicks(maxAirTicks); ++ } ++ // CraftBukkit end + } + } + +@@ -225,25 +254,36 @@ + this.world.methodProfiler.b(); + } + ++ // CraftBukkit start ++ public int getExpReward() { ++ int exp = this.getExpValue(this.killer); ++ ++ if (!this.world.isClientSide && (this.lastDamageByPlayerTime > 0 || this.alwaysGivesExp()) && this.ba() && this.world.getGameRules().getBoolean("doMobLoot")) { ++ return exp; ++ } else { ++ return 0; ++ } ++ } ++ // CraftBukkit end ++ + public boolean isBaby() { + return false; + } + + protected void aZ() { + ++this.deathTicks; +- if (this.deathTicks == 20) { ++ if (this.deathTicks >= 20 && !this.dead) { // CraftBukkit - (this.deathTicks == 20) -> (this.deathTicks >= 20 && !this.dead) + int i; + +- if (!this.world.isClientSide && (this.lastDamageByPlayerTime > 0 || this.alwaysGivesExp()) && this.ba() && this.world.getGameRules().getBoolean("doMobLoot")) { +- i = this.getExpValue(this.killer); +- +- while (i > 0) { +- int j = EntityExperienceOrb.getOrbValue(i); +- +- i -= j; +- this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j)); +- } ++ // CraftBukkit start - Update getExpReward() above if the removed if() changes! ++ i = this.expToDrop; ++ while (i > 0) { ++ int j = EntityExperienceOrb.getOrbValue(i); ++ i -= j; ++ this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j)); + } ++ this.expToDrop = 0; ++ // CraftBukkit end + + this.die(); + +@@ -380,6 +420,17 @@ + } + } + ++ // CraftBukkit start ++ if (nbttagcompound.hasKey("Bukkit.MaxHealth")) { ++ NBTBase nbtbase = nbttagcompound.get("Bukkit.MaxHealth"); ++ if (nbtbase.getTypeId() == 5) { ++ this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) ((NBTTagFloat) nbtbase).c()); ++ } else if (nbtbase.getTypeId() == 3) { ++ this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) ((NBTTagInt) nbtbase).d()); ++ } ++ } ++ // CraftBukkit end ++ + if (nbttagcompound.hasKeyOfType("HealF", 99)) { + this.setHealth(nbttagcompound.getFloat("HealF")); + } else { +@@ -399,9 +450,15 @@ + this.hurtTimestamp = nbttagcompound.getInt("HurtByTimestamp"); + } + ++ // CraftBukkit start ++ private boolean isTickingEffects = false; ++ private List effectsToProcess = Lists.newArrayList(); ++ // CraftBukkit end ++ + protected void bi() { + Iterator iterator = this.effects.keySet().iterator(); + ++ isTickingEffects = true; // CraftBukkit + while (iterator.hasNext()) { + Integer integer = (Integer) iterator.next(); + MobEffect mobeffect = (MobEffect) this.effects.get(integer); +@@ -415,6 +472,16 @@ + this.a(mobeffect, false); + } + } ++ // CraftBukkit start ++ isTickingEffects = false; ++ for (Object e : effectsToProcess) { ++ if (e instanceof MobEffect) { ++ addEffect((MobEffect) e); ++ } else { ++ removeEffect((Integer) e); ++ } ++ } ++ // CraftBukkit end + + if (this.updateEffects) { + if (!this.world.isClientSide) { +@@ -490,7 +557,8 @@ + } + + public boolean hasEffect(int i) { +- return this.effects.containsKey(Integer.valueOf(i)); ++ // CraftBukkit - Add size check for efficiency ++ return this.effects.size() != 0 && this.effects.containsKey(Integer.valueOf(i)); + } + + public boolean hasEffect(MobEffectList mobeffectlist) { +@@ -502,6 +570,12 @@ + } + + public void addEffect(MobEffect mobeffect) { ++ // CraftBukkit start ++ if (isTickingEffects) { ++ effectsToProcess.add(mobeffect); ++ return; ++ } ++ // CraftBukkit end + if (this.d(mobeffect)) { + if (this.effects.containsKey(Integer.valueOf(mobeffect.getEffectId()))) { + ((MobEffect) this.effects.get(Integer.valueOf(mobeffect.getEffectId()))).a(mobeffect); +@@ -531,6 +605,12 @@ + } + + public void removeEffect(int i) { ++ // CraftBukkit start ++ if (isTickingEffects) { ++ effectsToProcess.add(i); ++ return; ++ } ++ // CraftBukkit end + MobEffect mobeffect = (MobEffect) this.effects.remove(Integer.valueOf(i)); + + if (mobeffect != null) { +@@ -564,20 +644,52 @@ + + } + ++ // CraftBukkit start - Delegate so we can handle providing a reason for health being regained + public void heal(float f) { ++ heal(f, EntityRegainHealthEvent.RegainReason.CUSTOM); ++ } ++ ++ public void heal(float f, EntityRegainHealthEvent.RegainReason regainReason) { + float f1 = this.getHealth(); + + if (f1 > 0.0F) { +- this.setHealth(f1 + f); ++ EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), f, regainReason); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ this.setHealth((float) (this.getHealth() + event.getAmount())); ++ } ++ // CraftBukkit end + } + + } + + public final float getHealth() { ++ // CraftBukkit start - Use unscaled health ++ if (this instanceof EntityPlayer) { ++ return (float) ((EntityPlayer) this).getBukkitEntity().getHealth(); ++ } ++ // CraftBukkit end + return this.datawatcher.getFloat(6); + } + + public void setHealth(float f) { ++ // CraftBukkit start - Handle scaled health ++ if (this instanceof EntityPlayer) { ++ org.bukkit.craftbukkit.entity.CraftPlayer player = ((EntityPlayer) this).getBukkitEntity(); ++ // Squeeze ++ if (f < 0.0F) { ++ player.setRealHealth(0.0D); ++ } else if (f > player.getMaxHealth()) { ++ player.setRealHealth(player.getMaxHealth()); ++ } else { ++ player.setRealHealth(f); ++ } ++ ++ this.datawatcher.watch(6, Float.valueOf(player.getScaledHealth())); ++ return; ++ } ++ // CraftBukkit end + this.datawatcher.watch(6, Float.valueOf(MathHelper.a(f, 0.0F, this.getMaxHealth()))); + } + +@@ -593,7 +705,8 @@ + } else if (damagesource.o() && this.hasEffect(MobEffectList.FIRE_RESISTANCE)) { + return false; + } else { +- if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { ++ // CraftBukkit - Moved into d(DamageSource, float) ++ if (false && (damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { + this.getEquipment(4).damage((int) (f * 4.0F + this.random.nextFloat() * f * 2.0F), this); + f *= 0.75F; + } +@@ -603,19 +716,38 @@ + + if ((float) this.noDamageTicks > (float) this.maxNoDamageTicks / 2.0F) { + if (f <= this.lastDamage) { ++ this.forceExplosionKnockback = true; // CraftBukkit - SPIGOT-949 - for vanilla consistency, cooldown does not prevent explosion knockback + return false; + } + +- this.d(damagesource, f - this.lastDamage); ++ // CraftBukkit start ++ if (!this.d(damagesource, f - this.lastDamage)) { ++ return false; ++ } ++ // CraftBukkit end + this.lastDamage = f; + flag = false; + } else { ++ // CraftBukkit start ++ float previousHealth = this.getHealth(); ++ if (!this.d(damagesource, f)) { ++ return false; ++ } + this.lastDamage = f; + this.noDamageTicks = this.maxNoDamageTicks; +- this.d(damagesource, f); ++ // CraftBukkit end + this.hurtTicks = this.av = 10; + } + ++ // CraftBukkit start ++ if(this instanceof EntityAnimal){ ++ ((EntityAnimal)this).cq(); ++ if(this instanceof EntityTameableAnimal){ ++ ((EntityTameableAnimal)this).getGoalSit().setSitting(false); ++ } ++ } ++ // CraftBukkit end ++ + this.aw = 0.0F; + Entity entity = damagesource.getEntity(); + +@@ -721,11 +853,19 @@ + } + + if (this.ba() && this.world.getGameRules().getBoolean("doMobLoot")) { ++ this.drops = new ArrayList(); // CraftBukkit - Setup drop capture ++ + this.dropDeathLoot(this.lastDamageByPlayerTime > 0, i); + this.dropEquipment(this.lastDamageByPlayerTime > 0, i); + if (this.lastDamageByPlayerTime > 0 && this.random.nextFloat() < 0.025F + (float) i * 0.01F) { + this.getRareDrop(); + } ++ // CraftBukkit start - Call death event ++ CraftEventFactory.callEntityDeathEvent(this, this.drops); ++ this.drops = null; ++ } else { ++ CraftEventFactory.callEntityDeathEvent(this); ++ // CraftBukkit end + } + } + +@@ -785,8 +925,13 @@ + int i = MathHelper.f((f - 3.0F - f2) * f1); + + if (i > 0) { ++ // CraftBukkit start ++ if (!this.damageEntity(DamageSource.FALL, (float) i)) { ++ return; ++ } ++ // CraftBukkit end + this.makeSound(this.n(i), 1.0F, 1.0F); +- this.damageEntity(DamageSource.FALL, (float) i); ++ // this.damageEntity(DamageSource.FALL, (float) i); // CraftBukkit - moved up + int j = MathHelper.floor(this.locX); + int k = MathHelper.floor(this.locY - 0.20000000298023224D); + int l = MathHelper.floor(this.locZ); +@@ -830,7 +975,7 @@ + int i = 25 - this.br(); + float f1 = f * (float) i; + +- this.damageArmor(f); ++ // this.damageArmor(f); // CraftBukkit - Moved into d(DamageSource, float) + f = f1 / 25.0F; + } + +@@ -844,8 +989,9 @@ + int i; + int j; + float f1; +- +- if (this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { ++ ++ // CraftBukkit - Moved to d(DamageSource, float) ++ if (false && this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { + i = (this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5; + j = 25 - i; + f1 = f * (float) j; +@@ -871,22 +1017,121 @@ + } + } + +- protected void d(DamageSource damagesource, float f) { +- if (!this.isInvulnerable(damagesource)) { +- f = this.applyArmorModifier(damagesource, f); +- f = this.applyMagicModifier(damagesource, f); +- float f1 = f; ++ // CraftBukkit start ++ protected boolean d(final DamageSource damagesource, float f) { // void -> boolean, add final ++ if (!this.isInvulnerable(damagesource)) { ++ final boolean human = this instanceof EntityHuman; ++ float originalDamage = f; ++ Function hardHat = new Function() { ++ @Override ++ public Double apply(Double f) { ++ if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && EntityLiving.this.getEquipment(4) != null) { ++ return -(f - (f * 0.75F)); ++ } ++ return -0.0; ++ } ++ }; ++ float hardHatModifier = hardHat.apply((double) f).floatValue(); ++ f += hardHatModifier; ++ ++ Function blocking = new Function() { ++ @Override ++ public Double apply(Double f) { ++ if (human) { ++ if (!damagesource.ignoresArmor() && ((EntityHuman) EntityLiving.this).isBlocking() && f > 0.0F) { ++ return -(f - ((1.0F + f) * 0.5F)); ++ } ++ } ++ return -0.0; ++ } ++ }; ++ float blockingModifier = blocking.apply((double) f).floatValue(); ++ f += blockingModifier; ++ ++ Function armor = new Function() { ++ @Override ++ public Double apply(Double f) { ++ return -(f - EntityLiving.this.applyArmorModifier(damagesource, f.floatValue())); ++ } ++ }; ++ float armorModifier = armor.apply((double) f).floatValue(); ++ f += armorModifier; ++ ++ Function resistance = new Function() { ++ @Override ++ public Double apply(Double f) { ++ if (!damagesource.isStarvation() && EntityLiving.this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { ++ int i = (EntityLiving.this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5; ++ int j = 25 - i; ++ float f1 = f.floatValue() * (float) j; ++ return -(f - (f1 / 25.0F)); ++ } ++ return -0.0; ++ } ++ }; ++ float resistanceModifier = resistance.apply((double) f).floatValue(); ++ f += resistanceModifier; ++ ++ Function magic = new Function() { ++ @Override ++ public Double apply(Double f) { ++ return -(f - EntityLiving.this.applyMagicModifier(damagesource, f.floatValue())); ++ } ++ }; ++ float magicModifier = magic.apply((double) f).floatValue(); ++ f += magicModifier; ++ ++ Function absorption = new Function() { ++ @Override ++ public Double apply(Double f) { ++ return -(Math.max(f - Math.max(f - EntityLiving.this.getAbsorptionHearts(), 0.0F), 0.0F)); ++ } ++ }; ++ float absorptionModifier = absorption.apply((double) f).floatValue(); ++ ++ EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption); ++ if (event.isCancelled()) { ++ return false; ++ } ++ ++ f = (float) event.getFinalDamage(); ++ ++ // Apply damage to helmet ++ if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { ++ this.getEquipment(4).damage((int) (event.getDamage() * 4.0F + this.random.nextFloat() * event.getDamage() * 2.0F), this); ++ } ++ ++ // Apply damage to armor ++ if (!damagesource.ignoresArmor()) { ++ float armorDamage = (float) (event.getDamage() + event.getDamage(DamageModifier.BLOCKING) + event.getDamage(DamageModifier.HARD_HAT)); ++ this.damageArmor(armorDamage); ++ } + +- f = Math.max(f - this.getAbsorptionHearts(), 0.0F); +- this.setAbsorptionHearts(this.getAbsorptionHearts() - (f1 - f)); ++ absorptionModifier = (float) -event.getDamage(DamageModifier.ABSORPTION); ++ this.setAbsorptionHearts(Math.max(this.getAbsorptionHearts() - absorptionModifier, 0.0F)); + if (f != 0.0F) { ++ if (human) { ++ // PAIL: Be sure to drag all this code from the EntityHuman subclass each update. ++ ((EntityHuman) this).applyExhaustion(damagesource.getExhaustionCost()); ++ if (f < 3.4028235E37F) { ++ ((EntityHuman) this).a(StatisticList.x, Math.round(f * 10.0F)); ++ } ++ } ++ // CraftBukkit end + float f2 = this.getHealth(); + + this.setHealth(f2 - f); + this.bs().a(damagesource, f2, f); ++ // CraftBukkit start ++ if (human) { ++ return true; ++ } ++ // CraftBukkit end + this.setAbsorptionHearts(this.getAbsorptionHearts() - f); + } ++ return true; // CraftBukkit + } ++ return false; // CraftBukkit + } + + public CombatTracker bs() { +@@ -1240,7 +1485,8 @@ + if (f > 0.0025000002F) { + f3 = 1.0F; + f2 = (float) Math.sqrt((double) f) * 3.0F; +- f1 = (float) MathHelper.b(d1, d0) * 180.0F / 3.1415927F - 90.0F; ++ // CraftBukkit - Math -> TrigMath ++ f1 = (float) org.bukkit.craftbukkit.TrigMath.atan2(d1, d0) * 180.0F / 3.1415927F - 90.0F; + } + + if (this.az > 0.0F) { +@@ -1413,6 +1659,13 @@ + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + ++ // TODO better check now? ++ // CraftBukkit start - Only handle mob (non-player) collisions every other tick ++ if (entity instanceof EntityLiving && !(this instanceof EntityPlayer) && this.ticksLived % 2 == 0) { ++ continue; ++ } ++ // CraftBukkit end ++ + this.s(entity); + } + } +@@ -1425,6 +1678,18 @@ + + public void mount(Entity entity) { + if (this.vehicle != null && entity == null) { ++ // CraftBukkit start ++ Entity originalVehicle = this.vehicle; ++ if ((this.bukkitEntity instanceof LivingEntity) && (this.vehicle.getBukkitEntity() instanceof Vehicle)) { ++ VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.bukkitEntity); ++ getBukkitEntity().getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled() || vehicle != originalVehicle) { ++ return; ++ } ++ } ++ // CraftBukkit end ++ + if (!this.world.isClientSide) { + this.q(this.vehicle); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartAbstract.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartAbstract.patch new file mode 100644 index 0000000..252d080 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartAbstract.patch @@ -0,0 +1,226 @@ +--- a/net/minecraft/server/EntityMinecartAbstract.java ++++ b/net/minecraft/server/EntityMinecartAbstract.java +@@ -4,6 +4,15 @@ + import java.util.Iterator; + import java.util.Map; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.entity.Vehicle; ++import org.bukkit.event.vehicle.VehicleDamageEvent; ++import org.bukkit.event.vehicle.VehicleDestroyEvent; ++import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; ++import org.bukkit.util.Vector; ++// CraftBukkit end ++ + public abstract class EntityMinecartAbstract extends Entity implements INamableTileEntity { + + private boolean a; +@@ -16,6 +25,17 @@ + private double h; + private double i; + ++ // CraftBukkit start ++ public boolean slowWhenEmpty = true; ++ private double derailedX = 0.5; ++ private double derailedY = 0.5; ++ private double derailedZ = 0.5; ++ private double flyingX = 0.95; ++ private double flyingY = 0.95; ++ private double flyingZ = 0.95; ++ public double maxSpeed = 0.4D; ++ // CraftBukkit end ++ + public EntityMinecartAbstract(World world) { + super(world); + this.k = true; +@@ -81,6 +101,8 @@ + this.lastX = d0; + this.lastY = d1; + this.lastZ = d2; ++ ++ this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleCreateEvent((Vehicle) this.getBukkitEntity())); // CraftBukkit + } + + public double an() { +@@ -92,6 +114,19 @@ + if (this.isInvulnerable(damagesource)) { + return false; + } else { ++ // CraftBukkit start - fire VehicleDamageEvent ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.entity.Entity passenger = (damagesource.getEntity() == null) ? null : damagesource.getEntity().getBukkitEntity(); ++ ++ VehicleDamageEvent event = new VehicleDamageEvent(vehicle, passenger, f); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return true; ++ } ++ ++ f = (float) event.getDamage(); ++ // CraftBukkit end + this.k(-this.r()); + this.j(10); + this.ac(); +@@ -99,6 +134,15 @@ + boolean flag = damagesource.getEntity() instanceof EntityHuman && ((EntityHuman) damagesource.getEntity()).abilities.canInstantlyBuild; + + if (flag || this.getDamage() > 40.0F) { ++ // CraftBukkit start ++ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, passenger); ++ this.world.getServer().getPluginManager().callEvent(destroyEvent); ++ ++ if (destroyEvent.isCancelled()) { ++ this.setDamage(40); // Maximize damage so this doesn't get triggered again right away ++ return true; ++ } ++ // CraftBukkit end + if (this.passenger != null) { + this.passenger.mount((Entity) null); + } +@@ -140,6 +184,14 @@ + } + + public void t_() { ++ // CraftBukkit start ++ double prevX = this.locX; ++ double prevY = this.locY; ++ double prevZ = this.locZ; ++ float prevYaw = this.yaw; ++ float prevPitch = this.pitch; ++ // CraftBukkit end ++ + if (this.getType() > 0) { + this.j(this.getType() - 1); + } +@@ -160,7 +212,7 @@ + + i = this.L(); + if (this.ak) { +- if (minecraftserver.getAllowNether()) { ++ if (true || minecraftserver.getAllowNether()) { // CraftBukkit - multi-world should still allow teleport even if default vanilla nether disabled + if (this.vehicle == null && this.al++ >= i) { + this.al = i; + this.portalCooldown = this.aq(); +@@ -257,6 +309,20 @@ + } + + this.setYawPitch(this.yaw, this.pitch); ++ ++ // CraftBukkit start ++ org.bukkit.World bworld = this.world.getWorld(); ++ Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); ++ Location to = new Location(bworld, this.locX, this.locY, this.locZ, this.yaw, this.pitch); ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ ++ this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle)); ++ ++ if (!from.equals(to)) { ++ this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to)); ++ } ++ // CraftBukkit end ++ + Iterator iterator = this.world.getEntities(this, this.getBoundingBox().grow(0.20000000298023224D, 0.0D, 0.20000000298023224D)).iterator(); + + while (iterator.hasNext()) { +@@ -280,7 +346,7 @@ + } + + protected double m() { +- return 0.4D; ++ return this.maxSpeed; // CraftBukkit + } + + public void a(int i, int j, int k, boolean flag) {} +@@ -291,16 +357,20 @@ + this.motX = MathHelper.a(this.motX, -d0, d0); + this.motZ = MathHelper.a(this.motZ, -d0, d0); + if (this.onGround) { +- this.motX *= 0.5D; +- this.motY *= 0.5D; +- this.motZ *= 0.5D; ++ // CraftBukkit start - replace magic numbers with our variables ++ this.motX *= this.derailedX; ++ this.motY *= this.derailedY; ++ this.motZ *= this.derailedZ; ++ // CraftBukkit end + } + + this.move(this.motX, this.motY, this.motZ); + if (!this.onGround) { +- this.motX *= 0.949999988079071D; +- this.motY *= 0.949999988079071D; +- this.motZ *= 0.949999988079071D; ++ // CraftBukkit start - replace magic numbers with our variables ++ this.motX *= this.flyingX; ++ this.motY *= this.flyingY; ++ this.motZ *= this.flyingZ; ++ // CraftBukkit end + } + + } +@@ -488,7 +558,7 @@ + } + + protected void o() { +- if (this.passenger != null) { ++ if (this.passenger != null || !this.slowWhenEmpty) { // CraftBukkit - add !this.slowWhenEmpty + this.motX *= 0.996999979019165D; + this.motY *= 0.0D; + this.motZ *= 0.996999979019165D; +@@ -616,6 +686,17 @@ + if (!this.world.isClientSide) { + if (!entity.noclip && !this.noclip) { + if (entity != this.passenger) { ++ // CraftBukkit start ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.entity.Entity hitEntity = (entity == null) ? null : entity.getBukkitEntity(); ++ ++ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent(vehicle, hitEntity); ++ this.world.getServer().getPluginManager().callEvent(collisionEvent); ++ ++ if (collisionEvent.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + if (entity instanceof EntityLiving && !(entity instanceof EntityHuman) && !(entity instanceof EntityIronGolem) && this.s() == EntityMinecartAbstract.EnumMinecartType.RIDEABLE && this.motX * this.motX + this.motZ * this.motZ > 0.01D && this.passenger == null && entity.vehicle == null) { + entity.mount(this); + } +@@ -624,7 +705,8 @@ + double d1 = entity.locZ - this.locZ; + double d2 = d0 * d0 + d1 * d1; + +- if (d2 >= 9.999999747378752E-5D) { ++ // CraftBukkit - collision ++ if (d2 >= 9.999999747378752E-5D && !collisionEvent.isCollisionCancelled()) { + d2 = (double) MathHelper.sqrt(d2); + d0 /= d2; + d1 /= d2; +@@ -891,4 +973,26 @@ + + } + } ++ ++ // CraftBukkit start - Methods for getting and setting flying and derailed velocity modifiers ++ public Vector getFlyingVelocityMod() { ++ return new Vector(flyingX, flyingY, flyingZ); ++ } ++ ++ public void setFlyingVelocityMod(Vector flying) { ++ flyingX = flying.getX(); ++ flyingY = flying.getY(); ++ flyingZ = flying.getZ(); ++ } ++ ++ public Vector getDerailedVelocityMod() { ++ return new Vector(derailedX, derailedY, derailedZ); ++ } ++ ++ public void setDerailedVelocityMod(Vector derailed) { ++ derailedX = derailed.getX(); ++ derailedY = derailed.getY(); ++ derailedZ = derailed.getZ(); ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartCommandBlock.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartCommandBlock.patch new file mode 100644 index 0000000..33aa4bc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartCommandBlock.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/server/EntityMinecartCommandBlock.java ++++ b/net/minecraft/server/EntityMinecartCommandBlock.java +@@ -3,6 +3,9 @@ + public class EntityMinecartCommandBlock extends EntityMinecartAbstract { + + private final CommandBlockListenerAbstract a = new CommandBlockListenerAbstract() { ++ { ++ this.sender = (org.bukkit.craftbukkit.entity.CraftMinecartCommand) EntityMinecartCommandBlock.this.getBukkitEntity(); // CraftBukkit - Set the sender ++ } + public void h() { + EntityMinecartCommandBlock.this.getDataWatcher().watch(23, this.getCommand()); + EntityMinecartCommandBlock.this.getDataWatcher().watch(24, IChatBaseComponent.ChatSerializer.a(this.k())); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartContainer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartContainer.patch new file mode 100644 index 0000000..2356dae --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMinecartContainer.patch @@ -0,0 +1,62 @@ +--- a/net/minecraft/server/EntityMinecartContainer.java ++++ b/net/minecraft/server/EntityMinecartContainer.java +@@ -1,10 +1,49 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import java.util.List; ++ ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.inventory.InventoryHolder; ++// CraftBukkit end ++ + public abstract class EntityMinecartContainer extends EntityMinecartAbstract implements ITileInventory { + +- private ItemStack[] items = new ItemStack[36]; ++ private ItemStack[] items = new ItemStack[27]; // CraftBukkit - 36 -> 27 + private boolean b = true; + ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public InventoryHolder getOwner() { ++ org.bukkit.entity.Entity cart = getBukkitEntity(); ++ if(cart instanceof InventoryHolder) return (InventoryHolder) cart; ++ return null; ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public EntityMinecartContainer(World world) { + super(world); + } +@@ -84,7 +123,7 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return maxStack; // CraftBukkit + } + + public void c(int i) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMonster.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMonster.patch new file mode 100644 index 0000000..239b570 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMonster.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/server/EntityMonster.java ++++ b/net/minecraft/server/EntityMonster.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.entity.EntityCombustByEntityEvent; // CraftBukkit ++ + public abstract class EntityMonster extends EntityCreature implements IMonster { + + public EntityMonster(World world) { +@@ -79,7 +81,14 @@ + int j = EnchantmentManager.getFireAspectEnchantmentLevel(this); + + if (j > 0) { +- entity.setOnFire(j * 4); ++ // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item ++ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), j * 4); ++ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); ++ ++ if (!combustEvent.isCancelled()) { ++ entity.setOnFire(combustEvent.getDuration()); ++ } ++ // CraftBukkit end + } + + this.a((EntityLiving) this, entity); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMushroomCow.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMushroomCow.patch new file mode 100644 index 0000000..7702e6d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityMushroomCow.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/server/EntityMushroomCow.java ++++ b/net/minecraft/server/EntityMushroomCow.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.player.PlayerShearEntityEvent; // CraftBukkit ++ + public class EntityMushroomCow extends EntityCow { + + public EntityMushroomCow(World world) { +@@ -24,6 +26,14 @@ + } + + if (itemstack != null && itemstack.getItem() == Items.SHEARS && this.getAge() >= 0) { ++ // CraftBukkit start ++ PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ // 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]); + if (!this.world.isClientSide) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityOcelot.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityOcelot.patch new file mode 100644 index 0000000..6f1a161 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityOcelot.patch @@ -0,0 +1,48 @@ +--- a/net/minecraft/server/EntityOcelot.java ++++ b/net/minecraft/server/EntityOcelot.java +@@ -51,7 +51,7 @@ + } + + protected boolean isTypeNotPersistent() { +- return !this.isTamed() && this.ticksLived > 2400; ++ return !this.isTamed() /*&& this.ticksLived > 2400*/; // CraftBukkit + } + + protected void initAttributes() { +@@ -96,6 +96,9 @@ + return entity.damageEntity(DamageSource.mobAttack(this), 3.0F); + } + ++ /* CraftBukkit start ++ // Function disabled as it has no special function anymore after ++ // setSitting is disabled. + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; +@@ -104,6 +107,7 @@ + return super.damageEntity(damagesource, f); + } + } ++ // CraftBukkit end */ + + protected void dropDeathLoot(boolean flag, int i) {} + +@@ -124,7 +128,8 @@ + } + + if (!this.world.isClientSide) { +- if (this.random.nextInt(3) == 0) { ++ // CraftBukkit - added event call and isCancelled check ++ if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { + this.setTamed(true); + this.setCatType(1 + this.world.random.nextInt(3)); + this.setOwnerUUID(entityhuman.getUniqueID().toString()); +@@ -231,7 +236,7 @@ + + entityocelot.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); + entityocelot.setAgeRaw(-24000); +- this.world.addEntity(entityocelot); ++ this.world.addEntity(entityocelot, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OCELOT_BABY); // CraftBukkit - add SpawnReason + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPainting.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPainting.patch new file mode 100644 index 0000000..2e0e1c0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPainting.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/EntityPainting.java ++++ b/net/minecraft/server/EntityPainting.java +@@ -9,6 +9,7 @@ + + public EntityPainting(World world) { + super(world); ++ this.art = EnumArt.values()[this.random.nextInt(EnumArt.values().length)]; // CraftBukkit - generate a non-null painting + } + + public EntityPainting(World world, BlockPosition blockposition, EnumDirection enumdirection) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPig.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPig.patch new file mode 100644 index 0000000..2f7637b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPig.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/server/EntityPig.java ++++ b/net/minecraft/server/EntityPig.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntityPig extends EntityAnimal { + + private final PathfinderGoalPassengerCarrotStick bm; +@@ -112,6 +114,12 @@ + if (!this.world.isClientSide && !this.dead) { + EntityPigZombie entitypigzombie = new EntityPigZombie(this.world); + ++ // CraftBukkit start ++ if (CraftEventFactory.callPigZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ + entitypigzombie.setEquipment(0, new ItemStack(Items.GOLDEN_SWORD)); + entitypigzombie.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + entitypigzombie.k(this.ce()); +@@ -120,7 +128,8 @@ + entitypigzombie.setCustomNameVisible(this.getCustomNameVisible()); + } + +- this.world.addEntity(entitypigzombie); ++ // CraftBukkit - added a reason for spawning this creature ++ this.world.addEntity(entitypigzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); + this.die(); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPlayer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPlayer.patch new file mode 100644 index 0000000..fe51ea5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPlayer.patch @@ -0,0 +1,609 @@ +--- a/net/minecraft/server/EntityPlayer.java ++++ b/net/minecraft/server/EntityPlayer.java +@@ -13,6 +13,17 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import org.bukkit.Bukkit; ++import org.bukkit.WeatherType; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.inventory.InventoryType; ++import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; ++// CraftBukkit end ++ + public class EntityPlayer extends EntityHuman implements ICrafting { + + private static final Logger bH = LogManager.getLogger(); +@@ -40,6 +51,18 @@ + public int ping; + public boolean viewingCredits; + ++ // CraftBukkit start ++ public String displayName; ++ public IChatBaseComponent listName; ++ public org.bukkit.Location compassTarget; ++ public int newExp = 0; ++ public int newLevel = 0; ++ public int newTotalExp = 0; ++ public boolean keepLevel = false; ++ public double maxHealthCache; ++ public boolean joining = true; ++ // CraftBukkit end ++ + public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { + super(worldserver, gameprofile); + playerinteractmanager.player = this; +@@ -70,6 +93,11 @@ + this.setPosition(this.locX, this.locY + 1.0D, this.locZ); + } + ++ // CraftBukkit start ++ this.displayName = this.getName(); ++ // this.canPickUpLoot = true; TODO ++ this.maxHealthCache = this.getMaxHealth(); ++ // CraftBukkit end + } + + public void a(NBTTagCompound nbttagcompound) { +@@ -82,12 +110,40 @@ + } + } + ++ this.getBukkitEntity().readExtraData(nbttagcompound); // CraftBukkit + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("playerGameType", this.playerInteractManager.getGameMode().getId()); ++ ++ this.getBukkitEntity().setExtraData(nbttagcompound); // CraftBukkit ++ } ++ ++ // CraftBukkit start - World fallback code, either respawn location or global spawn ++ public void spawnIn(World world) { ++ super.spawnIn(world); ++ if (world == null) { ++ this.dead = false; ++ BlockPosition position = null; ++ if (this.spawnWorld != null && !this.spawnWorld.equals("")) { ++ CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(this.spawnWorld); ++ if (cworld != null && this.getBed() != null) { ++ world = cworld.getHandle(); ++ position = EntityHuman.getBed(cworld.getHandle(), this.getBed(), false); ++ } ++ } ++ if (world == null || position == null) { ++ world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(); ++ position = world.getSpawn(); ++ } ++ this.world = world; ++ this.setPosition(position.getX() + 0.5, position.getY(), position.getZ() + 0.5); ++ } ++ this.dimension = ((WorldServer) this.world).dimension; ++ this.playerInteractManager.a((WorldServer) world); + } ++ // CraftBukkit end + + public void levelDown(int i) { + super.levelDown(i); +@@ -114,6 +170,11 @@ + } + + public void t_() { ++ // CraftBukkit start ++ if (this.joining) { ++ this.joining = false; ++ } ++ // CraftBukkit end + this.playerInteractManager.a(); + --this.invulnerableTicks; + if (this.noDamageTicks > 0) { +@@ -155,7 +216,7 @@ + chunk = this.world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z); + if (chunk.isReady()) { + arraylist.add(chunk); +- arraylist1.addAll(((WorldServer) this.world).getTileEntities(chunkcoordintpair.x * 16, 0, chunkcoordintpair.z * 16, chunkcoordintpair.x * 16 + 16, 256, chunkcoordintpair.z * 16 + 16)); ++ arraylist1.addAll(chunk.tileEntities.values()); // CraftBukkit - Get tile entities directly from the chunk instead of the world + iterator1.remove(); + } + } +@@ -220,8 +281,9 @@ + } + } + ++ // CraftBukkit - Optionally scale health + if (this.getHealth() != this.bM || this.bN != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.bO) { +- this.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(this.getHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel())); ++ this.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel())); + this.bM = this.getHealth(); + this.bN = this.foodData.getFoodLevel(); + this.bO = this.foodData.getSaturationLevel() == 0.0F; +@@ -237,7 +299,14 @@ + + this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective).updateForList(Arrays.asList(new EntityHuman[] { this})); + } ++ // CraftBukkit - Update ALL the scores! ++ this.world.getServer().getScoreboardManager().updateAllScoresForList(IScoreboardCriteria.g, this.getName(), com.google.common.collect.ImmutableList.of(this)); ++ } ++ // CraftBukkit start - Force max health updates ++ if (this.maxHealthCache != this.getMaxHealth()) { ++ this.getBukkitEntity().updateScaledHealth(); + } ++ // CraftBukkit end + + if (this.expTotal != this.lastSentExp) { + this.lastSentExp = this.expTotal; +@@ -248,6 +317,16 @@ + this.i_(); + } + ++ // CraftBukkit start - initialize oldLevel and fire PlayerLevelChangeEvent ++ if (this.oldLevel == -1) { ++ this.oldLevel = this.expLevel; ++ } ++ ++ if (this.oldLevel != this.expLevel) { ++ CraftEventFactory.callPlayerLevelChangeEvent(this.world.getServer().getPlayer((EntityPlayer) this), this.oldLevel, this.expLevel); ++ this.oldLevel = this.expLevel; ++ } ++ // CraftBukkit end + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Ticking player"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Player being ticked"); +@@ -296,30 +375,63 @@ + } + + public void die(DamageSource damagesource) { +- if (this.world.getGameRules().getBoolean("showDeathMessages")) { +- ScoreboardTeamBase scoreboardteambase = this.getScoreboardTeam(); ++ // CraftBukkit start - fire PlayerDeathEvent ++ if (this.dead) { ++ return; ++ } ++ java.util.List loot = new java.util.ArrayList(); ++ boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory"); ++ ++ if (!keepInventory) { ++ for (int i = 0; i < this.inventory.items.length; ++i) { ++ if (this.inventory.items[i] != null) { ++ loot.add(CraftItemStack.asCraftMirror(this.inventory.items[i])); ++ } ++ } + +- if (scoreboardteambase != null && scoreboardteambase.j() != ScoreboardTeamBase.EnumNameTagVisibility.ALWAYS) { +- if (scoreboardteambase.j() == ScoreboardTeamBase.EnumNameTagVisibility.HIDE_FOR_OTHER_TEAMS) { +- this.server.getPlayerList().a((EntityHuman) this, this.bs().b()); +- } else if (scoreboardteambase.j() == ScoreboardTeamBase.EnumNameTagVisibility.HIDE_FOR_OWN_TEAM) { +- this.server.getPlayerList().b((EntityHuman) this, this.bs().b()); ++ for (int i = 0; i < this.inventory.armor.length; ++i) { ++ if (this.inventory.armor[i] != null) { ++ loot.add(CraftItemStack.asCraftMirror(this.inventory.armor[i])); + } ++ } ++ } ++ ++ IChatBaseComponent chatmessage = this.bs().b(); ++ ++ String deathmessage = chatmessage.c(); ++ org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, deathmessage, keepInventory); ++ ++ String deathMessage = event.getDeathMessage(); ++ ++ if (deathMessage != null && deathMessage.length() > 0 && this.world.getGameRules().getBoolean("showDeathMessages")) { // TODO: allow plugins to override? ++ if (deathMessage.equals(deathmessage)) { ++ this.server.getPlayerList().sendMessage(chatmessage); + } else { +- this.server.getPlayerList().sendMessage(this.bs().b()); ++ this.server.getPlayerList().sendMessage(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(deathMessage)); + } + } + +- if (!this.world.getGameRules().getBoolean("keepInventory")) { +- this.inventory.n(); ++ // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. ++ if (!event.getKeepInventory()) { ++ for (int i = 0; i < this.inventory.items.length; ++i) { ++ this.inventory.items[i] = null; ++ } ++ ++ for (int i = 0; i < this.inventory.armor.length; ++i) { ++ this.inventory.armor[i] = null; ++ } + } + +- Collection collection = this.world.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.d); ++ this.closeInventory(); ++ this.setSpectatorTarget(this); // Remove spectated target ++ // CraftBukkit end ++ ++ // CraftBukkit - Get our scores instead ++ Collection collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.d, this.getName(), new java.util.ArrayList()); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { +- ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); +- ScoreboardScore scoreboardscore = this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective); ++ ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); // CraftBukkit - Use our scores instead + + scoreboardscore.incrementScore(); + } +@@ -376,7 +488,8 @@ + } + + private boolean cr() { +- return this.server.getPVP(); ++ // CraftBukkit - this.server.getPvP() -> this.world.pvpMode ++ return this.world.pvpMode; + } + + public void c(int i) { +@@ -388,6 +501,8 @@ + } else { + if (this.dimension == 0 && i == 1) { + this.b((Statistic) AchievementList.C); ++ // CraftBukkit start - Rely on custom portal management ++ /* + BlockPosition blockposition = this.server.getWorldServer(i).getDimensionSpawn(); + + if (blockposition != null) { +@@ -395,11 +510,16 @@ + } + + i = 1; ++ */ ++ // CraftBukkit end + } else { + this.b((Statistic) AchievementList.y); + } + +- this.server.getPlayerList().changeDimension(this, i); ++ // CraftBukkit start ++ TeleportCause cause = (this.dimension == 1 || i == 1) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL; ++ this.server.getPlayerList().changeDimension(this, i, cause); ++ // CraftBukkit end + this.lastSentExp = -1; + this.bM = -1.0F; + this.bN = -1; +@@ -442,6 +562,7 @@ + } + + public void a(boolean flag, boolean flag1, boolean flag2) { ++ if (!this.sleeping) return; // CraftBukkit - Can't leave bed if not in one! + if (this.isSleeping()) { + this.u().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(this, 2)); + } +@@ -457,7 +578,7 @@ + Entity entity1 = this.vehicle; + + super.mount(entity); +- if (entity != entity1) { ++ if (this.vehicle != entity1) { // CraftBukkit + this.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this, this.vehicle)); + this.playerConnection.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + } +@@ -490,19 +611,46 @@ + this.playerConnection.sendPacket(new PacketPlayOutOpenSignEditor(tileentitysign.getPosition())); + } + +- private void nextContainerCounter() { ++ public int nextContainerCounter() { // CraftBukkit - private void -> public int + this.containerCounter = this.containerCounter % 100 + 1; ++ return containerCounter; // CraftBukkit + } + + public void openTileEntity(ITileEntityContainer itileentitycontainer) { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, itileentitycontainer.createContainer(this.inventory, this)); ++ if (container == null) { ++ return; ++ } ++ // CraftBukkit end + this.nextContainerCounter(); + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, itileentitycontainer.getContainerName(), itileentitycontainer.getScoreboardDisplayName())); +- this.activeContainer = itileentitycontainer.createContainer(this.inventory, this); ++ this.activeContainer = container; // CraftBukkit + this.activeContainer.windowId = this.containerCounter; + this.activeContainer.addSlotListener(this); + } + + public void openContainer(IInventory iinventory) { ++ // CraftBukkit start - Inventory open hook ++ // Copied from below ++ boolean cancelled = false; ++ if (iinventory instanceof ITileInventory) { ++ ITileInventory itileinventory = (ITileInventory) iinventory; ++ cancelled = itileinventory.r_() && !this.a(itileinventory.i()) && !this.isSpectator(); ++ } ++ ++ Container container; ++ if (iinventory instanceof ITileEntityContainer) { ++ container = ((ITileEntityContainer)iinventory).createContainer(this.inventory, this); ++ } else { ++ container = new ContainerChest(this.inventory, iinventory, this); ++ } ++ container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled); ++ if (container == null && !cancelled) { // Let pre-cancelled events fall through ++ iinventory.closeContainer(this); ++ return; ++ } ++ // CraftBukkit end + if (this.activeContainer != this.defaultContainer) { + this.closeInventory(); + } +@@ -510,9 +658,11 @@ + if (iinventory instanceof ITileInventory) { + ITileInventory itileinventory = (ITileInventory) iinventory; + +- if (itileinventory.r_() && !this.a(itileinventory.i()) && !this.isSpectator()) { ++ if (itileinventory.r_() && !this.a(itileinventory.i()) && !this.isSpectator() && container == null) { // CraftBukkit - allow plugins to uncancel the lock + this.playerConnection.sendPacket(new PacketPlayOutChat(new ChatMessage("container.isLocked", new Object[] { iinventory.getScoreboardDisplayName()}), (byte) 2)); + this.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("random.door_close", this.locX, this.locY, this.locZ, 1.0F, 1.0F)); ++ ++ iinventory.closeContainer(this); // CraftBukkit + return; + } + } +@@ -520,10 +670,10 @@ + this.nextContainerCounter(); + if (iinventory instanceof ITileEntityContainer) { + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, ((ITileEntityContainer) iinventory).getContainerName(), iinventory.getScoreboardDisplayName(), iinventory.getSize())); +- this.activeContainer = ((ITileEntityContainer) iinventory).createContainer(this.inventory, this); ++ this.activeContainer = container; // CraftBukkit + } else { + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "minecraft:container", iinventory.getScoreboardDisplayName(), iinventory.getSize())); +- this.activeContainer = new ContainerChest(this.inventory, iinventory, this); ++ this.activeContainer = container; // CraftBukkit + } + + this.activeContainer.windowId = this.containerCounter; +@@ -531,8 +681,14 @@ + } + + public void openTrade(IMerchant imerchant) { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerMerchant(this.inventory, imerchant, this.world)); ++ if (container == null) { ++ return; ++ } ++ // CraftBukkit end + this.nextContainerCounter(); +- this.activeContainer = new ContainerMerchant(this.inventory, imerchant, this.world); ++ this.activeContainer = container; // CraftBukkit + this.activeContainer.windowId = this.containerCounter; + this.activeContainer.addSlotListener(this); + InventoryMerchant inventorymerchant = ((ContainerMerchant) this.activeContainer).e(); +@@ -552,13 +708,20 @@ + } + + public void openHorseInventory(EntityHorse entityhorse, IInventory iinventory) { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHorse(this.inventory, iinventory, entityhorse, this)); ++ if (container == null) { ++ iinventory.closeContainer(this); ++ return; ++ } ++ // CraftBukkit end + if (this.activeContainer != this.defaultContainer) { + this.closeInventory(); + } + + this.nextContainerCounter(); + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "EntityHorse", iinventory.getScoreboardDisplayName(), iinventory.getSize(), entityhorse.getId())); +- this.activeContainer = new ContainerHorse(this.inventory, iinventory, entityhorse, this); ++ this.activeContainer = container; + this.activeContainer.windowId = this.containerCounter; + this.activeContainer.addSlotListener(this); + } +@@ -587,6 +750,11 @@ + public void a(Container container, List list) { + this.playerConnection.sendPacket(new PacketPlayOutWindowItems(container.windowId, list)); + this.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.inventory.getCarried())); ++ // CraftBukkit start - Send a Set Slot to update the crafting result slot ++ if (java.util.EnumSet.of(InventoryType.CRAFTING,InventoryType.WORKBENCH).contains(container.getBukkitView().getType())) { ++ this.playerConnection.sendPacket(new PacketPlayOutSetSlot(container.windowId, 0, container.getSlot(0).getItem())); ++ } ++ // CraftBukkit end + } + + public void setContainerData(Container container, int i, int j) { +@@ -601,6 +769,7 @@ + } + + public void closeInventory() { ++ CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit + this.playerConnection.sendPacket(new PacketPlayOutCloseWindow(this.activeContainer.windowId)); + this.p(); + } +@@ -681,8 +850,17 @@ + + public void triggerHealthUpdate() { + this.bM = -1.0E8F; ++ this.lastSentExp = -1; // CraftBukkit - Added to reset + } + ++ // CraftBukkit start - Support multi-line messages ++ public void sendMessage(IChatBaseComponent[] ichatbasecomponent) { ++ for (IChatBaseComponent component : ichatbasecomponent) { ++ this.sendMessage(component); ++ } ++ } ++ // CraftBukkit end ++ + public void b(IChatBaseComponent ichatbasecomponent) { + this.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent)); + } +@@ -747,6 +925,8 @@ + } + + public void a(WorldSettings.EnumGamemode worldsettings_enumgamemode) { ++ getBukkitEntity().setGameMode(org.bukkit.GameMode.getByValue(worldsettings_enumgamemode.getId())); ++ /* CraftBukkit start - defer to our setGameMode + this.playerInteractManager.setGameMode(worldsettings_enumgamemode); + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(3, (float) worldsettings_enumgamemode.getId())); + if (worldsettings_enumgamemode == WorldSettings.EnumGamemode.SPECTATOR) { +@@ -757,6 +937,7 @@ + + this.updateAbilities(); + this.bP(); ++ // CraftBukkit end */ + } + + public boolean isSpectator() { +@@ -768,7 +949,8 @@ + } + + public boolean a(int i, String s) { +- if ("seed".equals(s) && !this.server.ae()) { ++ /* CraftBukkit start ++ if ("seed".equals(s) && !this.server.ad()) { + return true; + } else if (!"tell".equals(s) && !"help".equals(s) && !"me".equals(s) && !"trigger".equals(s)) { + if (this.server.getPlayerList().isOp(this.getProfile())) { +@@ -781,6 +963,12 @@ + } else { + return true; + } ++ */ ++ if ("@".equals(s)) { ++ return getBukkitEntity().hasPermission("minecraft.command.selector"); ++ } ++ return true; ++ // CraftBukkit end + } + + public String w() { +@@ -867,6 +1055,129 @@ + } + + public IChatBaseComponent getPlayerListName() { +- return null; ++ return listName; // CraftBukkit ++ } ++ ++ // CraftBukkit start - Add per-player time and weather. ++ public long timeOffset = 0; ++ public boolean relativeTime = true; ++ ++ public long getPlayerTime() { ++ if (this.relativeTime) { ++ // Adds timeOffset to the current server time. ++ return this.world.getDayTime() + this.timeOffset; ++ } else { ++ // Adds timeOffset to the beginning of this day. ++ return this.world.getDayTime() - (this.world.getDayTime() % 24000) + this.timeOffset; ++ } ++ } ++ ++ public WeatherType weather = null; ++ ++ public WeatherType getPlayerWeather() { ++ return this.weather; ++ } ++ ++ public void setPlayerWeather(WeatherType type, boolean plugin) { ++ if (!plugin && this.weather != null) { ++ return; ++ } ++ ++ if (plugin) { ++ this.weather = type; ++ } ++ ++ if (type == WeatherType.DOWNFALL) { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(2, 0)); ++ } else { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(1, 0)); ++ } ++ } ++ ++ private float pluginRainPosition; ++ private float pluginRainPositionPrevious; ++ ++ public void updateWeather(float oldRain, float newRain, float oldThunder, float newThunder) { ++ if (this.weather == null) { ++ // Vanilla ++ if (oldRain != newRain) { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, newRain)); ++ } ++ } else { ++ // Plugin ++ if (pluginRainPositionPrevious != pluginRainPosition) { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, pluginRainPosition)); ++ } ++ } ++ ++ if (oldThunder != newThunder) { ++ if (weather == WeatherType.DOWNFALL || weather == null) { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, newThunder)); ++ } else { ++ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, 0)); ++ } ++ } ++ } ++ ++ public void tickWeather() { ++ if (this.weather == null) return; ++ ++ pluginRainPositionPrevious = pluginRainPosition; ++ if (weather == WeatherType.DOWNFALL) { ++ pluginRainPosition += 0.01; ++ } else { ++ pluginRainPosition -= 0.01; ++ } ++ ++ pluginRainPosition = MathHelper.a(pluginRainPosition, 0.0F, 1.0F); ++ } ++ ++ public void resetPlayerWeather() { ++ this.weather = null; ++ this.setPlayerWeather(this.world.getWorldData().hasStorm() ? WeatherType.DOWNFALL : WeatherType.CLEAR, false); ++ } ++ ++ @Override ++ public String toString() { ++ return super.toString() + "(" + this.getName() + " at " + this.locX + "," + this.locY + "," + this.locZ + ")"; ++ } ++ ++ public void reset() { ++ float exp = 0; ++ boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory"); ++ ++ if (this.keepLevel || keepInventory) { ++ exp = this.exp; ++ this.newTotalExp = this.expTotal; ++ this.newLevel = this.expLevel; ++ } ++ ++ this.setHealth(this.getMaxHealth()); ++ this.fireTicks = 0; ++ this.fallDistance = 0; ++ this.foodData = new FoodMetaData(this); ++ this.expLevel = this.newLevel; ++ this.expTotal = this.newTotalExp; ++ this.exp = 0; ++ this.deathTicks = 0; ++ this.removeAllEffects(); ++ this.updateEffects = true; ++ this.activeContainer = this.defaultContainer; ++ this.killer = null; ++ this.lastDamager = null; ++ this.combatTracker = new CombatTracker(this); ++ this.lastSentExp = -1; ++ if (this.keepLevel || keepInventory) { ++ this.exp = exp; ++ } else { ++ this.giveExp(this.newExp); ++ } ++ this.keepLevel = false; ++ } ++ ++ @Override ++ public CraftPlayer getBukkitEntity() { ++ return (CraftPlayer) super.getBukkitEntity(); + } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPotion.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPotion.patch new file mode 100644 index 0000000..d16a99c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityPotion.patch @@ -0,0 +1,71 @@ +--- a/net/minecraft/server/EntityPotion.java ++++ b/net/minecraft/server/EntityPotion.java +@@ -3,6 +3,13 @@ + import java.util.Iterator; + import java.util.List; + ++// CraftBukkit start ++import java.util.HashMap; ++ ++import org.bukkit.craftbukkit.entity.CraftLivingEntity; ++import org.bukkit.entity.LivingEntity; ++// CraftBukkit end ++ + public class EntityPotion extends EntityProjectile { + + public ItemStack item; +@@ -57,13 +64,16 @@ + if (!this.world.isClientSide) { + List list = Items.POTION.h(this.item); + +- if (list != null && !list.isEmpty()) { ++ if (true || list != null && !list.isEmpty()) { // CraftBukkit - Call event even if no effects to apply + AxisAlignedBB axisalignedbb = this.getBoundingBox().grow(4.0D, 2.0D, 4.0D); + List list1 = this.world.a(EntityLiving.class, axisalignedbb); + +- if (!list1.isEmpty()) { ++ if (true || !list1.isEmpty()) { // CraftBukkit - Run code even if there are no entities around + Iterator iterator = list1.iterator(); + ++ // CraftBukkit ++ HashMap affected = new HashMap(); ++ + while (iterator.hasNext()) { + EntityLiving entityliving = (EntityLiving) iterator.next(); + double d0 = this.h(entityliving); +@@ -75,12 +85,35 @@ + d1 = 1.0D; + } + ++ // CraftBukkit start ++ affected.put((LivingEntity) entityliving.getBukkitEntity(), d1); ++ } ++ } ++ ++ org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, affected); ++ if (!event.isCancelled() && list != null && !list.isEmpty()) { // do not process effects if there are no effects to process ++ for (LivingEntity victim : event.getAffectedEntities()) { ++ if (!(victim instanceof CraftLivingEntity)) { ++ continue; ++ } ++ ++ EntityLiving entityliving = ((CraftLivingEntity) victim).getHandle(); ++ double d1 = event.getIntensity(victim); ++ // CraftBukkit end ++ + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { + MobEffect mobeffect = (MobEffect) iterator1.next(); + int i = mobeffect.getEffectId(); + ++ // CraftBukkit start - Abide by PVP settings - for players only! ++ if (!this.world.pvpMode && this.getShooter() instanceof EntityPlayer && entityliving instanceof EntityPlayer && entityliving != this.getShooter()) { ++ // Block SLOWER_MOVEMENT, SLOWER_DIG, HARM, BLINDNESS, HUNGER, WEAKNESS and POISON potions ++ if (i == 2 || i == 4 || i == 7 || i == 15 || i == 17 || i == 18 || i == 19) continue; ++ } ++ // CraftBukkit end ++ + if (MobEffectList.byId[i].isInstant()) { + MobEffectList.byId[i].applyInstantEffect(this, this.getShooter(), entityliving, mobeffect.getAmplifier(), d1); + } else { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityProjectile.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityProjectile.patch new file mode 100644 index 0000000..460ea55 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityProjectile.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/server/EntityProjectile.java ++++ b/net/minecraft/server/EntityProjectile.java +@@ -26,6 +26,7 @@ + public EntityProjectile(World world, EntityLiving entityliving) { + super(world); + this.shooter = entityliving; ++ this.projectileSource = (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit + this.setSize(0.25F, 0.25F); + this.setPositionRotation(entityliving.locX, entityliving.locY + (double) entityliving.getHeadHeight(), entityliving.locZ, entityliving.yaw, entityliving.pitch); + this.locX -= (double) (MathHelper.cos(this.yaw / 180.0F * 3.1415927F) * 0.16F); +@@ -151,6 +152,11 @@ + this.d(movingobjectposition.a()); + } else { + this.a(movingobjectposition); ++ // CraftBukkit start ++ if (this.dead) { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); ++ } ++ // CraftBukkit end + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityRabbit.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityRabbit.patch new file mode 100644 index 0000000..37dd626 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityRabbit.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/server/EntityRabbit.java ++++ b/net/minecraft/server/EntityRabbit.java +@@ -21,6 +21,12 @@ + this.g = new EntityRabbit.ControllerJumpRabbit(this); + this.moveController = new EntityRabbit.ControllerMoveRabbit(this); + ((Navigation) this.getNavigation()).a(true); ++ this.initializePathFinderGoals(); // CraftBukkit - moved code ++ this.b(0.0D); ++ } ++ ++ // CraftBukkit start - code from constructor ++ public void initializePathFinderGoals(){ + this.navigation.a(2.5F); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new EntityRabbit.PathfinderGoalRabbitPanic(this, 1.33D)); +@@ -33,8 +39,8 @@ + this.goalSelector.a(11, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); + this.bm = new EntityRabbit.PathfinderGoalRabbitAvoidTarget(this, EntityWolf.class, 16.0F, 1.33D, 1.33D); + this.goalSelector.a(4, this.bm); +- this.b(0.0D); + } ++ // CraftBukkit end + + protected float bE() { + return this.moveController.a() && this.moveController.e() > this.locY + 0.5D ? 0.5F : this.bt.b(); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySheep.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySheep.patch new file mode 100644 index 0000000..a64b2a4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySheep.patch @@ -0,0 +1,68 @@ +--- a/net/minecraft/server/EntitySheep.java ++++ b/net/minecraft/server/EntitySheep.java +@@ -4,12 +4,25 @@ + import java.util.Map; + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.event.entity.SheepRegrowWoolEvent; ++import org.bukkit.event.player.PlayerShearEntityEvent; ++import org.bukkit.inventory.InventoryView; ++// CraftBukkit end ++ + public class EntitySheep extends EntityAnimal { + + private final InventoryCrafting bm = new InventoryCrafting(new Container() { + public boolean a(EntityHuman entityhuman) { + return false; + } ++ ++ // CraftBukkit start ++ @Override ++ public InventoryView getBukkitView() { ++ return null; // TODO: O.O ++ } ++ // CraftBukkit end + }, 2, 1); + private static final Map bo = Maps.newEnumMap(EnumColor.class); + private int bp; +@@ -34,6 +47,7 @@ + this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.bm.setItem(0, new ItemStack(Items.DYE, 1, 0)); + this.bm.setItem(1, new ItemStack(Items.DYE, 1, 0)); ++ this.bm.resultInventory = new InventoryCraftResult(); // CraftBukkit - add result slot for event + } + + protected void E() { +@@ -86,6 +100,15 @@ + + if (itemstack != null && itemstack.getItem() == Items.SHEARS && !this.isSheared() && !this.isBaby()) { + if (!this.world.isClientSide) { ++ // CraftBukkit start ++ PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ // CraftBukkit end ++ + this.setSheared(true); + int i = 1 + this.random.nextInt(3); + +@@ -173,7 +196,14 @@ + } + + public void v() { +- this.setSheared(false); ++ // CraftBukkit start ++ SheepRegrowWoolEvent event = new SheepRegrowWoolEvent((org.bukkit.entity.Sheep) this.getBukkitEntity()); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ this.setSheared(false); ++ } ++ // CraftBukkit end + if (this.isBaby()) { + this.setAge(60); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySilverfish.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySilverfish.patch new file mode 100644 index 0000000..9ea99cd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySilverfish.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/server/EntitySilverfish.java ++++ b/net/minecraft/server/EntitySilverfish.java +@@ -144,6 +144,11 @@ + IBlockData iblockdata = world.getType(blockposition); + + if (BlockMonsterEggs.d(iblockdata)) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.MONSTER_EGG, Block.getId(BlockMonsterEggs.getById(iblockdata.getBlock().toLegacyData(iblockdata)))).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.MONSTER_EGG.getBlockData().set(BlockMonsterEggs.VARIANT, BlockMonsterEggs.EnumMonsterEggVarient.a(iblockdata)), 3); + this.silverfish.y(); + this.silverfish.die(); +@@ -187,6 +192,11 @@ + IBlockData iblockdata = world.getType(blockposition1); + + if (iblockdata.getBlock() == Blocks.MONSTER_EGG) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), Blocks.AIR, 0).isCancelled()) { ++ continue; ++ } ++ // CraftBukkit end + if (world.getGameRules().getBoolean("mobGriefing")) { + world.setAir(blockposition1, true); + } else { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySkeleton.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySkeleton.patch new file mode 100644 index 0000000..6da92eb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySkeleton.patch @@ -0,0 +1,96 @@ +--- a/net/minecraft/server/EntitySkeleton.java ++++ b/net/minecraft/server/EntitySkeleton.java +@@ -2,6 +2,8 @@ + + import java.util.Calendar; + ++import org.bukkit.event.entity.EntityCombustEvent; // CraftBukkit ++ + public class EntitySkeleton extends EntityMonster implements IRangedEntity { + + private PathfinderGoalArrowAttack a = new PathfinderGoalArrowAttack(this, 1.0D, 20, 60, 15.0F); +@@ -89,7 +91,14 @@ + } + + if (flag) { +- this.setOnFire(8); ++ // CraftBukkit start ++ EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ this.setOnFire(event.getDuration()); ++ } ++ // CraftBukkit end + } + } + } +@@ -112,7 +121,7 @@ + } + + public void die(DamageSource damagesource) { +- super.die(damagesource); ++ // super.die(damagesource); // CraftBukkit + if (damagesource.i() instanceof EntityArrow && damagesource.getEntity() instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) damagesource.getEntity(); + double d0 = entityhuman.locX - this.locX; +@@ -123,16 +132,25 @@ + } + } else if (damagesource.getEntity() instanceof EntityCreeper && ((EntityCreeper) damagesource.getEntity()).isPowered() && ((EntityCreeper) damagesource.getEntity()).cp()) { + ((EntityCreeper) damagesource.getEntity()).cq(); +- this.a(new ItemStack(Items.SKULL, 1, this.getSkeletonType() == 1 ? 1 : 0), 0.0F); ++ // CraftBukkit start ++ // this.a(new ItemStack(Items.SKULL, 1, this.getSkeletonType() == 1 ? 1 : 0), 0.0F); ++ headDrop = new ItemStack(Items.SKULL, 1, this.getSkeletonType() == 1 ? 1 : 0); ++ // CraftBukkit end ++ + } + ++ super.die(damagesource); // CraftBukkit - moved from above ++ + } + ++ /* CraftBukkit start + protected Item getLoot() { + return Items.ARROW; + } ++ // CraftBukkit end */ + + protected void dropDeathLoot(boolean flag, int i) { ++ super.dropDeathLoot(flag, i); // CraftBukkit + int j; + int k; + +@@ -224,11 +242,30 @@ + } + + if (EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_FIRE.id, this.bA()) > 0 || this.getSkeletonType() == 1) { +- entityarrow.setOnFire(100); ++ // CraftBukkit start - call EntityCombustEvent ++ EntityCombustEvent event = new EntityCombustEvent(entityarrow.getBukkitEntity(), 100); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ entityarrow.setOnFire(event.getDuration()); ++ } ++ // CraftBukkit end ++ } ++ ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.bA(), entityarrow, 0.8F); ++ if (event.isCancelled()) { ++ event.getProjectile().remove(); ++ return; ++ } ++ ++ if (event.getProjectile() == entityarrow.getBukkitEntity()) { ++ world.addEntity(entityarrow); + } ++ // CraftBukkit end + + this.makeSound("random.bow", 1.0F, 1.0F / (this.bc().nextFloat() * 0.4F + 0.8F)); +- this.world.addEntity(entityarrow); ++ // this.world.addEntity(entityarrow); // CraftBukkit - moved up + } + + public int getSkeletonType() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySlice.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySlice.patch new file mode 100644 index 0000000..3f38104 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySlice.patch @@ -0,0 +1,38 @@ +--- a/net/minecraft/server/EntitySlice.java ++++ b/net/minecraft/server/EntitySlice.java +@@ -12,7 +12,7 @@ + + public class EntitySlice extends AbstractSet { + +- private static final Set> a = Sets.newHashSet(); ++ private static final Set> a = Sets.newConcurrentHashSet(); // CraftBukkit + private final Map, List> b = Maps.newHashMap(); + private final Set> c = Sets.newIdentityHashSet(); + private final Class d; +@@ -40,7 +40,7 @@ + Object object = iterator.next(); + + if (oclass.isAssignableFrom(object.getClass())) { +- this.a(object, oclass); ++ this.a((T) object, oclass); + } + } + +@@ -77,7 +77,7 @@ + List list = (List) this.b.get(oclass); + + if (list == null) { +- this.b.put(oclass, Lists.newArrayList(new Object[] { t0})); ++ this.b.put(oclass, Lists.newArrayList(t0)); + } else { + list.add(t0); + } +@@ -125,7 +125,7 @@ + } + + public Iterator iterator() { +- return this.e.isEmpty() ? Iterators.emptyIterator() : Iterators.unmodifiableIterator(this.e.iterator()); ++ return this.e.isEmpty() ? Iterators.emptyIterator() : Iterators.unmodifiableIterator(this.e.iterator()); + } + + public int size() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySlime.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySlime.patch new file mode 100644 index 0000000..2e3333d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySlime.patch @@ -0,0 +1,40 @@ +--- a/net/minecraft/server/EntitySlime.java ++++ b/net/minecraft/server/EntitySlime.java +@@ -1,5 +1,9 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.event.entity.SlimeSplitEvent; ++// CraftBukkit end ++ + public class EntitySlime extends EntityInsentient implements IMonster { + + public float a; +@@ -133,6 +137,18 @@ + if (!this.world.isClientSide && i > 1 && this.getHealth() <= 0.0F) { + int j = 2 + this.random.nextInt(3); + ++ // CraftBukkit start ++ SlimeSplitEvent event = new SlimeSplitEvent((org.bukkit.entity.Slime) this.getBukkitEntity(), j); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled() && event.getCount() > 0) { ++ j = event.getCount(); ++ } else { ++ super.die(); ++ return; ++ } ++ // CraftBukkit end ++ + for (int k = 0; k < j; ++k) { + float f = ((float) (k % 2) - 0.5F) * (float) i / 4.0F; + float f1 = ((float) (k / 2) - 0.5F) * (float) i / 4.0F; +@@ -148,7 +164,7 @@ + + entityslime.setSize(i / 2); + entityslime.setPositionRotation(this.locX + (double) f, this.locY + 0.5D, this.locZ + (double) f1, this.random.nextFloat() * 360.0F, 0.0F); +- this.world.addEntity(entityslime); ++ this.world.addEntity(entityslime, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SLIME_SPLIT); // CraftBukkit - SpawnReason + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySmallFireball.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySmallFireball.patch new file mode 100644 index 0000000..be58eb1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySmallFireball.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/server/EntitySmallFireball.java ++++ b/net/minecraft/server/EntitySmallFireball.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.entity.EntityCombustByEntityEvent; // CraftBukkit ++ + public class EntitySmallFireball extends EntityFireball { + + public EntitySmallFireball(World world) { +@@ -26,7 +28,14 @@ + if (flag) { + this.a(this.shooter, movingobjectposition.entity); + if (!movingobjectposition.entity.isFireProof()) { +- movingobjectposition.entity.setOnFire(5); ++ // CraftBukkit start - Entity damage by entity event + combust event ++ EntityCombustByEntityEvent event = new EntityCombustByEntityEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), movingobjectposition.entity.getBukkitEntity(), 5); ++ movingobjectposition.entity.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ movingobjectposition.entity.setOnFire(event.getDuration()); ++ } ++ // CraftBukkit end + } + } + } else { +@@ -39,7 +48,11 @@ + BlockPosition blockposition = movingobjectposition.a().shift(movingobjectposition.direction); + + if (this.world.isEmpty(blockposition)) { +- this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ // CraftBukkit start ++ if (isIncendiary && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { ++ this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ } ++ // CraftBukkit end + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySnowman.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySnowman.patch new file mode 100644 index 0000000..fbde5d2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySnowman.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/server/EntitySnowman.java ++++ b/net/minecraft/server/EntitySnowman.java +@@ -1,5 +1,11 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.event.block.EntityBlockFormEvent; ++// CraftBukkit end ++ + public class EntitySnowman extends EntityGolem implements IRangedEntity { + + public EntitySnowman(World world) { +@@ -31,7 +37,7 @@ + } + + if (this.world.getBiome(new BlockPosition(i, 0, k)).a(new BlockPosition(i, j, k)) > 1.0F) { +- this.damageEntity(DamageSource.BURN, 1.0F); ++ this.damageEntity(CraftEventFactory.MELTING, 1.0F); // CraftBukkit - DamageSource.BURN -> CraftEventFactory.MELTING + } + + for (int l = 0; l < 4; ++l) { +@@ -41,7 +47,17 @@ + BlockPosition blockposition = new BlockPosition(i, j, k); + + if (this.world.getType(blockposition).getBlock().getMaterial() == Material.AIR && this.world.getBiome(new BlockPosition(i, 0, k)).a(blockposition) < 0.8F && Blocks.SNOW_LAYER.canPlace(this.world, blockposition)) { +- this.world.setTypeUpdate(blockposition, Blocks.SNOW_LAYER.getBlockData()); ++ // CraftBukkit start ++ org.bukkit.block.BlockState blockState = this.world.getWorld().getBlockAt(i, j, k).getState(); ++ blockState.setType(CraftMagicNumbers.getMaterial(Blocks.SNOW_LAYER)); ++ ++ EntityBlockFormEvent event = new EntityBlockFormEvent(this.getBukkitEntity(), blockState.getBlock(), blockState); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if(!event.isCancelled()) { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySpider.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySpider.patch new file mode 100644 index 0000000..d4e19fd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySpider.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/EntitySpider.java ++++ b/net/minecraft/server/EntitySpider.java +@@ -112,7 +112,7 @@ + + entityskeleton.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); + entityskeleton.prepare(difficultydamagescaler, (GroupDataEntity) null); +- this.world.addEntity(entityskeleton); ++ this.world.addEntity(entityskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.JOCKEY); // CraftBukkit - add SpawnReason + entityskeleton.mount(this); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySquid.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySquid.patch new file mode 100644 index 0000000..da17073 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntitySquid.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/server/EntitySquid.java ++++ b/net/minecraft/server/EntitySquid.java +@@ -67,9 +67,11 @@ + + } + ++ /* CraftBukkit start - Delegate to Entity to use existing inWater value + public boolean V() { + return this.world.a(this.getBoundingBox().grow(0.0D, -0.6000000238418579D, 0.0D), Material.WATER, (Entity) this); + } ++ // CraftBukkit end */ + + public void m() { + super.m(); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTNTPrimed.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTNTPrimed.patch new file mode 100644 index 0000000..f9a1bf2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTNTPrimed.patch @@ -0,0 +1,52 @@ +--- a/net/minecraft/server/EntityTNTPrimed.java ++++ b/net/minecraft/server/EntityTNTPrimed.java +@@ -1,9 +1,13 @@ + package net.minecraft.server; + ++import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit ++ + public class EntityTNTPrimed extends Entity { + + public int fuseTicks; + private EntityLiving source; ++ public float yield = 4; // CraftBukkit - add field ++ public boolean isIncendiary = false; // CraftBukkit - add field + + public EntityTNTPrimed(World world) { + super(world); +@@ -52,10 +56,13 @@ + } + + if (this.fuseTicks-- <= 0) { +- this.die(); ++ // CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event ++ // this.die(); + if (!this.world.isClientSide) { + this.explode(); + } ++ this.die(); ++ // 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]); +@@ -64,9 +71,18 @@ + } + + private void explode() { +- float f = 4.0F; ++ // CraftBukkit start ++ // float f = 4.0F; ++ ++ org.bukkit.craftbukkit.CraftServer server = this.world.getServer(); + +- this.world.explode(this, this.locX, this.locY + (double) (this.length / 16.0F), this.locZ, f, true); ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) org.bukkit.craftbukkit.entity.CraftEntity.getEntity(server, this)); ++ server.getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ this.world.createExplosion(this, this.locX, this.locY + (double) (this.length / 2.0F), this.locZ, event.getRadius(), event.getFire(), true); ++ } ++ // CraftBukkit end + } + + protected void b(NBTTagCompound nbttagcompound) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityThrownExpBottle.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityThrownExpBottle.patch new file mode 100644 index 0000000..2e68849 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityThrownExpBottle.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/server/EntityThrownExpBottle.java ++++ b/net/minecraft/server/EntityThrownExpBottle.java +@@ -28,9 +28,18 @@ + + protected void a(MovingObjectPosition movingobjectposition) { + if (!this.world.isClientSide) { +- this.world.triggerEffect(2002, new BlockPosition(this), 0); ++ // CraftBukkit - moved to after event ++ // this.world.triggerEffect(2002, new BlockPosition(this), 0); + int i = 3 + this.world.random.nextInt(5) + this.world.random.nextInt(5); + ++ // CraftBukkit start ++ org.bukkit.event.entity.ExpBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExpBottleEvent(this, i); ++ i = event.getExperience(); ++ if (event.getShowEffect()) { ++ this.world.triggerEffect(2002, new BlockPosition(this), 0); ++ } ++ // CraftBukkit end ++ + while (i > 0) { + int j = EntityExperienceOrb.getOrbValue(i); + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTracker.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTracker.patch new file mode 100644 index 0000000..d42e4a6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTracker.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/server/EntityTracker.java ++++ b/net/minecraft/server/EntityTracker.java +@@ -113,11 +113,12 @@ + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity To Track"); + + crashreportsystemdetails.a("Tracking range", (Object) (i + " blocks")); ++ final int finalI = i; // CraftBukkit - fix decompile error + crashreportsystemdetails.a("Update interval", new Callable() { + public String a() throws Exception { +- String s = "Once per " + i + " ticks"; ++ String s = "Once per " + finalI + " ticks"; // CraftBukkit + +- if (i == Integer.MAX_VALUE) { ++ if (finalI == Integer.MAX_VALUE) { // CraftBukkit + s = "Maximum (" + s + ")"; + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTrackerEntry.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTrackerEntry.patch new file mode 100644 index 0000000..0a6cc77 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityTrackerEntry.patch @@ -0,0 +1,187 @@ +--- a/net/minecraft/server/EntityTrackerEntry.java ++++ b/net/minecraft/server/EntityTrackerEntry.java +@@ -8,6 +8,11 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.event.player.PlayerVelocityEvent; ++// CraftBukkit end ++ + public class EntityTrackerEntry { + + private static final Logger p = LogManager.getLogger(); +@@ -74,13 +79,13 @@ + this.broadcast(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle)); + } + +- if (this.tracker instanceof EntityItemFrame && this.m % 10 == 0) { ++ if (this.tracker instanceof EntityItemFrame /*&& this.m % 10 == 0*/) { // CraftBukkit - Moved below, should always enter this block + EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker; + ItemStack itemstack = entityitemframe.getItem(); + +- if (itemstack != null && itemstack.getItem() instanceof ItemWorldMap) { ++ if (this.m % 10 == 0 && itemstack != null && itemstack.getItem() instanceof ItemWorldMap) { // CraftBukkit - Moved this.m % 10 logic here so item frames do not enter the other blocks + WorldMap worldmap = Items.FILLED_MAP.getSavedMap(itemstack, this.tracker.world); +- Iterator iterator = list.iterator(); ++ Iterator iterator = this.trackedPlayers.iterator(); // CraftBukkit + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); +@@ -116,6 +121,19 @@ + boolean flag = Math.abs(j1) >= 4 || Math.abs(k1) >= 4 || Math.abs(l1) >= 4 || this.m % 60 == 0; + boolean flag1 = Math.abs(l - this.yRot) >= 4 || Math.abs(i1 - this.xRot) >= 4; + ++ // CraftBukkit start - Code moved from below ++ if (flag) { ++ this.xLoc = i; ++ this.yLoc = j; ++ this.zLoc = k; ++ } ++ ++ if (flag1) { ++ this.yRot = l; ++ this.xRot = i1; ++ } ++ // CraftBukkit end ++ + if (this.m > 0 || this.tracker instanceof EntityArrow) { + if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.v <= 400 && !this.x && this.y == this.tracker.onGround) { + if ((!flag || !flag1) && !(this.tracker instanceof EntityArrow)) { +@@ -130,6 +148,11 @@ + } else { + this.y = this.tracker.onGround; + this.v = 0; ++ // CraftBukkit start - Refresh list of who can see a player before sending teleport packet ++ if (this.tracker instanceof EntityPlayer) { ++ this.scanPlayers(new java.util.ArrayList(this.trackedPlayers)); ++ } ++ // CraftBukkit end + object = new PacketPlayOutEntityTeleport(this.tracker.getId(), i, j, k, (byte) l, (byte) i1, this.tracker.onGround); + } + } +@@ -154,6 +177,7 @@ + } + + this.b(); ++ /* CraftBukkit start - Code moved up + if (flag) { + this.xLoc = i; + this.yLoc = j; +@@ -164,6 +188,7 @@ + this.yRot = l; + this.xRot = i1; + } ++ // CraftBukkit end */ + + this.x = false; + } else { +@@ -195,7 +220,27 @@ + + ++this.m; + if (this.tracker.velocityChanged) { +- this.broadcastIncludingSelf(new PacketPlayOutEntityVelocity(this.tracker)); ++ // CraftBukkit start - Create PlayerVelocity event ++ boolean cancelled = false; ++ ++ if (this.tracker instanceof EntityPlayer) { ++ Player player = (Player) this.tracker.getBukkitEntity(); ++ org.bukkit.util.Vector velocity = player.getVelocity(); ++ ++ PlayerVelocityEvent event = new PlayerVelocityEvent(player, velocity.clone()); ++ this.tracker.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ cancelled = true; ++ } else if (!velocity.equals(event.getVelocity())) { ++ player.setVelocity(event.getVelocity()); ++ } ++ } ++ ++ if (!cancelled) { ++ this.broadcastIncludingSelf(new PacketPlayOutEntityVelocity(this.tracker)); ++ } ++ // CraftBukkit end + this.tracker.velocityChanged = false; + } + +@@ -213,6 +258,11 @@ + Set set = attributemapserver.getAttributes(); + + if (!set.isEmpty()) { ++ // CraftBukkit start - Send scaled max health ++ if (this.tracker instanceof EntityPlayer) { ++ ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(set, false); ++ } ++ // CraftBukkit end + this.broadcastIncludingSelf(new PacketPlayOutUpdateAttributes(this.tracker.getId(), set)); + } + +@@ -263,6 +313,16 @@ + if (entityplayer != this.tracker) { + if (this.c(entityplayer)) { + if (!this.trackedPlayers.contains(entityplayer) && (this.e(entityplayer) || this.tracker.attachedToPlayer)) { ++ // CraftBukkit start - respect vanish API ++ if (this.tracker instanceof EntityPlayer) { ++ Player player = ((EntityPlayer) this.tracker).getBukkitEntity(); ++ if (!entityplayer.getBukkitEntity().canSee(player)) { ++ return; ++ } ++ } ++ ++ entityplayer.removeQueue.remove(Integer.valueOf(this.tracker.getId())); ++ // CraftBukkit end + this.trackedPlayers.add(entityplayer); + Packet packet = this.c(); + +@@ -281,6 +341,12 @@ + AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap(); + Collection collection = attributemapserver.c(); + ++ // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health ++ if (this.tracker.getId() == entityplayer.getId()) { ++ ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(collection, false); ++ } ++ // CraftBukkit end ++ + if (!collection.isEmpty()) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(this.tracker.getId(), collection)); + } +@@ -319,6 +385,11 @@ + } + } + ++ // CraftBukkit start - Fix for nonsensical head yaw ++ this.i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); ++ this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i)); ++ // CraftBukkit end ++ + if (this.tracker instanceof EntityLiving) { + EntityLiving entityliving = (EntityLiving) this.tracker; + Iterator iterator = entityliving.getEffects().iterator(); +@@ -339,8 +410,10 @@ + } + + public boolean c(EntityPlayer entityplayer) { +- double d0 = entityplayer.locX - (double) (this.xLoc / 32); +- double d1 = entityplayer.locZ - (double) (this.zLoc / 32); ++ // CraftBukkit start - this.*Loc / 30 -> this.tracker.loc* ++ double d0 = entityplayer.locX - this.tracker.locX; ++ double d1 = entityplayer.locZ - this.tracker.locZ; ++ // CraftBukkit end + + return d0 >= (double) (-this.b) && d0 <= (double) this.b && d1 >= (double) (-this.b) && d1 <= (double) this.b && this.tracker.a(entityplayer); + } +@@ -358,7 +431,10 @@ + + private Packet c() { + if (this.tracker.dead) { +- EntityTrackerEntry.p.warn("Fetching addPacket for removed entity"); ++ // CraftBukkit start - Remove useless error spam, just return ++ // EntityTrackerEntry.p.warn("Fetching addPacket for removed entity"); ++ return null; ++ // CraftBukkit end + } + + if (this.tracker instanceof EntityItem) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityVillager.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityVillager.patch new file mode 100644 index 0000000..93c1439 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityVillager.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/server/EntityVillager.java ++++ b/net/minecraft/server/EntityVillager.java +@@ -2,6 +2,7 @@ + + import java.util.Iterator; + import java.util.Random; ++import org.bukkit.craftbukkit.entity.CraftVillager; // CraftBukkit + + public class EntityVillager extends EntityAgeable implements IMerchant, NPC { + +@@ -29,7 +30,7 @@ + + public EntityVillager(World world, int i) { + super(world); +- this.inventory = new InventorySubcontainer("Items", false, 8); ++ this.inventory = new InventorySubcontainer("Items", false, 8, (CraftVillager) this.getBukkitEntity()); // CraftBukkit add argument + this.setProfession(i); + this.setSize(0.6F, 1.8F); + ((Navigation) this.getNavigation()).b(true); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWither.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWither.patch new file mode 100644 index 0000000..ec2eb5d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWither.patch @@ -0,0 +1,78 @@ +--- a/net/minecraft/server/EntityWither.java ++++ b/net/minecraft/server/EntityWither.java +@@ -5,6 +5,12 @@ + import java.util.Iterator; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRegainHealthEvent; ++import org.bukkit.event.entity.ExplosionPrimeEvent; ++// CraftBukkit end ++ + public class EntityWither extends EntityMonster implements IRangedEntity { + + private float[] a = new float[2]; +@@ -168,13 +174,38 @@ + if (this.cl() > 0) { + i = this.cl() - 1; + if (i <= 0) { +- this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, 7.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); +- this.world.a(1013, new BlockPosition(this), 0); ++ // CraftBukkit start ++ // this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, 7.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, event.getRadius(), event.getFire(), this.world.getGameRules().getBoolean("mobGriefing")); ++ } ++ // CraftBukkit end ++ ++ // CraftBukkit start - Use relative location for far away sounds ++ // this.world.a(1013, new BlockPosition(this), 0); ++ int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; ++ for (EntityPlayer player : (List) MinecraftServer.getServer().getPlayerList().players) { ++ double deltaX = this.locX - player.locX; ++ double deltaZ = this.locZ - player.locZ; ++ double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; ++ if (distanceSquared > viewDistance * viewDistance) { ++ double deltaLength = Math.sqrt(distanceSquared); ++ double relativeX = player.locX + (deltaX / deltaLength) * viewDistance; ++ double relativeZ = player.locZ + (deltaZ / deltaLength) * viewDistance; ++ player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1013, new BlockPosition((int) relativeX, (int) this.locY, (int) relativeZ), 0, true)); ++ } else { ++ player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1013, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0, true)); ++ } ++ } ++ // CraftBukkit end + } + + this.r(i); + if (this.ticksLived % 10 == 0) { +- this.heal(10.0F); ++ this.heal(10.0F, EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit + } + + } else { +@@ -264,6 +295,11 @@ + Block block = this.world.getType(blockposition).getBlock(); + + if (block.getMaterial() != Material.AIR && a(block)) { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, j2, k2, l2, Blocks.AIR, 0).isCancelled()) { ++ continue; ++ } ++ // CraftBukkit end + flag = this.world.setAir(blockposition, true) || flag; + } + } +@@ -277,7 +313,7 @@ + } + + if (this.ticksLived % 20 == 0) { +- this.heal(1.0F); ++ this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWitherSkull.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWitherSkull.patch new file mode 100644 index 0000000..119a1b9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWitherSkull.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/server/EntityWitherSkull.java ++++ b/net/minecraft/server/EntityWitherSkull.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit ++ + public class EntityWitherSkull extends EntityFireball { + + public EntityWitherSkull(World world) { +@@ -35,9 +37,9 @@ + if (!this.world.isClientSide) { + if (movingobjectposition.entity != null) { + if (this.shooter != null) { +- if (movingobjectposition.entity.damageEntity(DamageSource.mobAttack(this.shooter), 8.0F)) { ++ if (movingobjectposition.entity.damageEntity(DamageSource.projectile(this, shooter), 8.0F)) { // CraftBukkit + if (!movingobjectposition.entity.isAlive()) { +- this.shooter.heal(5.0F); ++ this.shooter.heal(5.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER); // CraftBukkit + } else { + this.a(this.shooter, movingobjectposition.entity); + } +@@ -61,7 +63,15 @@ + } + } + +- this.world.createExplosion(this, this.locX, this.locY, this.locZ, 1.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); ++ // CraftBukkit start ++ // this.world.createExplosion(this, this.locX, this.locY, this.locZ, 1.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), this.world.getGameRules().getBoolean("mobGriefing")); ++ } ++ // CraftBukkit end + this.die(); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWolf.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWolf.patch new file mode 100644 index 0000000..d240d76 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityWolf.patch @@ -0,0 +1,97 @@ +--- a/net/minecraft/server/EntityWolf.java ++++ b/net/minecraft/server/EntityWolf.java +@@ -2,6 +2,11 @@ + + import com.google.common.base.Predicate; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityTargetEvent.TargetReason; ++// CraftBukkit end ++ + public class EntityWolf extends EntityTameableAnimal { + + private float bo; +@@ -64,6 +69,18 @@ + + } + ++ // CraftBukkit - add overriden version ++ @Override ++ public void setGoalTarget(EntityLiving entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason reason, boolean fire) { ++ super.setGoalTarget(entityliving, reason, fire); ++ if (entityliving == null) { ++ this.setAngry(false); ++ } else if (!this.isTamed()) { ++ this.setAngry(true); ++ } ++ } ++ // CraftBukkit end ++ + protected void E() { + this.datawatcher.watch(18, Float.valueOf(this.getHealth())); + } +@@ -95,7 +112,8 @@ + } + + protected String z() { +- return this.isAngry() ? "mob.wolf.growl" : (this.random.nextInt(3) == 0 ? (this.isTamed() && this.datawatcher.getFloat(18) < 10.0F ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark"); ++ // CraftBukkit - (getFloat(18) < 10) -> (getFloat(18) < this.getMaxHealth() / 2) ++ return this.isAngry() ? "mob.wolf.growl" : (this.random.nextInt(3) == 0 ? (this.isTamed() && this.datawatcher.getFloat(18) < this.getMaxHealth() / 2 ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark"); + } + + protected String bo() { +@@ -186,7 +204,8 @@ + } else { + Entity entity = damagesource.getEntity(); + +- this.bm.setSitting(false); ++ // CraftBukkit - moved into EntityLiving.d(DamageSource, float) ++ // this.bm.setSitting(false); + if (entity != null && !(entity instanceof EntityHuman) && !(entity instanceof EntityArrow)) { + f = (f + 1.0F) / 2.0F; + } +@@ -229,7 +248,7 @@ + --itemstack.count; + } + +- this.heal((float) itemfood.getNutrition(itemstack)); ++ this.heal((float) itemfood.getNutrition(itemstack), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit + if (itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } +@@ -254,7 +273,7 @@ + this.bm.setSitting(!this.isSitting()); + this.aY = false; + this.navigation.n(); +- this.setGoalTarget((EntityLiving) null); ++ this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason + } + } else if (itemstack != null && itemstack.getItem() == Items.BONE && !this.isAngry()) { + if (!entityhuman.abilities.canInstantlyBuild) { +@@ -266,12 +285,13 @@ + } + + if (!this.world.isClientSide) { +- if (this.random.nextInt(3) == 0) { ++ // CraftBukkit - added event call and isCancelled check. ++ if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { + this.setTamed(true); + this.navigation.n(); +- this.setGoalTarget((EntityLiving) null); ++ this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); + this.bm.setSitting(true); +- this.setHealth(20.0F); ++ this.setHealth(this.getMaxHealth()); // CraftBukkit - 20.0 -> getMaxHealth() + this.setOwnerUUID(entityhuman.getUniqueID().toString()); + this.l(true); + this.world.broadcastEntityEffect(this, (byte) 7); +@@ -358,7 +378,7 @@ + } + + protected boolean isTypeNotPersistent() { +- return !this.isTamed() && this.ticksLived > 2400; ++ return !this.isTamed() /*&& this.ticksLived > 2400*/; // CraftBukkit + } + + public boolean a(EntityLiving entityliving, EntityLiving entityliving1) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityZombie.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityZombie.patch new file mode 100644 index 0000000..81e4231 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/EntityZombie.patch @@ -0,0 +1,136 @@ +--- a/net/minecraft/server/EntityZombie.java ++++ b/net/minecraft/server/EntityZombie.java +@@ -4,6 +4,14 @@ + import java.util.List; + import java.util.UUID; + ++//CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftLivingEntity; ++import org.bukkit.event.entity.CreatureSpawnEvent; ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.entity.EntityCombustEvent; ++import org.bukkit.event.entity.EntityTargetEvent; ++//CraftBukkit end ++ + public class EntityZombie extends EntityMonster { + + protected static final IAttribute a = (new AttributeRanged((IAttribute) null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).a("Spawn Reinforcements Chance"); +@@ -14,6 +22,7 @@ + private boolean bo = false; + private float bp = -1.0F; + private float bq; ++ private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field + + public EntityZombie(World world) { + super(world); +@@ -135,7 +144,14 @@ + } + + if (flag) { +- this.setOnFire(8); ++ // CraftBukkit start ++ EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ this.setOnFire(event.getDuration()); ++ } ++ // CraftBukkit end + } + } + } +@@ -169,8 +185,8 @@ + if (World.a((IBlockAccess) this.world, new BlockPosition(i1, j1 - 1, k1)) && this.world.getLightLevel(new BlockPosition(i1, j1, k1)) < 10) { + entityzombie.setPosition((double) i1, (double) j1, (double) k1); + if (!this.world.isPlayerNearby((double) i1, (double) j1, (double) k1, 7.0D) && this.world.a(entityzombie.getBoundingBox(), (Entity) entityzombie) && this.world.getCubes(entityzombie, entityzombie.getBoundingBox()).isEmpty() && !this.world.containsLiquid(entityzombie.getBoundingBox())) { +- this.world.addEntity(entityzombie); +- entityzombie.setGoalTarget(entityliving); ++ this.world.addEntity(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit ++ entityzombie.setGoalTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); + entityzombie.prepare(this.world.E(new BlockPosition(entityzombie)), (GroupDataEntity) null); + this.getAttributeInstance(EntityZombie.a).b(new AttributeModifier("Zombie reinforcement caller charge", -0.05000000074505806D, 0)); + entityzombie.getAttributeInstance(EntityZombie.a).b(new AttributeModifier("Zombie reinforcement callee charge", -0.05000000074505806D, 0)); +@@ -190,6 +206,12 @@ + if (!this.world.isClientSide && this.cp()) { + int i = this.cr(); + ++ // CraftBukkit start - Use wall time instead of ticks for villager conversion ++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick; ++ this.lastTick = MinecraftServer.currentTick; ++ i *= elapsedTicks; ++ // CraftBukkit end ++ + this.bn -= i; + if (this.bn <= 0) { + this.cq(); +@@ -206,7 +228,14 @@ + int i = this.world.getDifficulty().a(); + + if (this.bA() == null && this.isBurning() && this.random.nextFloat() < (float) i * 0.3F) { +- entity.setOnFire(2 * i); ++ // CraftBukkit start ++ EntityCombustByEntityEvent event = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 2 * i); ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ entity.setOnFire(event.getDuration()); ++ } ++ // CraftBukkit end + } + } + +@@ -322,7 +351,7 @@ + entityzombie.setCustomNameVisible(entityinsentient.getCustomNameVisible()); + } + +- this.world.addEntity(entityzombie); ++ this.world.addEntity(entityzombie, CreatureSpawnEvent.SpawnReason.INFECTION); // CraftBukkit - add SpawnReason + this.world.a((EntityHuman) null, 1016, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0); + } + +@@ -375,7 +404,7 @@ + entitychicken1.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); + entitychicken1.prepare(difficultydamagescaler, (GroupDataEntity) null); + entitychicken1.l(true); +- this.world.addEntity(entitychicken1); ++ this.world.addEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); + this.mount(entitychicken1); + } + } +@@ -464,7 +493,7 @@ + entityvillager.setCustomNameVisible(this.getCustomNameVisible()); + } + +- this.world.addEntity(entityvillager); ++ this.world.addEntity(entityvillager, CreatureSpawnEvent.SpawnReason.CURED); // CraftBukkit - add SpawnReason + entityvillager.addEffect(new MobEffect(MobEffectList.CONFUSION.id, 200, 0)); + this.world.a((EntityHuman) null, 1017, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0); + } +@@ -500,7 +529,7 @@ + this.a(flag ? 0.5F : 1.0F); + } + +- protected final void setSize(float f, float f1) { ++ public final void setSize(float f, float f1) { // CraftBukkit - public + boolean flag = this.bp > 0.0F && this.bq > 0.0F; + + this.bp = f; +@@ -520,12 +549,16 @@ + } + + public void die(DamageSource damagesource) { +- super.die(damagesource); ++ // super.die(damagesource); // CraftBukkit + if (damagesource.getEntity() instanceof EntityCreeper && !(this instanceof EntityPigZombie) && ((EntityCreeper) damagesource.getEntity()).isPowered() && ((EntityCreeper) damagesource.getEntity()).cp()) { + ((EntityCreeper) damagesource.getEntity()).cq(); +- this.a(new ItemStack(Items.SKULL, 1, 2), 0.0F); ++ // CraftBukkit start ++ // this.a(new ItemStack(Items.SKULL, 1, 2), 0.0F); ++ headDrop = new ItemStack(Items.SKULL, 1, 2); ++ // CraftBukkit end + } + ++ super.die(damagesource); // CraftBukkit - moved from above + } + + static class SyntheticClass_1 { } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ExpirableListEntry.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ExpirableListEntry.patch new file mode 100644 index 0000000..aa81c82 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ExpirableListEntry.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/server/ExpirableListEntry.java ++++ b/net/minecraft/server/ExpirableListEntry.java +@@ -22,7 +22,7 @@ + } + + protected ExpirableListEntry(T t0, JsonObject jsonobject) { +- super(t0, jsonobject); ++ super(checkExpiry(t0, jsonobject), jsonobject); + + Date date; + +@@ -65,4 +65,30 @@ + jsonobject.addProperty("expires", this.d == null ? "forever" : ExpirableListEntry.a.format(this.d)); + jsonobject.addProperty("reason", this.e); + } ++ ++ // CraftBukkit start ++ public String getSource() { ++ return this.c; ++ } ++ ++ public Date getCreated() { ++ return this.b; ++ } ++ ++ private static T checkExpiry(T object, JsonObject jsonobject) { ++ Date expires = null; ++ ++ try { ++ expires = jsonobject.has("expires") ? a.parse(jsonobject.get("expires").getAsString()) : null; ++ } catch (ParseException ex) { ++ // Guess we don't have a date ++ } ++ ++ if (expires == null || expires.after(new Date())) { ++ return object; ++ } else { ++ return null; ++ } ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Explosion.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Explosion.patch new file mode 100644 index 0000000..5ee04c6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Explosion.patch @@ -0,0 +1,153 @@ +--- a/net/minecraft/server/Explosion.java ++++ b/net/minecraft/server/Explosion.java +@@ -9,6 +9,13 @@ + import java.util.Map; + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityExplodeEvent; ++import org.bukkit.Location; ++import org.bukkit.event.block.BlockExplodeEvent; ++// CraftBukkit end ++ + public class Explosion { + + private final boolean a; +@@ -22,11 +29,12 @@ + private final float size; + private final List blocks = Lists.newArrayList(); + private final Map k = Maps.newHashMap(); ++ public boolean wasCanceled = false; // CraftBukkit - add field + + public Explosion(World world, Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { + this.world = world; + this.source = entity; +- this.size = f; ++ this.size = (float) Math.max(f, 0.0); // CraftBukkit - clamp bad values + this.posX = d0; + this.posY = d1; + this.posZ = d2; +@@ -35,6 +43,11 @@ + } + + public void a() { ++ // CraftBukkit start ++ if (this.size < 0.1F) { ++ return; ++ } ++ // CraftBukkit end + HashSet hashset = Sets.newHashSet(); + boolean flag = true; + +@@ -68,7 +81,7 @@ + f -= (f2 + 0.3F) * 0.3F; + } + +- if (f > 0.0F && (this.source == null || this.source.a(this, this.world, blockposition, iblockdata, f))) { ++ if (f > 0.0F && (this.source == null || this.source.a(this, this.world, blockposition, iblockdata, f)) && blockposition.getY() < 256 && blockposition.getY() >= 0) { // CraftBukkit - don't wrap explosions + hashset.add(blockposition); + } + +@@ -112,7 +125,15 @@ + double d12 = (double) this.world.a(vec3d, entity.getBoundingBox()); + double d13 = (1.0D - d7) * d12; + +- entity.damageEntity(DamageSource.explosion(this), (float) ((int) ((d13 * d13 + d13) / 2.0D * 8.0D * (double) f3 + 1.0D))); ++ // entity.damageEntity(DamageSource.explosion(this), (float) ((int) ((d13 * d13 + d13) / 2.0D * 8.0D * (double) f3 + 1.0D)));+ // CraftBukkit start ++ CraftEventFactory.entityDamage = source; ++ entity.forceExplosionKnockback = false; ++ boolean wasDamaged = entity.damageEntity(DamageSource.explosion(this), (float) ((int) ((d13 * d13 + d13) / 2.0D * 8.0D * (double) f3 + 1.0D))); ++ CraftEventFactory.entityDamage = null; ++ if (!wasDamaged && !(entity instanceof EntityTNTPrimed || entity instanceof EntityFallingBlock) && !entity.forceExplosionKnockback) { ++ continue; ++ } ++ // CraftBukkit end + double d14 = EnchantmentProtection.a(entity, d13); + + entity.motX += d8 * d14; +@@ -140,6 +161,50 @@ + BlockPosition blockposition; + + if (this.b) { ++ // CraftBukkit start ++ org.bukkit.World bworld = this.world.getWorld(); ++ org.bukkit.entity.Entity explode = this.source == null ? null : this.source.getBukkitEntity(); ++ Location location = new Location(bworld, this.posX, this.posY, this.posZ); ++ ++ List blockList = Lists.newArrayList(); ++ for (int i1 = this.blocks.size() - 1; i1 >= 0; i1--) { ++ BlockPosition cpos = (BlockPosition) this.blocks.get(i1); ++ org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.getX(), cpos.getY(), cpos.getZ()); ++ if (bblock.getType() != org.bukkit.Material.AIR) { ++ blockList.add(bblock); ++ } ++ } ++ ++ boolean cancelled; ++ List bukkitBlocks; ++ float yield; ++ ++ if (explode != null) { ++ EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, 0.3F); ++ this.world.getServer().getPluginManager().callEvent(event); ++ cancelled = event.isCancelled(); ++ bukkitBlocks = event.blockList(); ++ yield = event.getYield(); ++ } else { ++ BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, 0.3F); ++ this.world.getServer().getPluginManager().callEvent(event); ++ cancelled = event.isCancelled(); ++ bukkitBlocks = event.blockList(); ++ yield = event.getYield(); ++ } ++ ++ this.blocks.clear(); ++ ++ for (org.bukkit.block.Block bblock : bukkitBlocks) { ++ BlockPosition coords = new BlockPosition(bblock.getX(), bblock.getY(), bblock.getZ()); ++ blocks.add(coords); ++ } ++ ++ if (cancelled) { ++ this.wasCanceled = true; ++ return; ++ } ++ // CraftBukkit end + iterator = this.blocks.iterator(); + + while (iterator.hasNext()) { +@@ -170,7 +235,8 @@ + + if (block.getMaterial() != Material.AIR) { + if (block.a(this)) { +- block.dropNaturally(this.world, blockposition, this.world.getType(blockposition), 1.0F / this.size, 0); ++ // CraftBukkit - add yield ++ block.dropNaturally(this.world, blockposition, this.world.getType(blockposition), yield, 0); + } + + this.world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); +@@ -185,7 +251,11 @@ + while (iterator.hasNext()) { + blockposition = (BlockPosition) iterator.next(); + if (this.world.getType(blockposition).getBlock().getMaterial() == Material.AIR && this.world.getType(blockposition.down()).getBlock().o() && this.c.nextInt(3) == 0) { +- this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ // CraftBukkit start - Ignition by explosion ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(this.world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { ++ this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ } ++ // CraftBukkit end + } + } + } +@@ -197,7 +267,9 @@ + } + + public EntityLiving getSource() { +- return this.source == null ? null : (this.source instanceof EntityTNTPrimed ? ((EntityTNTPrimed) this.source).getSource() : (this.source instanceof EntityLiving ? (EntityLiving) this.source : null)); ++ // CraftBukkit start - obtain Fireball shooter for explosion tracking ++ return this.source == null ? null : (this.source instanceof EntityTNTPrimed ? ((EntityTNTPrimed) this.source).getSource() : (this.source instanceof EntityLiving ? (EntityLiving) this.source : (this.source instanceof EntityFireball ? ((EntityFireball) this.source).shooter : null))); ++ // CraftBukkit end + } + + public void clearBlocks() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/FoodMetaData.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/FoodMetaData.patch new file mode 100644 index 0000000..aaeab26 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/FoodMetaData.patch @@ -0,0 +1,66 @@ +--- a/net/minecraft/server/FoodMetaData.java ++++ b/net/minecraft/server/FoodMetaData.java +@@ -6,9 +6,17 @@ + public float saturationLevel = 5.0F; + public float exhaustionLevel; + private int foodTickTimer; ++ private EntityHuman entityhuman; // CraftBukkit + private int e = 20; + +- public FoodMetaData() {} ++ public FoodMetaData() { throw new AssertionError("Whoopsie, we missed the bukkit."); } // CraftBukkit start - throw an error ++ ++ // CraftBukkit start - added EntityHuman constructor ++ public FoodMetaData(EntityHuman entityhuman) { ++ org.apache.commons.lang.Validate.notNull(entityhuman); ++ this.entityhuman = entityhuman; ++ } ++ // CraftBukkit end + + public void eat(int i, float f) { + this.foodLevel = Math.min(i + this.foodLevel, 20); +@@ -16,7 +24,17 @@ + } + + public void a(ItemFood itemfood, ItemStack itemstack) { +- this.eat(itemfood.getNutrition(itemstack), itemfood.getSaturationModifier(itemstack)); ++ // CraftBukkit start ++ int oldFoodLevel = foodLevel; ++ ++ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, itemfood.getNutrition(itemstack) + oldFoodLevel); ++ ++ if (!event.isCancelled()) { ++ this.eat(event.getFoodLevel() - oldFoodLevel, itemfood.getSaturationModifier(itemstack)); ++ } ++ ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel)); ++ // CraftBukkit end + } + + public void a(EntityHuman entityhuman) { +@@ -28,14 +46,23 @@ + if (this.saturationLevel > 0.0F) { + this.saturationLevel = Math.max(this.saturationLevel - 1.0F, 0.0F); + } else if (enumdifficulty != EnumDifficulty.PEACEFUL) { +- this.foodLevel = Math.max(this.foodLevel - 1, 0); ++ // CraftBukkit start ++ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, Math.max(this.foodLevel - 1, 0)); ++ ++ if (!event.isCancelled()) { ++ this.foodLevel = event.getFoodLevel(); ++ } ++ ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), this.foodLevel, this.saturationLevel)); ++ // CraftBukkit end + } + } + + if (entityhuman.world.getGameRules().getBoolean("naturalRegeneration") && this.foodLevel >= 18 && entityhuman.cm()) { + ++this.foodTickTimer; + if (this.foodTickTimer >= 80) { +- entityhuman.heal(1.0F); ++ // CraftBukkit - added RegainReason ++ entityhuman.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.SATIATED); + this.a(3.0F); + this.foodTickTimer = 0; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/HandshakeListener.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/HandshakeListener.patch new file mode 100644 index 0000000..a30ece5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/HandshakeListener.patch @@ -0,0 +1,70 @@ +--- a/net/minecraft/server/HandshakeListener.java ++++ b/net/minecraft/server/HandshakeListener.java +@@ -1,7 +1,17 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import java.net.InetAddress; ++import java.util.HashMap; ++// CraftBukkit end ++ + public class HandshakeListener implements PacketHandshakingInListener { + ++ // CraftBukkit start - add fields ++ private static final HashMap throttleTracker = new HashMap(); ++ private static int throttleCounter = 0; ++ // CraftBukkit end ++ + private final MinecraftServer a; + private final NetworkManager b; + +@@ -16,6 +26,41 @@ + this.b.a(EnumProtocol.LOGIN); + ChatComponentText chatcomponenttext; + ++ // CraftBukkit start - Connection throttle ++ try { ++ long currentTime = System.currentTimeMillis(); ++ long connectionThrottle = MinecraftServer.getServer().server.getConnectionThrottle(); ++ InetAddress address = ((java.net.InetSocketAddress) this.b.getSocketAddress()).getAddress(); ++ ++ synchronized (throttleTracker) { ++ if (throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - throttleTracker.get(address) < connectionThrottle) { ++ throttleTracker.put(address, currentTime); ++ chatcomponenttext = new ChatComponentText("Connection throttled! Please wait before reconnecting."); ++ this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext)); ++ this.b.close(chatcomponenttext); ++ return; ++ } ++ ++ throttleTracker.put(address, currentTime); ++ throttleCounter++; ++ if (throttleCounter > 200) { ++ throttleCounter = 0; ++ ++ // Cleanup stale entries ++ java.util.Iterator iter = throttleTracker.entrySet().iterator(); ++ while (iter.hasNext()) { ++ java.util.Map.Entry entry = (java.util.Map.Entry) iter.next(); ++ if (entry.getValue() > connectionThrottle) { ++ iter.remove(); ++ } ++ } ++ } ++ } ++ } catch (Throwable t) { ++ org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); ++ } ++ // CraftBukkit end ++ + if (packethandshakinginsetprotocol.b() > 47) { + chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.8.8"); + this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext)); +@@ -26,6 +71,7 @@ + this.b.close(chatcomponenttext); + } else { + this.b.a((PacketListener) (new LoginListener(this.a, this.b))); ++ ((LoginListener) this.b.getPacketListener()).hostname = packethandshakinginsetprotocol.hostname + ":" + packethandshakinginsetprotocol.port; // CraftBukkit - set hostname + } + break; + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/IDataManager.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/IDataManager.patch new file mode 100644 index 0000000..fb0b95c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/IDataManager.patch @@ -0,0 +1,9 @@ +--- a/net/minecraft/server/IDataManager.java ++++ b/net/minecraft/server/IDataManager.java +@@ -23,4 +23,6 @@ + File getDataFile(String s); + + String g(); ++ ++ java.util.UUID getUUID(); // CraftBukkit + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/IInventory.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/IInventory.patch new file mode 100644 index 0000000..9b2c12b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/IInventory.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/server/IInventory.java ++++ b/net/minecraft/server/IInventory.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; // CraftBukkit ++ + public interface IInventory extends INamableTileEntity { + + int getSize(); +@@ -31,4 +33,20 @@ + int g(); + + void l(); ++ ++ // CraftBukkit start ++ ItemStack[] getContents(); ++ ++ void onOpen(CraftHumanEntity who); ++ ++ void onClose(CraftHumanEntity who); ++ ++ java.util.List getViewers(); ++ ++ org.bukkit.inventory.InventoryHolder getOwner(); ++ ++ void setMaxStackSize(int size); ++ ++ int MAX_STACK = 64; ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/IRecipe.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/IRecipe.patch new file mode 100644 index 0000000..68aab81 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/IRecipe.patch @@ -0,0 +1,9 @@ +--- a/net/minecraft/server/IRecipe.java ++++ b/net/minecraft/server/IRecipe.java +@@ -11,4 +11,6 @@ + ItemStack b(); + + ItemStack[] b(InventoryCrafting inventorycrafting); ++ ++ org.bukkit.inventory.Recipe toBukkitRecipe(); // CraftBukkit + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryCraftResult.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryCraftResult.patch new file mode 100644 index 0000000..de8cd9a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryCraftResult.patch @@ -0,0 +1,49 @@ +--- a/net/minecraft/server/InventoryCraftResult.java ++++ b/net/minecraft/server/InventoryCraftResult.java +@@ -1,9 +1,37 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventoryCraftResult implements IInventory { + + private ItemStack[] items = new ItemStack[1]; + ++ // CraftBukkit start ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return null; // Result slots don't get an owner ++ } ++ ++ // Don't need a transaction; the InventoryCrafting keeps track of it for us ++ public void onOpen(CraftHumanEntity who) {} ++ public void onClose(CraftHumanEntity who) {} ++ public java.util.List getViewers() { ++ return new java.util.ArrayList(); ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public InventoryCraftResult() {} + + public int getSize() { +@@ -53,7 +81,7 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return maxStack; // CraftBukkit + } + + public void update() {} diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryCrafting.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryCrafting.patch new file mode 100644 index 0000000..59e32a2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryCrafting.patch @@ -0,0 +1,65 @@ +--- a/net/minecraft/server/InventoryCrafting.java ++++ b/net/minecraft/server/InventoryCrafting.java +@@ -1,5 +1,13 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import java.util.List; ++ ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.inventory.InventoryType; ++// CraftBukkit end ++ + public class InventoryCrafting implements IInventory { + + private final ItemStack[] items; +@@ -7,6 +15,48 @@ + private final int c; + private final Container d; + ++ // CraftBukkit start - add fields ++ public List transaction = new java.util.ArrayList(); ++ public IRecipe currentRecipe; ++ public IInventory resultInventory; ++ private EntityHuman owner; ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public InventoryType getInvType() { ++ return items.length == 4 ? InventoryType.CRAFTING : InventoryType.WORKBENCH; ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return (owner == null) ? null : owner.getBukkitEntity(); ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ resultInventory.setMaxStackSize(size); ++ } ++ ++ public InventoryCrafting(Container container, int i, int j, EntityHuman player) { ++ this(container, i, j); ++ this.owner = player; ++ } ++ // CraftBukkit end ++ + public InventoryCrafting(Container container, int i, int j) { + int k = i * j; + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryEnderChest.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryEnderChest.patch new file mode 100644 index 0000000..26b013c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryEnderChest.patch @@ -0,0 +1,52 @@ +--- a/net/minecraft/server/InventoryEnderChest.java ++++ b/net/minecraft/server/InventoryEnderChest.java +@@ -1,9 +1,49 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventoryEnderChest extends InventorySubcontainer { + + private TileEntityEnderChest a; + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ public org.bukkit.entity.Player player; ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return this.player; ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ ++ public int getMaxStackSize() { ++ return maxStack; ++ } ++ // CraftBukkit end ++ + public InventoryEnderChest() { + super("container.enderchest", false, 27); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryHorseChest.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryHorseChest.patch new file mode 100644 index 0000000..da3394f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryHorseChest.patch @@ -0,0 +1,63 @@ +--- a/net/minecraft/server/InventoryHorseChest.java ++++ b/net/minecraft/server/InventoryHorseChest.java +@@ -1,8 +1,60 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventoryHorseChest extends InventorySubcontainer { + + public InventoryHorseChest(String s, int i) { + super(s, false, i); + } ++ ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private EntityHorse horse; ++ private int maxStack = MAX_STACK; ++ ++ public InventoryHorseChest(String s, int i, EntityHorse horse) { ++ super(s, false, i, (org.bukkit.craftbukkit.entity.CraftHorse) horse.getBukkitEntity()); ++ this.horse = horse; ++ } ++ ++ @Override ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ @Override ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ @Override ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ @Override ++ public List getViewers() { ++ return transaction; ++ } ++ ++ @Override ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return (org.bukkit.entity.Horse) this.horse.getBukkitEntity(); ++ } ++ ++ @Override ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ ++ @Override ++ public int getMaxStackSize() { ++ return maxStack; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryLargeChest.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryLargeChest.patch new file mode 100644 index 0000000..a23b0cf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryLargeChest.patch @@ -0,0 +1,67 @@ +--- a/net/minecraft/server/InventoryLargeChest.java ++++ b/net/minecraft/server/InventoryLargeChest.java +@@ -1,11 +1,55 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import java.util.List; ++ ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventoryLargeChest implements ITileInventory { + + private String a; + public ITileInventory left; + public ITileInventory right; + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ ++ public ItemStack[] getContents() { ++ ItemStack[] result = new ItemStack[this.getSize()]; ++ for (int i = 0; i < result.length; i++) { ++ result[i] = this.getItem(i); ++ } ++ return result; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ this.left.onOpen(who); ++ this.right.onOpen(who); ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ this.left.onClose(who); ++ this.right.onClose(who); ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return null; // This method won't be called since CraftInventoryDoubleChest doesn't defer to here ++ } ++ ++ public void setMaxStackSize(int size) { ++ this.left.setMaxStackSize(size); ++ this.right.setMaxStackSize(size); ++ } ++ // CraftBukkit end ++ + public InventoryLargeChest(String s, ITileInventory itileinventory, ITileInventory itileinventory1) { + this.a = s; + if (itileinventory == null) { +@@ -68,7 +112,7 @@ + } + + public int getMaxStackSize() { +- return this.left.getMaxStackSize(); ++ return Math.min(this.left.getMaxStackSize(), this.right.getMaxStackSize()); // CraftBukkit - check both sides + } + + public void update() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryMerchant.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryMerchant.patch new file mode 100644 index 0000000..83227eb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventoryMerchant.patch @@ -0,0 +1,60 @@ +--- a/net/minecraft/server/InventoryMerchant.java ++++ b/net/minecraft/server/InventoryMerchant.java +@@ -1,5 +1,12 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.craftbukkit.entity.CraftVillager; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventoryMerchant implements IInventory { + + private final IMerchant merchant; +@@ -8,6 +15,35 @@ + private MerchantRecipe recipe; + private int e; + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.itemsInSlots; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int i) { ++ maxStack = i; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return (CraftVillager) ((EntityVillager) this.merchant).getBukkitEntity(); ++ } ++ // CraftBukkit end ++ + public InventoryMerchant(EntityHuman entityhuman, IMerchant imerchant) { + this.player = entityhuman; + this.merchant = imerchant; +@@ -94,7 +130,7 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventorySubcontainer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventorySubcontainer.patch new file mode 100644 index 0000000..5cb5243 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/InventorySubcontainer.patch @@ -0,0 +1,58 @@ +--- a/net/minecraft/server/InventorySubcontainer.java ++++ b/net/minecraft/server/InventorySubcontainer.java +@@ -3,6 +3,12 @@ + import com.google.common.collect.Lists; + import java.util.List; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventorySubcontainer implements IInventory { + + private String a; +@@ -11,7 +17,42 @@ + private List d; + private boolean e; + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ protected org.bukkit.inventory.InventoryHolder bukkitOwner; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int i) { ++ maxStack = i; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return bukkitOwner; ++ } ++ + public InventorySubcontainer(String s, boolean flag, int i) { ++ this(s, flag, i, null); ++ } ++ ++ public InventorySubcontainer(String s, boolean flag, int i, org.bukkit.inventory.InventoryHolder owner) { // Added argument ++ this.bukkitOwner = owner; ++ // CraftBukkit end + this.a = s; + this.e = flag; + this.b = i; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemArmor.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemArmor.patch new file mode 100644 index 0000000..e6beb5e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemArmor.patch @@ -0,0 +1,59 @@ +--- a/net/minecraft/server/ItemArmor.java ++++ b/net/minecraft/server/ItemArmor.java +@@ -3,6 +3,11 @@ + import com.google.common.base.Predicates; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end ++ + public class ItemArmor extends Item { + + private static final int[] k = new int[] { 11, 16, 15, 13}; +@@ -20,7 +25,34 @@ + EntityLiving entityliving = (EntityLiving) list.get(0); + int l = entityliving instanceof EntityHuman ? 1 : 0; + int i1 = EntityInsentient.c(itemstack); +- ItemStack itemstack1 = itemstack.cloneItemStack(); ++ ++ // CraftBukkit start ++ ItemStack itemstack1 = itemstack.cloneAndSubtract(1); ++ World world = isourceblock.getWorld(); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.count++; ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.count++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ // CraftBukkit end + + itemstack1.count = 1; + entityliving.setEquipment(i1 - l, itemstack1); +@@ -28,7 +60,7 @@ + ((EntityInsentient) entityliving).a(i1, 2.0F); + } + +- --itemstack.count; ++ // --itemstack.count; // CraftBukkit - handled above + return itemstack; + } else { + return super.b(isourceblock, itemstack); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBoat.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBoat.patch new file mode 100644 index 0000000..364ba05 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBoat.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/server/ItemBoat.java ++++ b/net/minecraft/server/ItemBoat.java +@@ -54,6 +54,14 @@ + if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + BlockPosition blockposition = movingobjectposition.a(); + ++ // CraftBukkit start - Boat placement ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(entityhuman, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, blockposition, movingobjectposition.direction, itemstack); ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ // CraftBukkit end ++ + if (world.getType(blockposition).getBlock() == Blocks.SNOW_LAYER) { + blockposition = blockposition.down(); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBow.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBow.patch new file mode 100644 index 0000000..b21506f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBow.patch @@ -0,0 +1,49 @@ +--- a/net/minecraft/server/ItemBow.java ++++ b/net/minecraft/server/ItemBow.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.entity.EntityCombustEvent; // CraftBukkit ++ + public class ItemBow extends Item { + + public static final String[] a = new String[] { "pulling_0", "pulling_1", "pulling_2"}; +@@ -45,9 +47,28 @@ + } + + if (EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_FIRE.id, itemstack) > 0) { +- entityarrow.setOnFire(100); ++ // CraftBukkit start - call EntityCombustEvent ++ EntityCombustEvent event = new EntityCombustEvent(entityarrow.getBukkitEntity(), 100); ++ entityarrow.world.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ entityarrow.setOnFire(event.getDuration()); ++ } ++ // CraftBukkit end ++ } ++ ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(entityhuman, itemstack, entityarrow, f); ++ if (event.isCancelled()) { ++ event.getProjectile().remove(); ++ return; + } + ++ if (event.getProjectile() == entityarrow.getBukkitEntity()) { ++ world.addEntity(entityarrow); ++ } ++ // CraftBukkit end ++ + itemstack.damage(1, entityhuman); + world.makeSound(entityhuman, "random.bow", 1.0F, 1.0F / (ItemBow.g.nextFloat() * 0.4F + 1.2F) + f * 0.5F); + if (flag) { +@@ -58,7 +79,7 @@ + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + if (!world.isClientSide) { +- world.addEntity(entityarrow); ++ // world.addEntity(entityarrow); // CraftBukkit - moved up + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBucket.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBucket.patch new file mode 100644 index 0000000..955279c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemBucket.patch @@ -0,0 +1,99 @@ +--- a/net/minecraft/server/ItemBucket.java ++++ b/net/minecraft/server/ItemBucket.java +@@ -1,5 +1,12 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.player.PlayerBucketEmptyEvent; ++import org.bukkit.event.player.PlayerBucketFillEvent; ++// CraftBukkit end ++ + public class ItemBucket extends Item { + + private Block a; +@@ -33,19 +40,41 @@ + Material material = iblockdata.getBlock().getMaterial(); + + if (material == Material.WATER && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0) { ++ // CraftBukkit start ++ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), null, itemstack, Items.WATER_BUCKET); ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ // CraftBukkit end + world.setAir(blockposition); + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); +- return this.a(itemstack, entityhuman, Items.WATER_BUCKET); ++ return this.a(itemstack, entityhuman, Items.WATER_BUCKET, event.getItemStack()); // CraftBukkit - added Event stack + } + + if (material == Material.LAVA && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0) { ++ // CraftBukkit start ++ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), null, itemstack, Items.LAVA_BUCKET); ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ // CraftBukkit end + world.setAir(blockposition); + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); +- return this.a(itemstack, entityhuman, Items.LAVA_BUCKET); ++ return this.a(itemstack, entityhuman, Items.LAVA_BUCKET, event.getItemStack()); // CraftBukkit - added Event stack + } + } else { + if (this.a == Blocks.AIR) { +- return new ItemStack(Items.BUCKET); ++ // CraftBukkit start ++ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), movingobjectposition.direction, itemstack); ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ ++ return CraftItemStack.asNMSCopy(event.getItemStack()); ++ // CraftBukkit end + } + + BlockPosition blockposition1 = blockposition.shift(movingobjectposition.direction); +@@ -54,9 +83,17 @@ + return itemstack; + } + ++ // CraftBukkit start ++ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), movingobjectposition.direction, itemstack); ++ ++ if (event.isCancelled()) { ++ return itemstack; ++ } ++ // CraftBukkit end ++ + if (this.a(world, blockposition1) && !entityhuman.abilities.canInstantlyBuild) { + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); +- return new ItemStack(Items.BUCKET); ++ return CraftItemStack.asNMSCopy(event.getItemStack()); // CraftBukkit + } + } + } +@@ -65,14 +102,15 @@ + } + } + +- private ItemStack a(ItemStack itemstack, EntityHuman entityhuman, Item item) { ++ // CraftBukkit - added ob.ItemStack result - TODO: Is this... the right way to handle this? ++ private ItemStack a(ItemStack itemstack, EntityHuman entityhuman, Item item, org.bukkit.inventory.ItemStack result) { + if (entityhuman.abilities.canInstantlyBuild) { + return itemstack; + } else if (--itemstack.count <= 0) { +- return new ItemStack(item); ++ return CraftItemStack.asNMSCopy(result); // CraftBukkit + } else { +- if (!entityhuman.inventory.pickup(new ItemStack(item))) { +- entityhuman.drop(new ItemStack(item, 1, 0), false); ++ if (!entityhuman.inventory.pickup(CraftItemStack.asNMSCopy(result))) { ++ entityhuman.drop(CraftItemStack.asNMSCopy(result), false); + } + + return itemstack; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemDye.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemDye.patch new file mode 100644 index 0000000..b01d80f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemDye.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/server/ItemDye.java ++++ b/net/minecraft/server/ItemDye.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.entity.SheepDyeWoolEvent; // CraftBukkit ++ + public class ItemDye extends Item { + + public static final int[] a = new int[] { 1973019, 11743532, 3887386, 5320730, 2437522, 8073150, 2651799, 11250603, 4408131, 14188952, 4312372, 14602026, 6719955, 12801229, 15435844, 15790320}; +@@ -89,6 +91,17 @@ + EnumColor enumcolor = EnumColor.fromInvColorIndex(itemstack.getData()); + + if (!entitysheep.isSheared() && entitysheep.getColor() != enumcolor) { ++ // CraftBukkit start ++ byte bColor = (byte) enumcolor.getColorIndex(); ++ SheepDyeWoolEvent event = new SheepDyeWoolEvent((org.bukkit.entity.Sheep) entitysheep.getBukkitEntity(), org.bukkit.DyeColor.getByData(bColor)); ++ entitysheep.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ ++ enumcolor = EnumColor.fromColorIndex((byte) event.getColor().getWoolData()); ++ // CraftBukkit end + entitysheep.setColor(enumcolor); + --itemstack.count; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFireball.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFireball.patch new file mode 100644 index 0000000..dc040d9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFireball.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/server/ItemFireball.java ++++ b/net/minecraft/server/ItemFireball.java +@@ -15,6 +15,14 @@ + return false; + } else { + if (world.getType(blockposition).getBlock().getMaterial() == Material.AIR) { ++ // CraftBukkit start - fire BlockIgniteEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, entityhuman).isCancelled()) { ++ if (!entityhuman.abilities.canInstantlyBuild) { ++ --itemstack.count; ++ } ++ return false; ++ } ++ // CraftBukkit end + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "item.fireCharge.use", 1.0F, (ItemFireball.g.nextFloat() - ItemFireball.g.nextFloat()) * 0.2F + 1.0F); + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFishingRod.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFishingRod.patch new file mode 100644 index 0000000..9091026 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFishingRod.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/server/ItemFishingRod.java ++++ b/net/minecraft/server/ItemFishingRod.java +@@ -1,5 +1,7 @@ + package net.minecraft.server; + ++import org.bukkit.event.player.PlayerFishEvent; // CraftBukkit ++ + public class ItemFishingRod extends Item { + + public ItemFishingRod() { +@@ -15,9 +17,18 @@ + itemstack.damage(i, entityhuman); + entityhuman.bw(); + } else { ++ // CraftBukkit start ++ EntityFishingHook hook = new EntityFishingHook(world, entityhuman); ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), null, (org.bukkit.entity.Fish) hook.getBukkitEntity(), PlayerFishEvent.State.FISHING); ++ world.getServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ return itemstack; ++ } ++ // CraftBukkit end + world.makeSound(entityhuman, "random.bow", 0.5F, 0.4F / (ItemFishingRod.g.nextFloat() * 0.4F + 0.8F)); + if (!world.isClientSide) { +- world.addEntity(new EntityFishingHook(world, entityhuman)); ++ world.addEntity(hook); // CraftBukkit - moved creation up + } + + entityhuman.bw(); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFlintAndSteel.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFlintAndSteel.patch new file mode 100644 index 0000000..ab3aef9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemFlintAndSteel.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/server/ItemFlintAndSteel.java ++++ b/net/minecraft/server/ItemFlintAndSteel.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.block.CraftBlockState; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++// CraftBukkit end ++ + public class ItemFlintAndSteel extends Item { + + public ItemFlintAndSteel() { +@@ -9,13 +14,31 @@ + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { ++ BlockPosition clicked = blockposition; // CraftBukkit + blockposition = blockposition.shift(enumdirection); + if (!entityhuman.a(blockposition, enumdirection, itemstack)) { + return false; + } else { + if (world.getType(blockposition).getBlock().getMaterial() == Material.AIR) { ++ // CraftBukkit start - Store the clicked block ++ if (CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, entityhuman).isCancelled()) { ++ itemstack.damage(1, entityhuman); ++ return false; ++ } ++ ++ CraftBlockState blockState = CraftBlockState.getBlockState(world, blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ // CraftBukkit end + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "fire.ignite", 1.0F, ItemFlintAndSteel.g.nextFloat() * 0.4F + 0.8F); + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); ++ ++ // CraftBukkit start ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockState, clicked.getX(), clicked.getY(), clicked.getZ()); ++ ++ if (placeEvent.isCancelled() || !placeEvent.canBuild()) { ++ placeEvent.getBlockPlaced().setTypeIdAndData(0, (byte) 0, false); ++ return false; ++ } ++ // CraftBukkit end + } + + itemstack.damage(1, entityhuman); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemHanging.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemHanging.patch new file mode 100644 index 0000000..d6ec92a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemHanging.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/server/ItemHanging.java ++++ b/net/minecraft/server/ItemHanging.java +@@ -1,5 +1,11 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.event.hanging.HangingPlaceEvent; ++import org.bukkit.event.painting.PaintingPlaceEvent; ++// CraftBukkit end ++ + public class ItemHanging extends Item { + + private final Class a; +@@ -24,6 +30,26 @@ + + if (entityhanging != null && entityhanging.survives()) { + if (!world.isClientSide) { ++ // CraftBukkit start - fire HangingPlaceEvent ++ Player who = (entityhuman == null) ? null : (Player) entityhuman.getBukkitEntity(); ++ org.bukkit.block.Block blockClicked = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection); ++ ++ HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityhanging.getBukkitEntity(), who, blockClicked, blockFace); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ PaintingPlaceEvent paintingEvent = null; ++ if (entityhanging instanceof EntityPainting) { ++ // Fire old painting event until it can be removed ++ paintingEvent = new PaintingPlaceEvent((org.bukkit.entity.Painting) entityhanging.getBukkitEntity(), who, blockClicked, blockFace); ++ paintingEvent.setCancelled(event.isCancelled()); ++ world.getServer().getPluginManager().callEvent(paintingEvent); ++ } ++ ++ if (event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { ++ return false; ++ } ++ // CraftBukkit end + world.addEntity(entityhanging); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemLeash.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemLeash.patch new file mode 100644 index 0000000..c9713f2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemLeash.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/server/ItemLeash.java ++++ b/net/minecraft/server/ItemLeash.java +@@ -3,6 +3,8 @@ + import java.util.Iterator; + import java.util.List; + ++import org.bukkit.event.hanging.HangingPlaceEvent; // CraftBukkit ++ + public class ItemLeash extends Item { + + public ItemLeash() { +@@ -40,7 +42,23 @@ + if (entityinsentient.cc() && entityinsentient.getLeashHolder() == entityhuman) { + if (entityleash == null) { + entityleash = EntityLeash.a(world, blockposition); ++ ++ // CraftBukkit start - fire HangingPlaceEvent ++ HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityleash.getBukkitEntity(), entityhuman != null ? (org.bukkit.entity.Player) entityhuman.getBukkitEntity() : null, world.getWorld().getBlockAt(i, j, k), org.bukkit.block.BlockFace.SELF); ++ world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ entityleash.die(); ++ return false; ++ } ++ // CraftBukkit end ++ } ++ ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(entityinsentient, entityleash, entityhuman).isCancelled()) { ++ continue; + } ++ // CraftBukkit end + + entityinsentient.setLeashHolder(entityleash, true); + flag = true; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMapEmpty.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMapEmpty.patch new file mode 100644 index 0000000..cc593bb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMapEmpty.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/server/ItemMapEmpty.java ++++ b/net/minecraft/server/ItemMapEmpty.java +@@ -7,15 +7,19 @@ + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { +- ItemStack itemstack1 = new ItemStack(Items.FILLED_MAP, 1, world.b("map")); ++ World worldMain = world.getServer().getServer().worlds.get(0); // CraftBukkit - store reference to primary world ++ ItemStack itemstack1 = new ItemStack(Items.FILLED_MAP, 1, worldMain.b("map")); // CraftBukkit - use primary world for maps + String s = "map_" + itemstack1.getData(); + WorldMap worldmap = new WorldMap(s); + +- world.a(s, (PersistentBase) worldmap); ++ worldMain.a(s, (PersistentBase) worldmap); // CraftBukkit + worldmap.scale = 0; + worldmap.a(entityhuman.locX, entityhuman.locZ, worldmap.scale); +- worldmap.map = (byte) world.worldProvider.getDimension(); ++ worldmap.map = (byte) ((WorldServer) world).dimension; // CraftBukkit - use bukkit dimension + worldmap.c(); ++ ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEvent(new org.bukkit.event.server.MapInitializeEvent(worldmap.mapView)); // CraftBukkit ++ + --itemstack.count; + if (itemstack.count <= 0) { + return itemstack1; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMinecart.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMinecart.patch new file mode 100644 index 0000000..ed8f094 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMinecart.patch @@ -0,0 +1,74 @@ +--- a/net/minecraft/server/ItemMinecart.java ++++ b/net/minecraft/server/ItemMinecart.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end ++ + public class ItemMinecart extends Item { + + private static final IDispenseBehavior a = new DispenseBehaviorItem() { +@@ -37,14 +42,43 @@ + } + } + +- EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.a(world, d0, d1 + d3, d2, ((ItemMinecart) itemstack.getItem()).b); ++ // CraftBukkit start ++ // EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.a(world, d0, d1 + d3, d2, ((ItemMinecart) itemstack.getItem()).b); ++ ItemStack itemstack1 = itemstack.cloneAndSubtract(1); ++ org.bukkit.block.Block block2 = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); ++ if (!BlockDispenser.eventFired) { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.count++; ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.count++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { ++ idispensebehavior.a(isourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); ++ EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.a(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), ((ItemMinecart) itemstack1.getItem()).b); + + if (itemstack.hasName()) { + entityminecartabstract.setCustomName(itemstack.getName()); + } + + world.addEntity(entityminecartabstract); +- itemstack.cloneAndSubtract(1); ++ // itemstack.a(1); // CraftBukkit - handled during event processing ++ // CraftBukkit end + return itemstack; + } + +@@ -73,6 +107,14 @@ + d0 = 0.5D; + } + ++ // CraftBukkit start - Minecarts ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(entityhuman, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, blockposition, enumdirection, itemstack); ++ ++ if (event.isCancelled()) { ++ return false; ++ } ++ // CraftBukkit end ++ + EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.a(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.0625D + d0, (double) blockposition.getZ() + 0.5D, this.b); + + if (itemstack.hasName()) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMonsterEgg.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMonsterEgg.patch new file mode 100644 index 0000000..e423631 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemMonsterEgg.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/server/ItemMonsterEgg.java ++++ b/net/minecraft/server/ItemMonsterEgg.java +@@ -109,6 +109,12 @@ + } + + public static Entity a(World world, int i, double d0, double d1, double d2) { ++ // CraftBukkit start - delegate to spawnCreature ++ return spawnCreature(world, i, d0, d1, d2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); ++ } ++ ++ public static Entity spawnCreature(World world, int i, double d0, double d1, double d2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { ++ // CraftBukkit end + if (!EntityTypes.eggInfo.containsKey(Integer.valueOf(i))) { + return null; + } else { +@@ -123,8 +129,13 @@ + entityinsentient.aK = entityinsentient.yaw; + entityinsentient.aI = entityinsentient.yaw; + entityinsentient.prepare(world.E(new BlockPosition(entityinsentient)), (GroupDataEntity) null); +- world.addEntity(entity); +- entityinsentient.x(); ++ // CraftBukkit start - don't return an entity when CreatureSpawnEvent is canceled ++ if (!world.addEntity(entity, spawnReason)) { ++ entity = null; ++ } else { ++ entityinsentient.x(); ++ } ++ // CraftBukkit end + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemRecord.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemRecord.patch new file mode 100644 index 0000000..0698a9d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemRecord.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/server/ItemRecord.java ++++ b/net/minecraft/server/ItemRecord.java +@@ -22,10 +22,14 @@ + if (world.isClientSide) { + return true; + } else { ++ // CraftBukkit Start ++ /* + ((BlockJukeBox) Blocks.JUKEBOX).a(world, blockposition, iblockdata, itemstack); + world.a((EntityHuman) null, 1005, blockposition, Item.getId(this)); + --itemstack.count; + entityhuman.b(StatisticList.X); ++ */ ++ // CraftBukkit End + return true; + } + } else { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemStack.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemStack.patch new file mode 100644 index 0000000..9a2c9a5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemStack.patch @@ -0,0 +1,251 @@ +--- a/net/minecraft/server/ItemStack.java ++++ b/net/minecraft/server/ItemStack.java +@@ -5,6 +5,19 @@ + import java.text.DecimalFormat; + import java.util.Random; + ++// CraftBukkit start ++import java.util.List; ++import java.util.Map; ++ ++import org.bukkit.Location; ++import org.bukkit.TreeType; ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.block.CraftBlockState; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.entity.Player; ++import org.bukkit.event.world.StructureGrowEvent; ++// CraftBukkit end ++ + public final class ItemStack { + + public static final DecimalFormat a = new DecimalFormat("#.###"); +@@ -46,10 +59,14 @@ + this.k = false; + this.item = item; + this.count = i; +- this.damage = j; +- if (this.damage < 0) { +- this.damage = 0; +- } ++ ++ // CraftBukkit start - Pass to setData to do filtering ++ this.setData(j); ++ //this.damage = j; ++ //if (this.damage < 0) { ++ // this.damage = 0; ++ //} ++ // CraftBukkit end + + } + +@@ -83,11 +100,128 @@ + } + + public boolean placeItem(EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { ++ // CraftBukkit start - handle all block place event logic here ++ int data = this.getData(); ++ int count = this.count; ++ ++ if (!(this.getItem() instanceof ItemBucket)) { // if not bucket ++ world.captureBlockStates = true; ++ // special case bonemeal ++ if (this.getItem() instanceof ItemDye && this.getData() == 15) { ++ Block block = world.getType(blockposition).getBlock(); ++ if (block == Blocks.SAPLING || block instanceof BlockMushroom) { ++ world.captureTreeGeneration = true; ++ } ++ } ++ } + boolean flag = this.getItem().interactWith(this, entityhuman, world, blockposition, enumdirection, f, f1, f2); ++ int newData = this.getData(); ++ int newCount = this.count; ++ this.count = count; ++ this.setData(data); ++ world.captureBlockStates = false; ++ if (flag && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) { ++ world.captureTreeGeneration = false; ++ Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ TreeType treeType = BlockSapling.treeType; ++ BlockSapling.treeType = null; ++ List blocks = (List) world.capturedBlockStates.clone(); ++ world.capturedBlockStates.clear(); ++ StructureGrowEvent event = null; ++ if (treeType != null) { ++ boolean isBonemeal = getItem() == Items.DYE && data == 15; ++ event = new StructureGrowEvent(location, treeType, isBonemeal, (Player) entityhuman.getBukkitEntity(), blocks); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ } ++ if (event == null || !event.isCancelled()) { ++ // Change the stack to its new contents if it hasn't been tampered with. ++ if (this.count == count && this.getData() == data) { ++ this.setData(newData); ++ this.count = newCount; ++ } ++ for (BlockState blockstate : blocks) { ++ blockstate.update(true); ++ } ++ } ++ ++ return flag; ++ } ++ world.captureTreeGeneration = false; + + if (flag) { +- entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this.item)]); ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = null; ++ List blocks = (List) world.capturedBlockStates.clone(); ++ world.capturedBlockStates.clear(); ++ if (blocks.size() > 1) { ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ } else if (blocks.size() == 1) { ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ } ++ ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { ++ flag = false; // cancel placement ++ // revert back all captured blocks ++ for (BlockState blockstate : blocks) { ++ blockstate.update(true, false); ++ } ++ } else { ++ // Change the stack to its new contents if it hasn't been tampered with. ++ if (this.count == count && this.getData() == data) { ++ this.setData(newData); ++ this.count = newCount; ++ } ++ for (BlockState blockstate : blocks) { ++ int x = blockstate.getX(); ++ int y = blockstate.getY(); ++ int z = blockstate.getZ(); ++ int updateFlag = ((CraftBlockState) blockstate).getFlag(); ++ org.bukkit.Material mat = blockstate.getType(); ++ Block oldBlock = CraftMagicNumbers.getBlock(mat); ++ BlockPosition newblockposition = new BlockPosition(x, y, z); ++ IBlockData block = world.getType(newblockposition); ++ ++ if (!(block instanceof BlockContainer)) { // Containers get placed automatically ++ block.getBlock().onPlace(world, newblockposition, block); ++ } ++ ++ world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block.getBlock(), updateFlag); // send null chunk as chunk.k() returns false by this point ++ } ++ ++ for (Map.Entry e : world.capturedTileEntities.entrySet()) { ++ world.setTileEntity(e.getKey(), e.getValue()); ++ } ++ ++ // Special case juke boxes as they update their tile entity. Copied from ItemRecord. ++ if (this.getItem() instanceof ItemRecord) { ++ ((BlockJukeBox) Blocks.JUKEBOX).a(world, blockposition, world.getType(blockposition), this); ++ world.a((EntityHuman) null, 1005, blockposition, Item.getId(this.getItem())); ++ --this.count; ++ entityhuman.b(StatisticList.X); ++ } ++ ++ if (this.getItem() == Items.SKULL) { // Special case skulls to allow wither spawns to be cancelled ++ BlockPosition bp = blockposition; ++ if (!world.getType(blockposition).getBlock().a(world, blockposition)) { ++ if (!world.getType(blockposition).getBlock().getMaterial().isBuildable()) { ++ bp = null; ++ } else { ++ bp = bp.shift(enumdirection); ++ } ++ } ++ if (bp != null) { ++ TileEntity te = world.getTileEntity(bp); ++ if (te instanceof TileEntitySkull) { ++ Blocks.SKULL.a(world, bp, (TileEntitySkull) te); ++ } ++ } ++ } ++ ++ entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this.item)]); ++ } + } ++ world.capturedTileEntities.clear(); ++ world.capturedBlockStates.clear(); ++ // CraftBukkit end + + return flag; + } +@@ -111,7 +245,7 @@ + nbttagcompound.setByte("Count", (byte) this.count); + nbttagcompound.setShort("Damage", (short) this.damage); + if (this.tag != null) { +- nbttagcompound.set("tag", this.tag); ++ nbttagcompound.set("tag", this.tag.clone()); // CraftBukkit - make defensive copy, data is going to another thread + } + + return nbttagcompound; +@@ -125,13 +259,18 @@ + } + + this.count = nbttagcompound.getByte("Count"); ++ /* CraftBukkit start - Route through setData for filtering + this.damage = nbttagcompound.getShort("Damage"); + if (this.damage < 0) { + this.damage = 0; + } ++ */ ++ this.setData(nbttagcompound.getShort("Damage")); ++ // CraftBukkit end + + if (nbttagcompound.hasKeyOfType("tag", 10)) { +- this.tag = nbttagcompound.getCompound("tag"); ++ // CraftBukkit - make defensive copy as this data may be coming from the save thread ++ this.tag = (NBTTagCompound) nbttagcompound.getCompound("tag").clone(); + if (this.item != null) { + this.item.a(this.tag); + } +@@ -168,8 +307,28 @@ + } + + public void setData(int i) { ++ // CraftBukkit start - Filter out data for items that shouldn't have it ++ // The crafting system uses this value for a special purpose so we have to allow it ++ if (i == 32767) { ++ this.damage = i; ++ return; ++ } ++ ++ // Is this a block? ++ if (CraftMagicNumbers.getBlock(CraftMagicNumbers.getId(this.getItem())) != Blocks.AIR) { ++ // If vanilla doesn't use data on it don't allow any ++ if (!(this.usesData() || this.getItem().usesDurability())) { ++ i = 0; ++ } ++ } ++ ++ // Filter invalid plant data ++ if (CraftMagicNumbers.getBlock(CraftMagicNumbers.getId(this.getItem())) == Blocks.DOUBLE_PLANT && (i > 5 || i < 0)) { ++ i = 0; ++ } ++ // CraftBukkit end + this.damage = i; +- if (this.damage < 0) { ++ if (this.damage < -1) { // CraftBukkit + this.damage = 0; + } + +@@ -223,6 +382,12 @@ + this.count = 0; + } + ++ // CraftBukkit start - Check for item breaking ++ if (this.count == 0 && entityliving instanceof EntityHuman) { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((EntityHuman) entityliving, this); ++ } ++ // CraftBukkit end ++ + this.damage = 0; + } + +@@ -489,6 +654,7 @@ + + public void setItem(Item item) { + this.item = item; ++ this.setData(this.getData()); // CraftBukkit - Set data again to ensure it is filtered properly + } + + public IChatBaseComponent C() { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemWaterLily.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemWaterLily.patch new file mode 100644 index 0000000..d4e7af0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemWaterLily.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/server/ItemWaterLily.java ++++ b/net/minecraft/server/ItemWaterLily.java +@@ -27,7 +27,15 @@ + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock().getMaterial() == Material.WATER && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0 && world.isEmpty(blockposition1)) { ++ // CraftBukkit start - special case for handling block placement with water lilies ++ org.bukkit.block.BlockState blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); + world.setTypeUpdate(blockposition1, Blocks.WATERLILY.getBlockData()); ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockstate, blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { ++ blockstate.update(true, false); ++ return itemstack; ++ } ++ // CraftBukkit end + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemWorldMap.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemWorldMap.patch new file mode 100644 index 0000000..f40ea52 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ItemWorldMap.patch @@ -0,0 +1,73 @@ +--- a/net/minecraft/server/ItemWorldMap.java ++++ b/net/minecraft/server/ItemWorldMap.java +@@ -4,6 +4,11 @@ + import com.google.common.collect.Iterables; + import com.google.common.collect.Multisets; + ++// CraftBukkit start ++import org.bukkit.Bukkit; ++import org.bukkit.event.server.MapInitializeEvent; ++// CraftBukkit end ++ + public class ItemWorldMap extends ItemWorldMapBase { + + protected ItemWorldMap() { +@@ -11,25 +16,32 @@ + } + + public WorldMap getSavedMap(ItemStack itemstack, World world) { ++ World worldMain = world.getServer().getServer().worlds.get(0); // CraftBukkit - store reference to primary world + String s = "map_" + itemstack.getData(); +- WorldMap worldmap = (WorldMap) world.a(WorldMap.class, s); ++ WorldMap worldmap = (WorldMap) worldMain.a(WorldMap.class, s); // CraftBukkit - use primary world for maps + + if (worldmap == null && !world.isClientSide) { +- itemstack.setData(world.b("map")); ++ itemstack.setData(worldMain.b("map")); // CraftBukkit - use primary world for maps + s = "map_" + itemstack.getData(); + worldmap = new WorldMap(s); + worldmap.scale = 3; + worldmap.a((double) world.getWorldData().c(), (double) world.getWorldData().e(), worldmap.scale); +- worldmap.map = (byte) world.worldProvider.getDimension(); ++ worldmap.map = (byte) ((WorldServer) world).dimension; // CraftBukkit - fixes Bukkit multiworld maps + worldmap.c(); +- world.a(s, (PersistentBase) worldmap); ++ worldMain.a(s, (PersistentBase) worldmap); // CraftBukkit - use primary world for maps ++ ++ // CraftBukkit start ++ MapInitializeEvent event = new MapInitializeEvent(worldmap.mapView); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end + } + + return worldmap; + } + + public void a(World world, Entity entity, WorldMap worldmap) { +- if (world.worldProvider.getDimension() == worldmap.map && entity instanceof EntityHuman) { ++ // CraftBukkit - world.worldProvider -> ((WorldServer) world) ++ if (((WorldServer) world).dimension == worldmap.map && entity instanceof EntityHuman) { + int i = 1 << worldmap.scale; + int j = worldmap.centerX; + int k = worldmap.centerZ; +@@ -181,6 +193,8 @@ + if (itemstack.hasTag() && itemstack.getTag().getBoolean("map_is_scaling")) { + WorldMap worldmap = Items.FILLED_MAP.getSavedMap(itemstack, world); + ++ world = world.getServer().getServer().worlds.get(0); // CraftBukkit - use primary world for maps ++ + itemstack.setData(world.b("map")); + WorldMap worldmap1 = new WorldMap("map_" + itemstack.getData()); + +@@ -193,6 +207,11 @@ + worldmap1.map = worldmap.map; + worldmap1.c(); + world.a("map_" + itemstack.getData(), (PersistentBase) worldmap1); ++ ++ // CraftBukkit start ++ MapInitializeEvent event = new MapInitializeEvent(worldmap1.mapView); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/JsonList.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/JsonList.patch new file mode 100644 index 0000000..10e6bce --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/JsonList.patch @@ -0,0 +1,47 @@ +--- a/net/minecraft/server/JsonList.java ++++ b/net/minecraft/server/JsonList.java +@@ -83,7 +83,7 @@ + + public V get(K k0) { + this.h(); +- return (JsonListEntry) this.d.get(this.a(k0)); ++ return (V) this.d.get(this.a(k0)); // CraftBukkit - fix decompile error + } + + public void remove(K k0) { +@@ -101,6 +101,12 @@ + return (String[]) this.d.keySet().toArray(new String[this.d.size()]); + } + ++ // CraftBukkit start ++ public Collection getValues() { ++ return this.d.values(); ++ } ++ // CraftBukkit end ++ + public boolean isEmpty() { + return this.d.size() < 1; + } +@@ -176,7 +182,7 @@ + JsonListEntry jsonlistentry = (JsonListEntry) iterator.next(); + + if (jsonlistentry.getKey() != null) { +- this.d.put(this.a(jsonlistentry.getKey()), jsonlistentry); ++ this.d.put(this.a((K) jsonlistentry.getKey()), (V) jsonlistentry); // CraftBukkit - fix decompile error + } + } + } +@@ -205,11 +211,11 @@ + } + } + +- public JsonElement serialize(Object object, Type type, JsonSerializationContext jsonserializationcontext) { ++ public JsonElement serialize(JsonListEntry object, Type type, JsonSerializationContext jsonserializationcontext) { // CraftBukkit - fix decompile error + return this.a((JsonListEntry) object, type, jsonserializationcontext); + } + +- public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { ++ public JsonListEntry deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { // CraftBukkit - fix decompile error + return this.a(jsonelement, type, jsondeserializationcontext); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/LoginListener.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/LoginListener.patch new file mode 100644 index 0000000..e44493c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/LoginListener.patch @@ -0,0 +1,125 @@ +--- a/net/minecraft/server/LoginListener.java ++++ b/net/minecraft/server/LoginListener.java +@@ -18,6 +18,12 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.Waitable; ++import org.bukkit.event.player.AsyncPlayerPreLoginEvent; ++import org.bukkit.event.player.PlayerPreLoginEvent; ++// CraftBukkit end ++ + public class LoginListener implements PacketLoginInListener, IUpdatePlayerListBox { + + private static final AtomicInteger b = new AtomicInteger(0); +@@ -32,6 +38,7 @@ + private String j; + private SecretKey loginKey; + private EntityPlayer l; ++ public String hostname = ""; // CraftBukkit - add field + + public LoginListener(MinecraftServer minecraftserver, NetworkManager networkmanager) { + this.g = LoginListener.EnumProtocolState.HELLO; +@@ -78,10 +85,12 @@ + this.i = this.a(this.i); + } + +- String s = this.server.getPlayerList().attemptLogin(this.networkManager.getSocketAddress(), this.i); ++ // CraftBukkit start - fire PlayerLoginEvent ++ EntityPlayer s = this.server.getPlayerList().attemptLogin(this, this.i, hostname); + +- if (s != null) { +- this.disconnect(s); ++ if (s == null) { ++ // this.disconnect(s); ++ // CraftBukkit end + } else { + this.g = LoginListener.EnumProtocolState.ACCEPTED; + if (this.server.aK() >= 0 && !this.networkManager.c()) { +@@ -90,7 +99,7 @@ + LoginListener.this.networkManager.a(LoginListener.this.server.aK()); + } + +- public void operationComplete(Future future) throws Exception { ++ public void operationComplete(ChannelFuture future) throws Exception { // CraftBukkit - fix decompile error + this.a((ChannelFuture) future); + } + }, new GenericFutureListener[0]); +@@ -101,9 +110,9 @@ + + if (entityplayer != null) { + this.g = LoginListener.EnumProtocolState.e; +- this.l = this.server.getPlayerList().processLogin(this.i); ++ this.l = this.server.getPlayerList().processLogin(this.i, s); // CraftBukkit - add player reference + } else { +- this.server.getPlayerList().a(this.networkManager, this.server.getPlayerList().processLogin(this.i)); ++ this.server.getPlayerList().a(this.networkManager, this.server.getPlayerList().processLogin(this.i, s)); // CraftBukkit - add player reference + } + } + +@@ -148,6 +157,43 @@ + + LoginListener.this.i = LoginListener.this.server.aD().hasJoinedServer(new GameProfile((UUID) null, gameprofile.getName()), s); + if (LoginListener.this.i != null) { ++ // CraftBukkit start - fire PlayerPreLoginEvent ++ if (!networkManager.g()) { ++ return; ++ } ++ ++ String playerName = i.getName(); ++ java.net.InetAddress address = ((java.net.InetSocketAddress) networkManager.getSocketAddress()).getAddress(); ++ java.util.UUID uniqueId = i.getId(); ++ final org.bukkit.craftbukkit.CraftServer server = LoginListener.this.server.server; ++ ++ AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId); ++ server.getPluginManager().callEvent(asyncEvent); ++ ++ if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) { ++ final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId); ++ if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) { ++ event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage()); ++ } ++ Waitable waitable = new Waitable() { ++ @Override ++ protected PlayerPreLoginEvent.Result evaluate() { ++ server.getPluginManager().callEvent(event); ++ return event.getResult(); ++ }}; ++ ++ LoginListener.this.server.processQueue.add(waitable); ++ if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED) { ++ disconnect(event.getKickMessage()); ++ return; ++ } ++ } else { ++ if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) { ++ disconnect(asyncEvent.getKickMessage()); ++ return; ++ } ++ } ++ // CraftBukkit end + LoginListener.c.info("UUID of player " + LoginListener.this.i.getName() + " is " + LoginListener.this.i.getId()); + LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; + } else if (LoginListener.this.server.T()) { +@@ -156,7 +202,7 @@ + LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; + } else { + LoginListener.this.disconnect("Failed to verify username!"); +- LoginListener.c.error("Username \'" + LoginListener.this.i.getName() + "\' tried to join with an invalid session"); ++ LoginListener.c.error("Username \'" + gameprofile.getName() + "\' tried to join with an invalid session"); // CraftBukkit - fix null pointer + } + } catch (AuthenticationUnavailableException authenticationunavailableexception) { + if (LoginListener.this.server.T()) { +@@ -167,6 +213,11 @@ + LoginListener.this.disconnect("Authentication servers are down. Please try again later, sorry!"); + LoginListener.c.error("Couldn\'t verify username because servers are unavailable"); + } ++ // CraftBukkit start - catch all exceptions ++ } catch (Exception exception) { ++ disconnect("Failed to verify username!"); ++ server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + gameprofile.getName(), exception); ++ // CraftBukkit end + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/MethodProfiler.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/MethodProfiler.patch new file mode 100644 index 0000000..71b91ba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/MethodProfiler.patch @@ -0,0 +1,145 @@ +--- a/net/minecraft/server/MethodProfiler.java ++++ b/net/minecraft/server/MethodProfiler.java +@@ -10,130 +10,30 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start - Strip down to empty methods, performance cost + public class MethodProfiler { + +- private static final Logger b = LogManager.getLogger(); +- private final List c = Lists.newArrayList(); +- private final List d = Lists.newArrayList(); + public boolean a; +- private String e = ""; +- private final Map f = Maps.newHashMap(); +- + public MethodProfiler() {} + + public void a() { +- this.f.clear(); +- this.e = ""; +- this.c.clear(); + } + + public void a(String s) { +- if (this.a) { +- if (this.e.length() > 0) { +- this.e = this.e + "."; +- } +- +- this.e = this.e + s; +- this.c.add(this.e); +- this.d.add(Long.valueOf(System.nanoTime())); +- } + } + + public void b() { +- if (this.a) { +- long i = System.nanoTime(); +- long j = ((Long) this.d.remove(this.d.size() - 1)).longValue(); +- +- this.c.remove(this.c.size() - 1); +- long k = i - j; +- +- if (this.f.containsKey(this.e)) { +- this.f.put(this.e, Long.valueOf(((Long) this.f.get(this.e)).longValue() + k)); +- } else { +- this.f.put(this.e, Long.valueOf(k)); +- } +- +- if (k > 100000000L) { +- MethodProfiler.b.warn("Something\'s taking too long! \'" + this.e + "\' took aprox " + (double) k / 1000000.0D + " ms"); +- } +- +- this.e = !this.c.isEmpty() ? (String) this.c.get(this.c.size() - 1) : ""; +- } + } + + public List b(String s) { +- if (!this.a) { +- return null; +- } else { +- long i = this.f.containsKey("root") ? ((Long) this.f.get("root")).longValue() : 0L; +- long j = this.f.containsKey(s) ? ((Long) this.f.get(s)).longValue() : -1L; +- ArrayList arraylist = Lists.newArrayList(); +- +- if (s.length() > 0) { +- s = s + "."; +- } +- +- long k = 0L; +- Iterator iterator = this.f.keySet().iterator(); +- +- while (iterator.hasNext()) { +- String s1 = (String) iterator.next(); +- +- if (s1.length() > s.length() && s1.startsWith(s) && s1.indexOf(".", s.length() + 1) < 0) { +- k += ((Long) this.f.get(s1)).longValue(); +- } +- } +- +- float f = (float) k; +- +- if (k < j) { +- k = j; +- } +- +- if (i < k) { +- i = k; +- } +- +- Iterator iterator1 = this.f.keySet().iterator(); +- +- String s2; +- +- while (iterator1.hasNext()) { +- s2 = (String) iterator1.next(); +- if (s2.length() > s.length() && s2.startsWith(s) && s2.indexOf(".", s.length() + 1) < 0) { +- long l = ((Long) this.f.get(s2)).longValue(); +- double d0 = (double) l * 100.0D / (double) k; +- double d1 = (double) l * 100.0D / (double) i; +- String s3 = s2.substring(s.length()); +- +- arraylist.add(new MethodProfiler.ProfilerInfo(s3, d0, d1)); +- } +- } +- +- iterator1 = this.f.keySet().iterator(); +- +- while (iterator1.hasNext()) { +- s2 = (String) iterator1.next(); +- this.f.put(s2, Long.valueOf(((Long) this.f.get(s2)).longValue() * 999L / 1000L)); +- } +- +- if ((float) k > f) { +- arraylist.add(new MethodProfiler.ProfilerInfo("unspecified", (double) ((float) k - f) * 100.0D / (double) k, (double) ((float) k - f) * 100.0D / (double) i)); +- } +- +- Collections.sort(arraylist); +- arraylist.add(0, new MethodProfiler.ProfilerInfo(s, 100.0D, (double) k * 100.0D / (double) i)); +- return arraylist; +- } ++ return null; + } + + public void c(String s) { +- this.b(); +- this.a(s); + } + + public String c() { +- return this.c.size() == 0 ? "[UNKNOWN]" : (String) this.c.get(this.c.size() - 1); ++ return ""; + } + + public static final class ProfilerInfo implements Comparable { +@@ -152,7 +52,7 @@ + return methodprofiler_profilerinfo.a < this.a ? -1 : (methodprofiler_profilerinfo.a > this.a ? 1 : methodprofiler_profilerinfo.c.compareTo(this.c)); + } + +- public int compareTo(Object object) { ++ public int compareTo(MethodProfiler.ProfilerInfo object) { + return this.a((MethodProfiler.ProfilerInfo) object); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/MinecraftServer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/MinecraftServer.patch new file mode 100644 index 0000000..2568fdd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/MinecraftServer.patch @@ -0,0 +1,678 @@ +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -38,6 +38,15 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.io.IOException; ++ ++import jline.console.ConsoleReader; ++import joptsimple.OptionSet; ++ ++import org.bukkit.craftbukkit.Main; ++// CraftBukkit end ++ + public abstract class MinecraftServer implements Runnable, ICommandListener, IAsyncTaskHandler, IMojangStatistics { + + public static final Logger LOGGER = LogManager.getLogger(); +@@ -94,19 +103,61 @@ + private Thread serverThread; + private long ab = az(); + +- public MinecraftServer(File file, Proxy proxy, File file1) { ++ // CraftBukkit start ++ public List worlds = new ArrayList(); ++ public org.bukkit.craftbukkit.CraftServer server; ++ public OptionSet options; ++ public org.bukkit.command.ConsoleCommandSender console; ++ public org.bukkit.command.RemoteConsoleCommandSender remoteConsole; ++ public ConsoleReader reader; ++ public static int currentTick = (int) (System.currentTimeMillis() / 50); ++ public final Thread primaryThread; ++ public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); ++ public int autosavePeriod; ++ // CraftBukkit end ++ ++ public MinecraftServer(OptionSet options, Proxy proxy, File file1) { + this.e = proxy; + MinecraftServer.l = this; +- this.universe = file; ++ // this.universe = file; // CraftBukkit + this.q = new ServerConnection(this); + this.Z = new UserCache(this, file1); + this.b = this.h(); +- this.convertable = new WorldLoaderServer(file); ++ // this.convertable = new WorldLoaderServer(file); // CraftBukkit - moved to DedicatedServer.init + this.V = new YggdrasilAuthenticationService(proxy, UUID.randomUUID().toString()); + this.W = this.V.createMinecraftSessionService(); + this.Y = this.V.createProfileRepository(); ++ // CraftBukkit start ++ this.options = options; ++ // Try to see if we're actually running in a terminal, disable jline if not ++ if (System.console() == null && System.getProperty("jline.terminal") == null) { ++ System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); ++ Main.useJline = false; ++ } ++ ++ try { ++ reader = new ConsoleReader(System.in, System.out); ++ reader.setExpandEvents(false); // Avoid parsing exceptions for uncommonly used event designators ++ } catch (Throwable e) { ++ try { ++ // Try again with jline disabled for Windows users without C++ 2008 Redistributable ++ System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); ++ System.setProperty("user.language", "en"); ++ Main.useJline = false; ++ reader = new ConsoleReader(System.in, System.out); ++ reader.setExpandEvents(false); ++ } catch (IOException ex) { ++ LOGGER.warn((String) null, ex); ++ } ++ } ++ Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this)); ++ ++ this.serverThread = primaryThread = new Thread(this, "Server thread"); // Moved from main + } + ++ public abstract PropertyManager getPropertyManager(); ++ // CraftBukkit end ++ + protected CommandDispatcher h() { + return new CommandDispatcher(); + } +@@ -144,6 +195,7 @@ + this.a(s); + this.b("menu.loadingLevel"); + this.worldServer = new WorldServer[3]; ++ /* CraftBukkit start - Remove ticktime arrays and worldsettings + this.i = new long[this.worldServer.length][100]; + IDataManager idatamanager = this.convertable.a(s, true); + +@@ -167,37 +219,108 @@ + worlddata.a(s1); + worldsettings = new WorldSettings(worlddata); + } ++ */ ++ int worldCount = 3; + +- for (int j = 0; j < this.worldServer.length; ++j) { +- byte b0 = 0; ++ for (int j = 0; j < worldCount; ++j) { ++ WorldServer world; ++ byte dimension = 0; + + if (j == 1) { +- b0 = -1; ++ if (getAllowNether()) { ++ dimension = -1; ++ } else { ++ continue; ++ } + } + + if (j == 2) { +- b0 = 1; ++ if (server.getAllowEnd()) { ++ dimension = 1; ++ } else { ++ continue; ++ } + } + ++ String worldType = org.bukkit.World.Environment.getEnvironment(dimension).toString().toLowerCase(); ++ String name = (dimension == 0) ? s : s + "_" + worldType; ++ ++ org.bukkit.generator.ChunkGenerator gen = this.server.getGenerator(name); ++ WorldSettings worldsettings = new WorldSettings(i, this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype); ++ worldsettings.setGeneratorSettings(s2); ++ + if (j == 0) { ++ IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), s1, true); ++ WorldData worlddata = idatamanager.getWorldData(); ++ if (worlddata == null) { ++ worlddata = new WorldData(worldsettings, s1); ++ } ++ worlddata.checkName(s1); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) + if (this.X()) { +- this.worldServer[j] = (WorldServer) (new DemoWorldServer(this, idatamanager, worlddata, b0, this.methodProfiler)).b(); ++ world = (WorldServer) (new DemoWorldServer(this, idatamanager, worlddata, dimension, this.methodProfiler)).b(); + } else { +- this.worldServer[j] = (WorldServer) (new WorldServer(this, idatamanager, worlddata, b0, this.methodProfiler)).b(); ++ world = (WorldServer) (new WorldServer(this, idatamanager, worlddata, dimension, this.methodProfiler, org.bukkit.World.Environment.getEnvironment(dimension), gen)).b(); + } + +- this.worldServer[j].a(worldsettings); ++ world.a(worldsettings); ++ this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard()); + } else { +- this.worldServer[j] = (WorldServer) (new SecondaryWorldServer(this, idatamanager, b0, this.worldServer[0], this.methodProfiler)).b(); ++ String dim = "DIM" + dimension; ++ ++ File newWorld = new File(new File(name), dim); ++ File oldWorld = new File(new File(s), dim); ++ ++ if ((!newWorld.isDirectory()) && (oldWorld.isDirectory())) { ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder required ----"); ++ MinecraftServer.LOGGER.info("Unfortunately due to the way that Minecraft implemented multiworld support in 1.6, Bukkit requires that you move your " + worldType + " folder to a new location in order to operate correctly."); ++ MinecraftServer.LOGGER.info("We will move this folder for you, but it will mean that you need to move it back should you wish to stop using Bukkit in the future."); ++ MinecraftServer.LOGGER.info("Attempting to move " + oldWorld + " to " + newWorld + "..."); ++ ++ if (newWorld.exists()) { ++ MinecraftServer.LOGGER.warn("A file or folder already exists at " + newWorld + "!"); ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); ++ } else if (newWorld.getParentFile().mkdirs()) { ++ if (oldWorld.renameTo(newWorld)) { ++ MinecraftServer.LOGGER.info("Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld); ++ // Migrate world data too. ++ try { ++ com.google.common.io.Files.copy(new File(new File(s), "level.dat"), new File(new File(name), "level.dat")); ++ } catch (IOException exception) { ++ MinecraftServer.LOGGER.warn("Unable to migrate world data."); ++ } ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder complete ----"); ++ } else { ++ MinecraftServer.LOGGER.warn("Could not move folder " + oldWorld + " to " + newWorld + "!"); ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); ++ } ++ } else { ++ MinecraftServer.LOGGER.warn("Could not create path for " + newWorld + "!"); ++ MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); ++ } ++ } ++ ++ IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), name, true); ++ // world =, b0 to dimension, s1 to name, added Environment and gen ++ WorldData worlddata = idatamanager.getWorldData(); ++ if (worlddata == null) { ++ worlddata = new WorldData(worldsettings, name); ++ } ++ worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) ++ world = (WorldServer) new SecondaryWorldServer(this, idatamanager, dimension, this.worlds.get(0), this.methodProfiler, worlddata, org.bukkit.World.Environment.getEnvironment(dimension), gen).b(); + } + +- this.worldServer[j].addIWorldAccess(new WorldManager(this, this.worldServer[j])); ++ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld())); ++ ++ world.addIWorldAccess(new WorldManager(this, world)); + if (!this.T()) { +- this.worldServer[j].getWorldData().setGameType(this.getGamemode()); ++ world.getWorldData().setGameType(this.getGamemode()); + } ++ ++ worlds.add(world); ++ getPlayerList().setPlayerFileData(worlds.toArray(new WorldServer[worlds.size()])); + } + +- this.v.setPlayerFileData(this.worldServer); ++ // CraftBukkit end + this.a(this.getDifficulty()); + this.k(); + } +@@ -212,25 +335,38 @@ + this.b("menu.generatingTerrain"); + byte b0 = 0; + +- MinecraftServer.LOGGER.info("Preparing start region for level " + b0); +- WorldServer worldserver = this.worldServer[b0]; +- BlockPosition blockposition = worldserver.getSpawn(); +- long j = az(); +- +- for (int k = -192; k <= 192 && this.isRunning(); k += 16) { +- for (int l = -192; l <= 192 && this.isRunning(); l += 16) { +- long i1 = az(); +- +- if (i1 - j > 1000L) { +- this.a_("Preparing spawn area", i * 100 / 625); +- j = i1; +- } ++ // CraftBukkit start - fire WorldLoadEvent and handle whether or not to keep the spawn in memory ++ for (int m = 0; m < worlds.size(); m++) { ++ WorldServer worldserver = this.worlds.get(m); ++ LOGGER.info("Preparing start region for level " + m + " (Seed: " + worldserver.getSeed() + ")"); ++ ++ if (!worldserver.getWorld().getKeepSpawnInMemory()) { ++ continue; ++ } ++ ++ BlockPosition blockposition = worldserver.getSpawn(); ++ long j = az(); ++ i = 0; ++ ++ for (int k = -192; k <= 192 && this.isRunning(); k += 16) { ++ for (int l = -192; l <= 192 && this.isRunning(); l += 16) { ++ long i1 = az(); ++ ++ if (i1 - j > 1000L) { ++ this.a_("Preparing spawn area", i * 100 / 625); ++ j = i1; ++ } + +- ++i; +- worldserver.chunkProviderServer.getChunkAt(blockposition.getX() + k >> 4, blockposition.getZ() + l >> 4); ++ ++i; ++ worldserver.chunkProviderServer.getChunkAt(blockposition.getX() + k >> 4, blockposition.getZ() + l >> 4); ++ } + } + } + ++ for (WorldServer world : this.worlds) { ++ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(world.getWorld())); ++ } ++ // CraftBukkit end + this.s(); + } + +@@ -266,15 +402,19 @@ + protected void s() { + this.f = null; + this.g = 0; ++ ++ this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); // CraftBukkit + } + +- protected void saveChunks(boolean flag) { ++ protected void saveChunks(boolean flag) throws ExceptionWorldConflict { // CraftBukkit - added throws + if (!this.N) { + WorldServer[] aworldserver = this.worldServer; + int i = aworldserver.length; + +- for (int j = 0; j < i; ++j) { +- WorldServer worldserver = aworldserver[j]; ++ // CraftBukkit start ++ for (int j = 0; j < worlds.size(); ++j) { ++ WorldServer worldserver = worlds.get(j); ++ // CraftBukkit end + + if (worldserver != null) { + if (!flag) { +@@ -283,6 +423,7 @@ + + try { + worldserver.save(true, (IProgressUpdate) null); ++ worldserver.saveLevel(); // CraftBukkit + } catch (ExceptionWorldConflict exceptionworldconflict) { + MinecraftServer.LOGGER.warn(exceptionworldconflict.getMessage()); + } +@@ -292,9 +433,25 @@ + } + } + +- protected void stop() { ++ // CraftBukkit start ++ private boolean hasStopped = false; ++ private final Object stopLock = new Object(); ++ // CraftBukkit end ++ ++ public void stop() throws ExceptionWorldConflict { // CraftBukkit - added throws ++ // CraftBukkit start - prevent double stopping on multiple threads ++ synchronized(stopLock) { ++ if (hasStopped) return; ++ hasStopped = true; ++ } ++ // CraftBukkit end + if (!this.N) { + MinecraftServer.LOGGER.info("Stopping server"); ++ // CraftBukkit start ++ if (this.server != null) { ++ this.server.disablePlugins(); ++ } ++ // CraftBukkit end + if (this.aq() != null) { + this.aq().b(); + } +@@ -303,17 +460,20 @@ + MinecraftServer.LOGGER.info("Saving players"); + this.v.savePlayers(); + this.v.u(); ++ try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets + } + + if (this.worldServer != null) { + MinecraftServer.LOGGER.info("Saving worlds"); + this.saveChunks(false); + ++ /* CraftBukkit start - Handled in saveChunks + for (int i = 0; i < this.worldServer.length; ++i) { + WorldServer worldserver = this.worldServer[i]; + + worldserver.saveLevel(); + } ++ // CraftBukkit end */ + } + + if (this.n.d()) { +@@ -354,6 +514,7 @@ + long k = j - this.ab; + + if (k > 2000L && this.ab - this.R >= 15000L) { ++ if (server.getWarnOnOverload()) // CraftBukkit + MinecraftServer.LOGGER.warn("Can\'t keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", new Object[] { Long.valueOf(k), Long.valueOf(k / 50L)}); + k = 2000L; + this.R = this.ab; +@@ -366,11 +527,12 @@ + + i += k; + this.ab = j; +- if (this.worldServer[0].everyoneDeeplySleeping()) { ++ if (this.worlds.get(0).everyoneDeeplySleeping()) { // CraftBukkit + this.A(); + i = 0L; + } else { + while (i > 50L) { ++ MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit + i -= 50L; + this.A(); + } +@@ -408,6 +570,12 @@ + } catch (Throwable throwable1) { + MinecraftServer.LOGGER.error("Exception stopping the server", throwable1); + } finally { ++ // CraftBukkit start - Restore terminal to original settings ++ try { ++ reader.getTerminal().restore(); ++ } catch (Exception ignored) { ++ } ++ // CraftBukkit end + this.z(); + } + +@@ -447,7 +615,7 @@ + + protected void z() {} + +- protected void A() { ++ protected void A() throws ExceptionWorldConflict { // CraftBukkit - added throws + long i = System.nanoTime(); + + ++this.ticks; +@@ -473,7 +641,7 @@ + this.r.b().a(agameprofile); + } + +- if (this.ticks % 900 == 0) { ++ if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit + this.methodProfiler.a("save"); + this.v.savePlayers(); + this.saveChunks(true); +@@ -508,20 +676,40 @@ + + this.methodProfiler.c("levels"); + ++ // CraftBukkit start ++ this.server.getScheduler().mainThreadHeartbeat(this.ticks); ++ ++ // Run tasks that are waiting on processing ++ while (!processQueue.isEmpty()) { ++ processQueue.remove().run(); ++ } ++ ++ org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick(); ++ ++ // Send time updates to everyone, it will get the right time from the world the player is in. ++ if (this.ticks % 20 == 0) { ++ for (int i = 0; i < this.getPlayerList().players.size(); ++i) { ++ EntityPlayer entityplayer = (EntityPlayer) this.getPlayerList().players.get(i); ++ entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean("doDaylightCycle"))); // Add support for per player time ++ } ++ } ++ + int i; + +- for (i = 0; i < this.worldServer.length; ++i) { ++ for (i = 0; i < this.worlds.size(); ++i) { + long j = System.nanoTime(); + +- if (i == 0 || this.getAllowNether()) { +- WorldServer worldserver = this.worldServer[i]; ++ // if (i == 0 || this.getAllowNether()) { ++ WorldServer worldserver = this.worlds.get(i); + + this.methodProfiler.a(worldserver.getWorldData().getName()); ++ /* Drop global time updates + if (this.ticks % 20 == 0) { + this.methodProfiler.a("timeSync"); + this.v.a(new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.worldProvider.getDimension()); + this.methodProfiler.b(); + } ++ // CraftBukkit end */ + + this.methodProfiler.a("tick"); + +@@ -548,9 +736,9 @@ + worldserver.getTracker().updatePlayers(); + this.methodProfiler.b(); + this.methodProfiler.b(); +- } ++ // } // CraftBukkit + +- this.i[i][this.ticks % 100] = System.nanoTime() - j; ++ // this.i[i][this.ticks % 100] = System.nanoTime() - j; // CraftBukkit + } + + this.methodProfiler.c("connection"); +@@ -574,10 +762,11 @@ + this.p.add(iupdateplayerlistbox); + } + +- public static void main(String[] astring) { ++ public static void main(final OptionSet options) { // CraftBukkit - replaces main(String[] astring) + DispenserRegistry.c(); + + try { ++ /* CraftBukkit start - Replace everything + boolean flag = true; + String s = null; + String s1 = "."; +@@ -655,15 +844,38 @@ + dedicatedserver.stop(); + } + }); ++ */ ++ ++ DedicatedServer dedicatedserver = new DedicatedServer(options); ++ ++ if (options.has("port")) { ++ int port = (Integer) options.valueOf("port"); ++ if (port > 0) { ++ dedicatedserver.setPort(port); ++ } ++ } ++ ++ if (options.has("universe")) { ++ dedicatedserver.universe = (File) options.valueOf("universe"); ++ } ++ ++ if (options.has("world")) { ++ dedicatedserver.setWorld((String) options.valueOf("world")); ++ } ++ ++ dedicatedserver.primaryThread.start(); ++ // CraftBukkit end + } catch (Exception exception) { + MinecraftServer.LOGGER.fatal("Failed to start the minecraft server", exception); + } + + } + +- public void D() { ++ public void C() { ++ /* CraftBukkit start - prevent abuse + this.serverThread = new Thread(this, "Server thread"); + this.serverThread.start(); ++ // CraftBukkit end */ + } + + public File d(String s) { +@@ -679,7 +891,14 @@ + } + + public WorldServer getWorldServer(int i) { +- return i == -1 ? this.worldServer[1] : (i == 1 ? this.worldServer[2] : this.worldServer[0]); ++ // CraftBukkit start ++ for (WorldServer world : worlds) { ++ if (world.dimension == i) { ++ return world; ++ } ++ } ++ return worlds.get(0); ++ // CraftBukkit end + } + + public String E() { +@@ -715,7 +934,7 @@ + } + + public boolean isDebugging() { +- return false; ++ return this.getPropertyManager().getBoolean("debug", false); // CraftBukkit - don't hardcode + } + + public void g(String s) { +@@ -730,7 +949,7 @@ + } + + public String getServerModName() { +- return "vanilla"; ++ return server.getName(); // CraftBukkit - cb > vanilla! + } + + public CrashReport b(CrashReport crashreport) { +@@ -759,6 +978,7 @@ + } + + public List tabCompleteCommand(ICommandListener icommandlistener, String s, BlockPosition blockposition) { ++ /* CraftBukkit start - Allow tab-completion of Bukkit commands + ArrayList arraylist = Lists.newArrayList(); + + if (s.startsWith("/")) { +@@ -797,6 +1017,9 @@ + + return arraylist; + } ++ */ ++ return server.tabComplete(icommandlistener, s); ++ // CraftBukkit end + } + + public static MinecraftServer getServer() { +@@ -804,7 +1027,7 @@ + } + + public boolean O() { +- return this.universe != null; ++ return true; // CraftBukkit + } + + public String getName() { +@@ -860,8 +1083,10 @@ + } + + public void a(EnumDifficulty enumdifficulty) { +- for (int i = 0; i < this.worldServer.length; ++i) { +- WorldServer worldserver = this.worldServer[i]; ++ // CraftBukkit start ++ for (int i = 0; i < this.worlds.size(); ++i) { ++ WorldServer worldserver = this.worlds.get(i); ++ // CraftBukkit end + + if (worldserver != null) { + if (worldserver.getWorldData().isHardcore()) { +@@ -903,15 +1128,17 @@ + this.N = true; + this.getConvertable().d(); + +- for (int i = 0; i < this.worldServer.length; ++i) { +- WorldServer worldserver = this.worldServer[i]; +- ++ // CraftBukkit start ++ for (int i = 0; i < this.worlds.size(); ++i) { ++ WorldServer worldserver = this.worlds.get(i); ++ // CraftBukkit end ++ + if (worldserver != null) { + worldserver.saveLevel(); + } + } + +- this.getConvertable().e(this.worldServer[0].getDataManager().g()); ++ this.getConvertable().e(this.worlds.get(0).getDataManager().g()); // CraftBukkit + this.safeShutdown(); + } + +@@ -944,9 +1171,11 @@ + int i = 0; + + if (this.worldServer != null) { +- for (int j = 0; j < this.worldServer.length; ++j) { +- if (this.worldServer[j] != null) { +- WorldServer worldserver = this.worldServer[j]; ++ // CraftBukkit start ++ for (int j = 0; j < this.worlds.size(); ++j) { ++ WorldServer worldserver = this.worlds.get(j); ++ if (worldserver != null) { ++ // CraftBukkit end + WorldData worlddata = worldserver.getWorldData(); + + mojangstatisticsgenerator.a("world[" + i + "][dimension]", Integer.valueOf(worldserver.worldProvider.getDimension())); +@@ -979,7 +1208,7 @@ + public abstract boolean ae(); + + public boolean getOnlineMode() { +- return this.onlineMode; ++ return server.getOnlineMode(); // CraftBukkit + } + + public void setOnlineMode(boolean flag) { +@@ -1051,8 +1280,9 @@ + } + + public void setGamemode(WorldSettings.EnumGamemode worldsettings_enumgamemode) { +- for (int i = 0; i < this.worldServer.length; ++i) { +- getServer().worldServer[i].getWorldData().setGameType(worldsettings_enumgamemode); ++ // CraftBukkit start ++ for (int i = 0; i < this.worlds.size(); ++i) { ++ getServer().worlds.get(i).getWorldData().setGameType(worldsettings_enumgamemode); + } + + } +@@ -1084,7 +1314,7 @@ + } + + public World getWorld() { +- return this.worldServer[0]; ++ return this.worlds.get(0); // CraftBukkit + } + + public Entity f() { +@@ -1155,8 +1385,10 @@ + WorldServer[] aworldserver = this.worldServer; + int i = aworldserver.length; + +- for (int j = 0; j < i; ++j) { +- WorldServer worldserver = aworldserver[j]; ++ // CraftBukkit start ++ for (int j = 0; j < worlds.size(); ++j) { ++ WorldServer worldserver = worlds.get(j); ++ // CraftBukkit end + + if (worldserver != null) { + Entity entity = worldserver.getEntity(uuid); +@@ -1171,7 +1403,7 @@ + } + + public boolean getSendCommandFeedback() { +- return getServer().worldServer[0].getGameRules().getBoolean("sendCommandFeedback"); ++ return getServer().worlds.get(0).getGameRules().getBoolean("sendCommandFeedback"); + } + + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) {} +@@ -1182,7 +1414,7 @@ + + public ListenableFuture a(Callable callable) { + Validate.notNull(callable); +- if (!this.isMainThread() && !this.isStopped()) { ++ if (!this.isMainThread()) { // CraftBukkit && !this.isStopped()) { + ListenableFutureTask listenablefuturetask = ListenableFutureTask.create(callable); + Queue queue = this.j; + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/MobEffectList.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/MobEffectList.patch new file mode 100644 index 0000000..dae68b4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/MobEffectList.patch @@ -0,0 +1,73 @@ +--- a/net/minecraft/server/MobEffectList.java ++++ b/net/minecraft/server/MobEffectList.java +@@ -7,6 +7,11 @@ + import java.util.UUID; + import java.util.Map.Entry; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; ++// CraftBukkit end ++ + public class MobEffectList { + + public static final MobEffectList[] byId = new MobEffectList[32]; +@@ -64,6 +69,7 @@ + } + + this.L = j; ++ org.bukkit.potion.PotionEffectType.registerPotionEffectType(new org.bukkit.craftbukkit.potion.CraftPotionEffectType(this)); // CraftBukkit + } + + public static MobEffectList b(String s) { +@@ -86,11 +92,11 @@ + public void tick(EntityLiving entityliving, int i) { + if (this.id == MobEffectList.REGENERATION.id) { + if (entityliving.getHealth() < entityliving.getMaxHealth()) { +- entityliving.heal(1.0F); ++ entityliving.heal(1.0F, RegainReason.MAGIC_REGEN); // CraftBukkit + } + } else if (this.id == MobEffectList.POISON.id) { + if (entityliving.getHealth() > 1.0F) { +- entityliving.damageEntity(DamageSource.MAGIC, 1.0F); ++ entityliving.damageEntity(CraftEventFactory.POISON, 1.0F); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON + } + } else if (this.id == MobEffectList.WITHER.id) { + entityliving.damageEntity(DamageSource.WITHER, 1.0F); +@@ -98,14 +104,25 @@ + ((EntityHuman) entityliving).applyExhaustion(0.025F * (float) (i + 1)); + } else if (this.id == MobEffectList.SATURATION.id && entityliving instanceof EntityHuman) { + if (!entityliving.world.isClientSide) { +- ((EntityHuman) entityliving).getFoodData().eat(i + 1, 1.0F); ++ // CraftBukkit start ++ EntityHuman entityhuman = (EntityHuman) entityliving; ++ int oldFoodLevel = entityhuman.getFoodData().foodLevel; ++ ++ org.bukkit.event.entity.FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, i + 1 + oldFoodLevel); ++ ++ if (!event.isCancelled()) { ++ entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 1.0F); ++ } ++ ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel)); ++ // CraftBukkit end + } + } else if ((this.id != MobEffectList.HEAL.id || entityliving.bm()) && (this.id != MobEffectList.HARM.id || !entityliving.bm())) { + if (this.id == MobEffectList.HARM.id && !entityliving.bm() || this.id == MobEffectList.HEAL.id && entityliving.bm()) { + entityliving.damageEntity(DamageSource.MAGIC, (float) (6 << i)); + } + } else { +- entityliving.heal((float) Math.max(4 << i, 0)); ++ entityliving.heal((float) Math.max(4 << i, 0), RegainReason.MAGIC); // CraftBukkit + } + + } +@@ -124,7 +141,7 @@ + } + } else { + j = (int) (d0 * (double) (4 << i) + 0.5D); +- entityliving.heal((float) j); ++ entityliving.heal((float) j, RegainReason.MAGIC); // CraftBukkit + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/MobSpawnerAbstract.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/MobSpawnerAbstract.patch new file mode 100644 index 0000000..ccf99ef --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/MobSpawnerAbstract.patch @@ -0,0 +1,50 @@ +--- a/net/minecraft/server/MobSpawnerAbstract.java ++++ b/net/minecraft/server/MobSpawnerAbstract.java +@@ -4,6 +4,8 @@ + import java.util.Iterator; + import java.util.List; + ++import org.bukkit.event.entity.CreatureSpawnEvent; // CraftBukkit ++ + public abstract class MobSpawnerAbstract { + + public int spawnDelay = 20; +@@ -24,6 +26,11 @@ + + public String getMobName() { + if (this.i() == null) { ++ // CraftBukkit start - fix NPE ++ if (this.mobName == null) { ++ this.mobName = "Pig"; ++ } ++ // CraftBukkit end + if (this.mobName != null && this.mobName.equals("Minecart")) { + this.mobName = "MinecartRideable"; + } +@@ -129,7 +136,7 @@ + + entity.f(nbttagcompound); + if (entity.world != null && flag) { +- entity.world.addEntity(entity); ++ entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + } + + NBTTagCompound nbttagcompound1; +@@ -154,7 +161,7 @@ + entity2.f(nbttagcompound2); + entity2.setPositionRotation(entity1.locX, entity1.locY, entity1.locZ, entity1.yaw, entity1.pitch); + if (entity.world != null && flag) { +- entity.world.addEntity(entity2); ++ entity.world.addEntity(entity2, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + } + + entity1.mount(entity2); +@@ -167,7 +174,7 @@ + ((EntityInsentient) entity).prepare(entity.world.E(new BlockPosition(entity)), (GroupDataEntity) null); + } + +- entity.world.addEntity(entity); ++ entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + } + + return entity; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/NBTTagList.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/NBTTagList.patch new file mode 100644 index 0000000..a91a3e3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/NBTTagList.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/NBTTagList.java ++++ b/net/minecraft/server/NBTTagList.java +@@ -40,6 +40,7 @@ + } else { + this.type = datainput.readByte(); + int j = datainput.readInt(); ++ nbtreadlimiter.a(j * 8); // CraftBukkit + + if (this.type == 0 && j > 0) { + throw new RuntimeException("Missing type on ListTag"); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/NameReferencingFileConverter.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/NameReferencingFileConverter.patch new file mode 100644 index 0000000..2d49bf1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/NameReferencingFileConverter.patch @@ -0,0 +1,90 @@ +--- a/net/minecraft/server/NameReferencingFileConverter.java ++++ b/net/minecraft/server/NameReferencingFileConverter.java +@@ -87,8 +87,9 @@ + if (gameprofilebanlist.c().exists()) { + try { + gameprofilebanlist.load(); +- } catch (FileNotFoundException filenotfoundexception) { +- NameReferencingFileConverter.e.warn("Could not load existing file " + gameprofilebanlist.c().getName(), filenotfoundexception); ++ // CraftBukkit start - FileNotFoundException -> IOException, don't print stacetrace ++ } catch (IOException filenotfoundexception) { ++ NameReferencingFileConverter.e.warn("Could not load existing file " + gameprofilebanlist.c().getName()); + } + } + +@@ -145,8 +146,9 @@ + if (ipbanlist.c().exists()) { + try { + ipbanlist.load(); +- } catch (FileNotFoundException filenotfoundexception) { +- NameReferencingFileConverter.e.warn("Could not load existing file " + ipbanlist.c().getName(), filenotfoundexception); ++ // CraftBukkit start - FileNotFoundException -> IOException, don't print stacetrace ++ } catch (IOException filenotfoundexception) { ++ NameReferencingFileConverter.e.warn("Could not load existing file " + ipbanlist.c().getName()); + } + } + +@@ -186,8 +188,9 @@ + if (oplist.c().exists()) { + try { + oplist.load(); +- } catch (FileNotFoundException filenotfoundexception) { +- NameReferencingFileConverter.e.warn("Could not load existing file " + oplist.c().getName(), filenotfoundexception); ++ // CraftBukkit start - FileNotFoundException -> IOException, don't print stacetrace ++ } catch (IOException filenotfoundexception) { ++ NameReferencingFileConverter.e.warn("Could not load existing file " + oplist.c().getName()); + } + } + +@@ -230,8 +233,9 @@ + if (whitelist.c().exists()) { + try { + whitelist.load(); +- } catch (FileNotFoundException filenotfoundexception) { +- NameReferencingFileConverter.e.warn("Could not load existing file " + whitelist.c().getName(), filenotfoundexception); ++ // CraftBukkit start - FileNotFoundException -> IOException, don't print stacetrace ++ } catch (IOException filenotfoundexception) { ++ NameReferencingFileConverter.e.warn("Could not load existing file " + whitelist.c().getName()); + } + } + +@@ -350,6 +354,30 @@ + File file1 = new File(file2, s + ".dat"); + File file3 = new File(file, s1 + ".dat"); + ++ // CraftBukkit start - Use old file name to seed lastKnownName ++ NBTTagCompound root = null; ++ ++ try { ++ root = NBTCompressedStreamTools.a(new java.io.FileInputStream(file1)); ++ } catch (Exception exception) { ++ exception.printStackTrace(); ++ } ++ ++ if (root != null) { ++ if (!root.hasKey("bukkit")) { ++ root.set("bukkit", new NBTTagCompound()); ++ } ++ NBTTagCompound data = root.getCompound("bukkit"); ++ data.setString("lastKnownName", s); ++ ++ try { ++ NBTCompressedStreamTools.a(root, new java.io.FileOutputStream(file2)); ++ } catch (Exception exception) { ++ exception.printStackTrace(); ++ } ++ } ++ // CraftBukkit end ++ + NameReferencingFileConverter.b(file); + if (!file1.renameTo(file3)) { + throw new NameReferencingFileConverter.FileConversionException("Could not convert file for " + s, null); +@@ -467,7 +495,7 @@ + + private static File d(PropertyManager propertymanager) { + String s = propertymanager.getString("level-name", "world"); +- File file = new File(s); ++ File file = new File(MinecraftServer.getServer().server.getWorldContainer(), s); // CraftBukkit - Respect container setting + + return new File(file, "players"); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/NetworkManager.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/NetworkManager.patch new file mode 100644 index 0000000..b41fb16 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/NetworkManager.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/NetworkManager.java ++++ b/net/minecraft/server/NetworkManager.java +@@ -231,7 +231,7 @@ + + public void close(IChatBaseComponent ichatbasecomponent) { + if (this.channel.isOpen()) { +- this.channel.close().awaitUninterruptibly(); ++ this.channel.close(); // We can't wait as this may be called from an event loop. + this.n = ichatbasecomponent; + } + +@@ -308,7 +308,7 @@ + } + } + +- protected void channelRead0(ChannelHandlerContext channelhandlercontext, Object object) throws Exception { ++ protected void channelRead0(ChannelHandlerContext channelhandlercontext, Packet object) throws Exception { // CraftBukkit - fix decompile error + this.a(channelhandlercontext, (Packet) object); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketDataSerializer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketDataSerializer.patch new file mode 100644 index 0000000..c66b7b5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketDataSerializer.patch @@ -0,0 +1,67 @@ +--- a/net/minecraft/server/PacketDataSerializer.java ++++ b/net/minecraft/server/PacketDataSerializer.java +@@ -21,6 +21,8 @@ + import java.nio.charset.Charset; + import java.util.UUID; + ++import org.bukkit.craftbukkit.inventory.CraftItemStack; // CraftBukkit ++ + public class PacketDataSerializer extends ByteBuf { + + private final ByteBuf a; +@@ -68,7 +70,7 @@ + } + + public > T a(Class oclass) { +- return ((Enum[]) oclass.getEnumConstants())[this.e()]; ++ return ((T[]) oclass.getEnumConstants())[this.e()]; // CraftBukkit - fix decompile error + } + + public void a(Enum oenum) { +@@ -142,7 +144,7 @@ + } else { + try { + NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) (new ByteBufOutputStream(this))); +- } catch (IOException ioexception) { ++ } catch (Exception ioexception) { // CraftBukkit - IOException -> Exception + throw new EncoderException(ioexception); + } + } +@@ -162,7 +164,7 @@ + } + + public void a(ItemStack itemstack) { +- if (itemstack == null) { ++ if (itemstack == null || itemstack.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem() + this.writeShort(-1); + } else { + this.writeShort(Item.getId(itemstack.getItem())); +@@ -189,6 +191,11 @@ + + itemstack = new ItemStack(Item.getById(short0), b0, short1); + itemstack.setTag(this.h()); ++ // CraftBukkit start ++ if (itemstack.getTag() != null) { ++ CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); ++ } ++ // CraftBukkit end + } + + return itemstack; +@@ -803,16 +810,4 @@ + public boolean release(int i) { + return this.a.release(i); + } +- +- public ReferenceCounted retain(int i) { +- return this.retain(i); +- } +- +- public ReferenceCounted retain() { +- return this.retain(); +- } +- +- public int compareTo(Object object) { +- return this.compareTo((ByteBuf) object); +- } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInBlockPlace.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInBlockPlace.patch new file mode 100644 index 0000000..c008192 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInBlockPlace.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/server/PacketPlayInBlockPlace.java ++++ b/net/minecraft/server/PacketPlayInBlockPlace.java +@@ -12,6 +12,8 @@ + private float f; + private float g; + ++ public long timestamp; // CraftBukkit ++ + public PacketPlayInBlockPlace() {} + + public PacketPlayInBlockPlace(ItemStack itemstack) { +@@ -28,6 +30,7 @@ + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { ++ timestamp = System.currentTimeMillis(); // CraftBukkit + this.b = packetdataserializer.c(); + this.c = packetdataserializer.readUnsignedByte(); + this.d = packetdataserializer.i(); +@@ -72,8 +75,4 @@ + public float f() { + return this.g; + } +- +- public void a(PacketListener packetlistener) { +- this.a((PacketListenerPlayIn) packetlistener); +- } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInCloseWindow.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInCloseWindow.patch new file mode 100644 index 0000000..b7678c6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInCloseWindow.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/server/PacketPlayInCloseWindow.java ++++ b/net/minecraft/server/PacketPlayInCloseWindow.java +@@ -8,6 +8,12 @@ + + public PacketPlayInCloseWindow() {} + ++ // CraftBukkit start ++ public PacketPlayInCloseWindow(int id) { ++ this.id = id; ++ } ++ // CraftBukkit end ++ + public void a(PacketListenerPlayIn packetlistenerplayin) { + packetlistenerplayin.a(this); + } +@@ -19,8 +25,4 @@ + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.writeByte(this.id); + } +- +- public void a(PacketListener packetlistener) { +- this.a((PacketListenerPlayIn) packetlistener); +- } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInResourcePackStatus.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInResourcePackStatus.patch new file mode 100644 index 0000000..b6bbd0d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketPlayInResourcePackStatus.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/server/PacketPlayInResourcePackStatus.java ++++ b/net/minecraft/server/PacketPlayInResourcePackStatus.java +@@ -5,7 +5,7 @@ + public class PacketPlayInResourcePackStatus implements Packet { + + private String a; +- private PacketPlayInResourcePackStatus.EnumResourcePackStatus b; ++ public PacketPlayInResourcePackStatus.EnumResourcePackStatus b; // PAIL: private -> public, rename: status + + public PacketPlayInResourcePackStatus() {} + +@@ -23,10 +23,6 @@ + packetlistenerplayin.a(this); + } + +- public void a(PacketListener packetlistener) { +- this.a((PacketListenerPlayIn) packetlistener); +- } +- + public static enum EnumResourcePackStatus { + + SUCCESSFULLY_LOADED, DECLINED, FAILED_DOWNLOAD, ACCEPTED; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketStatusListener.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketStatusListener.patch new file mode 100644 index 0000000..075488f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PacketStatusListener.patch @@ -0,0 +1,119 @@ +--- a/net/minecraft/server/PacketStatusListener.java ++++ b/net/minecraft/server/PacketStatusListener.java +@@ -1,5 +1,16 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import com.mojang.authlib.GameProfile; ++import io.netty.channel.ChannelFutureListener; ++import java.net.InetSocketAddress; ++import java.util.Iterator; ++ ++import org.bukkit.craftbukkit.util.CraftIconCache; ++import org.bukkit.entity.Player; ++ ++// CraftBukkit end ++ + public class PacketStatusListener implements PacketStatusInListener { + + private static final IChatBaseComponent a = new ChatComponentText("Status request has been handled."); +@@ -17,10 +28,96 @@ + public void a(PacketStatusInStart packetstatusinstart) { + if (this.d) { + this.networkManager.close(PacketStatusListener.a); +- } else { +- this.d = true; +- this.networkManager.handle(new PacketStatusOutServerInfo(this.minecraftServer.aG())); ++ // CraftBukkit start - fire ping event ++ return; ++ } ++ this.d = true; ++ // this.networkManager.handle(new PacketStatusOutServerInfo(this.minecraftServer.aG())); ++ final Object[] players = minecraftServer.getPlayerList().players.toArray(); ++ class ServerListPingEvent extends org.bukkit.event.server.ServerListPingEvent { ++ CraftIconCache icon = minecraftServer.server.getServerIcon(); ++ ++ ServerListPingEvent() { ++ super(((InetSocketAddress) networkManager.getSocketAddress()).getAddress(), minecraftServer.getMotd(), minecraftServer.getPlayerList().getMaxPlayers()); ++ } ++ ++ @Override ++ public void setServerIcon(org.bukkit.util.CachedServerIcon icon) { ++ if (!(icon instanceof CraftIconCache)) { ++ throw new IllegalArgumentException(icon + " was not created by " + org.bukkit.craftbukkit.CraftServer.class); ++ } ++ this.icon = (CraftIconCache) icon; ++ } ++ ++ @Override ++ public Iterator iterator() throws UnsupportedOperationException { ++ return new Iterator() { ++ int i; ++ int ret = Integer.MIN_VALUE; ++ EntityPlayer player; ++ ++ @Override ++ public boolean hasNext() { ++ if (player != null) { ++ return true; ++ } ++ final Object[] currentPlayers = players; ++ for (int length = currentPlayers.length, i = this.i; i < length; i++) { ++ final EntityPlayer player = (EntityPlayer) currentPlayers[i]; ++ if (player != null) { ++ this.i = i + 1; ++ this.player = player; ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ @Override ++ public Player next() { ++ if (!hasNext()) { ++ throw new java.util.NoSuchElementException(); ++ } ++ final EntityPlayer player = this.player; ++ this.player = null; ++ this.ret = this.i - 1; ++ return player.getBukkitEntity(); ++ } ++ ++ @Override ++ public void remove() { ++ final Object[] currentPlayers = players; ++ final int i = this.ret; ++ if (i < 0 || currentPlayers[i] == null) { ++ throw new IllegalStateException(); ++ } ++ currentPlayers[i] = null; ++ } ++ }; ++ } ++ } ++ ++ ServerListPingEvent event = new ServerListPingEvent(); ++ this.minecraftServer.server.getPluginManager().callEvent(event); ++ ++ java.util.List profiles = new java.util.ArrayList(players.length); ++ for (Object player : players) { ++ if (player != null) { ++ profiles.add(((EntityPlayer) player).getProfile()); ++ } + } ++ ++ ServerPing.ServerPingPlayerSample playerSample = new ServerPing.ServerPingPlayerSample(event.getMaxPlayers(), profiles.size()); ++ playerSample.a(profiles.toArray(new GameProfile[profiles.size()])); ++ ++ ServerPing ping = new ServerPing(); ++ ping.setFavicon(event.icon.value); ++ ping.setMOTD(new ChatComponentText(event.getMotd())); ++ ping.setPlayerSample(playerSample); ++ ping.setServerInfo(new ServerPing.ServerData(minecraftServer.getServerModName() + " " + minecraftServer.getVersion(), 47)); // TODO: Update when protocol changes ++ ++ this.networkManager.handle(new PacketStatusOutServerInfo(ping)); ++ // CraftBukkit end + } + + public void a(PacketStatusInPing packetstatusinping) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Path.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Path.patch new file mode 100644 index 0000000..caa5459 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Path.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/Path.java ++++ b/net/minecraft/server/Path.java +@@ -2,7 +2,7 @@ + + public class Path { + +- private PathPoint[] a = new PathPoint[1024]; ++ private PathPoint[] a = new PathPoint[128]; // CraftBukkit - reduce default size + private int b; + + public Path() {} diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalBreakDoor.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalBreakDoor.patch new file mode 100644 index 0000000..3f61dbe --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalBreakDoor.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/server/PathfinderGoalBreakDoor.java ++++ b/net/minecraft/server/PathfinderGoalBreakDoor.java +@@ -63,6 +63,12 @@ + } + + if (this.g == 240 && this.a.world.getDifficulty() == EnumDifficulty.HARD) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreakDoorEvent(this.a, this.b.getX(), this.b.getY(), this.b.getZ()).isCancelled()) { ++ this.c(); ++ return; ++ } ++ // CraftBukkit end + this.a.world.setAir(this.b); + this.a.world.triggerEffect(1012, this.b, 0); + this.a.world.triggerEffect(2001, this.b, Block.getId(this.c)); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalBreed.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalBreed.patch new file mode 100644 index 0000000..3ae9587 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalBreed.patch @@ -0,0 +1,23 @@ +--- a/net/minecraft/server/PathfinderGoalBreed.java ++++ b/net/minecraft/server/PathfinderGoalBreed.java +@@ -70,6 +70,11 @@ + EntityAgeable entityageable = this.d.createChild(this.e); + + if (entityageable != null) { ++ // CraftBukkit start - set persistence for tame animals ++ if (entityageable instanceof EntityTameableAnimal && ((EntityTameableAnimal) entityageable).isTamed()) { ++ entityageable.persistent = true; ++ } ++ // CraftBukkit end + EntityHuman entityhuman = this.d.cq(); + + if (entityhuman == null && this.e.cq() != null) { +@@ -89,7 +94,7 @@ + this.e.cs(); + entityageable.setAgeRaw(-24000); + entityageable.setPositionRotation(this.d.locX, this.d.locY, this.d.locZ, 0.0F, 0.0F); +- this.a.addEntity(entityageable); ++ this.a.addEntity(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + Random random = this.d.bc(); + + for (int i = 0; i < 7; ++i) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalDefendVillage.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalDefendVillage.patch new file mode 100644 index 0000000..ab0ddc4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalDefendVillage.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/PathfinderGoalDefendVillage.java ++++ b/net/minecraft/server/PathfinderGoalDefendVillage.java +@@ -34,7 +34,7 @@ + } + + public void c() { +- this.a.setGoalTarget(this.b); ++ this.a.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.DEFEND_VILLAGE, true); // CraftBukkit - reason + super.c(); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalEatTile.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalEatTile.patch new file mode 100644 index 0000000..f3d98e5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalEatTile.patch @@ -0,0 +1,34 @@ +--- a/net/minecraft/server/PathfinderGoalEatTile.java ++++ b/net/minecraft/server/PathfinderGoalEatTile.java +@@ -3,6 +3,11 @@ + import com.google.common.base.Predicate; + import com.google.common.base.Predicates; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.Material; ++// CraftBukkit end ++ + public class PathfinderGoalEatTile extends PathfinderGoal { + + private static final Predicate b = BlockStatePredicate.a((Block) Blocks.TALLGRASS).a(BlockLongGrass.TYPE, Predicates.equalTo(BlockLongGrass.EnumTallGrassType.GRASS)); +@@ -50,7 +55,8 @@ + BlockPosition blockposition = new BlockPosition(this.c.locX, this.c.locY, this.c.locZ); + + if (PathfinderGoalEatTile.b.apply(this.d.getType(blockposition))) { +- if (this.d.getGameRules().getBoolean("mobGriefing")) { ++ // CraftBukkit ++ if (!CraftEventFactory.callEntityChangeBlockEvent(this.c, this.c.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), Material.AIR, !this.d.getGameRules().getBoolean("mobGriefing")).isCancelled()) { + this.d.setAir(blockposition, false); + } + +@@ -59,7 +65,8 @@ + BlockPosition blockposition1 = blockposition.down(); + + if (this.d.getType(blockposition1).getBlock() == Blocks.GRASS) { +- if (this.d.getGameRules().getBoolean("mobGriefing")) { ++ // CraftBukkit ++ if (!CraftEventFactory.callEntityChangeBlockEvent(this.c, this.c.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), Material.AIR, !this.d.getGameRules().getBoolean("mobGriefing")).isCancelled()) { + this.d.triggerEffect(2001, blockposition1, Block.getId(Blocks.GRASS)); + this.d.setTypeAndData(blockposition1, Blocks.DIRT.getBlockData(), 2); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalHurtByTarget.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalHurtByTarget.patch new file mode 100644 index 0000000..e385566 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalHurtByTarget.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/server/PathfinderGoalHurtByTarget.java ++++ b/net/minecraft/server/PathfinderGoalHurtByTarget.java +@@ -23,7 +23,7 @@ + } + + public void c() { +- this.e.setGoalTarget(this.e.getLastDamager()); ++ this.e.setGoalTarget(this.e.getLastDamager(), org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - reason + this.b = this.e.be(); + if (this.a) { + double d0 = this.f(); +@@ -58,6 +58,6 @@ + } + + protected void a(EntityCreature entitycreature, EntityLiving entityliving) { +- entitycreature.setGoalTarget(entityliving); ++ entitycreature.setGoalTarget(entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true); // CraftBukkit - reason + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalMakeLove.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalMakeLove.patch new file mode 100644 index 0000000..2673a6b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalMakeLove.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/PathfinderGoalMakeLove.java ++++ b/net/minecraft/server/PathfinderGoalMakeLove.java +@@ -87,7 +87,7 @@ + this.b.o(false); + entityvillager.setAgeRaw(-24000); + entityvillager.setPositionRotation(this.b.locX, this.b.locY, this.b.locZ, 0.0F, 0.0F); +- this.d.addEntity(entityvillager); ++ this.d.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + this.d.broadcastEntityEffect(entityvillager, (byte) 12); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalNearestAttackableTarget.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalNearestAttackableTarget.patch new file mode 100644 index 0000000..860671e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalNearestAttackableTarget.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java ++++ b/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java +@@ -60,7 +60,7 @@ + } + + public boolean apply(Object object) { +- return this.a((EntityLiving) object); ++ return this.a((T) object); // CraftBukkit - fix decompile error + } + }; + } +@@ -83,7 +83,7 @@ + } + + public void c() { +- this.e.setGoalTarget(this.d); ++ this.e.setGoalTarget(this.d, d instanceof EntityPlayer ? org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER : org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // Craftbukkit - reason + super.c(); + } + +@@ -102,7 +102,7 @@ + return d0 < d1 ? -1 : (d0 > d1 ? 1 : 0); + } + +- public int compare(Object object, Object object1) { ++ public int compare(Entity object, Entity object1) { // CraftBukkit - fix decompile error + return this.a((Entity) object, (Entity) object1); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalNearestAttackableTargetInsentient.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalNearestAttackableTargetInsentient.patch new file mode 100644 index 0000000..624e0c1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalNearestAttackableTargetInsentient.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/PathfinderGoalNearestAttackableTargetInsentient.java ++++ b/net/minecraft/server/PathfinderGoalNearestAttackableTargetInsentient.java +@@ -68,7 +68,7 @@ + } + + public void c() { +- this.b.setGoalTarget(this.e); ++ this.b.setGoalTarget(this.e, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // CraftBukkit - reason + super.c(); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalOwnerHurtByTarget.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalOwnerHurtByTarget.patch new file mode 100644 index 0000000..5d62045 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalOwnerHurtByTarget.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java ++++ b/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java +@@ -30,7 +30,7 @@ + } + + public void c() { +- this.e.setGoalTarget(this.b); ++ this.e.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_OWNER, true); // CraftBukkit - reason + EntityLiving entityliving = this.a.getOwner(); + + if (entityliving != null) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalOwnerHurtTarget.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalOwnerHurtTarget.patch new file mode 100644 index 0000000..a837933 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalOwnerHurtTarget.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java ++++ b/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java +@@ -30,7 +30,7 @@ + } + + public void c() { +- this.e.setGoalTarget(this.b); ++ this.e.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET, true); // CraftBukkit - reason + EntityLiving entityliving = this.a.getOwner(); + + if (entityliving != null) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalPanic.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalPanic.patch new file mode 100644 index 0000000..8725c76 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalPanic.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/server/PathfinderGoalPanic.java ++++ b/net/minecraft/server/PathfinderGoalPanic.java +@@ -36,6 +36,12 @@ + } + + public boolean b() { ++ // CraftBukkit start - introduce a temporary timeout hack until this is fixed properly ++ if ((this.b.ticksLived - this.b.hurtTimestamp) > 100) { ++ this.b.b((EntityLiving) null); ++ return false; ++ } ++ // CraftBukkit end + return !this.b.getNavigation().m(); + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalSelector.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalSelector.patch new file mode 100644 index 0000000..27aa230 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalSelector.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/server/PathfinderGoalSelector.java ++++ b/net/minecraft/server/PathfinderGoalSelector.java +@@ -6,11 +6,13 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import org.bukkit.craftbukkit.util.UnsafeList; // CraftBukkit ++ + public class PathfinderGoalSelector { + + private static final Logger a = LogManager.getLogger(); +- private List b = Lists.newArrayList(); +- private List c = Lists.newArrayList(); ++ private List b = new UnsafeList(); ++ private List c = new UnsafeList(); + private final MethodProfiler d; + private int e; + private int f = 3; +@@ -107,9 +109,11 @@ + if (pathfindergoalselector_pathfindergoalselectoritem1 != pathfindergoalselector_pathfindergoalselectoritem) { + if (pathfindergoalselector_pathfindergoalselectoritem.b >= pathfindergoalselector_pathfindergoalselectoritem1.b) { + if (!this.a(pathfindergoalselector_pathfindergoalselectoritem, pathfindergoalselector_pathfindergoalselectoritem1) && this.c.contains(pathfindergoalselector_pathfindergoalselectoritem1)) { ++ ((UnsafeList.Itr) iterator).valid = false; // CraftBukkit - mark iterator for reuse + return false; + } + } else if (!pathfindergoalselector_pathfindergoalselectoritem1.a.i() && this.c.contains(pathfindergoalselector_pathfindergoalselectoritem1)) { ++ ((UnsafeList.Itr) iterator).valid = false; // CraftBukkit - mark iterator for reuse + return false; + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalSit.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalSit.patch new file mode 100644 index 0000000..e6ee998 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalSit.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/PathfinderGoalSit.java ++++ b/net/minecraft/server/PathfinderGoalSit.java +@@ -12,7 +12,7 @@ + + public boolean a() { + if (!this.entity.isTamed()) { +- return false; ++ return this.willSit && this.entity.getGoalTarget() == null; // CraftBukkit - Allow sitting for wild animals + } else if (this.entity.V()) { + return false; + } else if (!this.entity.onGround) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalTame.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalTame.patch new file mode 100644 index 0000000..2d4f3e9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalTame.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/server/PathfinderGoalTame.java ++++ b/net/minecraft/server/PathfinderGoalTame.java +@@ -45,7 +45,8 @@ + int i = this.entity.getTemper(); + int j = this.entity.getMaxDomestication(); + +- if (j > 0 && this.entity.bc().nextInt(j) < i) { ++ // CraftBukkit - fire EntityTameEvent ++ if (j > 0 && this.entity.bc().nextInt(j) < i && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this.entity, (EntityHuman) this.entity.passenger).isCancelled() && this.entity.passenger instanceof EntityHuman) { + this.entity.h((EntityHuman) this.entity.passenger); + this.entity.world.broadcastEntityEffect(this.entity, (byte) 7); + return; +@@ -54,8 +55,16 @@ + this.entity.u(5); + } + +- this.entity.passenger.mount((Entity) null); +- this.entity.passenger = null; ++ // CraftBukkit start - Handle dismounting to account for VehicleExitEvent being fired. ++ if (this.entity.passenger != null) { ++ this.entity.passenger.mount((Entity) null); ++ // If the entity still has a passenger, then a plugin cancelled the event. ++ if (this.entity.passenger != null) { ++ return; ++ } ++ } ++ // this.entity.passenger = null; ++ // CraftBukkit end + this.entity.cW(); + this.entity.world.broadcastEntityEffect(this.entity, (byte) 6); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalTargetNearestPlayer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalTargetNearestPlayer.patch new file mode 100644 index 0000000..1bdfde6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PathfinderGoalTargetNearestPlayer.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/PathfinderGoalTargetNearestPlayer.java ++++ b/net/minecraft/server/PathfinderGoalTargetNearestPlayer.java +@@ -91,7 +91,7 @@ + } + + public void c() { +- this.b.setGoalTarget(this.e); ++ this.b.setGoalTarget(this.e, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit - added reason + super.c(); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerChunkMap.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerChunkMap.patch new file mode 100644 index 0000000..1c9ec1d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerChunkMap.patch @@ -0,0 +1,271 @@ +--- a/net/minecraft/server/PlayerChunkMap.java ++++ b/net/minecraft/server/PlayerChunkMap.java +@@ -7,17 +7,26 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.util.Collections; ++import java.util.Queue; ++import java.util.LinkedList; ++import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; ++import java.util.HashMap; ++// CraftBukkit end ++ + public class PlayerChunkMap { + + private static final Logger a = LogManager.getLogger(); + private final WorldServer world; + private final List managedPlayers = Lists.newArrayList(); + private final LongHashMap d = new LongHashMap(); +- private final List e = Lists.newArrayList(); +- private final List f = Lists.newArrayList(); ++ private final Queue e = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue ++ private final Queue f = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue + private int g; + private long h; + private final int[][] i = new int[][] { { 1, 0}, { 0, 1}, { -1, 0}, { 0, -1}}; ++ private boolean wasNotEmpty; // CraftBukkit - add field + + public PlayerChunkMap(WorldServer worldserver) { + this.world = worldserver; +@@ -36,26 +45,37 @@ + if (i - this.h > 8000L) { + this.h = i; + +- for (j = 0; j < this.f.size(); ++j) { +- playerchunkmap_playerchunk = (PlayerChunkMap.PlayerChunk) this.f.get(j); ++ // CraftBukkit start - Use iterator ++ java.util.Iterator iterator = this.f.iterator(); ++ while (iterator.hasNext()) { ++ playerchunkmap_playerchunk = (PlayerChunk) iterator.next(); + playerchunkmap_playerchunk.b(); + playerchunkmap_playerchunk.a(); + } + } else { +- for (j = 0; j < this.e.size(); ++j) { +- playerchunkmap_playerchunk = (PlayerChunkMap.PlayerChunk) this.e.get(j); ++ java.util.Iterator iterator = this.e.iterator(); ++ while (iterator.hasNext()) { ++ playerchunkmap_playerchunk = (PlayerChunk) iterator.next(); + playerchunkmap_playerchunk.b(); ++ iterator.remove(); ++ // CraftBukkit end + } + } + +- this.e.clear(); ++ // this.e.clear(); //CraftBukkit - Removals are already covered + if (this.managedPlayers.isEmpty()) { ++ if (!wasNotEmpty) return; // CraftBukkit - Only do unload when we go from non-empty to empty + WorldProvider worldprovider = this.world.worldProvider; + + if (!worldprovider.e()) { + this.world.chunkProviderServer.b(); + } ++ // CraftBukkit start ++ wasNotEmpty = false; ++ } else { ++ wasNotEmpty = true; + } ++ // CraftBukkit end + + } + +@@ -78,6 +98,16 @@ + return playerchunkmap_playerchunk; + } + ++ // CraftBukkit start - add method ++ public final boolean isChunkInUse(int x, int z) { ++ PlayerChunk pi = a(x, z, false); ++ if (pi != null) { ++ return (pi.b.size() > 0); ++ } ++ return false; ++ } ++ // CraftBukkit end ++ + public void flagDirty(BlockPosition blockposition) { + int i = blockposition.getX() >> 4; + int j = blockposition.getZ() >> 4; +@@ -96,11 +126,20 @@ + entityplayer.d = entityplayer.locX; + entityplayer.e = entityplayer.locZ; + ++ // CraftBukkit start - Load nearby chunks first ++ List chunkList = new LinkedList(); ++ + for (int k = i - this.g; k <= i + this.g; ++k) { + for (int l = j - this.g; l <= j + this.g; ++l) { +- this.a(k, l, true).a(entityplayer); ++ chunkList.add(new ChunkCoordIntPair(k, l)); + } + } ++ ++ Collections.sort(chunkList, new ChunkCoordComparator(entityplayer)); ++ for (ChunkCoordIntPair pair : chunkList) { ++ this.a(pair.x, pair.z, true).a(entityplayer); ++ } ++ // CraftBukkit end + + this.managedPlayers.add(entityplayer); + this.b(entityplayer); +@@ -188,12 +227,13 @@ + int i1 = this.g; + int j1 = i - k; + int k1 = j - l; ++ List chunksToLoad = new LinkedList(); // CraftBukkit + + if (j1 != 0 || k1 != 0) { + for (int l1 = i - i1; l1 <= i + i1; ++l1) { + for (int i2 = j - i1; i2 <= j + i1; ++i2) { + if (!this.a(l1, i2, k, l, i1)) { +- this.a(l1, i2, true).a(entityplayer); ++ chunksToLoad.add(new ChunkCoordIntPair(l1, i2)); // CraftBukkit + } + + if (!this.a(l1 - j1, i2 - k1, i, j, i1)) { +@@ -209,6 +249,17 @@ + this.b(entityplayer); + entityplayer.d = entityplayer.locX; + entityplayer.e = entityplayer.locZ; ++ ++ // CraftBukkit start - send nearest chunks first ++ Collections.sort(chunksToLoad, new ChunkCoordComparator(entityplayer)); ++ for (ChunkCoordIntPair pair : chunksToLoad) { ++ this.a(pair.x, pair.z, true).a(entityplayer); ++ } ++ ++ if (j1 > 1 || j1 < -1 || k1 > 1 || k1 < -1) { ++ Collections.sort(entityplayer.chunkCoordIntPairQueue, new ChunkCoordComparator(entityplayer)); ++ } ++ // CraftBukkit end + } + } + } +@@ -271,12 +322,22 @@ + private int f; + private long g; + ++ // CraftBukkit start - add fields ++ private final HashMap players = new HashMap(); ++ private boolean loaded = false; ++ private Runnable loadedRunnable = new Runnable() { ++ public void run() { ++ PlayerChunk.this.loaded = true; ++ } ++ }; ++ // CraftBukkit end ++ + public PlayerChunk(int i, int j) { + this.location = new ChunkCoordIntPair(i, j); +- PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(i, j); ++ PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(i, j, loadedRunnable); // CraftBukkit + } + +- public void a(EntityPlayer entityplayer) { ++ public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument + if (this.b.contains(entityplayer)) { + PlayerChunkMap.a.debug("Failed to add player. {} already is in chunk {}, {}", new Object[] { entityplayer, Integer.valueOf(this.location.x), Integer.valueOf(this.location.z)}); + } else { +@@ -285,18 +346,50 @@ + } + + this.b.add(entityplayer); +- entityplayer.chunkCoordIntPairQueue.add(this.location); ++ // CraftBukkit start - use async chunk io ++ Runnable playerRunnable; ++ if (this.loaded) { ++ playerRunnable = null; ++ entityplayer.chunkCoordIntPairQueue.add(this.location); ++ } else { ++ playerRunnable = new Runnable() { ++ public void run() { ++ entityplayer.chunkCoordIntPairQueue.add(PlayerChunk.this.location); ++ } ++ }; ++ PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(this.location.x, this.location.z, playerRunnable); ++ } ++ ++ this.players.put(entityplayer, playerRunnable); ++ // CraftBukkit end + } + } + + public void b(EntityPlayer entityplayer) { + if (this.b.contains(entityplayer)) { ++ // CraftBukkit start - If we haven't loaded yet don't load the chunk just so we can clean it up ++ if (!this.loaded) { ++ ChunkIOExecutor.dropQueuedChunkLoad(PlayerChunkMap.this.a(), this.location.x, this.location.z, this.players.get(entityplayer)); ++ this.b.remove(entityplayer); ++ this.players.remove(entityplayer); ++ ++ if (this.b.isEmpty()) { ++ ChunkIOExecutor.dropQueuedChunkLoad(PlayerChunkMap.this.a(), this.location.x, this.location.z, this.loadedRunnable); ++ long i = (long) this.location.x + 2147483647L | (long) this.location.z + 2147483647L << 32; ++ PlayerChunkMap.this.d.remove(i); ++ PlayerChunkMap.this.f.remove(this); ++ } ++ ++ return; ++ } ++ // CraftBukkit end + Chunk chunk = PlayerChunkMap.this.world.getChunkAt(this.location.x, this.location.z); + + if (chunk.isReady()) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(chunk, true, 0)); + } + ++ this.players.remove(entityplayer); // CraftBukkit + this.b.remove(entityplayer); + entityplayer.chunkCoordIntPairQueue.remove(this.location); + if (this.b.isEmpty()) { +@@ -421,4 +514,47 @@ + + } + } ++ ++ // CraftBukkit start - Sorter to load nearby chunks first ++ private static class ChunkCoordComparator implements java.util.Comparator { ++ private int x; ++ private int z; ++ ++ public ChunkCoordComparator (EntityPlayer entityplayer) { ++ x = (int) entityplayer.locX >> 4; ++ z = (int) entityplayer.locZ >> 4; ++ } ++ ++ public int compare(ChunkCoordIntPair a, ChunkCoordIntPair b) { ++ if (a.equals(b)) { ++ return 0; ++ } ++ ++ // Subtract current position to set center point ++ int ax = a.x - this.x; ++ int az = a.z - this.z; ++ int bx = b.x - this.x; ++ int bz = b.z - this.z; ++ ++ int result = ((ax - bx) * (ax + bx)) + ((az - bz) * (az + bz)); ++ if (result != 0) { ++ return result; ++ } ++ ++ if (ax < 0) { ++ if (bx < 0) { ++ return bz - az; ++ } else { ++ return -1; ++ } ++ } else { ++ if (bx < 0) { ++ return 1; ++ } else { ++ return az - bz; ++ } ++ } ++ } ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerConnection.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerConnection.patch new file mode 100644 index 0000000..a1f3b52 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerConnection.patch @@ -0,0 +1,1540 @@ +--- a/net/minecraft/server/PlayerConnection.java ++++ b/net/minecraft/server/PlayerConnection.java +@@ -19,6 +19,49 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.util.concurrent.ExecutionException; ++import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; ++import java.util.HashSet; ++ ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.util.CraftChatMessage; ++import org.bukkit.craftbukkit.util.LazyPlayerSet; ++import org.bukkit.craftbukkit.util.Waitable; ++ ++import org.bukkit.Location; ++import org.bukkit.entity.Player; ++import org.bukkit.event.Event; ++import org.bukkit.event.block.Action; ++import org.bukkit.event.block.SignChangeEvent; ++import org.bukkit.event.inventory.ClickType; ++import org.bukkit.event.inventory.CraftItemEvent; ++import org.bukkit.event.inventory.InventoryAction; ++import org.bukkit.event.inventory.InventoryClickEvent; ++import org.bukkit.event.inventory.InventoryCreativeEvent; ++import org.bukkit.event.inventory.InventoryType.SlotType; ++import org.bukkit.event.player.AsyncPlayerChatEvent; ++import org.bukkit.event.player.PlayerAnimationEvent; ++import org.bukkit.event.player.PlayerChatEvent; ++import org.bukkit.event.player.PlayerCommandPreprocessEvent; ++import org.bukkit.event.player.PlayerInteractEntityEvent; ++import org.bukkit.event.player.PlayerInteractAtEntityEvent; ++import org.bukkit.event.player.PlayerItemHeldEvent; ++import org.bukkit.event.player.PlayerKickEvent; ++import org.bukkit.event.player.PlayerMoveEvent; ++import org.bukkit.event.player.PlayerResourcePackStatusEvent; ++import org.bukkit.event.player.PlayerTeleportEvent; ++import org.bukkit.event.player.PlayerToggleFlightEvent; ++import org.bukkit.event.player.PlayerToggleSneakEvent; ++import org.bukkit.event.player.PlayerToggleSprintEvent; ++import org.bukkit.inventory.CraftingInventory; ++import org.bukkit.inventory.InventoryView; ++import org.bukkit.util.NumberConversions; ++// CraftBukkit end ++ + public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerListBox { + + private static final Logger c = LogManager.getLogger(); +@@ -32,13 +75,17 @@ + private int i; + private long j; + private long k; +- private int chatThrottle; ++ // CraftBukkit start - multithreaded fields ++ private volatile int chatThrottle; ++ private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(PlayerConnection.class, "chatThrottle"); ++ // CraftBukkit end + private int m; + private IntHashMap n = new IntHashMap(); + private double o; + private double p; + private double q; + private boolean checkMovement = true; ++ private boolean processedDisconnect; // CraftBukkit - added + + public PlayerConnection(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) { + this.minecraftServer = minecraftserver; +@@ -46,7 +93,31 @@ + networkmanager.a((PacketListener) this); + this.player = entityplayer; + entityplayer.playerConnection = this; ++ ++ // CraftBukkit start - add fields and methods ++ this.server = minecraftserver.server; ++ } ++ ++ private final org.bukkit.craftbukkit.CraftServer server; ++ private int lastTick = MinecraftServer.currentTick; ++ private int lastDropTick = MinecraftServer.currentTick; ++ private int dropCount = 0; ++ private static final int SURVIVAL_PLACE_DISTANCE_SQUARED = 6 * 6; ++ private static final int CREATIVE_PLACE_DISTANCE_SQUARED = 7 * 7; ++ ++ // Get position of last block hit for BlockDamageLevel.STOPPED ++ private double lastPosX = Double.MAX_VALUE; ++ private double lastPosY = Double.MAX_VALUE; ++ private double lastPosZ = Double.MAX_VALUE; ++ private float lastPitch = Float.MAX_VALUE; ++ private float lastYaw = Float.MAX_VALUE; ++ private boolean justTeleported = false; ++ ++ public CraftPlayer getPlayer() { ++ return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity(); + } ++ private final static HashSet invalidItems = new HashSet(java.util.Arrays.asList(8, 9, 10, 11, 26, 34, 36, 43, 51, 52, 55, 59, 60, 62, 63, 64, 68, 71, 74, 75, 83, 90, 92, 93, 94, 104, 105, 115, 117, 118, 119, 125, 127, 132, 140, 141, 142, 144)); // TODO: Check after every update. ++ // CraftBukkit end + + public void c() { + this.h = false; +@@ -60,15 +131,21 @@ + } + + this.minecraftServer.methodProfiler.b(); ++ // CraftBukkit start ++ for (int spam; (spam = this.chatThrottle) > 0 && !chatSpamField.compareAndSet(this, spam, spam - 1); ) ; ++ /* Use thread-safe field access instead + if (this.chatThrottle > 0) { + --this.chatThrottle; + } ++ */ ++ // CraftBukkit end + + if (this.m > 0) { + --this.m; + } + + if (this.player.D() > 0L && this.minecraftServer.getIdleTimeout() > 0 && MinecraftServer.az() - this.player.D() > (long) (this.minecraftServer.getIdleTimeout() * 1000 * 60)) { ++ this.player.resetIdleTimer(); // CraftBukkit - SPIGOT-854 + this.disconnect("You have been idle for too long!"); + } + +@@ -79,19 +156,37 @@ + } + + public void disconnect(String s) { ++ // CraftBukkit start - fire PlayerKickEvent ++ String leaveMessage = EnumChatFormat.YELLOW + this.player.getName() + " left the game."; ++ ++ PlayerKickEvent event = new PlayerKickEvent(this.server.getPlayer(this.player), s, leaveMessage); ++ ++ if (this.server.getServer().isRunning()) { ++ this.server.getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ // Do not kick the player ++ return; ++ } ++ // Send the possibly modified leave message ++ s = event.getReason(); ++ // CraftBukkit end + final ChatComponentText chatcomponenttext = new ChatComponentText(s); + + this.networkManager.a(new PacketPlayOutKickDisconnect(chatcomponenttext), new GenericFutureListener() { +- public void operationComplete(Future future) throws Exception { ++ public void operationComplete(Future future) throws Exception { // CraftBukkit - fix decompile error + PlayerConnection.this.networkManager.close(chatcomponenttext); + } + }, new GenericFutureListener[0]); ++ this.a(chatcomponenttext); // CraftBukkit - fire quit instantly + this.networkManager.k(); +- Futures.getUnchecked(this.minecraftServer.postToMainThread(new Runnable() { +- public void run() { +- PlayerConnection.this.networkManager.l(); ++ // CraftBukkit - Don't wait ++ this.minecraftServer.postToMainThread(new Runnable() { ++ public void run() { ++ PlayerConnection.this.networkManager.l(); + } +- })); ++ }); + } + + public void a(PacketPlayInSteerVehicle packetplayinsteervehicle) { +@@ -126,8 +221,66 @@ + this.checkMovement = true; + } + } ++ // CraftBukkit start - fire PlayerMoveEvent ++ Player player = this.getPlayer(); ++ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. ++ Location to = player.getLocation().clone(); // Start off the To location as the Players current location. ++ ++ // If the packet contains movement information then we update the To location with the correct XYZ. ++ if (packetplayinflying.hasPos && !(packetplayinflying.hasPos && packetplayinflying.y == -999.0D)) { ++ to.setX(packetplayinflying.x); ++ to.setY(packetplayinflying.y); ++ to.setZ(packetplayinflying.z); ++ } ++ ++ // If the packet contains look information then we update the To location with the correct Yaw & Pitch. ++ if (packetplayinflying.hasLook) { ++ to.setYaw(packetplayinflying.yaw); ++ to.setPitch(packetplayinflying.pitch); ++ } ++ ++ // Prevent 40 event-calls for less than a single pixel of movement >.> ++ double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2); ++ float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch()); ++ ++ if ((delta > 1f / 256 || deltaAngle > 10f) && (this.checkMovement && !this.player.dead)) { ++ this.lastPosX = to.getX(); ++ this.lastPosY = to.getY(); ++ this.lastPosZ = to.getZ(); ++ this.lastYaw = to.getYaw(); ++ this.lastPitch = to.getPitch(); ++ ++ // Skip the first time we do this ++ if (from.getX() != Double.MAX_VALUE) { ++ Location oldTo = to.clone(); ++ PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); ++ this.server.getPluginManager().callEvent(event); ++ ++ // If the event is cancelled we move the player back to their old location. ++ if (event.isCancelled()) { ++ this.player.playerConnection.sendPacket(new PacketPlayOutPosition(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet())); ++ return; ++ } + +- if (this.checkMovement) { ++ /* If a Plugin has changed the To destination then we teleport the Player ++ there to avoid any 'Moved wrongly' or 'Moved too quickly' errors. ++ We only do this if the Event was not cancelled. */ ++ if (!oldTo.equals(event.getTo()) && !event.isCancelled()) { ++ this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.UNKNOWN); ++ return; ++ } ++ ++ /* Check to see if the Players Location has some how changed during the call of the event. ++ This can happen due to a plugin teleporting the player instead of using .setTo() */ ++ if (!from.equals(this.getPlayer().getLocation()) && this.justTeleported) { ++ this.justTeleported = false; ++ return; ++ } ++ } ++ } ++ ++ if (this.checkMovement && !this.player.dead) { ++ // CraftBukkit end + this.f = this.e; + double d7; + double d8; +@@ -155,6 +308,7 @@ + + this.minecraftServer.getPlayerList().d(this.player); + if (this.player.vehicle != null) { ++ this.player.vehicle.ai = true; // CraftBukkit - moved from below + if (d3 > 4.0D) { + Entity entity = this.player.vehicle; + +@@ -162,7 +316,7 @@ + this.a(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch); + } + +- this.player.vehicle.ai = true; ++ // this.player.vehicle.ai = true; // CraftBukkit - moved up + } + + if (this.checkMovement) { +@@ -224,7 +378,7 @@ + double d14 = this.player.motX * this.player.motX + this.player.motY * this.player.motY + this.player.motZ * this.player.motZ; + double d15 = d11 * d11 + d12 * d12 + d13 * d13; + +- if (d15 - d14 > 100.0D && (!this.minecraftServer.T() || !this.minecraftServer.S().equals(this.player.getName()))) { ++ if (d15 - d14 > 100.0D && this.checkMovement && (!this.minecraftServer.T() || !this.minecraftServer.S().equals(this.player.getName()))) { // CraftBukkit - Added this.checkMovement condition to solve this check being triggered by teleports + PlayerConnection.c.warn(this.player.getName() + " moved too quickly! " + d11 + "," + d12 + "," + d13 + " (" + d11 + ", " + d12 + ", " + d13 + ")"); + this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch); + return; +@@ -288,16 +442,73 @@ + } else if (this.e - this.f > 20) { + this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch); + } +- + } ++ + } + } + + public void a(double d0, double d1, double d2, float f, float f1) { +- this.a(d0, d1, d2, f, f1, Collections.emptySet()); ++ this.a(d0, d1, d2, f, f1, Collections.emptySet()); // CraftBukkit fix decompile errors + } + + public void a(double d0, double d1, double d2, float f, float f1, Set set) { ++ // CraftBukkit start - Delegate to teleport(Location) ++ Player player = this.getPlayer(); ++ Location from = player.getLocation(); ++ ++ double x = d0; ++ double y = d1; ++ double z = d2; ++ float yaw = f; ++ float pitch = f1; ++ if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X)) { ++ x += from.getX(); ++ } ++ if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y)) { ++ y += from.getY(); ++ } ++ if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z)) { ++ z += from.getZ(); ++ } ++ if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y_ROT)) { ++ yaw += from.getYaw(); ++ } ++ if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X_ROT)) { ++ pitch += from.getPitch(); ++ } ++ ++ ++ Location to = new Location(this.getPlayer().getWorld(), x, y, z, yaw, pitch); ++ PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), PlayerTeleportEvent.TeleportCause.UNKNOWN); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled() || to.equals(event.getTo())) { ++ set.clear(); // Can't relative teleport ++ to = event.isCancelled() ? event.getFrom() : event.getTo(); ++ d0 = to.getX(); ++ d1 = to.getY(); ++ d2 = to.getZ(); ++ f = to.getYaw(); ++ f1 = to.getPitch(); ++ } ++ ++ this.internalTeleport(d0, d1, d2, f, f1, set); ++ } ++ ++ public void teleport(Location dest) { ++ internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.emptySet()); ++ } ++ ++ private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set set) { ++ if (Float.isNaN(f)) { ++ f = 0; ++ } ++ ++ if (Float.isNaN(f1)) { ++ f1 = 0; ++ } ++ this.justTeleported = true; ++ // CraftBukkit end + this.checkMovement = false; + this.o = d0; + this.p = d1; +@@ -325,38 +536,63 @@ + f3 = f1 + this.player.pitch; + } + ++ // CraftBukkit start - update last location ++ this.lastPosX = this.o; ++ this.lastPosY = this.p; ++ this.lastPosZ = this.q; ++ this.lastYaw = f2; ++ this.lastPitch = f3; ++ // CraftBukkit end ++ + this.player.setLocation(this.o, this.p, this.q, f2, f3); + this.player.playerConnection.sendPacket(new PacketPlayOutPosition(d0, d1, d2, f, f1, set)); + } + + public void a(PacketPlayInBlockDig packetplayinblockdig) { + PlayerConnectionUtils.ensureMainThread(packetplayinblockdig, this, this.player.u()); ++ if (this.player.dead) return; // CraftBukkit + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); + BlockPosition blockposition = packetplayinblockdig.a(); + + this.player.resetIdleTimer(); ++ // CraftBukkit start + switch (PlayerConnection.SyntheticClass_1.a[packetplayinblockdig.c().ordinal()]) { +- case 1: ++ case 1: // DROP_ITEM + if (!this.player.isSpectator()) { ++ // limit how quickly items can be dropped ++ // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick. ++ if (this.lastDropTick != MinecraftServer.currentTick) { ++ this.dropCount = 0; ++ this.lastDropTick = MinecraftServer.currentTick; ++ } else { ++ // Else we increment the drop count and check the amount. ++ this.dropCount++; ++ if (this.dropCount >= 20) { ++ this.c.warn(this.player.getName() + " dropped their items too quickly!"); ++ this.disconnect("You dropped your items too quickly (Hacking?)"); ++ return; ++ } ++ } ++ // CraftBukkit end + this.player.a(false); + } + + return; + +- case 2: ++ case 2: // DROP_ALL_ITEMS + if (!this.player.isSpectator()) { + this.player.a(true); + } + + return; + +- case 3: ++ case 3: // RELEASE_USE_ITEM + this.player.bU(); + return; + +- case 4: +- case 5: +- case 6: ++ case 4: // START_DESTROY_BLOCK ++ case 5: // ABORT_DESTROY_BLOCK ++ case 6: // STOP_DESTROY_BLOCK + double d0 = this.player.locX - ((double) blockposition.getX() + 0.5D); + double d1 = this.player.locY - ((double) blockposition.getY() + 0.5D) + 1.5D; + double d2 = this.player.locZ - ((double) blockposition.getZ() + 0.5D); +@@ -371,7 +607,15 @@ + if (!this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { + this.player.playerInteractManager.a(blockposition, packetplayinblockdig.b()); + } else { ++ // CraftBukkit start - fire PlayerInteractEvent ++ CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, packetplayinblockdig.b(), this.player.inventory.getItemInHand()); + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); ++ // Update any tile entity data for this block ++ TileEntity tileentity = worldserver.getTileEntity(blockposition); ++ if (tileentity != null) { ++ this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); ++ } ++ // CraftBukkit end + } + } else { + if (packetplayinblockdig.c() == PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { +@@ -391,11 +635,22 @@ + default: + throw new IllegalArgumentException("Invalid player action"); + } ++ // CraftBukkit end + } + + public void a(PacketPlayInBlockPlace packetplayinblockplace) { + PlayerConnectionUtils.ensureMainThread(packetplayinblockplace, this, this.player.u()); + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); ++ ++ // CraftBukkit start ++ if (this.player.dead) return; ++ ++ // CraftBukkit - if rightclick decremented the item, always send the update packet. */ ++ // this is not here for CraftBukkit's own functionality; rather it is to fix ++ // a notch bug where the item doesn't update correctly. ++ boolean always = false; ++ // CraftBukkit end ++ + ItemStack itemstack = this.player.inventory.getItemInHand(); + boolean flag = false; + BlockPosition blockposition = packetplayinblockplace.a(); +@@ -407,7 +662,50 @@ + return; + } + +- this.player.playerInteractManager.useItem(this.player, worldserver, itemstack); ++ // CraftBukkit start ++ int itemstackAmount = itemstack.count; ++ ++ // Raytrace to look for 'rogue armswings' ++ float f1 = this.player.pitch; ++ float f2 = this.player.yaw; ++ double d0 = this.player.locX; ++ double d1 = this.player.locY + (double) this.player.getHeadHeight(); ++ double d2 = this.player.locZ; ++ Vec3D vec3d = new Vec3D(d0, d1, d2); ++ ++ float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); ++ float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); ++ float f5 = -MathHelper.cos(-f1 * 0.017453292F); ++ float f6 = MathHelper.sin(-f1 * 0.017453292F); ++ float f7 = f4 * f5; ++ float f8 = f3 * f5; ++ double d3 = player.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.CREATIVE ? 5.0D : 4.5D; ++ Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); ++ MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, false); ++ ++ boolean cancelled = false; ++ if (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK) { ++ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack); ++ cancelled = event.useItemInHand() == Event.Result.DENY; ++ } else { ++ if (player.playerInteractManager.firedInteract) { ++ player.playerInteractManager.firedInteract = false; ++ cancelled = player.playerInteractManager.interactResult; ++ } else { ++ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectposition.a(), movingobjectposition.direction, itemstack, true); ++ cancelled = event.useItemInHand() == Event.Result.DENY; ++ } ++ } ++ ++ if (!cancelled) { ++ this.player.playerInteractManager.useItem(this.player, this.player.world, itemstack); ++ } ++ ++ // CraftBukkit - notch decrements the counter by 1 in the above method with food, ++ // snowballs and so forth, but he does it in a place that doesn't cause the ++ // inventory update packet to get sent ++ always = (itemstack.count != itemstackAmount) || itemstack.getItem() == Item.getItemOf(Blocks.WATERLILY); ++ // CraftBukkit end + } else if (blockposition.getY() >= this.minecraftServer.getMaxBuildHeight() - 1 && (enumdirection == EnumDirection.UP || blockposition.getY() >= this.minecraftServer.getMaxBuildHeight())) { + ChatMessage chatmessage = new ChatMessage("build.tooHigh", new Object[] { Integer.valueOf(this.minecraftServer.getMaxBuildHeight())}); + +@@ -415,8 +713,19 @@ + this.player.playerConnection.sendPacket(new PacketPlayOutChat(chatmessage)); + flag = true; + } else { ++ // CraftBukkit start - Check if we can actually do something over this large a distance ++ Location eyeLoc = this.getPlayer().getEyeLocation(); ++ double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ()); ++ if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) { ++ return; ++ } ++ ++ if (!worldserver.getWorldBorder().a(blockposition)) { ++ return; ++ } ++ + if (this.checkMovement && this.player.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && !this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { +- this.player.playerInteractManager.interact(this.player, worldserver, itemstack, blockposition, enumdirection, packetplayinblockplace.d(), packetplayinblockplace.e(), packetplayinblockplace.f()); ++ always = !this.player.playerInteractManager.interact(this.player, worldserver, itemstack, blockposition, enumdirection, packetplayinblockplace.d(), packetplayinblockplace.e(), packetplayinblockplace.f()); + } + + flag = true; +@@ -440,7 +749,8 @@ + + this.player.activeContainer.b(); + this.player.g = false; +- if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack())) { ++ // CraftBukkit - TODO CHECK IF NEEDED -- new if structure might not need 'always'. Kept it in for now, but may be able to remove in future ++ if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack()) || always) { + this.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, slot.rawSlotIndex, this.player.inventory.getItemInHand())); + } + } +@@ -454,8 +764,8 @@ + WorldServer[] aworldserver = this.minecraftServer.worldServer; + int i = aworldserver.length; + +- for (int j = 0; j < i; ++j) { +- WorldServer worldserver = aworldserver[j]; ++ // CraftBukkit - use the worlds array list ++ for (WorldServer worldserver : minecraftServer.worlds) { + + if (worldserver != null) { + entity = packetplayinspectate.a(worldserver); +@@ -468,6 +778,8 @@ + if (entity != null) { + this.player.setSpectatorTarget(this.player); + this.player.mount((Entity) null); ++ ++ /* CraftBukkit start - replace with bukkit handling for multi-world + if (entity.world != this.player.world) { + WorldServer worldserver1 = this.player.u(); + WorldServer worldserver2 = (WorldServer) entity.world; +@@ -492,22 +804,44 @@ + } else { + this.player.enderTeleportTo(entity.locX, entity.locY, entity.locZ); + } ++ */ ++ this.player.getBukkitEntity().teleport(entity.getBukkitEntity(), PlayerTeleportEvent.TeleportCause.SPECTATE); ++ // CraftBukkit end + } + } + + } + +- public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) {} ++ // CraftBukkit start ++ public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) { ++ this.server.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getPlayer(), PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.b.ordinal()])); ++ } ++ // CraftBukkit end + + public void a(IChatBaseComponent ichatbasecomponent) { +- PlayerConnection.c.info(this.player.getName() + " lost connection: " + ichatbasecomponent); ++ // CraftBukkit start - Rarely it would send a disconnect line twice ++ if (this.processedDisconnect) { ++ return; ++ } else { ++ this.processedDisconnect = true; ++ } ++ // CraftBukkit end ++ PlayerConnection.c.info(this.player.getName() + " lost connection: " + ichatbasecomponent.c()); // CraftBukkit: Don't toString(). // PAIL: Rename ++ // CraftBukkit start - Replace vanilla quit message handling with our own. ++ /* + this.minecraftServer.aH(); + ChatMessage chatmessage = new ChatMessage("multiplayer.player.left", new Object[] { this.player.getScoreboardDisplayName()}); + + chatmessage.getChatModifier().setColor(EnumChatFormat.YELLOW); + this.minecraftServer.getPlayerList().sendMessage(chatmessage); ++ */ ++ + this.player.q(); +- this.minecraftServer.getPlayerList().disconnect(this.player); ++ String quitMessage = this.minecraftServer.getPlayerList().disconnect(this.player); ++ if ((quitMessage != null) && (quitMessage.length() > 0)) { ++ this.minecraftServer.getPlayerList().sendMessage(CraftChatMessage.fromString(quitMessage)); ++ } ++ // CraftBukkit end + if (this.minecraftServer.T() && this.player.getName().equals(this.minecraftServer.S())) { + PlayerConnection.c.info("Stopping singleplayer server as player logged out"); + this.minecraftServer.safeShutdown(); +@@ -529,6 +863,15 @@ + } + } + ++ // CraftBukkit start ++ if (packet == null) { ++ return; ++ } else if (packet instanceof PacketPlayOutSpawnPosition) { ++ PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet; ++ this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); ++ } ++ // CraftBukkit end ++ + try { + this.networkManager.handle(packet); + } catch (Throwable throwable) { +@@ -549,18 +892,34 @@ + } + + public void a(PacketPlayInHeldItemSlot packetplayinhelditemslot) { ++ // CraftBukkit start ++ if (this.player.dead) return; + PlayerConnectionUtils.ensureMainThread(packetplayinhelditemslot, this, this.player.u()); + if (packetplayinhelditemslot.a() >= 0 && packetplayinhelditemslot.a() < PlayerInventory.getHotbarSize()) { ++ PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayer(), this.player.inventory.itemInHandIndex, packetplayinhelditemslot.a()); ++ this.server.getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ this.sendPacket(new PacketPlayOutHeldItemSlot(this.player.inventory.itemInHandIndex)); ++ this.player.resetIdleTimer(); ++ return; ++ } ++ // CraftBukkit end + this.player.inventory.itemInHandIndex = packetplayinhelditemslot.a(); + this.player.resetIdleTimer(); + } else { + PlayerConnection.c.warn(this.player.getName() + " tried to set an invalid carried item"); ++ this.disconnect("Nope!"); // CraftBukkit + } + } + + public void a(PacketPlayInChat packetplayinchat) { +- PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.u()); +- if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { ++ // CraftBukkit start - async chat ++ boolean isSync = packetplayinchat.a().startsWith("/"); ++ if (packetplayinchat.a().startsWith("/")) { ++ PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.u()); ++ } ++ // CraftBukkit end ++ if (this.player.dead || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales + ChatMessage chatmessage = new ChatMessage("chat.cannotSend", new Object[0]); + + chatmessage.getChatModifier().setColor(EnumChatFormat.RED); +@@ -573,39 +932,249 @@ + + for (int i = 0; i < s.length(); ++i) { + if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) { +- this.disconnect("Illegal characters in chat"); ++ // CraftBukkit start - threadsafety ++ if (!isSync) { ++ Waitable waitable = new Waitable() { ++ @Override ++ protected Object evaluate() { ++ PlayerConnection.this.disconnect("Illegal characters in chat"); ++ return null; ++ } ++ }; ++ ++ this.minecraftServer.processQueue.add(waitable); ++ ++ try { ++ waitable.get(); ++ } catch (InterruptedException e) { ++ Thread.currentThread().interrupt(); ++ } catch (ExecutionException e) { ++ throw new RuntimeException(e); ++ } ++ } else { ++ this.disconnect("Illegal characters in chat"); ++ } ++ // CraftBukkit end + return; + } + } + +- if (s.startsWith("/")) { +- this.handleCommand(s); ++ // CraftBukkit start ++ if (isSync) { ++ try { ++ this.minecraftServer.server.playerCommandState = true; ++ this.handleCommand(s); ++ } finally { ++ this.minecraftServer.server.playerCommandState = false; ++ } ++ } else if (s.isEmpty()) { ++ c.warn(this.player.getName() + " tried to send an empty message"); ++ } else if (getPlayer().isConversing()) { ++ getPlayer().acceptConversationInput(s); ++ } else if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.SYSTEM) { // Re-add "Command Only" flag check ++ ChatMessage chatmessage = new ChatMessage("chat.cannotSend", new Object[0]); ++ ++ chatmessage.getChatModifier().setColor(EnumChatFormat.RED); ++ this.sendPacket(new PacketPlayOutChat(chatmessage)); ++ } else if (true) { ++ this.chat(s, true); ++ // CraftBukkit end - the below is for reference. :) + } else { + ChatMessage chatmessage1 = new ChatMessage("chat.type.text", new Object[] { this.player.getScoreboardDisplayName(), s}); + + this.minecraftServer.getPlayerList().sendMessage(chatmessage1, false); + } + +- this.chatThrottle += 20; +- if (this.chatThrottle > 200 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { +- this.disconnect("disconnect.spam"); ++ // CraftBukkit start - replaced with thread safe throttle ++ // this.chatThrottle += 20; ++ if (chatSpamField.addAndGet(this, 20) > 200 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { ++ if (!isSync) { ++ Waitable waitable = new Waitable() { ++ @Override ++ protected Object evaluate() { ++ PlayerConnection.this.disconnect("disconnect.spam"); ++ return null; ++ } ++ }; ++ ++ this.minecraftServer.processQueue.add(waitable); ++ ++ try { ++ waitable.get(); ++ } catch (InterruptedException e) { ++ Thread.currentThread().interrupt(); ++ } catch (ExecutionException e) { ++ throw new RuntimeException(e); ++ } ++ } else { ++ this.disconnect("disconnect.spam"); ++ } ++ // CraftBukkit end + } + + } + } + +- private void handleCommand(String s) { +- this.minecraftServer.getCommandHandler().a(this.player, s); ++ // CraftBukkit start - add method ++ public void chat(String s, boolean async) { ++ if (s.isEmpty() || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { ++ return; ++ } ++ ++ if (!async && s.startsWith("/")) { ++ this.handleCommand(s); ++ } else if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.SYSTEM) { ++ // Do nothing, this is coming from a plugin ++ } else { ++ Player player = this.getPlayer(); ++ AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) { ++ // Evil plugins still listening to deprecated event ++ final PlayerChatEvent queueEvent = new PlayerChatEvent(player, event.getMessage(), event.getFormat(), event.getRecipients()); ++ queueEvent.setCancelled(event.isCancelled()); ++ Waitable waitable = new Waitable() { ++ @Override ++ protected Object evaluate() { ++ org.bukkit.Bukkit.getPluginManager().callEvent(queueEvent); ++ ++ if (queueEvent.isCancelled()) { ++ return null; ++ } ++ ++ String message = String.format(queueEvent.getFormat(), queueEvent.getPlayer().getDisplayName(), queueEvent.getMessage()); ++ PlayerConnection.this.minecraftServer.console.sendMessage(message); ++ if (((LazyPlayerSet) queueEvent.getRecipients()).isLazy()) { ++ for (Object player : PlayerConnection.this.minecraftServer.getPlayerList().players) { ++ ((EntityPlayer) player).sendMessage(CraftChatMessage.fromString(message)); ++ } ++ } else { ++ for (Player player : queueEvent.getRecipients()) { ++ player.sendMessage(message); ++ } ++ } ++ return null; ++ }}; ++ if (async) { ++ minecraftServer.processQueue.add(waitable); ++ } else { ++ waitable.run(); ++ } ++ try { ++ waitable.get(); ++ } catch (InterruptedException e) { ++ Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on! ++ } catch (ExecutionException e) { ++ throw new RuntimeException("Exception processing chat event", e.getCause()); ++ } ++ } else { ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage()); ++ minecraftServer.console.sendMessage(s); ++ if (((LazyPlayerSet) event.getRecipients()).isLazy()) { ++ for (Object recipient : minecraftServer.getPlayerList().players) { ++ ((EntityPlayer) recipient).sendMessage(CraftChatMessage.fromString(s)); ++ } ++ } else { ++ for (Player recipient : event.getRecipients()) { ++ recipient.sendMessage(s); ++ } ++ } ++ } ++ } ++ } ++ // CraftBukkit end ++ ++ private void handleCommand(String s) { ++ // CraftBukkit start - whole method ++ this.c.info(this.player.getName() + " issued server command: " + s); ++ ++ CraftPlayer player = this.getPlayer(); ++ ++ PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, s, new LazyPlayerSet()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ try { ++ if (this.server.dispatchCommand(event.getPlayer(), event.getMessage().substring(1))) { ++ return; ++ } ++ } catch (org.bukkit.command.CommandException ex) { ++ player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); ++ java.util.logging.Logger.getLogger(PlayerConnection.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); ++ return; ++ } ++ // this.minecraftServer.getCommandHandler().a(this.player, s); ++ // CraftBukkit end + } + + public void a(PacketPlayInArmAnimation packetplayinarmanimation) { ++ if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinarmanimation, this, this.player.u()); + this.player.resetIdleTimer(); ++ // CraftBukkit start - Raytrace to look for 'rogue armswings' ++ float f1 = this.player.pitch; ++ float f2 = this.player.yaw; ++ double d0 = this.player.locX; ++ double d1 = this.player.locY + (double) this.player.getHeadHeight(); ++ double d2 = this.player.locZ; ++ Vec3D vec3d = new Vec3D(d0, d1, d2); ++ ++ float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); ++ float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); ++ float f5 = -MathHelper.cos(-f1 * 0.017453292F); ++ float f6 = MathHelper.sin(-f1 * 0.017453292F); ++ float f7 = f4 * f5; ++ float f8 = f3 * f5; ++ double d3 = player.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.CREATIVE ? 5.0D : 4.5D; ++ Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); ++ MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, false); ++ ++ if (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK) { ++ CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.inventory.getItemInHand()); ++ } ++ ++ // Arm swing animation ++ PlayerAnimationEvent event = new PlayerAnimationEvent(this.getPlayer()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) return; ++ // CraftBukkit end + this.player.bw(); + } + + public void a(PacketPlayInEntityAction packetplayinentityaction) { + PlayerConnectionUtils.ensureMainThread(packetplayinentityaction, this, this.player.u()); ++ // CraftBukkit start ++ if (this.player.dead) return; ++ switch (packetplayinentityaction.b()) { ++ case START_SNEAKING: ++ case STOP_SNEAKING: ++ PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getPlayer(), packetplayinentityaction.b() == PacketPlayInEntityAction.EnumPlayerAction.START_SNEAKING); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ break; ++ case START_SPRINTING: ++ case STOP_SPRINTING: ++ PlayerToggleSprintEvent e2 = new PlayerToggleSprintEvent(this.getPlayer(), packetplayinentityaction.b() == PacketPlayInEntityAction.EnumPlayerAction.START_SPRINTING); ++ this.server.getPluginManager().callEvent(e2); ++ ++ if (e2.isCancelled()) { ++ return; ++ } ++ break; ++ } ++ // CraftBukkit end + this.player.resetIdleTimer(); + switch (PlayerConnection.SyntheticClass_1.b[packetplayinentityaction.b().ordinal()]) { + case 1: +@@ -626,7 +1195,7 @@ + + case 5: + this.player.a(false, true, true); +- this.checkMovement = false; ++ // this.checkMovement = false; // CraftBukkit - this is handled in teleport + break; + + case 6: +@@ -648,6 +1217,7 @@ + } + + public void a(PacketPlayInUseEntity packetplayinuseentity) { ++ if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinuseentity, this, this.player.u()); + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); + Entity entity = packetplayinuseentity.a((World) worldserver); +@@ -662,18 +1232,67 @@ + } + + if (this.player.h(entity) < d0) { ++ ItemStack itemInHand = this.player.inventory.getItemInHand(); // CraftBukkit ++ ++ if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT ++ || packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) { ++ // CraftBukkit start ++ boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof EntityInsentient; ++ Item origItem = this.player.inventory.getItemInHand() == null ? null : this.player.inventory.getItemInHand().getItem(); ++ PlayerInteractEntityEvent event; ++ if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT) { ++ event = new PlayerInteractEntityEvent((Player) this.getPlayer(), entity.getBukkitEntity()); ++ } else { ++ Vec3D target = packetplayinuseentity.b(); ++ event = new PlayerInteractAtEntityEvent((Player) this.getPlayer(), entity.getBukkitEntity(), new org.bukkit.util.Vector(target.a, target.b, target.c)); ++ } ++ this.server.getPluginManager().callEvent(event); ++ ++ if (triggerLeashUpdate && (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != Items.LEAD)) { ++ // Refresh the current leash state ++ this.sendPacket(new PacketPlayOutAttachEntity(1, entity, ((EntityInsentient) entity).getLeashHolder())); ++ } ++ ++ if (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != origItem) { ++ // Refresh the current entity metadata ++ this.sendPacket(new PacketPlayOutEntityMetadata(entity.getId(), entity.datawatcher, true)); ++ } ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end ++ } + if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT) { + this.player.u(entity); ++ ++ // CraftBukkit start ++ if (itemInHand != null && itemInHand.count <= -1) { ++ this.player.updateInventory(this.player.activeContainer); ++ } ++ // CraftBukkit end + } else if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) { + entity.a((EntityHuman) this.player, packetplayinuseentity.b()); ++ ++ // CraftBukkit start ++ if (itemInHand != null && itemInHand.count <= -1) { ++ this.player.updateInventory(this.player.activeContainer); ++ } ++ // CraftBukkit end + } else if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.ATTACK) { +- if (entity instanceof EntityItem || entity instanceof EntityExperienceOrb || entity instanceof EntityArrow || entity == this.player) { ++ if (entity instanceof EntityItem || entity instanceof EntityExperienceOrb || entity instanceof EntityArrow || (entity == this.player && !player.isSpectator())) { // CraftBukkit + this.disconnect("Attempting to attack an invalid entity"); + this.minecraftServer.warning("Player " + this.player.getName() + " tried to attack an invalid entity"); + return; + } + + this.player.attack(entity); ++ ++ // CraftBukkit start ++ if (itemInHand != null && itemInHand.count <= -1) { ++ this.player.updateInventory(this.player.activeContainer); ++ } ++ // CraftBukkit end + } + } + } +@@ -688,7 +1307,8 @@ + switch (PlayerConnection.SyntheticClass_1.c[packetplayinclientcommand_enumclientcommand.ordinal()]) { + case 1: + if (this.player.viewingCredits) { +- this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true); ++ // this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true); ++ this.minecraftServer.getPlayerList().changeDimension(this.player, 0, PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management + } else if (this.player.u().getWorldData().isHardcore()) { + if (this.minecraftServer.T() && this.player.getName().equals(this.minecraftServer.S())) { + this.player.playerConnection.disconnect("You have died. Game over, man, it\'s game over!"); +@@ -719,15 +1339,21 @@ + } + + public void a(PacketPlayInCloseWindow packetplayinclosewindow) { ++ if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinclosewindow, this, this.player.u()); ++ ++ CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit ++ + this.player.p(); + } + + public void a(PacketPlayInWindowClick packetplayinwindowclick) { ++ if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinwindowclick, this, this.player.u()); + this.player.resetIdleTimer(); + if (this.player.activeContainer.windowId == packetplayinwindowclick.a() && this.player.activeContainer.c(this.player)) { +- if (this.player.isSpectator()) { ++ boolean cancelled = this.player.isSpectator(); // CraftBukkit - see below if ++ if (false) { // this.player.isSpectator()) { + ArrayList arraylist = Lists.newArrayList(); + + for (int i = 0; i < this.player.activeContainer.c.size(); ++i) { +@@ -736,7 +1362,270 @@ + + this.player.a(this.player.activeContainer, (List) arraylist); + } else { +- ItemStack itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); ++ // ItemStack itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); ++ // CraftBukkit start - Call InventoryClickEvent ++ if (packetplayinwindowclick.b() < -1 && packetplayinwindowclick.b() != -999) { ++ return; ++ } ++ ++ InventoryView inventory = this.player.activeContainer.getBukkitView(); ++ SlotType type = CraftInventoryView.getSlotType(inventory, packetplayinwindowclick.b()); ++ ++ InventoryClickEvent event = null; ++ ClickType click = ClickType.UNKNOWN; ++ InventoryAction action = InventoryAction.UNKNOWN; ++ ++ ItemStack itemstack = null; ++ ++ if (packetplayinwindowclick.b() == -1) { ++ type = SlotType.OUTSIDE; // override ++ click = packetplayinwindowclick.c() == 0 ? ClickType.WINDOW_BORDER_LEFT : ClickType.WINDOW_BORDER_RIGHT; ++ action = InventoryAction.NOTHING; ++ } else if (packetplayinwindowclick.f() == 0) { ++ if (packetplayinwindowclick.c() == 0) { ++ click = ClickType.LEFT; ++ } else if (packetplayinwindowclick.c() == 1) { ++ click = ClickType.RIGHT; ++ } ++ if (packetplayinwindowclick.c() == 0 || packetplayinwindowclick.c() == 1) { ++ action = InventoryAction.NOTHING; // Don't want to repeat ourselves ++ if (packetplayinwindowclick.b() == -999) { ++ if (player.inventory.getCarried() != null) { ++ action = packetplayinwindowclick.c() == 0 ? InventoryAction.DROP_ALL_CURSOR : InventoryAction.DROP_ONE_CURSOR; ++ } ++ } else { ++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); ++ if (slot != null) { ++ ItemStack clickedItem = slot.getItem(); ++ ItemStack cursor = player.inventory.getCarried(); ++ if (clickedItem == null) { ++ if (cursor != null) { ++ action = packetplayinwindowclick.c() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; ++ } ++ } else if (slot.isAllowed(player)) { ++ if (cursor == null) { ++ action = packetplayinwindowclick.c() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; ++ } else if (slot.isAllowed(cursor)) { ++ if (clickedItem.doMaterialsMatch(cursor) && ItemStack.equals(clickedItem, cursor)) { ++ int toPlace = packetplayinwindowclick.c() == 0 ? cursor.count : 1; ++ toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.count); ++ toPlace = Math.min(toPlace, slot.inventory.getMaxStackSize() - clickedItem.count); ++ if (toPlace == 1) { ++ action = InventoryAction.PLACE_ONE; ++ } else if (toPlace == cursor.count) { ++ action = InventoryAction.PLACE_ALL; ++ } else if (toPlace < 0) { ++ action = toPlace != -1 ? InventoryAction.PICKUP_SOME : InventoryAction.PICKUP_ONE; // this happens with oversized stacks ++ } else if (toPlace != 0) { ++ action = InventoryAction.PLACE_SOME; ++ } ++ } else if (cursor.count <= slot.getMaxStackSize()) { ++ action = InventoryAction.SWAP_WITH_CURSOR; ++ } ++ } else if (cursor.getItem() == clickedItem.getItem() && (!cursor.usesData() || cursor.getData() == clickedItem.getData()) && ItemStack.equals(cursor, clickedItem)) { ++ if (clickedItem.count >= 0) { ++ if (clickedItem.count + cursor.count <= cursor.getMaxStackSize()) { ++ // As of 1.5, this is result slots only ++ action = InventoryAction.PICKUP_ALL; ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ } else if (packetplayinwindowclick.f() == 1) { ++ if (packetplayinwindowclick.c() == 0) { ++ click = ClickType.SHIFT_LEFT; ++ } else if (packetplayinwindowclick.c() == 1) { ++ click = ClickType.SHIFT_RIGHT; ++ } ++ if (packetplayinwindowclick.c() == 0 || packetplayinwindowclick.c() == 1) { ++ if (packetplayinwindowclick.b() < 0) { ++ action = InventoryAction.NOTHING; ++ } else { ++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); ++ if (slot != null && slot.isAllowed(this.player) && slot.hasItem()) { ++ action = InventoryAction.MOVE_TO_OTHER_INVENTORY; ++ } else { ++ action = InventoryAction.NOTHING; ++ } ++ } ++ } ++ } else if (packetplayinwindowclick.f() == 2) { ++ if (packetplayinwindowclick.c() >= 0 && packetplayinwindowclick.c() < 9) { ++ click = ClickType.NUMBER_KEY; ++ Slot clickedSlot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); ++ if (clickedSlot.isAllowed(player)) { ++ ItemStack hotbar = this.player.inventory.getItem(packetplayinwindowclick.c()); ++ boolean canCleanSwap = hotbar == null || (clickedSlot.inventory == player.inventory && clickedSlot.isAllowed(hotbar)); // the slot will accept the hotbar item ++ if (clickedSlot.hasItem()) { ++ if (canCleanSwap) { ++ action = InventoryAction.HOTBAR_SWAP; ++ } else { ++ int firstEmptySlot = player.inventory.getFirstEmptySlotIndex(); ++ if (firstEmptySlot > -1) { ++ action = InventoryAction.HOTBAR_MOVE_AND_READD; ++ } else { ++ action = InventoryAction.NOTHING; // This is not sane! Mojang: You should test for other slots of same type ++ } ++ } ++ } else if (!clickedSlot.hasItem() && hotbar != null && clickedSlot.isAllowed(hotbar)) { ++ action = InventoryAction.HOTBAR_SWAP; ++ } else { ++ action = InventoryAction.NOTHING; ++ } ++ } else { ++ action = InventoryAction.NOTHING; ++ } ++ // Special constructor for number key ++ event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c()); ++ } ++ } else if (packetplayinwindowclick.f() == 3) { ++ if (packetplayinwindowclick.c() == 2) { ++ click = ClickType.MIDDLE; ++ if (packetplayinwindowclick.b() == -999) { ++ action = InventoryAction.NOTHING; ++ } else { ++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); ++ if (slot != null && slot.hasItem() && player.abilities.canInstantlyBuild && player.inventory.getCarried() == null) { ++ action = InventoryAction.CLONE_STACK; ++ } else { ++ action = InventoryAction.NOTHING; ++ } ++ } ++ } else { ++ click = ClickType.UNKNOWN; ++ action = InventoryAction.UNKNOWN; ++ } ++ } else if (packetplayinwindowclick.f() == 4) { ++ if (packetplayinwindowclick.b() >= 0) { ++ if (packetplayinwindowclick.c() == 0) { ++ click = ClickType.DROP; ++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); ++ if (slot != null && slot.hasItem() && slot.isAllowed(player) && slot.getItem() != null && slot.getItem().getItem() != Item.getItemOf(Blocks.AIR)) { ++ action = InventoryAction.DROP_ONE_SLOT; ++ } else { ++ action = InventoryAction.NOTHING; ++ } ++ } else if (packetplayinwindowclick.c() == 1) { ++ click = ClickType.CONTROL_DROP; ++ Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); ++ if (slot != null && slot.hasItem() && slot.isAllowed(player) && slot.getItem() != null && slot.getItem().getItem() != Item.getItemOf(Blocks.AIR)) { ++ action = InventoryAction.DROP_ALL_SLOT; ++ } else { ++ action = InventoryAction.NOTHING; ++ } ++ } ++ } else { ++ // Sane default (because this happens when they are holding nothing. Don't ask why.) ++ click = ClickType.LEFT; ++ if (packetplayinwindowclick.c() == 1) { ++ click = ClickType.RIGHT; ++ } ++ action = InventoryAction.NOTHING; ++ } ++ } else if (packetplayinwindowclick.f() == 5) { ++ itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), 5, this.player); ++ } else if (packetplayinwindowclick.f() == 6) { ++ click = ClickType.DOUBLE_CLICK; ++ action = InventoryAction.NOTHING; ++ if (packetplayinwindowclick.b() >= 0 && this.player.inventory.getCarried() != null) { ++ ItemStack cursor = this.player.inventory.getCarried(); ++ action = InventoryAction.NOTHING; ++ // Quick check for if we have any of the item ++ if (inventory.getTopInventory().contains(org.bukkit.Material.getMaterial(Item.getId(cursor.getItem()))) || inventory.getBottomInventory().contains(org.bukkit.Material.getMaterial(Item.getId(cursor.getItem())))) { ++ action = InventoryAction.COLLECT_TO_CURSOR; ++ } ++ } ++ } ++ // TODO check on updates ++ ++ if (packetplayinwindowclick.f() != 5) { ++ if (click == ClickType.NUMBER_KEY) { ++ event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c()); ++ } else { ++ event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.b(), click, action); ++ } ++ ++ org.bukkit.inventory.Inventory top = inventory.getTopInventory(); ++ if (packetplayinwindowclick.b() == 0 && top instanceof CraftingInventory) { ++ org.bukkit.inventory.Recipe recipe = ((CraftingInventory) top).getRecipe(); ++ if (recipe != null) { ++ if (click == ClickType.NUMBER_KEY) { ++ event = new CraftItemEvent(recipe, inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c()); ++ } else { ++ event = new CraftItemEvent(recipe, inventory, type, packetplayinwindowclick.b(), click, action); ++ } ++ } ++ } ++ ++ event.setCancelled(cancelled); ++ server.getPluginManager().callEvent(event); ++ ++ switch (event.getResult()) { ++ case ALLOW: ++ case DEFAULT: ++ itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); ++ break; ++ case DENY: ++ /* Needs enum constructor in InventoryAction ++ if (action.modifiesOtherSlots()) { ++ ++ } else { ++ if (action.modifiesCursor()) { ++ this.player.playerConnection.sendPacket(new Packet103SetSlot(-1, -1, this.player.inventory.getCarried())); ++ } ++ if (action.modifiesClicked()) { ++ this.player.playerConnection.sendPacket(new Packet103SetSlot(this.player.activeContainer.windowId, packet102windowclick.slot, this.player.activeContainer.getSlot(packet102windowclick.slot).getItem())); ++ } ++ }*/ ++ switch (action) { ++ // Modified other slots ++ case PICKUP_ALL: ++ case MOVE_TO_OTHER_INVENTORY: ++ case HOTBAR_MOVE_AND_READD: ++ case HOTBAR_SWAP: ++ case COLLECT_TO_CURSOR: ++ case UNKNOWN: ++ this.player.updateInventory(this.player.activeContainer); ++ break; ++ // Modified cursor and clicked ++ case PICKUP_SOME: ++ case PICKUP_HALF: ++ case PICKUP_ONE: ++ case PLACE_ALL: ++ case PLACE_SOME: ++ case PLACE_ONE: ++ case SWAP_WITH_CURSOR: ++ this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.player.inventory.getCarried())); ++ this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, packetplayinwindowclick.b(), this.player.activeContainer.getSlot(packetplayinwindowclick.b()).getItem())); ++ break; ++ // Modified clicked only ++ case DROP_ALL_SLOT: ++ case DROP_ONE_SLOT: ++ this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, packetplayinwindowclick.b(), this.player.activeContainer.getSlot(packetplayinwindowclick.b()).getItem())); ++ break; ++ // Modified cursor only ++ case DROP_ALL_CURSOR: ++ case DROP_ONE_CURSOR: ++ case CLONE_STACK: ++ this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.player.inventory.getCarried())); ++ break; ++ // Nothing ++ case NOTHING: ++ break; ++ } ++ return; ++ } ++ ++ if (event instanceof CraftItemEvent) { ++ // Need to update the inventory on crafting to ++ // correctly support custom recipes ++ player.updateInventory(player.activeContainer); ++ } ++ } ++ // CraftBukkit end + + if (ItemStack.matches(packetplayinwindowclick.e(), itemstack)) { + this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.a(), packetplayinwindowclick.d(), true)); +@@ -797,8 +1686,48 @@ + } + + boolean flag1 = packetplayinsetcreativeslot.a() >= 1 && packetplayinsetcreativeslot.a() < 36 + PlayerInventory.getHotbarSize(); +- boolean flag2 = itemstack == null || itemstack.getItem() != null; ++ // CraftBukkit - Add invalidItems check ++ boolean flag2 = itemstack == null || itemstack.getItem() != null && !invalidItems.contains(Item.getId(itemstack.getItem())); + boolean flag3 = itemstack == null || itemstack.getData() >= 0 && itemstack.count <= 64 && itemstack.count > 0; ++ // CraftBukkit start - Call click event ++ if (flag || (flag1 && !ItemStack.matches(this.player.defaultContainer.getSlot(packetplayinsetcreativeslot.a()).getItem(), packetplayinsetcreativeslot.getItemStack()))) { // Insist on valid slot ++ ++ org.bukkit.entity.HumanEntity player = this.player.getBukkitEntity(); ++ InventoryView inventory = new CraftInventoryView(player, player.getInventory(), this.player.defaultContainer); ++ org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(packetplayinsetcreativeslot.getItemStack()); ++ ++ SlotType type = SlotType.QUICKBAR; ++ if (flag) { ++ type = SlotType.OUTSIDE; ++ } else if (packetplayinsetcreativeslot.a() < 36) { ++ if (packetplayinsetcreativeslot.a() >= 5 && packetplayinsetcreativeslot.a() < 9) { ++ type = SlotType.ARMOR; ++ } else { ++ type = SlotType.CONTAINER; ++ } ++ } ++ InventoryCreativeEvent event = new InventoryCreativeEvent(inventory, type, flag ? -999 : packetplayinsetcreativeslot.a(), item); ++ server.getPluginManager().callEvent(event); ++ ++ itemstack = CraftItemStack.asNMSCopy(event.getCursor()); ++ ++ switch (event.getResult()) { ++ case ALLOW: ++ // Plugin cleared the id / stacksize checks ++ flag2 = flag3 = true; ++ break; ++ case DEFAULT: ++ break; ++ case DENY: ++ // Reset the slot ++ if (packetplayinsetcreativeslot.a() >= 0) { ++ this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.defaultContainer.windowId, packetplayinsetcreativeslot.a(), this.player.defaultContainer.getSlot(packetplayinsetcreativeslot.a()).getItem())); ++ this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, null)); ++ } ++ return; ++ } ++ } ++ // CraftBukkit end + + if (flag1 && flag2 && flag3) { + if (itemstack == null) { +@@ -821,6 +1750,7 @@ + } + + public void a(PacketPlayInTransaction packetplayintransaction) { ++ if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayintransaction, this, this.player.u()); + Short oshort = (Short) this.n.get(this.player.activeContainer.windowId); + +@@ -831,6 +1761,7 @@ + } + + public void a(PacketPlayInUpdateSign packetplayinupdatesign) { ++ if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinupdatesign, this, this.player.u()); + this.player.resetIdleTimer(); + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); +@@ -847,14 +1778,30 @@ + + if (!tileentitysign.b() || tileentitysign.c() != this.player) { + this.minecraftServer.warning("Player " + this.player.getName() + " just tried to change non-editable sign"); ++ this.sendPacket(new PacketPlayOutUpdateSign(tileentity.world, packetplayinupdatesign.a(), tileentitysign.lines)); // CraftBukkit + return; + } + + IChatBaseComponent[] aichatbasecomponent = packetplayinupdatesign.b(); + ++ // CraftBukkit start ++ Player player = this.server.getPlayer(this.player); ++ int x = packetplayinupdatesign.a().getX(); ++ int y = packetplayinupdatesign.a().getY(); ++ int z = packetplayinupdatesign.a().getZ(); ++ String[] lines = new String[4]; ++ + for (int i = 0; i < aichatbasecomponent.length; ++i) { +- tileentitysign.lines[i] = new ChatComponentText(EnumChatFormat.a(aichatbasecomponent[i].c())); ++ lines[i] = EnumChatFormat.a(aichatbasecomponent[i].c()); + } ++ SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(x, y, z), this.server.getPlayer(this.player), lines); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ System.arraycopy(org.bukkit.craftbukkit.block.CraftSign.sanitizeLines(event.getLines()), 0, tileentitysign.lines, 0, 4); ++ tileentitysign.isEditable = false; ++ } ++ // CraftBukkit end + + tileentitysign.update(); + worldserver.notify(blockposition); +@@ -877,11 +1824,27 @@ + + public void a(PacketPlayInAbilities packetplayinabilities) { + PlayerConnectionUtils.ensureMainThread(packetplayinabilities, this, this.player.u()); +- this.player.abilities.isFlying = packetplayinabilities.isFlying() && this.player.abilities.canFly; ++ // CraftBukkit start ++ if (this.player.abilities.canFly && this.player.abilities.isFlying != packetplayinabilities.isFlying()) { ++ PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.server.getPlayer(this.player), packetplayinabilities.isFlying()); ++ this.server.getPluginManager().callEvent(event); ++ if (!event.isCancelled()) { ++ this.player.abilities.isFlying = packetplayinabilities.isFlying(); // Actually set the player's flying status ++ } else { ++ this.player.updateAbilities(); // Tell the player their ability was reverted ++ } ++ } ++ // CraftBukkit end + } + + public void a(PacketPlayInTabComplete packetplayintabcomplete) { + PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.u()); ++ // CraftBukkit start ++ if (chatSpamField.addAndGet(this, 10) > 500 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { ++ this.disconnect("disconnect.spam"); ++ return; ++ } ++ // CraftBukkit end + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = this.minecraftServer.tabCompleteCommand(this.player, packetplayintabcomplete.a(), packetplayintabcomplete.b()).iterator(); + +@@ -905,6 +1868,7 @@ + ItemStack itemstack; + ItemStack itemstack1; + ++ try { // CraftBukkit + if ("MC|BEdit".equals(packetplayincustompayload.a())) { + packetdataserializer = new PacketDataSerializer(Unpooled.wrappedBuffer(packetplayincustompayload.b())); + +@@ -921,13 +1885,16 @@ + itemstack1 = this.player.inventory.getItemInHand(); + if (itemstack1 != null) { + if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack.getItem() == itemstack1.getItem()) { ++ itemstack1 = new ItemStack(Items.WRITABLE_BOOK); // CraftBukkit + itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); ++ CraftEventFactory.handleEditBookEvent(player, itemstack1); // CraftBukkit + } + + return; + } + } catch (Exception exception) { + PlayerConnection.c.error("Couldn\'t handle book info", exception); ++ this.disconnect("Invalid book data!"); // CraftBukkit + return; + } finally { + packetdataserializer.release(); +@@ -950,16 +1917,21 @@ + itemstack1 = this.player.inventory.getItemInHand(); + if (itemstack1 != null) { + if (itemstack.getItem() == Items.WRITTEN_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) { ++ // CraftBukkit start ++ itemstack1 = new ItemStack(Items.WRITTEN_BOOK); + itemstack1.a("author", (NBTBase) (new NBTTagString(this.player.getName()))); + itemstack1.a("title", (NBTBase) (new NBTTagString(itemstack.getTag().getString("title")))); + itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); + itemstack1.setItem(Items.WRITTEN_BOOK); ++ CraftEventFactory.handleEditBookEvent(player, itemstack1); ++ // CraftBukkit end + } + + return; + } + } catch (Exception exception1) { + PlayerConnection.c.error("Couldn\'t sign book", exception1); ++ this.disconnect("Invalid book data!"); // CraftBukkit + return; + } finally { + packetdataserializer.release(); +@@ -976,11 +1948,12 @@ + } + } catch (Exception exception2) { + PlayerConnection.c.error("Couldn\'t select trade", exception2); ++ this.disconnect("Invalid trade data!"); // CraftBukkit + } + } else if ("MC|AdvCdm".equals(packetplayincustompayload.a())) { + if (!this.minecraftServer.getEnableCommandBlock()) { + this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0])); +- } else if (this.player.a(2, "") && this.player.abilities.canInstantlyBuild) { ++ } else if (this.player.getBukkitEntity().isOp() && this.player.abilities.canInstantlyBuild) { // CraftBukkit - Change to Bukkit OP versus Vanilla OP + packetdataserializer = packetplayincustompayload.b(); + + try { +@@ -1016,6 +1989,7 @@ + } + } catch (Exception exception3) { + PlayerConnection.c.error("Couldn\'t set command block", exception3); ++ this.disconnect("Invalid CommandBlock data!"); // CraftBukkit + } finally { + packetdataserializer.release(); + } +@@ -1041,6 +2015,7 @@ + } + } catch (Exception exception4) { + PlayerConnection.c.error("Couldn\'t set beacon", exception4); ++ this.disconnect("Invalid beacon data!"); // CraftBukkit + } + } + } else if ("MC|ItemName".equals(packetplayincustompayload.a()) && this.player.activeContainer instanceof ContainerAnvil) { +@@ -1056,7 +2031,35 @@ + containeranvil.a(""); + } + } ++ // CraftBukkit start ++ else if (packetplayincustompayload.a().equals("REGISTER")) { ++ String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8); ++ for (String channel : channels.split("\0")) { ++ getPlayer().addChannel(channel); ++ } ++ } else if (packetplayincustompayload.a().equals("UNREGISTER")) { ++ String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8); ++ for (String channel : channels.split("\0")) { ++ getPlayer().removeChannel(channel); ++ } ++ } else { ++ byte[] data = new byte[packetplayincustompayload.b().readableBytes()]; ++ packetplayincustompayload.b().readBytes(data); ++ server.getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), packetplayincustompayload.a(), data); ++ } ++ // CraftBukkit end ++ // CraftBukkit start ++ } finally { ++ if (packetplayincustompayload.b().refCnt() > 0) { ++ packetplayincustompayload.b().release(); ++ } ++ } ++ // CraftBukkit end ++ } + ++ // CraftBukkit start - Add "isDisconnected" method ++ public final boolean isDisconnected() { ++ return !this.player.joining && !this.networkManager.channel.config().isAutoRead(); + } + + static class SyntheticClass_1 { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerInteractManager.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerInteractManager.patch new file mode 100644 index 0000000..c4b0f19 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerInteractManager.patch @@ -0,0 +1,298 @@ +--- a/net/minecraft/server/PlayerInteractManager.java ++++ b/net/minecraft/server/PlayerInteractManager.java +@@ -1,5 +1,13 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.event.block.BlockBreakEvent; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.Event; ++import org.bukkit.event.block.Action; ++import org.bukkit.event.player.PlayerInteractEvent; ++// CraftBukkit end ++ + public class PlayerInteractManager { + + public World world; +@@ -26,7 +34,7 @@ + this.gamemode = worldsettings_enumgamemode; + worldsettings_enumgamemode.a(this.player.abilities); + this.player.updateAbilities(); +- this.player.server.getPlayerList().sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_GAME_MODE, new EntityPlayer[] { this.player})); ++ this.player.server.getPlayerList().sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_GAME_MODE, new EntityPlayer[] { this.player}), this.player); // CraftBukkit + } + + public WorldSettings.EnumGamemode getGameMode() { +@@ -50,7 +58,7 @@ + } + + public void a() { +- ++this.currentTick; ++ this.currentTick = MinecraftServer.currentTick; // CraftBukkit; + float f; + int i; + +@@ -95,6 +103,19 @@ + } + + public void a(BlockPosition blockposition, EnumDirection enumdirection) { ++ // CraftBukkit start ++ PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.inventory.getItemInHand()); ++ if (event.isCancelled()) { ++ // Let the client know the block still exists ++ ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); ++ // Update any tile entity data for this block ++ TileEntity tileentity = this.world.getTileEntity(blockposition); ++ if (tileentity != null) { ++ this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); ++ } ++ return; ++ } ++ // CraftBukkit end + if (this.isCreative()) { + if (!this.world.douseFire((EntityHuman) null, blockposition, enumdirection)) { + this.breakBlock(blockposition); +@@ -121,14 +142,48 @@ + } + } + +- this.world.douseFire((EntityHuman) null, blockposition, enumdirection); ++ // this.world.douseFire((EntityHuman) null, blockposition, enumdirection); // CraftBukkit - Moved down + this.lastDigTick = this.currentTick; + float f = 1.0F; + +- if (block.getMaterial() != Material.AIR) { ++ // CraftBukkit start - Swings at air do *NOT* exist. ++ if (event.useInteractedBlock() == Event.Result.DENY) { ++ // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. ++ IBlockData data = this.world.getType(blockposition); ++ if (block == Blocks.WOODEN_DOOR) { ++ // For some reason *BOTH* the bottom/top part have to be marked updated. ++ boolean bottom = data.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER; ++ ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); ++ ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, bottom ? blockposition.up() : blockposition.down())); ++ } else if (block == Blocks.TRAPDOOR) { ++ ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); ++ } ++ } else if (block.getMaterial() != Material.AIR) { + block.attack(this.world, blockposition, this.player); + f = block.getDamage(this.player, this.player.world, blockposition); ++ // Allow fire punching to be blocked ++ this.world.douseFire((EntityHuman) null, blockposition, enumdirection); ++ } ++ ++ if (event.useItemInHand() == Event.Result.DENY) { ++ // If we 'insta destroyed' then the client needs to be informed. ++ if (f > 1.0f) { ++ ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); ++ } ++ return; ++ } ++ org.bukkit.event.block.BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.player.inventory.getItemInHand(), f >= 1.0f); ++ ++ if (blockEvent.isCancelled()) { ++ // Let the client know the block still exists ++ ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); ++ return; ++ } ++ ++ if (blockEvent.getInstaBreak()) { ++ f = 2.0f; + } ++ // CraftBukkit end + + if (block.getMaterial() != Material.AIR && f >= 1.0F) { + this.breakBlock(blockposition); +@@ -146,6 +201,7 @@ + + public void a(BlockPosition blockposition) { + if (blockposition.equals(this.f)) { ++ this.currentTick = MinecraftServer.currentTick; // CraftBukkit + int i = this.currentTick - this.lastDigTick; + Block block = this.world.getType(blockposition).getBlock(); + +@@ -163,6 +219,10 @@ + this.j = this.lastDigTick; + } + } ++ // CraftBukkit start - Force block reset to client ++ } else { ++ this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); ++ // CraftBukkit end + } + + } +@@ -186,12 +246,72 @@ + } + + public boolean breakBlock(BlockPosition blockposition) { +- if (this.gamemode.d() && this.player.bA() != null && this.player.bA().getItem() instanceof ItemSword) { ++ // CraftBukkit start - fire BlockBreakEvent ++ BlockBreakEvent event = null; ++ ++ if (this.player instanceof EntityPlayer) { ++ org.bukkit.block.Block block = this.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ ++ // Sword + Creative mode pre-cancel ++ boolean isSwordNoBreak = this.gamemode.d() && this.player.bA() != null && this.player.bA().getItem() instanceof ItemSword; ++ ++ // Tell client the block is gone immediately then process events ++ // Don't tell the client if its a creative sword break because its not broken! ++ if (world.getTileEntity(blockposition) == null && !isSwordNoBreak) { ++ PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, blockposition); ++ packet.block = Blocks.AIR.getBlockData(); ++ ((EntityPlayer) this.player).playerConnection.sendPacket(packet); ++ } ++ ++ event = new BlockBreakEvent(block, this.player.getBukkitEntity()); ++ ++ // Sword + Creative mode pre-cancel ++ event.setCancelled(isSwordNoBreak); ++ ++ // Calculate default block experience ++ IBlockData nmsData = this.world.getType(blockposition); ++ Block nmsBlock = nmsData.getBlock(); ++ ++ if (nmsBlock != null && !event.isCancelled() && !this.isCreative() && this.player.b(nmsBlock)) { ++ // Copied from block.a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, TileEntity tileentity) ++ if (!(nmsBlock.I() && EnchantmentManager.hasSilkTouchEnchantment(this.player))) { ++ int data = block.getData(); ++ int bonusLevel = EnchantmentManager.getBonusBlockLootEnchantmentLevel(this.player); ++ ++ event.setExpToDrop(nmsBlock.getExpDrop(this.world, nmsData, bonusLevel)); ++ } ++ } ++ ++ this.world.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ if (isSwordNoBreak) { ++ return false; ++ } ++ // Let the client know the block still exists ++ ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); ++ // Update any tile entity data for this block ++ TileEntity tileentity = this.world.getTileEntity(blockposition); ++ if (tileentity != null) { ++ this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); ++ } ++ return false; ++ } ++ } ++ if (false && this.gamemode.d() && this.player.bA() != null && this.player.bA().getItem() instanceof ItemSword) { + return false; + } else { + IBlockData iblockdata = this.world.getType(blockposition); ++ if (iblockdata.getBlock() == Blocks.AIR) return false; // CraftBukkit - A plugin set block to air without cancelling + TileEntity tileentity = this.world.getTileEntity(blockposition); + ++ // CraftBukkit start - Special case skulls, their item data comes from a tile entity ++ if (iblockdata.getBlock() == Blocks.SKULL && !this.isCreative()) { ++ iblockdata.getBlock().dropNaturally(world, blockposition, iblockdata, 1.0F, 0); ++ return this.c(blockposition); ++ } ++ // CraftBukkit end ++ + if (this.gamemode.c()) { + if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { + return false; +@@ -230,6 +350,12 @@ + iblockdata.getBlock().a(this.world, this.player, blockposition, iblockdata, tileentity); + } + } ++ ++ // CraftBukkit start - Drop event experience ++ if (flag && event != null) { ++ iblockdata.getBlock().dropExperience(this.world, blockposition, event.getExpToDrop()); ++ } ++ // CraftBukkit end + + return flag; + } +@@ -267,7 +393,13 @@ + } + } + ++ // CraftBukkit start ++ public boolean interactResult = false; ++ public boolean firedInteract = false; ++ // CraftBukkit end ++ + public boolean interact(EntityHuman entityhuman, World world, ItemStack itemstack, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { ++ /* CraftBukkit start - whole method + if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { + TileEntity tileentity = world.getTileEntity(blockposition); + +@@ -312,6 +444,72 @@ + return itemstack.placeItem(entityhuman, world, blockposition, enumdirection, f, f1, f2); + } + } ++ // Interract event */ ++ IBlockData blockdata = world.getType(blockposition); ++ boolean result = false; ++ if (blockdata.getBlock() != Blocks.AIR) { ++ boolean cancelledBlock = false; ++ ++ if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { ++ TileEntity tileentity = world.getTileEntity(blockposition); ++ cancelledBlock = !(tileentity instanceof ITileInventory || tileentity instanceof IInventory); ++ } ++ ++ if (!entityhuman.getBukkitEntity().isOp() && itemstack != null && Block.asBlock(itemstack.getItem()) instanceof BlockCommand) { ++ cancelledBlock = true; ++ } ++ ++ PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(entityhuman, Action.RIGHT_CLICK_BLOCK, blockposition, enumdirection, itemstack, cancelledBlock); ++ firedInteract = true; ++ interactResult = event.useItemInHand() == Event.Result.DENY; ++ ++ if (event.useInteractedBlock() == Event.Result.DENY) { ++ // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. ++ if (blockdata.getBlock() instanceof BlockDoor) { ++ boolean bottom = blockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER; ++ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, bottom ? blockposition.up() : blockposition.down())); ++ } ++ result = (event.useItemInHand() != Event.Result.ALLOW); ++ } else if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { ++ TileEntity tileentity = world.getTileEntity(blockposition); ++ ++ if (tileentity instanceof ITileInventory) { ++ Block block = world.getType(blockposition).getBlock(); ++ ITileInventory itileinventory = (ITileInventory) tileentity; ++ ++ if (itileinventory instanceof TileEntityChest && block instanceof BlockChest) { ++ itileinventory = ((BlockChest) block).f(world, blockposition); ++ } ++ ++ if (itileinventory != null) { ++ entityhuman.openContainer(itileinventory); ++ return true; ++ } ++ } else if (tileentity instanceof IInventory) { ++ entityhuman.openContainer((IInventory) tileentity); ++ return true; ++ } ++ ++ return false; ++ } else if (!entityhuman.isSneaking() || itemstack == null) { ++ result = blockdata.getBlock().interact(world, blockposition, blockdata, entityhuman, enumdirection, f, f1, f2); ++ } ++ ++ if (itemstack != null && !result && !interactResult) { // add !interactResult SPIGOT-764 ++ int j1 = itemstack.getData(); ++ int k1 = itemstack.count; ++ ++ result = itemstack.placeItem(entityhuman, world, blockposition, enumdirection, f, f1, f2); ++ ++ // The item count should not decrement in Creative mode. ++ if (this.isCreative()) { ++ itemstack.setData(j1); ++ itemstack.count = k1; ++ } ++ } ++ } ++ return result; ++ // CraftBukkit end + } + + public void a(WorldServer worldserver) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerInventory.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerInventory.patch new file mode 100644 index 0000000..cf26956 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerInventory.patch @@ -0,0 +1,100 @@ +--- a/net/minecraft/server/PlayerInventory.java ++++ b/net/minecraft/server/PlayerInventory.java +@@ -2,6 +2,13 @@ + + import java.util.concurrent.Callable; + ++// CraftBukkit start ++import java.util.List; ++ ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class PlayerInventory implements IInventory { + + public ItemStack[] items = new ItemStack[36]; +@@ -11,6 +18,39 @@ + private ItemStack f; + public boolean e; + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public ItemStack[] getArmorContents() { ++ return this.armor; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return this.player.getBukkitEntity(); ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public PlayerInventory(EntityHuman entityhuman) { + this.player = entityhuman; + } +@@ -43,6 +83,22 @@ + return -1; + } + ++ // CraftBukkit start - Watch method above! :D ++ public int canHold(ItemStack itemstack) { ++ int remains = itemstack.count; ++ for (int i = 0; i < this.items.length; ++i) { ++ if (this.items[i] == null) return itemstack.count; ++ ++ // Taken from firstPartial(ItemStack) ++ if (this.items[i] != null && this.items[i].getItem() == itemstack.getItem() && this.items[i].isStackable() && this.items[i].count < this.items[i].getMaxStackSize() && this.items[i].count < this.getMaxStackSize() && (!this.items[i].usesData() || this.items[i].getData() == itemstack.getData()) && ItemStack.equals(this.items[i], itemstack)) { ++ remains -= (this.items[i].getMaxStackSize() < this.getMaxStackSize() ? this.items[i].getMaxStackSize() : this.getMaxStackSize()) - this.items[i].count; ++ } ++ if (remains <= 0) return itemstack.count; ++ } ++ return itemstack.count - remains; ++ } ++ // CraftBukkit end ++ + public int getFirstEmptySlotIndex() { + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] == null) { +@@ -390,7 +446,7 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return maxStack; // CraftBukkit + } + + public boolean b(Block block) { +@@ -466,6 +522,11 @@ + } + + public ItemStack getCarried() { ++ // CraftBukkit start ++ if (this.f != null && this.f.count == 0) { ++ this.setCarried(null); ++ } ++ // CraftBukkit end + return this.f; + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerList.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerList.patch new file mode 100644 index 0000000..52d22e6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PlayerList.patch @@ -0,0 +1,875 @@ +--- a/net/minecraft/server/PlayerList.java ++++ b/net/minecraft/server/PlayerList.java +@@ -18,6 +18,26 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; ++ ++import org.bukkit.Bukkit; ++import org.bukkit.Location; ++import org.bukkit.TravelAgent; ++import org.bukkit.craftbukkit.util.CraftChatMessage; ++import org.bukkit.entity.Player; ++import org.bukkit.event.player.PlayerChangedWorldEvent; ++import org.bukkit.event.player.PlayerPortalEvent; ++import org.bukkit.event.player.PlayerJoinEvent; ++import org.bukkit.event.player.PlayerLoginEvent; ++import org.bukkit.event.player.PlayerQuitEvent; ++import org.bukkit.event.player.PlayerRespawnEvent; ++import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; ++import org.bukkit.util.Vector; ++// CraftBukkit end ++ + public abstract class PlayerList { + + public static final File a = new File("banned-players.json"); +@@ -27,7 +47,7 @@ + private static final Logger f = LogManager.getLogger(); + private static final SimpleDateFormat g = new SimpleDateFormat("yyyy-MM-dd \'at\' HH:mm:ss z"); + private final MinecraftServer server; +- public final List players = Lists.newArrayList(); ++ public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety + private final Map j = Maps.newHashMap(); + private final GameProfileBanList k; + private final IpBanList l; +@@ -42,7 +62,15 @@ + private boolean t; + private int u; + ++ // CraftBukkit start ++ private CraftServer cserver; ++ + public PlayerList(MinecraftServer minecraftserver) { ++ this.cserver = minecraftserver.server = new CraftServer(minecraftserver, this); ++ minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance(); ++ minecraftserver.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(minecraftserver.server)); ++ // CraftBukkit end ++ + this.k = new GameProfileBanList(PlayerList.a); + this.l = new IpBanList(PlayerList.b); + this.operators = new OpList(PlayerList.c); +@@ -62,6 +90,12 @@ + + usercache.a(gameprofile); + NBTTagCompound nbttagcompound = this.a(entityplayer); ++ // CraftBukkit start - Better rename detection ++ if (nbttagcompound != null && nbttagcompound.hasKey("bukkit")) { ++ NBTTagCompound bukkit = nbttagcompound.getCompound("bukkit"); ++ s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s; ++ } ++ // CraftBukkit end + + entityplayer.spawnIn(this.server.getWorldServer(entityplayer.dimension)); + entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); +@@ -71,7 +105,8 @@ + s1 = networkmanager.getSocketAddress().toString(); + } + +- PlayerList.f.info(entityplayer.getName() + "[" + s1 + "] logged in with entity id " + entityplayer.getId() + " at (" + entityplayer.locX + ", " + entityplayer.locY + ", " + entityplayer.locZ + ")"); ++ // CraftBukkit - Moved message to after join ++ // PlayerList.f.info(entityplayer.getName() + "[" + s1 + "] logged in with entity id " + entityplayer.getId() + " at (" + entityplayer.locX + ", " + entityplayer.locY + ", " + entityplayer.locZ + ")"); + WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); + WorldData worlddata = worldserver.getWorldData(); + BlockPosition blockposition = worldserver.getSpawn(); +@@ -79,7 +114,8 @@ + this.a(entityplayer, (EntityPlayer) null, worldserver); + PlayerConnection playerconnection = new PlayerConnection(this.server, networkmanager, entityplayer); + +- playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), worlddata.isHardcore(), worldserver.worldProvider.getDimension(), worldserver.getDifficulty(), this.getMaxPlayers(), worlddata.getType(), worldserver.getGameRules().getBoolean("reducedDebugInfo"))); ++ playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), worlddata.isHardcore(), worldserver.worldProvider.getDimension(), worldserver.getDifficulty(), Math.min(this.getMaxPlayers(), 60), worlddata.getType(), worldserver.getGameRules().getBoolean("reducedDebugInfo"))); // CraftBukkit - cap player list to 60 ++ entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit + playerconnection.sendPacket(new PacketPlayOutCustomPayload("MC|Brand", (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); + playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + playerconnection.sendPacket(new PacketPlayOutSpawnPosition(blockposition)); +@@ -89,17 +125,23 @@ + entityplayer.getStatisticManager().updateStatistics(entityplayer); + this.sendScoreboard((ScoreboardServer) worldserver.getScoreboard(), entityplayer); + this.server.aH(); +- ChatMessage chatmessage; ++ // CraftBukkit start - login message is handled in the event ++ // ChatMessage chatmessage; + ++ String joinMessage; + if (!entityplayer.getName().equalsIgnoreCase(s)) { +- chatmessage = new ChatMessage("multiplayer.player.joined.renamed", new Object[] { entityplayer.getScoreboardDisplayName(), s}); ++ // chatmessage = new ChatMessage("multiplayer.player.joined.renamed", new Object[] { entityplayer.getScoreboardDisplayName(), s}); ++ joinMessage = "\u00A7e" + LocaleI18n.a("multiplayer.player.joined.renamed", entityplayer.getName(), s); + } else { +- chatmessage = new ChatMessage("multiplayer.player.joined", new Object[] { entityplayer.getScoreboardDisplayName()}); ++ // chatmessage = new ChatMessage("multiplayer.player.joined", new Object[] { entityplayer.getScoreboardDisplayName()}); ++ joinMessage = "\u00A7e" + LocaleI18n.a("multiplayer.player.joined", entityplayer.getName()); + } + +- chatmessage.getChatModifier().setColor(EnumChatFormat.YELLOW); +- this.sendMessage(chatmessage); +- this.onPlayerJoin(entityplayer); ++ // chatmessage.getChatModifier().setColor(EnumChatFormat.YELLOW); ++ // this.sendMessage(chatmessage); ++ this.onPlayerJoin(entityplayer, joinMessage); ++ // CraftBukkit end ++ worldserver = server.getWorldServer(entityplayer.dimension); // CraftBukkit - Update in case join event changed it + playerconnection.a(entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch); + this.b(entityplayer, worldserver); + if (this.server.getResourcePack().length() > 0) { +@@ -126,6 +168,8 @@ + } + } + ++ // CraftBukkit - Moved from above, added world ++ PlayerList.f.info(entityplayer.getName() + "[" + s1 + "] logged in with entity id " + entityplayer.getId() + " at ([" + entityplayer.world.worldData.getName() + "]" + entityplayer.locX + ", " + entityplayer.locY + ", " + entityplayer.locZ + ")"); + } + + public void sendScoreboard(ScoreboardServer scoreboardserver, EntityPlayer entityplayer) { +@@ -158,6 +202,7 @@ + } + + public void setPlayerFileData(WorldServer[] aworldserver) { ++ if (playerFileData != null) return; // CraftBukkit + this.playerFileData = aworldserver[0].getDataManager().getPlayerFileData(); + aworldserver[0].getWorldBorder().a(new IWorldBorderListener() { + public void a(WorldBorder worldborder, double d0) { +@@ -202,7 +247,7 @@ + } + + public NBTTagCompound a(EntityPlayer entityplayer) { +- NBTTagCompound nbttagcompound = this.server.worldServer[0].getWorldData().i(); ++ NBTTagCompound nbttagcompound = this.server.worlds.get(0).getWorldData().i(); // CraftBukkit + NBTTagCompound nbttagcompound1; + + if (entityplayer.getName().equals(this.server.S()) && nbttagcompound != null) { +@@ -226,33 +271,72 @@ + + } + +- public void onPlayerJoin(EntityPlayer entityplayer) { ++ public void onPlayerJoin(EntityPlayer entityplayer, String joinMessage) { // CraftBukkit added param + this.players.add(entityplayer); + this.j.put(entityplayer.getUniqueID(), entityplayer); +- this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[] { entityplayer})); ++ // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[] { entityplayer})); // CraftBukkit - replaced with loop below + WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); + +- worldserver.addEntity(entityplayer); +- this.a(entityplayer, (WorldServer) null); ++ // CraftBukkit start ++ PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage); ++ cserver.getPluginManager().callEvent(playerJoinEvent); ++ ++ joinMessage = playerJoinEvent.getJoinMessage(); ++ ++ if (joinMessage != null && joinMessage.length() > 0) { ++ for (IChatBaseComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) { ++ server.getPlayerList().sendAll(new PacketPlayOutChat(line)); ++ } ++ } ++ ++ ChunkIOExecutor.adjustPoolSize(getPlayerCount()); ++ // CraftBukkit end ++ ++ // CraftBukkit start - sendAll above replaced with this loop ++ PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, entityplayer); + + for (int i = 0; i < this.players.size(); ++i) { + EntityPlayer entityplayer1 = (EntityPlayer) this.players.get(i); + ++ if (entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { ++ entityplayer1.playerConnection.sendPacket(packet); ++ } ++ ++ if (!entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) { ++ continue; ++ } ++ + entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[] { entityplayer1})); + } ++ // CraftBukkit end + ++ // CraftBukkit start - Only add if the player wasn't moved in the event ++ if (entityplayer.world == worldserver && !worldserver.players.contains(entityplayer)) { ++ worldserver.addEntity(entityplayer); ++ this.a(entityplayer, (WorldServer) null); ++ } ++ // CraftBukkit end + } + + public void d(EntityPlayer entityplayer) { + entityplayer.u().getPlayerChunkMap().movePlayer(entityplayer); + } + +- public void disconnect(EntityPlayer entityplayer) { ++ public String disconnect(EntityPlayer entityplayer) { // CraftBukkit - return string + entityplayer.b(StatisticList.f); ++ ++ // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleInventoryCloseEvent(entityplayer); ++ ++ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), "\u00A7e" + entityplayer.getName() + " left the game."); ++ cserver.getPluginManager().callEvent(playerQuitEvent); ++ entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); ++ // CraftBukkit end ++ + this.savePlayerFile(entityplayer); + WorldServer worldserver = entityplayer.u(); + +- if (entityplayer.vehicle != null) { ++ if (entityplayer.vehicle != null && !(entityplayer.vehicle instanceof EntityPlayer)) { // CraftBukkit - Don't remove players + worldserver.removeEntity(entityplayer.vehicle); + PlayerList.f.debug("removing player mount"); + } +@@ -268,13 +352,61 @@ + this.o.remove(uuid); + } + +- this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[] { entityplayer})); ++ // CraftBukkit start ++ // this.sendAll(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[] { entityplayer})); ++ PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityplayer); ++ for (int i = 0; i < players.size(); i++) { ++ EntityPlayer entityplayer2 = (EntityPlayer) this.players.get(i); ++ ++ if (entityplayer2.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { ++ entityplayer2.playerConnection.sendPacket(packet); ++ } else { ++ entityplayer2.getBukkitEntity().removeDisconnectingPlayer(entityplayer.getBukkitEntity()); ++ } ++ } ++ // This removes the scoreboard (and player reference) for the specific player in the manager ++ cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); ++ // CraftBukkit end ++ ++ ChunkIOExecutor.adjustPoolSize(this.getPlayerCount()); // CraftBukkit ++ ++ return playerQuitEvent.getQuitMessage(); // CraftBukkit + } + +- public String attemptLogin(SocketAddress socketaddress, GameProfile gameprofile) { ++ // CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer ++ public EntityPlayer attemptLogin(LoginListener loginlistener, GameProfile gameprofile, String hostname) { ++ // Moved from processLogin ++ UUID uuid = EntityHuman.a(gameprofile); ++ ArrayList arraylist = Lists.newArrayList(); ++ ++ EntityPlayer entityplayer; ++ ++ for (int i = 0; i < this.players.size(); ++i) { ++ entityplayer = (EntityPlayer) this.players.get(i); ++ if (entityplayer.getUniqueID().equals(uuid)) { ++ arraylist.add(entityplayer); ++ } ++ } ++ ++ Iterator iterator = arraylist.iterator(); ++ ++ while (iterator.hasNext()) { ++ entityplayer = (EntityPlayer) iterator.next(); ++ savePlayerFile(entityplayer); // CraftBukkit - Force the player's inventory to be saved ++ entityplayer.playerConnection.disconnect("You logged in from another location"); ++ } ++ ++ // Instead of kicking then returning, we need to store the kick reason ++ // in the event, check with plugins to see if it's ok, and THEN kick ++ // depending on the outcome. ++ SocketAddress socketaddress = loginlistener.networkManager.getSocketAddress(); ++ ++ EntityPlayer entity = new EntityPlayer(server, server.getWorldServer(0), gameprofile, new PlayerInteractManager(server.getWorldServer(0))); ++ Player player = entity.getBukkitEntity(); ++ PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress()); + String s; + +- if (this.k.isBanned(gameprofile)) { ++ if (getProfileBans().isBanned(gameprofile) && !getProfileBans().get(gameprofile).hasExpired()) { + GameProfileBanEntry gameprofilebanentry = (GameProfileBanEntry) this.k.get(gameprofile); + + s = "You are banned from this server!\nReason: " + gameprofilebanentry.getReason(); +@@ -282,10 +414,12 @@ + s = s + "\nYour ban will be removed on " + PlayerList.g.format(gameprofilebanentry.getExpires()); + } + +- return s; ++ // return s; ++ event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s); + } else if (!this.isWhitelisted(gameprofile)) { +- return "You are not white-listed on this server!"; +- } else if (this.l.isBanned(socketaddress)) { ++ // return "You are not white-listed on this server!"; ++ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "You are not white-listed on this server!"); ++ } else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) { + IpBanEntry ipbanentry = this.l.get(socketaddress); + + s = "Your IP address is banned from this server!\nReason: " + ipbanentry.getReason(); +@@ -293,13 +427,25 @@ + s = s + "\nYour ban will be removed on " + PlayerList.g.format(ipbanentry.getExpires()); + } + +- return s; ++ // return s; ++ event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s); + } else { +- return this.players.size() >= this.maxPlayers && !this.f(gameprofile) ? "The server is full!" : null; ++ // return this.players.size() >= this.maxPlayers && !this.f(gameprofile) ? "The server is full!" : null; ++ if (this.players.size() >= this.maxPlayers && !this.f(gameprofile)) { ++ event.disallow(PlayerLoginEvent.Result.KICK_FULL, "The server is full"); ++ } + } ++ ++ cserver.getPluginManager().callEvent(event); ++ if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { ++ loginlistener.disconnect(event.getKickMessage()); ++ return null; ++ } ++ return entity; + } + +- public EntityPlayer processLogin(GameProfile gameprofile) { ++ public EntityPlayer processLogin(GameProfile gameprofile, EntityPlayer player) { // CraftBukkit - added EntityPlayer ++ /* CraftBukkit startMoved up + UUID uuid = EntityHuman.a(gameprofile); + ArrayList arraylist = Lists.newArrayList(); + +@@ -334,17 +480,25 @@ + } + + return new EntityPlayer(this.server, this.server.getWorldServer(0), gameprofile, (PlayerInteractManager) object); ++ */ ++ return player; ++ // CraftBukkit end + } + ++ // CraftBukkit start + public EntityPlayer moveToWorld(EntityPlayer entityplayer, int i, boolean flag) { ++ return this.moveToWorld(entityplayer, i, flag, null, true); ++ } ++ public EntityPlayer moveToWorld(EntityPlayer entityplayer, int i, boolean flag, Location location, boolean avoidSuffocation) { + entityplayer.u().getTracker().untrackPlayer(entityplayer); +- entityplayer.u().getTracker().untrackEntity(entityplayer); ++ // entityplayer.u().getTracker().untrackEntity(entityplayer); // CraftBukkit + entityplayer.u().getPlayerChunkMap().removePlayer(entityplayer); + this.players.remove(entityplayer); + this.server.getWorldServer(entityplayer.dimension).removeEntity(entityplayer); + BlockPosition blockposition = entityplayer.getBed(); + boolean flag1 = entityplayer.isRespawnForced(); + ++ /* CraftBukkit start + entityplayer.dimension = i; + Object object; + +@@ -355,80 +509,276 @@ + } + + EntityPlayer entityplayer1 = new EntityPlayer(this.server, this.server.getWorldServer(entityplayer.dimension), entityplayer.getProfile(), (PlayerInteractManager) object); +- ++ // */ ++ EntityPlayer entityplayer1 = entityplayer; ++ org.bukkit.World fromWorld = entityplayer.getBukkitEntity().getWorld(); ++ entityplayer.viewingCredits = false; ++ // CraftBukkit end ++ + entityplayer1.playerConnection = entityplayer.playerConnection; + entityplayer1.copyTo(entityplayer, flag); + entityplayer1.d(entityplayer.getId()); + entityplayer1.o(entityplayer); +- WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); ++ // WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); // CraftBukkit - handled later + +- this.a(entityplayer1, entityplayer, worldserver); ++ // this.a(entityplayer1, entityplayer, worldserver); // CraftBukkit - removed + BlockPosition blockposition1; + +- if (blockposition != null) { +- blockposition1 = EntityHuman.getBed(this.server.getWorldServer(entityplayer.dimension), blockposition, flag1); +- if (blockposition1 != null) { +- entityplayer1.setPositionRotation((double) ((float) blockposition1.getX() + 0.5F), (double) ((float) blockposition1.getY() + 0.1F), (double) ((float) blockposition1.getZ() + 0.5F), 0.0F, 0.0F); +- entityplayer1.setRespawnPosition(blockposition, flag1); +- } else { +- entityplayer1.playerConnection.sendPacket(new PacketPlayOutGameStateChange(0, 0.0F)); ++ // CraftBukkit start - fire PlayerRespawnEvent ++ if (location == null) { ++ boolean isBedSpawn = false; ++ CraftWorld cworld = (CraftWorld) this.server.server.getWorld(entityplayer.spawnWorld); ++ if (cworld != null && blockposition != null) { ++ blockposition1 = EntityHuman.getBed(cworld.getHandle(), blockposition, flag1); ++ if (blockposition1 != null) { ++ isBedSpawn = true; ++ location = new Location(cworld, blockposition1.getX() + 0.5, blockposition1.getY(), blockposition1.getZ() + 0.5); ++ } else { ++ entityplayer1.setRespawnPosition(null, true); ++ entityplayer1.playerConnection.sendPacket(new PacketPlayOutGameStateChange(0, 0.0F)); ++ } + } ++ ++ if (location == null) { ++ cworld = (CraftWorld) this.server.server.getWorlds().get(0); ++ blockposition = cworld.getHandle().getSpawn(); ++ location = new Location(cworld, blockposition.getX() + 0.5, blockposition.getY(), blockposition.getZ() + 0.5); ++ } ++ ++ Player respawnPlayer = cserver.getPlayer(entityplayer1); ++ PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn); ++ cserver.getPluginManager().callEvent(respawnEvent); ++ ++ location = respawnEvent.getRespawnLocation(); ++ entityplayer.reset(); ++ } else { ++ location.setWorld(server.getWorldServer(i).getWorld()); + } ++ WorldServer worldserver = ((CraftWorld) location.getWorld()).getHandle(); ++ entityplayer1.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); ++ // CraftBukkit end + + worldserver.chunkProviderServer.getChunkAt((int) entityplayer1.locX >> 4, (int) entityplayer1.locZ >> 4); + +- while (!worldserver.getCubes(entityplayer1, entityplayer1.getBoundingBox()).isEmpty() && entityplayer1.locY < 256.0D) { ++ while (avoidSuffocation && !worldserver.getCubes(entityplayer1, entityplayer1.getBoundingBox()).isEmpty() && entityplayer1.locY < 256.0D) { + entityplayer1.setPosition(entityplayer1.locX, entityplayer1.locY + 1.0D, entityplayer1.locZ); + } +- +- entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(entityplayer1.dimension, entityplayer1.world.getDifficulty(), entityplayer1.world.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode())); ++ // CraftBukkit start ++ byte actualDimension = (byte) (worldserver.getWorld().getEnvironment().getId()); ++ // Force the client to refresh their chunk cache ++ if (fromWorld.getEnvironment() == worldserver.getWorld().getEnvironment()) { ++ entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn((byte) (actualDimension >= 0 ? -1 : 0), worldserver.getDifficulty(), worldserver.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode())); ++ } ++ entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(actualDimension, worldserver.getDifficulty(), worldserver.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode())); ++ entityplayer1.spawnIn(worldserver); ++ entityplayer1.dead = false; ++ entityplayer1.playerConnection.teleport(new Location(worldserver.getWorld(), entityplayer1.locX, entityplayer1.locY, entityplayer1.locZ, entityplayer1.yaw, entityplayer1.pitch)); ++ entityplayer1.setSneaking(false); + blockposition1 = worldserver.getSpawn(); +- entityplayer1.playerConnection.a(entityplayer1.locX, entityplayer1.locY, entityplayer1.locZ, entityplayer1.yaw, entityplayer1.pitch); ++ // entityplayer1.playerConnection.a(entityplayer1.locX, entityplayer1.locY, entityplayer1.locZ, entityplayer1.yaw, entityplayer1.pitch); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutSpawnPosition(blockposition1)); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutExperience(entityplayer1.exp, entityplayer1.expTotal, entityplayer1.expLevel)); + this.b(entityplayer1, worldserver); +- worldserver.getPlayerChunkMap().addPlayer(entityplayer1); +- worldserver.addEntity(entityplayer1); +- this.players.add(entityplayer1); +- this.j.put(entityplayer1.getUniqueID(), entityplayer1); +- entityplayer1.syncInventory(); ++ ++ if (!entityplayer.playerConnection.isDisconnected()) { ++ worldserver.getPlayerChunkMap().addPlayer(entityplayer1); ++ worldserver.addEntity(entityplayer1); ++ this.players.add(entityplayer1); ++ this.j.put(entityplayer1.getUniqueID(), entityplayer1); ++ } ++ // Added from changeDimension ++ updateClient(entityplayer); // Update health, etc... ++ entityplayer.updateAbilities(); ++ for (Object o1 : entityplayer.getEffects()) { ++ MobEffect mobEffect = (MobEffect) o1; ++ entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(entityplayer.getId(), mobEffect)); ++ } ++ // entityplayer1.syncInventory(); ++ // CraftBukkit end + entityplayer1.setHealth(entityplayer1.getHealth()); ++ ++ // CraftBukkit start ++ // Don't fire on respawn ++ if (fromWorld != location.getWorld()) { ++ PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(entityplayer.getBukkitEntity(), fromWorld); ++ server.server.getPluginManager().callEvent(event); ++ } ++ ++ // Save player file again if they were disconnected ++ if (entityplayer.playerConnection.isDisconnected()) { ++ this.savePlayerFile(entityplayer); ++ } ++ // CraftBukkit end + return entityplayer1; + } + +- public void changeDimension(EntityPlayer entityplayer, int i) { +- int j = entityplayer.dimension; +- WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); ++ // CraftBukkit start - Replaced the standard handling of portals with a more customised method. ++ public void changeDimension(EntityPlayer entityplayer, int i, TeleportCause cause) { ++ WorldServer exitWorld = null; ++ if (entityplayer.dimension < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // plugins must specify exit from custom Bukkit worlds ++ // only target existing worlds (compensate for allow-nether/allow-end as false) ++ for (WorldServer world : this.server.worlds) { ++ if (world.dimension == i) { ++ exitWorld = world; ++ } ++ } ++ } + +- entityplayer.dimension = i; +- WorldServer worldserver1 = this.server.getWorldServer(entityplayer.dimension); ++ Location enter = entityplayer.getBukkitEntity().getLocation(); ++ Location exit = null; ++ boolean useTravelAgent = false; // don't use agent for custom worlds or return from THE_END ++ if (exitWorld != null) { ++ if ((cause == TeleportCause.END_PORTAL) && (i == 0)) { ++ // THE_END -> NORMAL; use bed if available, otherwise default spawn ++ exit = ((org.bukkit.craftbukkit.entity.CraftPlayer) entityplayer.getBukkitEntity()).getBedSpawnLocation(); ++ if (exit == null || ((CraftWorld) exit.getWorld()).getHandle().dimension != 0) { ++ exit = exitWorld.getWorld().getSpawnLocation(); ++ } ++ } else { ++ // NORMAL <-> NETHER or NORMAL -> THE_END ++ exit = this.calculateTarget(enter, exitWorld); ++ useTravelAgent = true; ++ } ++ } + +- entityplayer.playerConnection.sendPacket(new PacketPlayOutRespawn(entityplayer.dimension, entityplayer.world.getDifficulty(), entityplayer.world.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode())); +- worldserver.removeEntity(entityplayer); +- entityplayer.dead = false; +- this.changeWorld(entityplayer, j, worldserver, worldserver1); +- this.a(entityplayer, worldserver); +- entityplayer.playerConnection.a(entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch); +- entityplayer.playerInteractManager.a(worldserver1); +- this.b(entityplayer, worldserver1); +- this.updateClient(entityplayer); +- Iterator iterator = entityplayer.getEffects().iterator(); ++ TravelAgent agent = exit != null ? (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().getTravelAgent() : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins ++ PlayerPortalEvent event = new PlayerPortalEvent(entityplayer.getBukkitEntity(), enter, exit, agent, cause); ++ event.useTravelAgent(useTravelAgent); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled() || event.getTo() == null) { ++ return; ++ } + +- while (iterator.hasNext()) { +- MobEffect mobeffect = (MobEffect) iterator.next(); ++ exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo(); ++ if (exit == null) { ++ return; ++ } ++ exitWorld = ((CraftWorld) exit.getWorld()).getHandle(); + +- entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(entityplayer.getId(), mobeffect)); ++ org.bukkit.event.player.PlayerTeleportEvent tpEvent = new org.bukkit.event.player.PlayerTeleportEvent(entityplayer.getBukkitEntity(), enter, exit, cause); ++ Bukkit.getServer().getPluginManager().callEvent(tpEvent); ++ if (tpEvent.isCancelled() || tpEvent.getTo() == null) { ++ return; + } + ++ Vector velocity = entityplayer.getBukkitEntity().getVelocity(); ++ boolean before = exitWorld.chunkProviderServer.forceChunkLoad; ++ exitWorld.chunkProviderServer.forceChunkLoad = true; ++ exitWorld.getTravelAgent().adjustExit(entityplayer, exit, velocity); ++ exitWorld.chunkProviderServer.forceChunkLoad = before; ++ ++ this.moveToWorld(entityplayer, exitWorld.dimension, true, exit, false); // Vanilla doesn't check for suffocation when handling portals, so neither should we ++ if (entityplayer.motX != velocity.getX() || entityplayer.motY != velocity.getY() || entityplayer.motZ != velocity.getZ()) { ++ entityplayer.getBukkitEntity().setVelocity(velocity); ++ } + } + + public void changeWorld(Entity entity, int i, WorldServer worldserver, WorldServer worldserver1) { ++ // CraftBukkit start - Split into modular functions ++ Location exit = calculateTarget(entity.getBukkitEntity().getLocation(), worldserver1); ++ repositionEntity(entity, exit, true); ++ } ++ ++ // Copy of original changeWorld(Entity, int, WorldServer, WorldServer) method with only location calculation logic ++ public Location calculateTarget(Location enter, World target) { ++ WorldServer worldserver = ((CraftWorld) enter.getWorld()).getHandle(); ++ WorldServer worldserver1 = ((CraftWorld) target.getWorld()).getHandle(); ++ int i = worldserver.dimension; ++ ++ double y = enter.getY(); ++ float yaw = enter.getYaw(); ++ float pitch = enter.getPitch(); ++ double d0 = enter.getX(); ++ double d1 = enter.getZ(); ++ double d2 = 8.0D; ++ /* + double d0 = entity.locX; + double d1 = entity.locZ; + double d2 = 8.0D; + float f = entity.yaw; + + worldserver.methodProfiler.a("moving"); ++ */ ++ if (worldserver1.dimension == -1) { ++ d0 = MathHelper.a(d0 / d2, worldserver1.getWorldBorder().b()+ 16.0D, worldserver1.getWorldBorder().d() - 16.0D); ++ d1 = MathHelper.a(d1 / d2, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); ++ /* ++ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ */ ++ } else if (worldserver1.dimension == 0) { ++ d0 = MathHelper.a(d0 * d2, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); ++ d1 = MathHelper.a(d1 * d2, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); ++ /* ++ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ */ ++ } else { ++ BlockPosition blockposition; ++ ++ if (i == 1) { ++ // use default NORMAL world spawn instead of target ++ worldserver1 = this.server.worlds.get(0); ++ blockposition = worldserver1.getSpawn(); ++ } else { ++ blockposition = worldserver1.getDimensionSpawn(); ++ } ++ ++ d0 = (double) blockposition.getX(); ++ y = (double) blockposition.getY(); ++ d1 = (double) blockposition.getZ(); ++ /* ++ entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ */ ++ } ++ ++ // worldserver.methodProfiler.b(); ++ if (i != 1) { ++ worldserver.methodProfiler.a("placing"); ++ d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872); ++ d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872); ++ /* ++ if (entity.isAlive()) { ++ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ worldserver1.getTravelAgent().a(entity, f); ++ worldserver1.addEntity(entity); ++ worldserver1.entityJoinedWorld(entity, false); ++ } ++ ++ worldserver.methodProfiler.b(); ++ */ ++ } ++ ++ // entity.spawnIn(worldserver1); ++ return new Location(worldserver1.getWorld(), d0, y, d1, yaw, pitch); ++ } ++ ++ // copy of original a(Entity, int, WorldServer, WorldServer) method with only entity repositioning logic ++ public void repositionEntity(Entity entity, Location exit, boolean portal) { ++ WorldServer worldserver = (WorldServer) entity.world; ++ WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); ++ int i = worldserver.dimension; ++ ++ /* ++ double d0 = entity.locX; ++ double d1 = entity.locZ; ++ double d2 = 8.0D; ++ float f = entity.yaw; ++ ++ worldserver.methodProfiler.a("moving"); ++ */ ++ entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ /* + if (entity.dimension == -1) { + d0 = MathHelper.a(d0 / d2, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); + d1 = MathHelper.a(d1 / d2, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); +@@ -447,6 +797,8 @@ + BlockPosition blockposition; + + if (i == 1) { ++ // use default NORMAL world spawn instead of target ++ worldserver1 = this.server.worlds.get(0); + blockposition = worldserver1.getSpawn(); + } else { + blockposition = worldserver1.getDimensionSpawn(); +@@ -460,15 +812,26 @@ + worldserver.entityJoinedWorld(entity, false); + } + } ++ */ + + worldserver.methodProfiler.b(); + if (i != 1) { + worldserver.methodProfiler.a("placing"); ++ /* + d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872); + d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872); ++ */ + if (entity.isAlive()) { +- entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); +- worldserver1.getTravelAgent().a(entity, f); ++ // entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ // worldserver1.getTravelAgent().a(entity, f); ++ if (portal) { ++ Vector velocity = entity.getBukkitEntity().getVelocity(); ++ worldserver1.getTravelAgent().adjustExit(entity, exit, velocity); ++ entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); ++ if (entity.motX != velocity.getX() || entity.motY != velocity.getY() || entity.motZ != velocity.getZ()) { ++ entity.getBukkitEntity().setVelocity(velocity); ++ } ++ } + worldserver1.addEntity(entity); + worldserver1.entityJoinedWorld(entity, false); + } +@@ -477,6 +840,7 @@ + } + + entity.spawnIn(worldserver1); ++ // CraftBukkit end + } + + public void tick() { +@@ -494,6 +858,25 @@ + + } + ++ // CraftBukkit start - add a world/entity limited version ++ public void sendAll(Packet packet, EntityHuman entityhuman) { ++ for (int i = 0; i < this.players.size(); ++i) { ++ EntityPlayer entityplayer = this.players.get(i); ++ if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { ++ continue; ++ } ++ ((EntityPlayer) this.players.get(i)).playerConnection.sendPacket(packet); ++ } ++ } ++ ++ public void sendAll(Packet packet, World world) { ++ for (int i = 0; i < world.players.size(); ++i) { ++ ((EntityPlayer) world.players.get(i)).playerConnection.sendPacket(packet); ++ } ++ ++ } ++ // CraftBukkit end ++ + public void a(Packet packet, int i) { + for (int j = 0; j < this.players.size(); ++j) { + EntityPlayer entityplayer = (EntityPlayer) this.players.get(j); +@@ -589,10 +972,24 @@ + + public void addOp(GameProfile gameprofile) { + this.operators.add(new OpListEntry(gameprofile, this.server.p(), this.operators.b(gameprofile))); ++ ++ // CraftBukkit start ++ Player player = server.server.getPlayer(gameprofile.getId()); ++ if (player != null) { ++ player.recalculatePermissions(); ++ } ++ // CraftBukkit end + } + + public void removeOp(GameProfile gameprofile) { + this.operators.remove(gameprofile); ++ ++ // CraftBukkit start ++ Player player = server.server.getPlayer(gameprofile.getId()); ++ if (player != null) { ++ player.recalculatePermissions(); ++ } ++ // CraftBukkit end + } + + public boolean isWhitelisted(GameProfile gameprofile) { +@@ -600,7 +997,7 @@ + } + + public boolean isOp(GameProfile gameprofile) { +- return this.operators.d(gameprofile) || this.server.T() && this.server.worldServer[0].getWorldData().v() && this.server.S().equalsIgnoreCase(gameprofile.getName()) || this.t; ++ return this.operators.d(gameprofile) || this.server.T() && this.server.worlds.get(0).getWorldData().v() && this.server.S().equalsIgnoreCase(gameprofile.getName()) || this.t; // CraftBukkit + } + + public EntityPlayer getPlayer(String s) { +@@ -627,6 +1024,12 @@ + for (int j = 0; j < this.players.size(); ++j) { + EntityPlayer entityplayer = (EntityPlayer) this.players.get(j); + ++ // CraftBukkit start - Test if player receiving packet can see the source of the packet ++ if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { ++ continue; ++ } ++ // CraftBukkit end ++ + if (entityplayer != entityhuman && entityplayer.dimension == i) { + double d4 = d0 - entityplayer.locX; + double d5 = d1 - entityplayer.locY; +@@ -674,21 +1077,26 @@ + public void reloadWhitelist() {} + + public void b(EntityPlayer entityplayer, WorldServer worldserver) { +- WorldBorder worldborder = this.server.worldServer[0].getWorldBorder(); ++ WorldBorder worldborder = entityplayer.world.getWorldBorder(); // CraftBukkit + + entityplayer.playerConnection.sendPacket(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.INITIALIZE)); + entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle"))); + if (worldserver.S()) { +- entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(1, 0.0F)); +- entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, worldserver.j(1.0F))); +- entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, worldserver.h(1.0F))); ++ // CraftBukkit start - handle player weather ++ // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(1, 0.0F)); ++ // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, worldserver.j(1.0F))); ++ // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, worldserver.h(1.0F))); ++ entityplayer.setPlayerWeather(org.bukkit.WeatherType.DOWNFALL, false); ++ entityplayer.updateWeather(-worldserver.p, worldserver.p, -worldserver.r, worldserver.r); ++ // CraftBukkit end + } + + } + + public void updateClient(EntityPlayer entityplayer) { + entityplayer.updateInventory(entityplayer.defaultContainer); +- entityplayer.triggerHealthUpdate(); ++ // entityplayer.triggerHealthUpdate(); ++ entityplayer.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange + entityplayer.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex)); + } + +@@ -701,7 +1109,7 @@ + } + + public String[] getSeenPlayers() { +- return this.server.worldServer[0].getDataManager().getPlayerFileData().getSeenPlayers(); ++ return this.server.worlds.get(0).getDataManager().getPlayerFileData().getSeenPlayers(); // CraftBukkit + } + + public boolean getHasWhitelist() { +@@ -751,16 +1159,26 @@ + + public void u() { + for (int i = 0; i < this.players.size(); ++i) { +- ((EntityPlayer) this.players.get(i)).playerConnection.disconnect("Server closed"); ++ ((EntityPlayer) this.players.get(i)).playerConnection.disconnect(this.server.server.getShutdownMessage()); // CraftBukkit - add custom shutdown message + } + + } + ++ // CraftBukkit start ++ public void sendMessage(IChatBaseComponent[] iChatBaseComponents) { ++ for (IChatBaseComponent component : iChatBaseComponents) { ++ sendMessage(component, true); ++ } ++ } ++ // CraftBukkit end ++ + public void sendMessage(IChatBaseComponent ichatbasecomponent, boolean flag) { + this.server.sendMessage(ichatbasecomponent); + int i = flag ? 1 : 0; + +- this.sendAll(new PacketPlayOutChat(ichatbasecomponent, (byte) i)); ++ // CraftBukkit start - we run this through our processor first so we can get web links etc ++ this.sendAll(new PacketPlayOutChat(CraftChatMessage.fixComponent(ichatbasecomponent), (byte) i)); ++ // CraftBukkit end + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { +@@ -797,8 +1215,10 @@ + WorldServer[] aworldserver = this.server.worldServer; + int j = aworldserver.length; + +- for (int k = 0; k < j; ++k) { +- WorldServer worldserver = aworldserver[k]; ++ // CraftBukkit start ++ for (int k = 0; k < server.worlds.size(); ++k) { ++ WorldServer worldserver = server.worlds.get(0); ++ // CraftBukkit end + + if (worldserver != null) { + worldserver.getPlayerChunkMap().a(i); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PortalTravelAgent.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PortalTravelAgent.patch new file mode 100644 index 0000000..73698d3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PortalTravelAgent.patch @@ -0,0 +1,262 @@ +--- a/net/minecraft/server/PortalTravelAgent.java ++++ b/net/minecraft/server/PortalTravelAgent.java +@@ -5,6 +5,12 @@ + import java.util.List; + import java.util.Random; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.event.entity.EntityPortalExitEvent; ++import org.bukkit.util.Vector; ++// CraftBukkit end ++ + public class PortalTravelAgent { + + private final WorldServer a; +@@ -27,6 +33,19 @@ + int i = MathHelper.floor(entity.locX); + int j = MathHelper.floor(entity.locY) - 1; + int k = MathHelper.floor(entity.locZ); ++ // CraftBukkit start - Modularize end portal creation ++ BlockPosition created = this.createEndPortal(entity.locX, entity.locY, entity.locZ); ++ entity.setPositionRotation((double) created.getX(), (double) created.getY(), (double) created.getZ(), entity.yaw, 0.0F); ++ entity.motX = entity.motY = entity.motZ = 0.0D; ++ } ++ } ++ ++ // Split out from original a(Entity, double, double, double, float) method in order to enable being called from createPortal ++ private BlockPosition createEndPortal(double x, double y, double z) { ++ int i = MathHelper.floor(x); ++ int j = MathHelper.floor(y) - 1; ++ int k = MathHelper.floor(z); ++ // CraftBukkit end + byte b0 = 1; + byte b1 = 0; + +@@ -43,16 +62,63 @@ + } + } + +- entity.setPositionRotation((double) i, (double) j, (double) k, entity.yaw, 0.0F); +- entity.motX = entity.motY = entity.motZ = 0.0D; ++ // CraftBukkit start ++ return new BlockPosition(i, k, k); ++ } ++ ++ // use logic based on creation to verify end portal ++ private BlockPosition findEndPortal(BlockPosition portal) { ++ int i = portal.getX(); ++ int j = portal.getY() - 1; ++ int k = portal.getZ(); ++ byte b0 = 1; ++ byte b1 = 0; ++ ++ for (int l = -2; l <= 2; ++l) { ++ for (int i1 = -2; i1 <= 2; ++i1) { ++ for (int j1 = -1; j1 < 3; ++j1) { ++ int k1 = i + i1 * b0 + l * b1; ++ int l1 = j + j1; ++ int i2 = k + i1 * b1 - l * b0; ++ boolean flag = j1 < 0; ++ ++ if (this.a.getType(new BlockPosition(k1, l1, i2)).getBlock() != (flag ? Blocks.OBSIDIAN : Blocks.AIR)) { ++ return null; ++ } ++ } ++ } + } ++ return new BlockPosition(i, j, k); + } ++ // CraftBukkit end + + public boolean b(Entity entity, float f) { +- boolean flag = true; ++ // CraftBukkit start - Modularize portal search process and entity teleportation ++ BlockPosition found = this.findPortal(entity.locX, entity.locY, entity.locZ, 128); ++ if (found == null) { ++ return false; ++ } ++ ++ Location exit = new Location(this.a.getWorld(), found.getX(), found.getY(), found.getZ(), f, entity.pitch); ++ Vector velocity = entity.getBukkitEntity().getVelocity(); ++ this.adjustExit(entity, exit, velocity); ++ entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); ++ if (entity.motX != velocity.getX() || entity.motY != velocity.getY() || entity.motZ != velocity.getZ()) { ++ entity.getBukkitEntity().setVelocity(velocity); ++ } ++ return true; ++ } ++ ++ public BlockPosition findPortal(double x, double y, double z, int short1) { ++ if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { ++ return this.findEndPortal(this.a.worldProvider.h()); ++ } ++ // CraftBukkit end + double d0 = -1.0D; +- int i = MathHelper.floor(entity.locX); +- int j = MathHelper.floor(entity.locZ); ++ // CraftBukkit start ++ int i = MathHelper.floor(x); ++ int j = MathHelper.floor(z); ++ // CraftBukkit end + boolean flag1 = true; + Object object = BlockPosition.ZERO; + long k = ChunkCoordIntPair.a(i, j); +@@ -65,7 +131,7 @@ + portaltravelagent_chunkcoordinatesportal.c = this.a.getTime(); + flag1 = false; + } else { +- BlockPosition blockposition = new BlockPosition(entity); ++ BlockPosition blockposition = new BlockPosition(x, y, z); + + for (int l = -128; l <= 128; ++l) { + BlockPosition blockposition1; +@@ -95,6 +161,29 @@ + this.c.put(k, new PortalTravelAgent.ChunkCoordinatesPortal((BlockPosition) object, this.a.getTime())); + this.d.add(Long.valueOf(k)); + } ++ // CraftBukkit start - Move entity teleportation logic into exit ++ return (BlockPosition) object; ++ } else { ++ return null; ++ } ++ } ++ ++ // Entity repositioning logic split out from original b method and combined with repositioning logic for The End from original a method ++ public void adjustExit(Entity entity, Location position, Vector velocity) { ++ Location from = position.clone(); ++ Vector before = velocity.clone(); ++ BlockPosition object = new BlockPosition(position.getBlockX(), position.getBlockY(), position.getBlockZ()); ++ float f = position.getYaw(); ++ ++ if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END || entity.getBukkitEntity().getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END || entity.aG() == null) { ++ // entity.setPositionRotation((double) i, (double) j, (double) k, entity.yaw, 0.0F); ++ // entity.motX = entity.motY = entity.motZ = 0.0D; ++ position.setPitch(0.0F); ++ velocity.setX(0); ++ velocity.setY(0); ++ velocity.setZ(0); ++ } else { ++ // CraftBukkit end + + double d2 = (double) ((BlockPosition) object).getX() + 0.5D; + double d3 = (double) ((BlockPosition) object).getY() + 0.5D; +@@ -132,26 +221,60 @@ + f3 = -1.0F; + f4 = 1.0F; + } +- +- double d6 = entity.motX; +- double d7 = entity.motZ; +- +- entity.motX = d6 * (double) f1 + d7 * (double) f4; +- entity.motZ = d6 * (double) f3 + d7 * (double) f2; +- entity.yaw = f - (float) (entity.aH().opposite().b() * 90) + (float) (shapedetector_shapedetectorcollection.b().b() * 90); +- entity.setPositionRotation(d2, d3, d4, entity.yaw, entity.pitch); +- return true; ++ ++ // CraftBukkit start ++ double d6 = velocity.getX(); ++ double d7 = velocity.getZ(); ++ // CraftBukkit end ++ ++ // CraftBukkit start - Adjust position and velocity instances instead of entity ++ velocity.setX(d6 * (double) f1 + d7 * (double) f4); ++ velocity.setZ(d6 * (double) f3 + d7 * (double) f2); ++ f = f - (float) (entity.aH().opposite().b() * 90) + (float) (shapedetector_shapedetectorcollection.b().b() * 90); ++ // entity.setPositionRotation(d2, d3, d4, entity.yaw, entity.pitch); ++ position.setX(d2); ++ position.setY(d3); ++ position.setZ(d4); ++ position.setYaw(f); ++ } ++ EntityPortalExitEvent event = new EntityPortalExitEvent(entity.getBukkitEntity(), from, position, before, velocity); ++ this.a.getServer().getPluginManager().callEvent(event); ++ Location to = event.getTo(); ++ if (event.isCancelled() || to == null || !entity.isAlive()) { ++ position.setX(from.getX()); ++ position.setY(from.getY()); ++ position.setZ(from.getZ()); ++ position.setYaw(from.getYaw()); ++ position.setPitch(from.getPitch()); ++ velocity.copy(before); + } else { +- return false; ++ position.setX(to.getX()); ++ position.setY(to.getY()); ++ position.setZ(to.getZ()); ++ position.setYaw(to.getYaw()); ++ position.setPitch(to.getPitch()); ++ velocity.copy(event.getAfter()); // event.getAfter() will never be null, as setAfter() will cause an NPE if null is passed in + } ++ // CraftBukkit end + } + + public boolean a(Entity entity) { +- byte b0 = 16; ++ // CraftBukkit start - Allow for portal creation to be based on coordinates instead of entity ++ return this.createPortal(entity.locX, entity.locY, entity.locZ, 16); ++ } ++ ++ public boolean createPortal(double x, double y, double z, int b0) { ++ if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { ++ createEndPortal(x, y, z); ++ return true; ++ } ++ // CraftBukkit end + double d0 = -1.0D; +- int i = MathHelper.floor(entity.locX); +- int j = MathHelper.floor(entity.locY); +- int k = MathHelper.floor(entity.locZ); ++ // CraftBukkit start ++ int i = MathHelper.floor(x); ++ int j = MathHelper.floor(y); ++ int k = MathHelper.floor(z); ++ // CraftBukkit end + int l = i; + int i1 = j; + int j1 = k; +@@ -176,10 +299,10 @@ + double d4; + + for (i2 = i - b0; i2 <= i + b0; ++i2) { +- d1 = (double) i2 + 0.5D - entity.locX; ++ d1 = (double) i2 + 0.5D - x; // CraftBukkit + + for (j2 = k - b0; j2 <= k + b0; ++j2) { +- d2 = (double) j2 + 0.5D - entity.locZ; ++ d2 = (double) j2 + 0.5D - z; // CraftBukkit + + label271: + for (k2 = this.a.V() - 1; k2 >= 0; --k2) { +@@ -211,7 +334,7 @@ + } + } + +- d3 = (double) k2 + 0.5D - entity.locY; ++ d3 = (double) k2 + 0.5D - y; // CraftBukkit + d4 = d1 * d1 + d3 * d3 + d2 * d2; + if (d0 < 0.0D || d4 < d0) { + d0 = d4; +@@ -228,10 +351,10 @@ + + if (d0 < 0.0D) { + for (i2 = i - b0; i2 <= i + b0; ++i2) { +- d1 = (double) i2 + 0.5D - entity.locX; ++ d1 = (double) i2 + 0.5D - x; // CraftBukkit + + for (j2 = k - b0; j2 <= k + b0; ++j2) { +- d2 = (double) j2 + 0.5D - entity.locZ; ++ d2 = (double) j2 + 0.5D - z; // CraftBukkit + + label219: + for (k2 = this.a.V() - 1; k2 >= 0; --k2) { +@@ -256,7 +379,7 @@ + } + } + +- d3 = (double) k2 + 0.5D - entity.locY; ++ d3 = (double) k2 + 0.5D - y; // CraftBukkit + d4 = d1 * d1 + d3 * d3 + d2 * d2; + if (d0 < 0.0D || d4 < d0) { + d0 = d4; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/PropertyManager.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PropertyManager.patch new file mode 100644 index 0000000..c312cda --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/PropertyManager.patch @@ -0,0 +1,93 @@ +--- a/net/minecraft/server/PropertyManager.java ++++ b/net/minecraft/server/PropertyManager.java +@@ -8,6 +8,8 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import joptsimple.OptionSet; // CraftBukkit ++ + public class PropertyManager { + + private static final Logger a = LogManager.getLogger(); +@@ -42,6 +44,24 @@ + + } + ++ // CraftBukkit start ++ private OptionSet options = null; ++ ++ public PropertyManager(final OptionSet options) { ++ this((File) options.valueOf("config")); ++ ++ this.options = options; ++ } ++ ++ private T getOverride(String name, T value) { ++ if ((this.options != null) && (this.options.has(name))) { ++ return (T) this.options.valueOf(name); ++ } ++ ++ return value; ++ } ++ // CraftBukkit end ++ + public void a() { + PropertyManager.a.info("Generating new properties file"); + this.savePropertiesFile(); +@@ -51,6 +71,12 @@ + FileOutputStream fileoutputstream = null; + + try { ++ // CraftBukkit start - Don't attempt writing to file if it's read only ++ if (this.file.exists() && !this.file.canWrite()) { ++ return; ++ } ++ // CraftBukkit end ++ + fileoutputstream = new FileOutputStream(this.file); + this.properties.store(fileoutputstream, "Minecraft server properties"); + } catch (Exception exception) { +@@ -80,36 +106,36 @@ + this.savePropertiesFile(); + } + +- return this.properties.getProperty(s, s1); ++ return getOverride(s, this.properties.getProperty(s, s1)); // CraftBukkit + } + + public int getInt(String s, int i) { + try { +- return Integer.parseInt(this.getString(s, "" + i)); ++ return getOverride(s, Integer.parseInt(this.getString(s, "" + i))); // CraftBukkit + } catch (Exception exception) { + this.properties.setProperty(s, "" + i); + this.savePropertiesFile(); +- return i; ++ return getOverride(s, i); // CraftBukkit + } + } + + public long getLong(String s, long i) { + try { +- return Long.parseLong(this.getString(s, "" + i)); ++ return getOverride(s, Long.parseLong(this.getString(s, "" + i))); // CraftBukkit + } catch (Exception exception) { + this.properties.setProperty(s, "" + i); + this.savePropertiesFile(); +- return i; ++ return getOverride(s, i); // CraftBukkit + } + } + + public boolean getBoolean(String s, boolean flag) { + try { +- return Boolean.parseBoolean(this.getString(s, "" + flag)); ++ return getOverride(s, Boolean.parseBoolean(this.getString(s, "" + flag))); //CraftBukkit + } catch (Exception exception) { + this.properties.setProperty(s, "" + flag); + this.savePropertiesFile(); +- return flag; ++ return getOverride(s, flag); // CraftBukkit + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeArmorDye.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeArmorDye.patch new file mode 100644 index 0000000..2bf96ca --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeArmorDye.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/server/RecipeArmorDye.java ++++ b/net/minecraft/server/RecipeArmorDye.java +@@ -3,9 +3,13 @@ + import com.google.common.collect.Lists; + import java.util.ArrayList; + +-public class RecipeArmorDye implements IRecipe { ++public class RecipeArmorDye extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + +- public RecipeArmorDye() {} ++ // CraftBukkit start - Delegate to new parent class with bogus info ++ public RecipeArmorDye() { ++ super(new ItemStack(Items.LEATHER_HELMET, 0, 0), java.util.Arrays.asList(new ItemStack(Items.DYE, 0, 5))); ++ } ++ // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + ItemStack itemstack = null; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeBookClone.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeBookClone.patch new file mode 100644 index 0000000..d815fcd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeBookClone.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/server/RecipeBookClone.java ++++ b/net/minecraft/server/RecipeBookClone.java +@@ -1,8 +1,12 @@ + package net.minecraft.server; + +-public class RecipeBookClone implements IRecipe { ++public class RecipeBookClone extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + +- public RecipeBookClone() {} ++ // CraftBukkit start - Delegate to new parent class ++ public RecipeBookClone() { ++ super(new ItemStack(Items.WRITTEN_BOOK, 0, -1), java.util.Arrays.asList(new ItemStack(Items.WRITABLE_BOOK, 0, 0))); ++ } ++ // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + int i = 0; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeFireworks.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeFireworks.patch new file mode 100644 index 0000000..039e6b5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeFireworks.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/server/RecipeFireworks.java ++++ b/net/minecraft/server/RecipeFireworks.java +@@ -3,11 +3,15 @@ + import com.google.common.collect.Lists; + import java.util.ArrayList; + +-public class RecipeFireworks implements IRecipe { ++public class RecipeFireworks extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + + private ItemStack a; + +- public RecipeFireworks() {} ++ // CraftBukkit start - Delegate to new parent class with bogus info ++ public RecipeFireworks() { ++ super(new ItemStack(Items.FIREWORKS, 0, 0), java.util.Arrays.asList(new ItemStack(Items.GUNPOWDER, 0, 5))); ++ } ++ // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + this.a = null; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeMapClone.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeMapClone.patch new file mode 100644 index 0000000..2349634 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeMapClone.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/server/RecipeMapClone.java ++++ b/net/minecraft/server/RecipeMapClone.java +@@ -1,8 +1,12 @@ + package net.minecraft.server; + +-public class RecipeMapClone implements IRecipe { ++public class RecipeMapClone extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + +- public RecipeMapClone() {} ++ // CraftBukkit start - Delegate to new parent class ++ public RecipeMapClone() { ++ super(new ItemStack(Items.MAP, 0, -1), java.util.Arrays.asList(new ItemStack(Items.MAP, 0, 0))); ++ } ++ // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + int i = 0; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeRepair.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeRepair.patch new file mode 100644 index 0000000..1d0f914 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipeRepair.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/server/RecipeRepair.java ++++ b/net/minecraft/server/RecipeRepair.java +@@ -3,9 +3,13 @@ + import com.google.common.collect.Lists; + import java.util.ArrayList; + +-public class RecipeRepair implements IRecipe { ++public class RecipeRepair extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + +- public RecipeRepair() {} ++ // CraftBukkit start - Delegate to new parent class ++ public RecipeRepair() { ++ super(new ItemStack(Items.LEATHER_HELMET), java.util.Arrays.asList(new ItemStack(Items.LEATHER_HELMET))); ++ } ++ // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + ArrayList arraylist = Lists.newArrayList(); +@@ -62,7 +66,17 @@ + i1 = 0; + } + +- return new ItemStack(itemstack2.getItem(), 1, i1); ++ // CraftBukkit start - Construct a dummy repair recipe ++ ItemStack result = new ItemStack(itemstack.getItem(), 1, i1); ++ java.util.List ingredients = new ArrayList(); ++ ingredients.add(itemstack2.cloneItemStack()); ++ ingredients.add(itemstack.cloneItemStack()); ++ ShapelessRecipes recipe = new ShapelessRecipes(result.cloneItemStack(), ingredients); ++ inventorycrafting.currentRecipe = recipe; ++ result = org.bukkit.craftbukkit.event.CraftEventFactory.callPreCraftEvent(inventorycrafting, result, CraftingManager.getInstance().lastCraftView, true); ++ return result; ++ // return new ItemStack(itemstack2.getItem(), 1, i1); ++ // CraftBukkit end + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipesBanner.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipesBanner.patch new file mode 100644 index 0000000..8e1e1e2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipesBanner.patch @@ -0,0 +1,34 @@ +--- a/net/minecraft/server/RecipesBanner.java ++++ b/net/minecraft/server/RecipesBanner.java +@@ -20,9 +20,13 @@ + + static class SyntheticClass_1 { } + +- static class AddRecipe implements IRecipe { ++ static class AddRecipe extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + +- private AddRecipe() {} ++ // CraftBukkit start - Delegate to new parent class with bogus info ++ private AddRecipe() { ++ super(new ItemStack(Items.BANNER, 0, 0), java.util.Arrays.asList(new ItemStack(Items.BANNER))); ++ } ++ // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + boolean flag = false; +@@ -210,9 +214,13 @@ + } + } + +- static class DuplicateRecipe implements IRecipe { ++ static class DuplicateRecipe extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + +- private DuplicateRecipe() {} ++ // CraftBukkit start - Delegate to new parent class with bogus info ++ private DuplicateRecipe() { ++ super(new ItemStack(Items.BANNER, 0, 0), java.util.Arrays.asList(new ItemStack(Items.DYE, 0, 5))); ++ } ++ // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + ItemStack itemstack = null; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipesFurnace.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipesFurnace.patch new file mode 100644 index 0000000..79bae8a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RecipesFurnace.patch @@ -0,0 +1,56 @@ +--- a/net/minecraft/server/RecipesFurnace.java ++++ b/net/minecraft/server/RecipesFurnace.java +@@ -10,12 +10,13 @@ + private static final RecipesFurnace a = new RecipesFurnace(); + public Map recipes = Maps.newHashMap(); + private Map c = Maps.newHashMap(); ++ public Map customRecipes = Maps.newHashMap(); // CraftBukkit - add field + + public static RecipesFurnace getInstance() { + return RecipesFurnace.a; + } + +- private RecipesFurnace() { ++ public RecipesFurnace() { // PAIL: Public + this.registerRecipe(Blocks.IRON_ORE, new ItemStack(Items.IRON_INGOT), 0.7F); + this.registerRecipe(Blocks.GOLD_ORE, new ItemStack(Items.GOLD_INGOT), 1.0F); + this.registerRecipe(Blocks.DIAMOND_ORE, new ItemStack(Items.DIAMOND), 1.0F); +@@ -53,6 +54,12 @@ + this.registerRecipe(Blocks.QUARTZ_ORE, new ItemStack(Items.QUARTZ), 0.2F); + } + ++ // CraftBukkit start - add method ++ public void registerRecipe(ItemStack itemstack, ItemStack itemstack1) { ++ this.customRecipes.put(itemstack, itemstack1); ++ } ++ // CraftBukkit end ++ + public void registerRecipe(Block block, ItemStack itemstack, float f) { + this.a(Item.getItemOf(block), itemstack, f); + } +@@ -67,13 +74,23 @@ + } + + public ItemStack getResult(ItemStack itemstack) { +- Iterator iterator = this.recipes.entrySet().iterator(); ++ // CraftBukkit start - initialize to customRecipes ++ boolean vanilla = false; ++ Iterator iterator = this.customRecipes.entrySet().iterator(); ++ // CraftBukkit end + + Entry entry; + + do { + if (!iterator.hasNext()) { +- return null; ++ // CraftBukkit start - fall back to vanilla recipes ++ if (!vanilla && !recipes.isEmpty()) { ++ iterator = this.recipes.entrySet().iterator(); ++ vanilla = true; ++ } else { ++ return null; ++ } ++ // CraftBukkit end + } + + entry = (Entry) iterator.next(); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RegionFile.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RegionFile.patch new file mode 100644 index 0000000..6153576 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RegionFile.patch @@ -0,0 +1,48 @@ +--- a/net/minecraft/server/RegionFile.java ++++ b/net/minecraft/server/RegionFile.java +@@ -90,6 +90,45 @@ + + } + ++ // CraftBukkit start - This is a copy (sort of) of the method below it, make sure they stay in sync ++ public synchronized boolean chunkExists(int i, int j) { ++ if (this.d(i, j)) { ++ return false; ++ } else { ++ try { ++ int k = this.e(i, j); ++ ++ if (k == 0) { ++ return false; ++ } else { ++ int l = k >> 8; ++ int i1 = k & 255; ++ ++ if (l + i1 > this.f.size()) { ++ return false; ++ } ++ ++ this.c.seek((long) (l * 4096)); ++ int j1 = this.c.readInt(); ++ ++ if (j1 > 4096 * i1 || j1 <= 0) { ++ return false; ++ } ++ ++ byte b0 = this.c.readByte(); ++ if (b0 == 1 || b0 == 2) { ++ return true; ++ } ++ } ++ } catch (IOException ioexception) { ++ return false; ++ } ++ } ++ ++ return false; ++ } ++ // CraftBukkit end ++ + public synchronized DataInputStream a(int i, int j) { + if (this.d(i, j)) { + return null; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/RemoteControlCommandListener.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RemoteControlCommandListener.patch new file mode 100644 index 0000000..6331f69 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/RemoteControlCommandListener.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/server/RemoteControlCommandListener.java ++++ b/net/minecraft/server/RemoteControlCommandListener.java +@@ -27,6 +27,12 @@ + return new ChatComponentText(this.getName()); + } + ++ // CraftBukkit start - Send a String ++ public void sendMessage(String message) { ++ this.b.append(message); ++ } ++ // CraftBukkit end ++ + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + this.b.append(ichatbasecomponent.c()); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ScoreboardServer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ScoreboardServer.patch new file mode 100644 index 0000000..c480fff --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ScoreboardServer.patch @@ -0,0 +1,126 @@ +--- a/net/minecraft/server/ScoreboardServer.java ++++ b/net/minecraft/server/ScoreboardServer.java +@@ -21,7 +21,7 @@ + public void handleScoreChanged(ScoreboardScore scoreboardscore) { + super.handleScoreChanged(scoreboardscore); + if (this.b.contains(scoreboardscore.getObjective())) { +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardScore(scoreboardscore)); ++ this.sendAll(new PacketPlayOutScoreboardScore(scoreboardscore)); + } + + this.b(); +@@ -29,13 +29,13 @@ + + public void handlePlayerRemoved(String s) { + super.handlePlayerRemoved(s); +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardScore(s)); ++ this.sendAll(new PacketPlayOutScoreboardScore(s)); + this.b(); + } + + public void a(String s, ScoreboardObjective scoreboardobjective) { + super.a(s, scoreboardobjective); +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardScore(s, scoreboardobjective)); ++ this.sendAll(new PacketPlayOutScoreboardScore(s, scoreboardobjective)); + this.b(); + } + +@@ -45,7 +45,7 @@ + super.setDisplaySlot(i, scoreboardobjective); + if (scoreboardobjective1 != scoreboardobjective && scoreboardobjective1 != null) { + if (this.h(scoreboardobjective1) > 0) { +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardDisplayObjective(i, scoreboardobjective)); ++ this.sendAll(new PacketPlayOutScoreboardDisplayObjective(i, scoreboardobjective)); + } else { + this.g(scoreboardobjective1); + } +@@ -53,7 +53,7 @@ + + if (scoreboardobjective != null) { + if (this.b.contains(scoreboardobjective)) { +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardDisplayObjective(i, scoreboardobjective)); ++ this.sendAll(new PacketPlayOutScoreboardDisplayObjective(i, scoreboardobjective)); + } else { + this.e(scoreboardobjective); + } +@@ -66,7 +66,7 @@ + if (super.addPlayerToTeam(s, s1)) { + ScoreboardTeam scoreboardteam = this.getTeam(s1); + +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 3)); ++ this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 3)); + this.b(); + return true; + } else { +@@ -76,7 +76,7 @@ + + public void removePlayerFromTeam(String s, ScoreboardTeam scoreboardteam) { + super.removePlayerFromTeam(s, scoreboardteam); +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 4)); ++ this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 4)); + this.b(); + } + +@@ -88,7 +88,7 @@ + public void handleObjectiveChanged(ScoreboardObjective scoreboardobjective) { + super.handleObjectiveChanged(scoreboardobjective); + if (this.b.contains(scoreboardobjective)) { +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardObjective(scoreboardobjective, 2)); ++ this.sendAll(new PacketPlayOutScoreboardObjective(scoreboardobjective, 2)); + } + + this.b(); +@@ -105,19 +105,19 @@ + + public void handleTeamAdded(ScoreboardTeam scoreboardteam) { + super.handleTeamAdded(scoreboardteam); +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 0)); ++ this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 0)); + this.b(); + } + + public void handleTeamChanged(ScoreboardTeam scoreboardteam) { + super.handleTeamChanged(scoreboardteam); +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 2)); ++ this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 2)); + this.b(); + } + + public void handleTeamRemoved(ScoreboardTeam scoreboardteam) { + super.handleTeamRemoved(scoreboardteam); +- this.a.getPlayerList().sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 1)); ++ this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 1)); + this.b(); + } + +@@ -160,6 +160,7 @@ + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); ++ if (entityplayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { +@@ -192,6 +193,7 @@ + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); ++ if (entityplayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { +@@ -215,4 +217,14 @@ + + return i; + } ++ ++ // CraftBukkit start - Send to players ++ private void sendAll(Packet packet) { ++ for (EntityPlayer entityplayer : (List) this.a.getPlayerList().players) { ++ if (entityplayer.getBukkitEntity().getScoreboard().getHandle() == this) { ++ entityplayer.playerConnection.sendPacket(packet); ++ } ++ } ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/SecondaryWorldServer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/SecondaryWorldServer.patch new file mode 100644 index 0000000..a26d9cd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/SecondaryWorldServer.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/server/SecondaryWorldServer.java ++++ b/net/minecraft/server/SecondaryWorldServer.java +@@ -4,9 +4,12 @@ + + private WorldServer a; + +- public SecondaryWorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, int i, WorldServer worldserver, MethodProfiler methodprofiler) { +- super(minecraftserver, idatamanager, new SecondaryWorldData(worldserver.getWorldData()), i, methodprofiler); ++ // CraftBukkit start - Add WorldData, Environment and ChunkGenerator arguments ++ public SecondaryWorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, int i, WorldServer worldserver, MethodProfiler methodprofiler, WorldData worldData, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { ++ super(minecraftserver, idatamanager, worldData, i, methodprofiler, env, gen); ++ // CraftBukkit end + this.a = worldserver; ++ /* CraftBukkit start + worldserver.getWorldBorder().a(new IWorldBorderListener() { + public void a(WorldBorder worldborder, double d0) { + SecondaryWorldServer.this.getWorldBorder().setSize(d0); +@@ -36,13 +39,14 @@ + SecondaryWorldServer.this.getWorldBorder().setDamageBuffer(d0); + } + }); ++ // CraftBukkit end */ + } + +- protected void a() {} ++ // protected void a() {} // CraftBukkit + + public World b() { + this.worldMaps = this.a.T(); +- this.scoreboard = this.a.getScoreboard(); ++ // this.scoreboard = this.a.getScoreboard(); // CraftBukkit + String s = PersistentVillage.a(this.worldProvider); + PersistentVillage persistentvillage = (PersistentVillage) this.worldMaps.get(PersistentVillage.class, s); + +@@ -54,6 +58,6 @@ + this.villages.a((World) this); + } + +- return this; ++ return super.b(); // CraftBukkit + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ShapedRecipes.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ShapedRecipes.patch new file mode 100644 index 0000000..699a2af --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ShapedRecipes.patch @@ -0,0 +1,76 @@ +--- a/net/minecraft/server/ShapedRecipes.java ++++ b/net/minecraft/server/ShapedRecipes.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; ++// CraftBukkit end ++ + public class ShapedRecipes implements IRecipe { + + private final int width; +@@ -15,6 +20,62 @@ + this.result = itemstack; + } + ++ // CraftBukkit start ++ public org.bukkit.inventory.ShapedRecipe toBukkitRecipe() { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ CraftShapedRecipe recipe = new CraftShapedRecipe(result, this); ++ switch (this.height) { ++ case 1: ++ switch (this.width) { ++ case 1: ++ recipe.shape("a"); ++ break; ++ case 2: ++ recipe.shape("ab"); ++ break; ++ case 3: ++ recipe.shape("abc"); ++ break; ++ } ++ break; ++ case 2: ++ switch (this.width) { ++ case 1: ++ recipe.shape("a","b"); ++ break; ++ case 2: ++ recipe.shape("ab","cd"); ++ break; ++ case 3: ++ recipe.shape("abc","def"); ++ break; ++ } ++ break; ++ case 3: ++ switch (this.width) { ++ case 1: ++ recipe.shape("a","b","c"); ++ break; ++ case 2: ++ recipe.shape("ab","cd","ef"); ++ break; ++ case 3: ++ recipe.shape("abc","def","ghi"); ++ break; ++ } ++ break; ++ } ++ char c = 'a'; ++ for (ItemStack stack : this.items) { ++ if (stack != null) { ++ recipe.setIngredient(c, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), stack.getData()); ++ } ++ c++; ++ } ++ return recipe; ++ } ++ // CraftBukkit end ++ + public ItemStack b() { + return this.result; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/ShapelessRecipes.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ShapelessRecipes.patch new file mode 100644 index 0000000..0ed46af --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/ShapelessRecipes.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/server/ShapelessRecipes.java ++++ b/net/minecraft/server/ShapelessRecipes.java +@@ -5,6 +5,11 @@ + import java.util.Iterator; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; ++// CraftBukkit end ++ + public class ShapelessRecipes implements IRecipe { + + private final ItemStack result; +@@ -15,6 +20,20 @@ + this.ingredients = list; + } + ++ // CraftBukkit start ++ @SuppressWarnings("unchecked") ++ public org.bukkit.inventory.ShapelessRecipe toBukkitRecipe() { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ CraftShapelessRecipe recipe = new CraftShapelessRecipe(result, this); ++ for (ItemStack stack : (List) this.ingredients) { ++ if (stack != null) { ++ recipe.addIngredient(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), stack.getData()); ++ } ++ } ++ return recipe; ++ } ++ // CraftBukkit end ++ + public ItemStack b() { + return this.result; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Slot.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Slot.patch new file mode 100644 index 0000000..a9b73d5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Slot.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/server/Slot.java ++++ b/net/minecraft/server/Slot.java +@@ -45,6 +45,9 @@ + } + + public boolean hasItem() { ++ if (getItem() != null && getItem().count == 0) { ++ set(null); ++ } + return this.getItem() != null; + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/SlotFurnaceResult.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/SlotFurnaceResult.patch new file mode 100644 index 0000000..cb27c68 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/SlotFurnaceResult.patch @@ -0,0 +1,32 @@ +--- a/net/minecraft/server/SlotFurnaceResult.java ++++ b/net/minecraft/server/SlotFurnaceResult.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.event.inventory.FurnaceExtractEvent; ++// CraftBukkit end ++ + public class SlotFurnaceResult extends Slot { + + private EntityHuman a; +@@ -50,6 +55,18 @@ + i = j; + } + ++ // CraftBukkit start - fire FurnaceExtractEvent ++ Player player = (Player) a.getBukkitEntity(); ++ TileEntityFurnace furnace = ((TileEntityFurnace) this.inventory); ++ org.bukkit.block.Block block = a.world.getWorld().getBlockAt(furnace.position.getX(), furnace.position.getY(), furnace.position.getZ()); ++ ++ if (b != 0) { ++ FurnaceExtractEvent event = new FurnaceExtractEvent(player, block, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(itemstack.getItem()), b, i); ++ a.world.getServer().getPluginManager().callEvent(event); ++ i = event.getExpToDrop(); ++ } ++ // CraftBukkit end ++ + while (i > 0) { + j = EntityExperienceOrb.getOrbValue(i); + i -= j; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/SpawnerCreature.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/SpawnerCreature.patch new file mode 100644 index 0000000..be143f6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/SpawnerCreature.patch @@ -0,0 +1,108 @@ +--- a/net/minecraft/server/SpawnerCreature.java ++++ b/net/minecraft/server/SpawnerCreature.java +@@ -6,10 +6,16 @@ + import java.util.Random; + import java.util.Set; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.LongHash; ++import org.bukkit.craftbukkit.util.LongHashSet; ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; ++// CraftBukkit end ++ + public final class SpawnerCreature { + + private static final int a = (int) Math.pow(17.0D, 2.0D); +- private final Set b = Sets.newHashSet(); ++ private final LongHashSet b = new LongHashSet(); // CraftBukkit + + public SpawnerCreature() {} + +@@ -36,14 +42,17 @@ + for (int i1 = -b0; i1 <= b0; ++i1) { + for (k = -b0; k <= b0; ++k) { + boolean flag3 = i1 == -b0 || i1 == b0 || k == -b0 || k == b0; +- ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i1 + l, k + j); ++ // CraftBukkit start - use LongHash and LongHashSet ++ // ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i1 + l, k + j); + +- if (!this.b.contains(chunkcoordintpair)) { ++ long chunkCoords = LongHash.toLong(i1 + l, k + j); ++ if (!this.b.contains(chunkCoords)) { + ++i; +- if (!flag3 && worldserver.getWorldBorder().isInBounds(chunkcoordintpair)) { +- this.b.add(chunkcoordintpair); ++ if (!flag3 && worldserver.getWorldBorder().isInBounds(i1 + l, k + j)) { ++ this.b.add(chunkCoords); + } + } ++ // CraftBukkit end + } + } + } +@@ -58,17 +67,41 @@ + for (int k1 = 0; k1 < j; ++k1) { + EnumCreatureType enumcreaturetype = aenumcreaturetype[k1]; + ++ // CraftBukkit start - Use per-world spawn limits ++ int limit = enumcreaturetype.b(); ++ switch (enumcreaturetype) { ++ case MONSTER: ++ limit = worldserver.getWorld().getMonsterSpawnLimit(); ++ break; ++ case CREATURE: ++ limit = worldserver.getWorld().getAnimalSpawnLimit(); ++ break; ++ case WATER_CREATURE: ++ limit = worldserver.getWorld().getWaterAnimalSpawnLimit(); ++ break; ++ case AMBIENT: ++ limit = worldserver.getWorld().getAmbientSpawnLimit(); ++ break; ++ } ++ ++ if (limit == 0) { ++ continue; ++ } ++ // CraftBukkit end ++ + if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2)) { + k = worldserver.a(enumcreaturetype.a()); +- int l1 = enumcreaturetype.b() * i / SpawnerCreature.a; ++ int l1 = limit * i / a; // CraftBukkit - use per-world limits + + if (k <= l1) { + Iterator iterator1 = this.b.iterator(); + + label115: + while (iterator1.hasNext()) { +- ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair) iterator1.next(); +- BlockPosition blockposition1 = getRandomPosition(worldserver, chunkcoordintpair1.x, chunkcoordintpair1.z); ++ // CraftBukkit start = use LongHash and LongObjectHashMap ++ long key = ((Long) iterator1.next()).longValue(); ++ BlockPosition blockposition1 = getRandomPosition(worldserver, LongHash.msw(key), LongHash.lsw(key)); ++ // CraftBukkit + int i2 = blockposition1.getX(); + int j2 = blockposition1.getY(); + int k2 = blockposition1.getZ(); +@@ -120,7 +153,7 @@ + groupdataentity = entityinsentient.prepare(worldserver.E(new BlockPosition(entityinsentient)), groupdataentity); + if (entityinsentient.canSpawn()) { + ++l2; +- worldserver.addEntity(entityinsentient); ++ worldserver.addEntity(entityinsentient, SpawnReason.NATURAL); // CraftBukkit - Added a reason for spawning this creature + } + + if (l2 >= entityinsentient.bV()) { +@@ -214,8 +247,10 @@ + } + + entityinsentient.setPositionRotation((double) ((float) j1 + 0.5F), (double) blockposition.getY(), (double) ((float) k1 + 0.5F), random.nextFloat() * 360.0F, 0.0F); +- world.addEntity(entityinsentient); ++ // CraftBukkit start - Added a reason for spawning this creature, moved entityinsentient.prepare(groupdataentity) up + groupdataentity = entityinsentient.prepare(world.E(new BlockPosition(entityinsentient)), groupdataentity); ++ world.addEntity(entityinsentient, SpawnReason.CHUNK_GEN); ++ // CraftBukkit end + flag = true; + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/StatisticManager.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/StatisticManager.patch new file mode 100644 index 0000000..c935908 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/StatisticManager.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/server/StatisticManager.java ++++ b/net/minecraft/server/StatisticManager.java +@@ -19,6 +19,12 @@ + + public void b(EntityHuman entityhuman, Statistic statistic, int i) { + if (!statistic.d() || this.b((Achievement) statistic)) { ++ // CraftBukkit start - fire Statistic events ++ org.bukkit.event.Cancellable cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.handleStatisticsIncrease(entityhuman, statistic, this.getStatisticValue(statistic), i); ++ if (cancellable != null && cancellable.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + this.setStatistic(entityhuman, statistic, this.getStatisticValue(statistic) + i); + } + } +@@ -43,7 +49,7 @@ + public T b(Statistic statistic) { + StatisticWrapper statisticwrapper = (StatisticWrapper) this.a.get(statistic); + +- return statisticwrapper != null ? statisticwrapper.b() : null; ++ return statisticwrapper != null ? (T) statisticwrapper.b() : null; // CraftBukkit - fix decompile error + } + + public T a(Statistic statistic, T t0) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntity.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntity.patch new file mode 100644 index 0000000..c4c4ea6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntity.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/server/TileEntity.java ++++ b/net/minecraft/server/TileEntity.java +@@ -6,6 +6,8 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import org.bukkit.inventory.InventoryHolder; // CraftBukkit ++ + public abstract class TileEntity { + + private static final Logger a = LogManager.getLogger(); +@@ -221,4 +223,13 @@ + a(TileEntityFlowerPot.class, "FlowerPot"); + a(TileEntityBanner.class, "Banner"); + } ++ ++ // CraftBukkit start - add method ++ public InventoryHolder getOwner() { ++ if (world == null) return null; ++ org.bukkit.block.BlockState state = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(); ++ if (state instanceof InventoryHolder) return (InventoryHolder) state; ++ return null; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBanner.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBanner.patch new file mode 100644 index 0000000..f8cd7bc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBanner.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/server/TileEntityBanner.java ++++ b/net/minecraft/server/TileEntityBanner.java +@@ -20,6 +20,11 @@ + + if (nbttagcompound.hasKey("Patterns")) { + this.patterns = (NBTTagList) nbttagcompound.getList("Patterns", 10).clone(); ++ // CraftBukkit start ++ while (this.patterns.size() > 20) { ++ this.patterns.a(20); // PAIL Rename remove ++ } ++ // CraftBukkit end + } + + if (nbttagcompound.hasKeyOfType("Base", 99)) { +@@ -54,6 +59,11 @@ + super.a(nbttagcompound); + this.color = nbttagcompound.getInt("Base"); + this.patterns = nbttagcompound.getList("Patterns", 10); ++ // CraftBukkit start ++ while (this.patterns.size() > 20) { ++ this.patterns.a(20); // PAIL Rename remove ++ } ++ // CraftBukkit end + this.h = null; + this.i = null; + this.j = null; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBeacon.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBeacon.patch new file mode 100644 index 0000000..7b81e98 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBeacon.patch @@ -0,0 +1,54 @@ +--- a/net/minecraft/server/TileEntityBeacon.java ++++ b/net/minecraft/server/TileEntityBeacon.java +@@ -5,6 +5,11 @@ + import java.util.Iterator; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class TileEntityBeacon extends TileEntityContainer implements IUpdatePlayerListBox, IInventory { + + public static final MobEffectList[][] a = new MobEffectList[][] { { MobEffectList.FASTER_MOVEMENT, MobEffectList.FASTER_DIG}, { MobEffectList.RESISTANCE, MobEffectList.JUMP}, { MobEffectList.INCREASE_DAMAGE}, { MobEffectList.REGENERATION}}; +@@ -15,6 +20,30 @@ + private int l; + private ItemStack inventorySlot; + private String n; ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return new ItemStack[] { this.inventorySlot }; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end + + public TileEntityBeacon() {} + +@@ -246,7 +275,7 @@ + } + + public int getMaxStackSize() { +- return 1; ++ return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBrewingStand.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBrewingStand.patch new file mode 100644 index 0000000..d0158f5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityBrewingStand.patch @@ -0,0 +1,94 @@ +--- a/net/minecraft/server/TileEntityBrewingStand.java ++++ b/net/minecraft/server/TileEntityBrewingStand.java +@@ -3,6 +3,12 @@ + import java.util.Arrays; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.inventory.BrewEvent; ++// CraftBukkit end ++ + public class TileEntityBrewingStand extends TileEntityContainer implements IUpdatePlayerListBox, IWorldInventory { + + private static final int[] a = new int[] { 3}; +@@ -12,9 +18,35 @@ + private boolean[] i; + private Item j; + private String k; ++ private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field + + public TileEntityBrewingStand() {} + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = 64; ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public String getName() { + return this.hasCustomName() ? this.k : "container.brewing"; + } +@@ -32,9 +64,14 @@ + } + + public void c() { ++ // CraftBukkit start - Use wall time instead of ticks for brewing ++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick; ++ this.lastTick = MinecraftServer.currentTick; ++ + if (this.brewTime > 0) { +- --this.brewTime; +- if (this.brewTime == 0) { ++ this.brewTime -= elapsedTicks; ++ if (this.brewTime <= 0) { // == -> <= ++ // CraftBukkit end + this.o(); + this.update(); + } else if (!this.n()) { +@@ -110,6 +147,16 @@ + if (this.n()) { + ItemStack itemstack = this.items[3]; + ++ // CraftBukkit start ++ if (getOwner() != null) { ++ BrewEvent event = new BrewEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), (org.bukkit.inventory.BrewerInventory) this.getOwner().getInventory()); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return; ++ } ++ } ++ // CraftBukkit end ++ + for (int i = 0; i < 3; ++i) { + if (this.items[i] != null && this.items[i].getItem() == Items.POTION) { + int j = this.items[i].getData(); +@@ -221,7 +268,7 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return this.maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityChest.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityChest.patch new file mode 100644 index 0000000..605ced7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityChest.patch @@ -0,0 +1,117 @@ +--- a/net/minecraft/server/TileEntityChest.java ++++ b/net/minecraft/server/TileEntityChest.java +@@ -3,6 +3,11 @@ + import java.util.Iterator; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class TileEntityChest extends TileEntityContainer implements IUpdatePlayerListBox, IInventory { + + private ItemStack[] items = new ItemStack[27]; +@@ -20,6 +25,31 @@ + + public TileEntityChest() {} + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public int getSize() { + return 27; + } +@@ -125,10 +155,11 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { ++ if (this.world == null) return true; // CraftBukkit + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + +@@ -304,9 +335,21 @@ + if (this.l < 0) { + this.l = 0; + } ++ int oldPower = Math.max(0, Math.min(15, this.l)); // CraftBukkit - Get power before new viewer is added + + ++this.l; ++ if (this.world == null) return; // CraftBukkit + this.world.playBlockAction(this.position, this.w(), 1, this.l); ++ ++ // CraftBukkit start - Call redstone event ++ if (this.w() == Blocks.TRAPPED_CHEST) { ++ int newPower = Math.max(0, Math.min(15, this.l)); ++ ++ if (oldPower != newPower) { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, position.getX(), position.getY(), position.getZ(), oldPower, newPower); ++ } ++ } ++ // CraftBukkit end + this.world.applyPhysics(this.position, this.w()); + this.world.applyPhysics(this.position.down(), this.w()); + } +@@ -315,8 +358,20 @@ + + public void closeContainer(EntityHuman entityhuman) { + if (!entityhuman.isSpectator() && this.w() instanceof BlockChest) { ++ int oldPower = Math.max(0, Math.min(15, this.l)); // CraftBukkit - Get power before new viewer is added + --this.l; ++ if (this.world == null) return; // CraftBukkit + this.world.playBlockAction(this.position, this.w(), 1, this.l); ++ ++ // CraftBukkit start - Call redstone event ++ if (this.w() == Blocks.TRAPPED_CHEST) { ++ int newPower = Math.max(0, Math.min(15, this.l)); ++ ++ if (oldPower != newPower) { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, position.getX(), position.getY(), position.getZ(), oldPower, newPower); ++ } ++ } ++ // CraftBukkit end + this.world.applyPhysics(this.position, this.w()); + this.world.applyPhysics(this.position.down(), this.w()); + } +@@ -370,6 +425,14 @@ + + } + ++ // CraftBukkit start ++ // PAIL ++ @Override ++ public boolean F() { ++ return true; ++ } ++ // CraftBukkit end ++ + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityCommand.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityCommand.patch new file mode 100644 index 0000000..9ef1c0a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityCommand.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/server/TileEntityCommand.java ++++ b/net/minecraft/server/TileEntityCommand.java +@@ -3,6 +3,9 @@ + public class TileEntityCommand extends TileEntity { + + private final CommandBlockListenerAbstract a = new CommandBlockListenerAbstract() { ++ { ++ sender = new org.bukkit.craftbukkit.command.CraftBlockCommandSender(this); // CraftBukkit - add sender ++ } + public BlockPosition getChunkCoordinates() { + return TileEntityCommand.this.position; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityDispenser.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityDispenser.patch new file mode 100644 index 0000000..ec176e9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityDispenser.patch @@ -0,0 +1,64 @@ +--- a/net/minecraft/server/TileEntityDispenser.java ++++ b/net/minecraft/server/TileEntityDispenser.java +@@ -2,12 +2,44 @@ + + import java.util.Random; + ++// CraftBukkit start ++import java.util.List; ++ ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class TileEntityDispenser extends TileEntityContainer implements IInventory { + + private static final Random f = new Random(); + private ItemStack[] items = new ItemStack[9]; + protected String a; + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public TileEntityDispenser() {} + + public int getSize() { +@@ -58,6 +90,7 @@ + + for (int k = 0; k < this.items.length; ++k) { + if (this.items[k] != null && TileEntityDispenser.f.nextInt(j++) == 0) { ++ if (this.items[k].count == 0) continue; // CraftBukkit + i = k; + } + } +@@ -140,7 +173,7 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityFurnace.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityFurnace.patch new file mode 100644 index 0000000..796d323 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityFurnace.patch @@ -0,0 +1,188 @@ +--- a/net/minecraft/server/TileEntityFurnace.java ++++ b/net/minecraft/server/TileEntityFurnace.java +@@ -1,5 +1,15 @@ + package net.minecraft.server; + ++// CraftBukkit start ++import java.util.List; ++ ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.inventory.FurnaceBurnEvent; ++import org.bukkit.event.inventory.FurnaceSmeltEvent; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++// CraftBukkit end ++ + public class TileEntityFurnace extends TileEntityContainer implements IUpdatePlayerListBox, IWorldInventory { + + private static final int[] a = new int[] { 0}; +@@ -12,6 +22,32 @@ + private int cookTimeTotal; + private String m; + ++ // CraftBukkit start - add fields and methods ++ private int lastTick = MinecraftServer.currentTick; ++ private int maxStack = MAX_STACK; ++ public List transaction = new java.util.ArrayList(); ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public TileEntityFurnace() {} + + public int getSize() { +@@ -132,7 +168,7 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return maxStack; // CraftBukkit + } + + public boolean isBurning() { +@@ -140,11 +176,29 @@ + } + + public void c() { +- boolean flag = this.isBurning(); ++ boolean flag = (this.w() == Blocks.LIT_FURNACE); // CraftBukkit - SPIGOT-844 - Check if furnace block is lit using the block instead of burn time // PAIL: Rename + boolean flag1 = false; + ++ // CraftBukkit start - Use wall time instead of ticks for cooking ++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick; ++ this.lastTick = MinecraftServer.currentTick; ++ ++ // CraftBukkit - moved from below ++ if (this.isBurning() && this.canBurn()) { ++ this.cookTime += elapsedTicks; ++ if (this.cookTime >= this.cookTimeTotal) { ++ this.cookTime = 0; ++ this.cookTimeTotal = this.a(this.items[0]); ++ this.burn(); ++ flag1 = true; ++ } ++ } else { ++ this.cookTime = 0; ++ } ++ // CraftBukkit end ++ + if (this.isBurning()) { +- --this.burnTime; ++ this.burnTime -= elapsedTicks; // CraftBukkit - use elapsedTicks in place of constant + } + + if (!this.world.isClientSide) { +@@ -153,9 +207,21 @@ + this.cookTime = MathHelper.clamp(this.cookTime - 2, 0, this.cookTimeTotal); + } + } else { +- if (!this.isBurning() && this.canBurn()) { +- this.ticksForCurrentFuel = this.burnTime = fuelTime(this.items[1]); +- if (this.isBurning()) { ++ // CraftBukkit start - Handle multiple elapsed ticks ++ if (this.burnTime <= 0 && this.canBurn()) { // CraftBukkit - == to <= ++ CraftItemStack fuel = CraftItemStack.asCraftMirror(this.items[1]); ++ ++ FurnaceBurnEvent furnaceBurnEvent = new FurnaceBurnEvent(this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), fuel, fuelTime(this.items[1])); ++ this.world.getServer().getPluginManager().callEvent(furnaceBurnEvent); ++ ++ if (furnaceBurnEvent.isCancelled()) { ++ return; ++ } ++ ++ this.ticksForCurrentFuel = furnaceBurnEvent.getBurnTime(); ++ this.burnTime += this.ticksForCurrentFuel; ++ if (this.burnTime > 0 && furnaceBurnEvent.isBurning()) { ++ // CraftBukkit end + flag1 = true; + if (this.items[1] != null) { + --this.items[1].count; +@@ -168,6 +234,7 @@ + } + } + ++ /* CraftBukkit start - Moved up + if (this.isBurning() && this.canBurn()) { + ++this.cookTime; + if (this.cookTime == this.cookTimeTotal) { +@@ -179,11 +246,13 @@ + } else { + this.cookTime = 0; + } ++ */ + } + + if (flag != this.isBurning()) { + flag1 = true; + BlockFurnace.a(this.isBurning(), this.world, this.position); ++ this.E(); // CraftBukkit - Invalidate tile entity's cached block type // PAIL: Rename + } + } + +@@ -203,7 +272,8 @@ + } else { + ItemStack itemstack = RecipesFurnace.getInstance().getResult(this.items[0]); + +- return itemstack == null ? false : (this.items[2] == null ? true : (!this.items[2].doMaterialsMatch(itemstack) ? false : (this.items[2].count < this.getMaxStackSize() && this.items[2].count < this.items[2].getMaxStackSize() ? true : this.items[2].count < itemstack.getMaxStackSize()))); ++ // CraftBukkit - consider resultant count instead of current count ++ return itemstack == null ? false : (this.items[2] == null ? true : (!this.items[2].doMaterialsMatch(itemstack) ? false : (this.items[2].count + itemstack.count <= this.getMaxStackSize() && this.items[2].count < this.items[2].getMaxStackSize() ? true : this.items[2].count + itemstack.count <= itemstack.getMaxStackSize()))); + } + } + +@@ -211,11 +281,38 @@ + if (this.canBurn()) { + ItemStack itemstack = RecipesFurnace.getInstance().getResult(this.items[0]); + ++ // CraftBukkit start - fire FurnaceSmeltEvent ++ CraftItemStack source = CraftItemStack.asCraftMirror(this.items[0]); ++ org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack); ++ ++ FurnaceSmeltEvent furnaceSmeltEvent = new FurnaceSmeltEvent(this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), source, result); ++ this.world.getServer().getPluginManager().callEvent(furnaceSmeltEvent); ++ ++ if (furnaceSmeltEvent.isCancelled()) { ++ return; ++ } ++ ++ result = furnaceSmeltEvent.getResult(); ++ itemstack = CraftItemStack.asNMSCopy(result); ++ ++ if (itemstack != null) { ++ if (this.items[2] == null) { ++ this.items[2] = itemstack; ++ } else if (CraftItemStack.asCraftMirror(this.items[2]).isSimilar(result)) { ++ this.items[2].count += itemstack.count; ++ } else { ++ return; ++ } ++ } ++ ++ /* + if (this.items[2] == null) { + this.items[2] = itemstack.cloneItemStack(); + } else if (this.items[2].getItem() == itemstack.getItem()) { + ++this.items[2].count; + } ++ */ ++ // CraftBukkit end + + if (this.items[0].getItem() == Item.getItemOf(Blocks.SPONGE) && this.items[0].getData() == 1 && this.items[1] != null && this.items[1].getItem() == Items.BUCKET) { + this.items[1] = new ItemStack(Items.WATER_BUCKET); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityHopper.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityHopper.patch new file mode 100644 index 0000000..e3ed30c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityHopper.patch @@ -0,0 +1,154 @@ +--- a/net/minecraft/server/TileEntityHopper.java ++++ b/net/minecraft/server/TileEntityHopper.java +@@ -3,12 +3,46 @@ + import java.util.Iterator; + import java.util.List; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.inventory.InventoryMoveItemEvent; ++import org.bukkit.event.inventory.InventoryPickupItemEvent; ++import org.bukkit.inventory.Inventory; ++// CraftBukkit end ++ + public class TileEntityHopper extends TileEntityContainer implements IHopper, IUpdatePlayerListBox { + + private ItemStack[] items = new ItemStack[5]; + private String f; + private int g = -1; + ++ // CraftBukkit start - add fields and methods ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() { ++ return this.items; ++ } ++ ++ public void onOpen(CraftHumanEntity who) { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public TileEntityHopper() {} + + public void a(NBTTagCompound nbttagcompound) { +@@ -120,7 +154,7 @@ + } + + public int getMaxStackSize() { +- return 64; ++ return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { +@@ -216,10 +250,35 @@ + for (int i = 0; i < this.getSize(); ++i) { + if (this.getItem(i) != null) { + ItemStack itemstack = this.getItem(i).cloneItemStack(); +- ItemStack itemstack1 = addItem(iinventory, this.splitStack(i, 1), enumdirection); ++ // ItemStack itemstack1 = addItem(iinventory, this.splitStack(i, 1), enumdirection); ++ ++ // CraftBukkit start - Call event when pushing items into other inventories ++ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, 1)); ++ ++ Inventory destinationInventory; ++ // Have to special case large chests as they work oddly ++ if (iinventory instanceof InventoryLargeChest) { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); ++ } else { ++ destinationInventory = iinventory.getOwner().getInventory(); ++ } ++ ++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); ++ this.getWorld().getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ this.setItem(i, itemstack); ++ this.d(8); // Delay hopper checks ++ return false; ++ } ++ ItemStack itemstack1 = addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), enumdirection); + + if (itemstack1 == null || itemstack1.count == 0) { +- iinventory.update(); ++ if (event.getItem().equals(oitemstack)) { ++ iinventory.update(); ++ } else { ++ this.setItem(i, itemstack); ++ } ++ // CraftBukkit end + return true; + } + +@@ -330,10 +389,41 @@ + + if (itemstack != null && b(iinventory, itemstack, i, enumdirection)) { + ItemStack itemstack1 = itemstack.cloneItemStack(); +- ItemStack itemstack2 = addItem(ihopper, iinventory.splitStack(i, 1), (EnumDirection) null); ++ // ItemStack itemstack2 = addItem(ihopper, iinventory.splitStack(i, 1), (EnumDirection) null); ++ // CraftBukkit start - Call event on collection of items from inventories into the hopper ++ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, 1)); ++ ++ Inventory sourceInventory; ++ // Have to special case large chests as they work oddly ++ if (iinventory instanceof InventoryLargeChest) { ++ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); ++ } else { ++ sourceInventory = iinventory.getOwner().getInventory(); ++ } ++ ++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false); ++ ++ ihopper.getWorld().getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ iinventory.setItem(i, itemstack1); ++ ++ if (ihopper instanceof TileEntityHopper) { ++ ((TileEntityHopper) ihopper).d(8); // Delay hopper checks ++ } else if (ihopper instanceof EntityMinecartHopper) { ++ ((EntityMinecartHopper) ihopper).m(4); // Delay hopper minecart checks ++ } ++ ++ return false; ++ } ++ ItemStack itemstack2 = addItem(ihopper, CraftItemStack.asNMSCopy(event.getItem()), null); + + if (itemstack2 == null || itemstack2.count == 0) { +- iinventory.update(); ++ if (event.getItem().equals(oitemstack)) { ++ iinventory.update(); ++ } else { ++ iinventory.setItem(i, itemstack1); ++ } ++ // CraftBukkit end + return true; + } + +@@ -349,6 +439,13 @@ + if (entityitem == null) { + return false; + } else { ++ // CraftBukkit start ++ InventoryPickupItemEvent event = new InventoryPickupItemEvent(iinventory.getOwner().getInventory(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); ++ entityitem.world.getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return false; ++ } ++ // CraftBukkit end + ItemStack itemstack = entityitem.getItemStack().cloneItemStack(); + ItemStack itemstack1 = addItem(iinventory, itemstack, (EnumDirection) null); + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityNote.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityNote.patch new file mode 100644 index 0000000..3e969b7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityNote.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/server/TileEntityNote.java ++++ b/net/minecraft/server/TileEntityNote.java +@@ -44,7 +44,12 @@ + b0 = 4; + } + +- world.playBlockAction(blockposition, Blocks.NOTEBLOCK, b0, this.note); ++ // CraftBukkit start ++ org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(this.world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), b0, this.note); ++ if (!event.isCancelled()) { ++ world.playBlockAction(blockposition, Blocks.NOTEBLOCK, event.getInstrument().getType(), event.getNote().getId()); ++ } ++ // CraftBukkit end + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityPiston.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityPiston.patch new file mode 100644 index 0000000..6e1f13a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntityPiston.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/TileEntityPiston.java ++++ b/net/minecraft/server/TileEntityPiston.java +@@ -104,6 +104,7 @@ + } + + public void c() { ++ if (this.world == null) return; // CraftBukkit + this.j = this.i; + if (this.j >= 1.0F) { + this.a(1.0F, 0.25F); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntitySign.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntitySign.patch new file mode 100644 index 0000000..e03d670 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntitySign.patch @@ -0,0 +1,55 @@ +--- a/net/minecraft/server/TileEntitySign.java ++++ b/net/minecraft/server/TileEntitySign.java +@@ -21,6 +21,12 @@ + nbttagcompound.setString("Text" + (i + 1), s); + } + ++ // CraftBukkit start ++ if (Boolean.getBoolean("convertLegacySigns")) { ++ nbttagcompound.setBoolean("Bukkit.isConverted", true); ++ } ++ // CraftBukkit end ++ + this.i.b(nbttagcompound); + } + +@@ -65,12 +71,27 @@ + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) {} + }; + ++ // CraftBukkit start - Add an option to convert signs correctly ++ // This is done with a flag instead of all the time because ++ // we have no way to tell whether a sign is from 1.7.10 or 1.8 ++ ++ boolean oldSign = Boolean.getBoolean("convertLegacySigns") && !nbttagcompound.getBoolean("Bukkit.isConverted"); ++ + for (int i = 0; i < 4; ++i) { + String s = nbttagcompound.getString("Text" + (i + 1)); ++ if (s != null && s.length() > 2048) { ++ s = "\"\""; ++ } + + try { + IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s); + ++ if (oldSign) { ++ lines[i] = org.bukkit.craftbukkit.util.CraftChatMessage.fromString(s)[0]; ++ continue; ++ } ++ // CraftBukkit end ++ + try { + this.lines[i] = ChatComponentUtils.filterForDisplay(icommandlistener, ichatbasecomponent, (Entity) null); + } catch (CommandException commandexception) { +@@ -155,7 +176,10 @@ + ChatClickable chatclickable = chatmodifier.h(); + + if (chatclickable.a() == ChatClickable.EnumClickAction.RUN_COMMAND) { +- MinecraftServer.getServer().getCommandHandler().a(icommandlistener, chatclickable.b()); ++ // CraftBukkit start ++ // MinecraftServer.getServer().getCommandHandler().a(tileentitysignplayerwrapper, chatclickable.b()); ++ CommandBlockListenerAbstract.executeCommand(entityhuman, (org.bukkit.entity.Player) entityhuman.getBukkitEntity(), chatclickable.b()); ++ // CraftBukkit end + } + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntitySkull.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntitySkull.patch new file mode 100644 index 0000000..c420196 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/TileEntitySkull.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/server/TileEntitySkull.java ++++ b/net/minecraft/server/TileEntitySkull.java +@@ -105,4 +105,10 @@ + public void setRotation(int i) { + this.rotation = i; + } ++ ++ // CraftBukkit start - add method ++ public int getRotation() { ++ return this.rotation; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/UserCache.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/UserCache.patch new file mode 100644 index 0000000..1433fce --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/UserCache.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/server/UserCache.java ++++ b/net/minecraft/server/UserCache.java +@@ -42,7 +42,7 @@ + public static final SimpleDateFormat a = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); + private final Map c = Maps.newHashMap(); + private final Map d = Maps.newHashMap(); +- private final LinkedList e = Lists.newLinkedList(); ++ private final java.util.Deque e = new java.util.concurrent.LinkedBlockingDeque(); // CraftBukkit + private final MinecraftServer f; + protected final Gson b; + private final File g; +@@ -323,11 +323,11 @@ + } + } + +- public JsonElement serialize(Object object, Type type, JsonSerializationContext jsonserializationcontext) { ++ public JsonElement serialize(UserCacheEntry object, Type type, JsonSerializationContext jsonserializationcontext) { // CraftBukkit - decompile error + return this.a((UserCache.UserCacheEntry) object, type, jsonserializationcontext); + } + +- public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { ++ public UserCacheEntry deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { // CraftBukkit - decompile error + return this.a(jsonelement, type, jsondeserializationcontext); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/Village.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Village.patch new file mode 100644 index 0000000..ee57a43 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/Village.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/Village.java ++++ b/net/minecraft/server/Village.java +@@ -62,7 +62,7 @@ + EntityIronGolem entityirongolem = new EntityIronGolem(this.a); + + entityirongolem.setPosition(vec3d.a, vec3d.b, vec3d.c); +- this.a.addEntity(entityirongolem); ++ this.a.addEntity(entityirongolem, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE); // CraftBukkit + ++this.l; + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/VillageSiege.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/VillageSiege.patch new file mode 100644 index 0000000..9b174ab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/VillageSiege.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/VillageSiege.java ++++ b/net/minecraft/server/VillageSiege.java +@@ -140,7 +140,7 @@ + } + + entityzombie.setPositionRotation(vec3d.a, vec3d.b, vec3d.c, this.a.random.nextFloat() * 360.0F, 0.0F); +- this.a.addEntity(entityzombie); ++ this.a.addEntity(entityzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_INVASION); // CraftBukkit + BlockPosition blockposition = this.f.a(); + + entityzombie.a(blockposition, this.f.b()); diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/World.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/World.patch new file mode 100644 index 0000000..484a9e0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/World.patch @@ -0,0 +1,654 @@ +--- a/net/minecraft/server/World.java ++++ b/net/minecraft/server/World.java +@@ -13,6 +13,25 @@ + import java.util.UUID; + import java.util.concurrent.Callable; + ++// CraftBukkit start ++import com.google.common.collect.Maps; ++import java.util.Map; ++ ++import org.bukkit.Bukkit; ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.craftbukkit.util.LongHashSet; ++import org.bukkit.generator.ChunkGenerator; ++import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.block.BlockCanBuildEvent; ++import org.bukkit.event.block.BlockPhysicsEvent; ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; ++import org.bukkit.event.weather.WeatherChangeEvent; ++import org.bukkit.event.weather.ThunderChangeEvent; ++// CraftBukkit end ++ + public abstract class World implements IBlockAccess { + + private int a = 63; +@@ -36,27 +55,72 @@ + protected float r; + private int J; + public final Random random = new Random(); +- public final WorldProvider worldProvider; ++ public WorldProvider worldProvider; // CraftBukkit - remove final + protected List u = Lists.newArrayList(); + protected IChunkProvider chunkProvider; + protected final IDataManager dataManager; +- protected WorldData worldData; ++ public WorldData worldData; // CraftBukkit - public + protected boolean isLoading; +- protected PersistentCollection worldMaps; ++ public PersistentCollection worldMaps; // CraftBukkit - public + protected PersistentVillage villages; + public final MethodProfiler methodProfiler; + private final Calendar K = Calendar.getInstance(); +- protected Scoreboard scoreboard = new Scoreboard(); ++ public Scoreboard scoreboard = new Scoreboard(); // CraftBukkit - public + public final boolean isClientSide; +- protected Set chunkTickList = Sets.newHashSet(); ++ // CraftBukkit - longhashset ++ protected LongHashSet chunkTickList = new LongHashSet(); + private int L; +- protected boolean allowMonsters; +- protected boolean allowAnimals; ++ public boolean allowMonsters; // CraftBukkit - public ++ public boolean allowAnimals; // CraftBukkit - public + private boolean M; + private final WorldBorder N; + int[] H; + +- protected World(IDataManager idatamanager, WorldData worlddata, WorldProvider worldprovider, MethodProfiler methodprofiler, boolean flag) { ++ // CraftBukkit start Added the following ++ private final CraftWorld world; ++ public boolean pvpMode; ++ public boolean keepSpawnInMemory = true; ++ public ChunkGenerator generator; ++ ++ public boolean captureBlockStates = false; ++ public boolean captureTreeGeneration = false; ++ public ArrayList capturedBlockStates= new ArrayList(){ ++ @Override ++ public boolean add( BlockState blockState ) { ++ Iterator blockStateIterator = this.iterator(); ++ while( blockStateIterator.hasNext() ) { ++ BlockState blockState1 = blockStateIterator.next(); ++ if ( blockState1.getLocation().equals( blockState.getLocation() ) ) { ++ return false; ++ } ++ } ++ ++ return super.add( blockState ); ++ } ++ }; ++ public long ticksPerAnimalSpawns; ++ public long ticksPerMonsterSpawns; ++ public boolean populating; ++ private int tickPosition; ++ ++ public CraftWorld getWorld() { ++ return this.world; ++ } ++ ++ public CraftServer getServer() { ++ return (CraftServer) Bukkit.getServer(); ++ } ++ ++ public Chunk getChunkIfLoaded(int x, int z) { ++ return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(x, z); ++ } ++ ++ protected World(IDataManager idatamanager, WorldData worlddata, WorldProvider worldprovider, MethodProfiler methodprofiler, boolean flag, ChunkGenerator gen, org.bukkit.World.Environment env) { ++ this.generator = gen; ++ this.world = new CraftWorld((WorldServer) this, gen, env); ++ this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit ++ this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit ++ // CraftBukkit end + this.L = this.random.nextInt(12000); + this.allowMonsters = true; + this.allowAnimals = true; +@@ -67,6 +131,35 @@ + this.worldProvider = worldprovider; + this.isClientSide = flag; + this.N = worldprovider.getWorldBorder(); ++ // CraftBukkit start ++ // Moved from PlayerList ++ this.N.a(new IWorldBorderListener() { ++ public void a(WorldBorder worldborder, double d0) { ++ getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_SIZE), World.this); ++ } ++ ++ public void a(WorldBorder worldborder, double d0, double d1, long i) { ++ getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.LERP_SIZE), World.this); ++ } ++ ++ public void a(WorldBorder worldborder, double d0, double d1) { ++ getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_CENTER), World.this); ++ } ++ ++ public void a(WorldBorder worldborder, int i) { ++ getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_WARNING_TIME), World.this); ++ } ++ ++ public void b(WorldBorder worldborder, int i) { ++ getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_WARNING_BLOCKS), World.this); ++ } ++ ++ public void b(WorldBorder worldborder, double d0) {} ++ ++ public void c(WorldBorder worldborder, double d0) {} ++ }); ++ this.getServer().addWorld(this.world); ++ // CraftBukkit end + } + + public World b() { +@@ -193,6 +286,27 @@ + } + + public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { ++ // CraftBukkit start - tree generation ++ if (this.captureTreeGeneration) { ++ BlockState blockstate = null; ++ Iterator it = capturedBlockStates.iterator(); ++ while (it.hasNext()) { ++ BlockState previous = it.next(); ++ if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) { ++ blockstate = previous; ++ it.remove(); ++ break; ++ } ++ } ++ if (blockstate == null) { ++ blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, blockposition.getX(), blockposition.getY(), blockposition.getZ(), i); ++ } ++ blockstate.setTypeId(CraftMagicNumbers.getId(iblockdata.getBlock())); ++ blockstate.setRawData((byte) iblockdata.getBlock().toLegacyData(iblockdata)); ++ this.capturedBlockStates.add(blockstate); ++ return true; ++ } ++ // CraftBukkit end + if (!this.isValidLocation(blockposition)) { + return false; + } else if (!this.isClientSide && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { +@@ -200,9 +314,23 @@ + } else { + Chunk chunk = this.getChunkAtWorldCoords(blockposition); + Block block = iblockdata.getBlock(); ++ ++ // CraftBukkit start - capture blockstates ++ BlockState blockstate = null; ++ if (this.captureBlockStates) { ++ blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, blockposition.getX(), blockposition.getY(), blockposition.getZ(), i); ++ this.capturedBlockStates.add(blockstate); ++ } ++ // CraftBukkit end ++ + IBlockData iblockdata1 = chunk.a(blockposition, iblockdata); + + if (iblockdata1 == null) { ++ // CraftBukkit start - remove blockstate if failed ++ if (this.captureBlockStates) { ++ this.capturedBlockStates.remove(blockstate); ++ } ++ // CraftBukkit end + return false; + } else { + Block block1 = iblockdata1.getBlock(); +@@ -213,6 +341,7 @@ + this.methodProfiler.b(); + } + ++ /* + if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && chunk.isReady()) { + this.notify(blockposition); + } +@@ -223,12 +352,35 @@ + this.updateAdjacentComparators(blockposition, block); + } + } ++ */ ++ ++ // CraftBukkit start ++ if (!this.captureBlockStates) { // Don't notify clients or update physics while capturing blockstates ++ // Modularize client and physic updates ++ notifyAndUpdatePhysics(blockposition, chunk, block1, block, i); ++ } ++ // CraftBukkit end + + return true; + } + } + } + ++ // CraftBukkit start - Split off from original setTypeAndData(int i, int j, int k, Block block, int l, int i1) method in order to directly send client and physic updates ++ public void notifyAndUpdatePhysics(BlockPosition blockposition, Chunk chunk, Block oldBlock, Block newBLock, int flag) { ++ if ((flag & 2) != 0 && (chunk == null || chunk.isReady())) { // allow chunk to be null here as chunk.isReady() is false when we send our notification during block placement ++ this.notify(blockposition); ++ } ++ ++ if (!this.isClientSide && (flag & 1) != 0) { ++ this.update(blockposition, oldBlock); ++ if (newBLock.isComplexRedstone()) { ++ this.updateAdjacentComparators(blockposition, newBLock); ++ } ++ } ++ } ++ // CraftBukkit end ++ + public boolean setAir(BlockPosition blockposition) { + return this.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); + } +@@ -262,6 +414,11 @@ + + public void update(BlockPosition blockposition, Block block) { + if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { ++ // CraftBukkit start ++ if (populating) { ++ return; ++ } ++ // CraftBukkit end + this.applyPhysics(blockposition, block); + } + +@@ -337,6 +494,17 @@ + IBlockData iblockdata = this.getType(blockposition); + + try { ++ // CraftBukkit start ++ CraftWorld world = ((WorldServer) this).getWorld(); ++ if (world != null) { ++ BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftMagicNumbers.getId(block)); ++ this.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ } ++ // CraftBukkit end + iblockdata.getBlock().doPhysics(this, blockposition, iblockdata, block); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Exception while updating neighbours"); +@@ -518,6 +686,17 @@ + } + + public IBlockData getType(BlockPosition blockposition) { ++ // CraftBukkit start - tree generation ++ if (captureTreeGeneration) { ++ Iterator it = capturedBlockStates.iterator(); ++ while (it.hasNext()) { ++ BlockState previous = it.next(); ++ if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) { ++ return CraftMagicNumbers.getBlock(previous.getTypeId()).fromLegacyData(previous.getRawData()); ++ } ++ } ++ } ++ // CraftBukkit end + if (!this.isValidLocation(blockposition)) { + return Blocks.AIR.getBlockData(); + } else { +@@ -723,6 +902,13 @@ + } + + public boolean addEntity(Entity entity) { ++ // CraftBukkit start - Used for entities other than creatures ++ return addEntity(entity, SpawnReason.DEFAULT); ++ } ++ ++ public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason ++ if (entity == null) return false; ++ // CraftBukkit end + int i = MathHelper.floor(entity.locX / 16.0D); + int j = MathHelper.floor(entity.locZ / 16.0D); + boolean flag = entity.attachedToPlayer; +@@ -731,7 +917,35 @@ + flag = true; + } + ++ // CraftBukkit start ++ org.bukkit.event.Cancellable event = null; ++ if (entity instanceof EntityLiving && !(entity instanceof EntityPlayer)) { ++ boolean isAnimal = entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal || entity instanceof EntityGolem; ++ boolean isMonster = entity instanceof EntityMonster || entity instanceof EntityGhast || entity instanceof EntitySlime; ++ ++ if (spawnReason != SpawnReason.CUSTOM) { ++ if (isAnimal && !allowAnimals || isMonster && !allowMonsters) { ++ entity.dead = true; ++ return false; ++ } ++ } ++ ++ event = CraftEventFactory.callCreatureSpawnEvent((EntityLiving) entity, spawnReason); ++ } else if (entity instanceof EntityItem) { ++ event = CraftEventFactory.callItemSpawnEvent((EntityItem) entity); ++ } else if (entity.getBukkitEntity() instanceof org.bukkit.entity.Projectile) { ++ // Not all projectiles extend EntityProjectile, so check for Bukkit interface instead ++ event = CraftEventFactory.callProjectileLaunchEvent(entity); ++ } ++ ++ if (event != null && (event.isCancelled() || entity.dead)) { ++ entity.dead = true; ++ return false; ++ } ++ // CraftBukkit end ++ + if (!flag && !this.isChunkLoaded(i, j, true)) { ++ entity.dead = true; + return false; + } else { + if (entity instanceof EntityHuman) { +@@ -753,6 +967,7 @@ + ((IWorldAccess) this.u.get(i)).a(entity); + } + ++ entity.valid = true; // CraftBukkit + } + + protected void b(Entity entity) { +@@ -760,6 +975,7 @@ + ((IWorldAccess) this.u.get(i)).b(entity); + } + ++ entity.valid = false; // CraftBukkit + } + + public void kill(Entity entity) { +@@ -794,7 +1010,15 @@ + this.getChunkAt(i, j).b(entity); + } + +- this.entityList.remove(entity); ++ // CraftBukkit start - Decrement loop variable field if we've already ticked this entity ++ int index = this.entityList.indexOf(entity); ++ if (index != -1) { ++ if (index <= this.tickPosition) { ++ this.tickPosition--; ++ } ++ this.entityList.remove(index); ++ } ++ // CraftBukkit end + this.b(entity); + } + +@@ -978,6 +1202,11 @@ + + for (i = 0; i < this.k.size(); ++i) { + entity = (Entity) this.k.get(i); ++ // CraftBukkit start - Fixed an NPE ++ if (entity == null) { ++ continue; ++ } ++ // CraftBukkit end + + try { + ++entity.ticksLived; +@@ -1021,8 +1250,10 @@ + this.g.clear(); + this.methodProfiler.c("regular"); + +- for (i = 0; i < this.entityList.size(); ++i) { +- entity = (Entity) this.entityList.get(i); ++ // CraftBukkit start - Use field for loop variable ++ for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) { ++ entity = (Entity) this.entityList.get(this.tickPosition); ++ // CraftBukkit end + if (entity.vehicle != null) { + if (!entity.vehicle.dead && entity.vehicle.passenger == entity) { + continue; +@@ -1053,7 +1284,7 @@ + this.getChunkAt(j, k).b(entity); + } + +- this.entityList.remove(i--); ++ this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable + this.b(entity); + } + +@@ -1062,6 +1293,13 @@ + + this.methodProfiler.c("blockEntities"); + this.M = true; ++ // CraftBukkit start - From below, clean up tile entities before ticking them ++ if (!this.c.isEmpty()) { ++ this.tileEntityList.removeAll(this.c); ++ this.h.removeAll(this.c); ++ this.c.clear(); ++ } ++ // CraftBukkit end + Iterator iterator = this.tileEntityList.iterator(); + + while (iterator.hasNext()) { +@@ -1093,11 +1331,13 @@ + } + + this.M = false; ++ /* CraftBukkit start - Moved up + if (!this.c.isEmpty()) { + this.tileEntityList.removeAll(this.c); + this.h.removeAll(this.c); + this.c.clear(); + } ++ // CraftBukkit end */ + + this.methodProfiler.c("pendingBlockEntities"); + if (!this.b.isEmpty()) { +@@ -1105,9 +1345,11 @@ + TileEntity tileentity1 = (TileEntity) this.b.get(l); + + if (!tileentity1.x()) { ++ /* CraftBukkit start - Order matters, moved down + if (!this.h.contains(tileentity1)) { + this.a(tileentity1); + } ++ // CraftBukkit end */ + + if (this.isLoaded(tileentity1.getPosition())) { + this.getChunkAtWorldCoords(tileentity1.getPosition()).a(tileentity1.getPosition(), tileentity1); +@@ -1161,7 +1403,10 @@ + int j = MathHelper.floor(entity.locZ); + byte b0 = 32; + +- if (!flag || this.isAreaLoaded(i - b0, 0, j - b0, i + b0, 0, j + b0, true)) { ++ // CraftBukkit start - Use neighbor cache instead of looking up ++ Chunk startingChunk = this.getChunkIfLoaded(i >> 4, j >> 4); ++ if (!flag || (startingChunk != null && startingChunk.areNeighborsLoaded(2)) /* this.isAreaLoaded(i - b0, 0, j - b0, i + b0, 0, j + b0) */) { ++ // CraftBukkit end + entity.P = entity.locX; + entity.Q = entity.locY; + entity.R = entity.locZ; +@@ -1479,10 +1724,18 @@ + } + } + ++ public Map capturedTileEntities = Maps.newHashMap(); ++ + public TileEntity getTileEntity(BlockPosition blockposition) { + if (!this.isValidLocation(blockposition)) { + return null; + } else { ++ // CraftBukkit start ++ if (capturedTileEntities.containsKey(blockposition)) { ++ return capturedTileEntities.get(blockposition); ++ } ++ // CraftBukkit end ++ + TileEntity tileentity = null; + int i; + TileEntity tileentity1; +@@ -1517,6 +1770,14 @@ + + public void setTileEntity(BlockPosition blockposition, TileEntity tileentity) { + if (tileentity != null && !tileentity.x()) { ++ // CraftBukkit start ++ if (captureBlockStates) { ++ tileentity.a(this); ++ tileentity.a(blockposition); ++ capturedTileEntities.put(blockposition, tileentity); ++ return; ++ } ++ // CraftBukkit end + if (this.M) { + tileentity.a(blockposition); + Iterator iterator = this.b.iterator(); +@@ -1679,12 +1940,20 @@ + } + + this.p = MathHelper.a(this.p, 0.0F, 1.0F); ++ ++ // CraftBukkit start ++ for (int idx = 0; idx < this.players.size(); ++idx) { ++ if (((EntityPlayer) this.players.get(idx)).world == this) { ++ ((EntityPlayer) this.players.get(idx)).tickWeather(); ++ } ++ } ++ // CraftBukkit end + } + } + } + + protected void D() { +- this.chunkTickList.clear(); ++ // this.chunkTickList.clear(); // CraftBukkit - removed + this.methodProfiler.a("buildList"); + + int i; +@@ -1701,7 +1970,7 @@ + + for (int i1 = -l; i1 <= l; ++i1) { + for (int j1 = -l; j1 <= l; ++j1) { +- this.chunkTickList.add(new ChunkCoordIntPair(i1 + j, j1 + k)); ++ this.chunkTickList.add(org.bukkit.craftbukkit.util.LongHash.toLong(i1 + j, j1 + k)); + } + } + } +@@ -1879,7 +2148,10 @@ + } + + public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition) { +- if (!this.areChunksLoaded(blockposition, 17, false)) { ++ // CraftBukkit start - Use neighbor cache instead of looking up ++ Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); ++ if (chunk == null || !chunk.areNeighborsLoaded(1) /*!this.areChunksLoaded(blockposition, 17, false)*/) { ++ // CraftBukkit end + return false; + } else { + int i = 0; +@@ -2042,7 +2314,7 @@ + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + +- if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply(entity)) { ++ if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply((T) entity)) { // CraftBukkit - fix decompile error + arraylist.add(entity); + } + } +@@ -2057,7 +2329,7 @@ + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + +- if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply(entity)) { ++ if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply((T) entity)) { // CraftBukkit - fix decompile error + arraylist.add(entity); + } + } +@@ -2105,7 +2377,7 @@ + } + } + +- return entity; ++ return (T) entity; // CraftBukkit fix decompile error + } + + public Entity a(int i) { +@@ -2125,8 +2397,17 @@ + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); +- +- if ((!(entity instanceof EntityInsentient) || !((EntityInsentient) entity).isPersistent()) && oclass.isAssignableFrom(entity.getClass())) { ++ // CraftBukkit start - Split out persistent check, don't apply it to special persistent mobs ++ if (entity instanceof EntityInsentient) { ++ EntityInsentient entityinsentient = (EntityInsentient) entity; ++ if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { ++ continue; ++ } ++ } ++ ++ if (oclass.isAssignableFrom(entity.getClass())) { ++ // if ((!(entity instanceof EntityInsentient) || !((EntityInsentient) entity).isPersistent()) && oclass.isAssignableFrom(entity.getClass())) { ++ // CraftBukkit end + ++i; + } + } +@@ -2135,12 +2416,18 @@ + } + + public void b(Collection collection) { +- this.entityList.addAll(collection); ++ // CraftBukkit start ++ // this.entityList.addAll(collection); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + ++ if (entity == null) { ++ continue; ++ } ++ this.entityList.add(entity); ++ // CraftBukkit end + this.a(entity); + } + +@@ -2154,7 +2441,13 @@ + Block block1 = this.getType(blockposition).getBlock(); + AxisAlignedBB axisalignedbb = flag ? null : block.a(this, blockposition, block.getBlockData()); + +- return axisalignedbb != null && !this.a(axisalignedbb, entity) ? false : (block1.getMaterial() == Material.ORIENTABLE && block == Blocks.ANVIL ? true : block1.getMaterial().isReplaceable() && block.canPlace(this, blockposition, enumdirection, itemstack)); ++ // CraftBukkit start - store default return ++ boolean defaultReturn = axisalignedbb != null && !this.a(axisalignedbb, entity) ? false : (block1.getMaterial() == Material.ORIENTABLE && block == Blocks.ANVIL ? true : block1.getMaterial().isReplaceable() && block.canPlace(this, blockposition, enumdirection, itemstack)); ++ BlockCanBuildEvent event = new BlockCanBuildEvent(this.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftMagicNumbers.getId(block), defaultReturn); ++ this.getServer().getPluginManager().callEvent(event); ++ ++ return event.isBuildable(); ++ // CraftBukkit end + } + + public int F() { +@@ -2253,6 +2546,11 @@ + + for (int i = 0; i < this.players.size(); ++i) { + EntityHuman entityhuman1 = (EntityHuman) this.players.get(i); ++ // CraftBukkit start - Fixed an NPE ++ if (entityhuman1 == null || entityhuman1.dead) { ++ continue; ++ } ++ // CraftBukkit end + + if (IEntitySelector.d.apply(entityhuman1)) { + double d5 = entityhuman1.e(d0, d1, d2); +@@ -2369,6 +2667,16 @@ + + public void everyoneSleeping() {} + ++ // CraftBukkit start ++ // Calls the method that checks to see if players are sleeping ++ // Called by CraftPlayer.setPermanentSleeping() ++ public void checkSleepStatus() { ++ if (!this.isClientSide) { ++ this.everyoneSleeping(); ++ } ++ } ++ // CraftBukkit end ++ + public float h(float f) { + return (this.q + (this.r - this.q) * f) * this.j(f); + } +@@ -2592,6 +2900,6 @@ + int l = j * 16 + 8 - blockposition.getZ(); + short short0 = 128; + +- return k >= -short0 && k <= short0 && l >= -short0 && l <= short0; ++ return k >= -short0 && k <= short0 && l >= -short0 && l <= short0 && this.keepSpawnInMemory; // CraftBukkit - Added 'this.keepSpawnInMemory' + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldBorder.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldBorder.patch new file mode 100644 index 0000000..d40f879 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldBorder.patch @@ -0,0 +1,39 @@ +--- a/net/minecraft/server/WorldBorder.java ++++ b/net/minecraft/server/WorldBorder.java +@@ -18,6 +18,7 @@ + private double j; + private int k; + private int l; ++ public WorldServer world; // CraftBukkit + + public WorldBorder() { + this.e = this.d; +@@ -32,8 +33,19 @@ + return (double) (blockposition.getX() + 1) > this.b() && (double) blockposition.getX() < this.d() && (double) (blockposition.getZ() + 1) > this.c() && (double) blockposition.getZ() < this.e(); + } + ++ // CraftBukkit start - split method + public boolean isInBounds(ChunkCoordIntPair chunkcoordintpair) { +- return (double) chunkcoordintpair.e() > this.b() && (double) chunkcoordintpair.c() < this.d() && (double) chunkcoordintpair.f() > this.c() && (double) chunkcoordintpair.d() < this.e(); ++ return isInBounds(chunkcoordintpair.x, chunkcoordintpair.z); ++ } ++ ++ // Inlined the getters from ChunkCoordIntPair ++ public boolean isInBounds(long chunkcoords) { ++ return isInBounds(org.bukkit.craftbukkit.util.LongHash.msw(chunkcoords), org.bukkit.craftbukkit.util.LongHash.lsw(chunkcoords)); ++ } ++ ++ // Inlined the getters from ChunkCoordIntPair ++ public boolean isInBounds(int x, int z) { ++ return (double) ((x << 4) + 15) > this.b() && (double) (x << 4) < this.d() && (double) ((z << 4) + 15) > this.c() && (double) (x << 4) < this.e(); + } + + public boolean a(AxisAlignedBB axisalignedbb) { +@@ -177,6 +189,7 @@ + } + + public void a(IWorldBorderListener iworldborderlistener) { ++ if (a.contains(iworldborderlistener)) return; // CraftBukkit + this.a.add(iworldborderlistener); + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldData.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldData.patch new file mode 100644 index 0000000..d225068 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldData.patch @@ -0,0 +1,86 @@ +--- a/net/minecraft/server/WorldData.java ++++ b/net/minecraft/server/WorldData.java +@@ -1,6 +1,11 @@ + package net.minecraft.server; + + import java.util.concurrent.Callable; ++// CraftBukkit start ++import org.bukkit.Bukkit; ++import org.bukkit.event.weather.ThunderChangeEvent; ++import org.bukkit.event.weather.WeatherChangeEvent; ++// CraftBukkit end + + public class WorldData { + +@@ -41,6 +46,7 @@ + private int I; + private int J; + private GameRules K; ++ public WorldServer world; // CraftBukkit + + protected WorldData() { + this.c = WorldType.NORMAL; +@@ -395,6 +401,18 @@ + } + + public void setThundering(boolean flag) { ++ // CraftBukkit start ++ org.bukkit.World world = Bukkit.getWorld(getName()); ++ if (world != null) { ++ ThunderChangeEvent thunder = new ThunderChangeEvent(world, flag); ++ Bukkit.getServer().getPluginManager().callEvent(thunder); ++ if (thunder.isCancelled()) { ++ return; ++ } ++ ++ setThunderDuration(0); // Will force a time reset ++ } ++ // CraftBukkit end + this.s = flag; + } + +@@ -411,6 +429,18 @@ + } + + public void setStorm(boolean flag) { ++ // CraftBukkit start ++ org.bukkit.World world = Bukkit.getWorld(getName()); ++ if (world != null) { ++ WeatherChangeEvent weather = new WeatherChangeEvent(world, flag); ++ Bukkit.getServer().getPluginManager().callEvent(weather); ++ if (weather.isCancelled()) { ++ return; ++ } ++ ++ setWeatherDuration(0); // Will force a time reset ++ } ++ // CraftBukkit end + this.q = flag; + } + +@@ -556,6 +586,12 @@ + + public void setDifficulty(EnumDifficulty enumdifficulty) { + this.z = enumdifficulty; ++ // CraftBukkit start ++ PacketPlayOutServerDifficulty packet = new PacketPlayOutServerDifficulty(this.getDifficulty(), this.isDifficultyLocked()); ++ for (EntityPlayer player : (java.util.List) (java.util.List) world.players) { ++ player.playerConnection.sendPacket(packet); ++ } ++ // CraftBukkit end + } + + public boolean isDifficultyLocked() { +@@ -664,4 +700,12 @@ + } + }); + } ++ ++ // CraftBukkit start - Check if the name stored in NBT is the correct one ++ public void checkName( String name ) { ++ if ( !this.n.equals( name ) ) { ++ this.n = name; ++ } ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenGroundBush.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenGroundBush.patch new file mode 100644 index 0000000..4afb31c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenGroundBush.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/server/WorldGenGroundBush.java ++++ b/net/minecraft/server/WorldGenGroundBush.java +@@ -46,7 +46,12 @@ + } + } + } ++ // CraftBukkit start - Return false if gen was unsuccessful ++ } else { ++ return false; + } ++ // CraftBukkit end ++ + + return true; + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenMegaTreeAbstract.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenMegaTreeAbstract.patch new file mode 100644 index 0000000..99dd51e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenMegaTreeAbstract.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/WorldGenMegaTreeAbstract.java ++++ b/net/minecraft/server/WorldGenMegaTreeAbstract.java +@@ -42,7 +42,7 @@ + + for (int k = -b0; k <= b0 && flag; ++k) { + for (int l = -b0; l <= b0 && flag; ++l) { +- if (blockposition.getY() + j < 0 || blockposition.getY() + j >= 256 || !this.a(world.getType(blockposition.a(k, j, l)).getBlock())) { ++ if (blockposition.getY() + j < 0 || blockposition.getY() + j >= 256 || (!this.a(world.getType(blockposition.a(k, j, l)).getBlock()) && world.getType(blockposition.a(k, j, l)).getBlock() != Blocks.SAPLING)) { // CraftBukkit - ignore our own saplings + flag = false; + } + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenRegistration.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenRegistration.patch new file mode 100644 index 0000000..736860c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenRegistration.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/WorldGenRegistration.java ++++ b/net/minecraft/server/WorldGenRegistration.java +@@ -108,7 +108,7 @@ + + entitywitch.setPositionRotation((double) i1 + 0.5D, (double) j1, (double) k1 + 0.5D, 0.0F, 0.0F); + entitywitch.prepare(world.E(new BlockPosition(i1, j1, k1)), (GroupDataEntity) null); +- world.addEntity(entitywitch); ++ world.addEntity(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason + } + } + diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenVillagePieces.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenVillagePieces.patch new file mode 100644 index 0000000..4c46ae3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldGenVillagePieces.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/server/WorldGenVillagePieces.java ++++ b/net/minecraft/server/WorldGenVillagePieces.java +@@ -1559,7 +1559,7 @@ + entityvillager.setPositionRotation((double) j1 + 0.5D, (double) k1, (double) l1 + 0.5D, 0.0F, 0.0F); + entityvillager.prepare(world.E(new BlockPosition(entityvillager)), (GroupDataEntity) null); + entityvillager.setProfession(this.c(i1, entityvillager.getProfession())); +- world.addEntity(entityvillager); ++ world.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason + } + + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldManager.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldManager.patch new file mode 100644 index 0000000..4a9fa5b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldManager.patch @@ -0,0 +1,54 @@ +--- a/net/minecraft/server/WorldManager.java ++++ b/net/minecraft/server/WorldManager.java +@@ -24,11 +24,13 @@ + } + + public void a(String s, double d0, double d1, double d2, float f, float f1) { +- this.a.getPlayerList().sendPacketNearby(d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.worldProvider.getDimension(), new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1)); ++ // CraftBukkit - this.world.dimension ++ this.a.getPlayerList().sendPacketNearby(d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.dimension, new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1)); + } + + public void a(EntityHuman entityhuman, String s, double d0, double d1, double d2, float f, float f1) { +- this.a.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.worldProvider.getDimension(), new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1)); ++ // CraftBukkit - this.world.dimension ++ this.a.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.dimension, new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1)); + } + + public void a(int i, int j, int k, int l, int i1, int j1) {} +@@ -42,7 +44,8 @@ + public void a(String s, BlockPosition blockposition) {} + + public void a(EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { +- this.a.getPlayerList().sendPacketNearby(entityhuman, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 64.0D, this.world.worldProvider.getDimension(), new PacketPlayOutWorldEvent(i, blockposition, j, false)); ++ // CraftBukkit - this.world.dimension ++ this.a.getPlayerList().sendPacketNearby(entityhuman, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 64.0D, this.world.dimension, new PacketPlayOutWorldEvent(i, blockposition, j, false)); + } + + public void a(int i, BlockPosition blockposition, int j) { +@@ -52,6 +55,12 @@ + public void b(int i, BlockPosition blockposition, int j) { + Iterator iterator = this.a.getPlayerList().v().iterator(); + ++ // CraftBukkit start ++ EntityHuman entityhuman = null; ++ Entity entity = world.a(i); // PAIL Rename getEntity ++ if (entity instanceof EntityHuman) entityhuman = (EntityHuman) entity; ++ // CraftBukkit end ++ + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + +@@ -60,6 +69,12 @@ + double d1 = (double) blockposition.getY() - entityplayer.locY; + double d2 = (double) blockposition.getZ() - entityplayer.locZ; + ++ // CraftBukkit start ++ if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { ++ continue; ++ } ++ // CraftBukkit end ++ + if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutBlockBreakAnimation(i, blockposition, j)); + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldMap.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldMap.patch new file mode 100644 index 0000000..ab9784f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldMap.patch @@ -0,0 +1,122 @@ +--- a/net/minecraft/server/WorldMap.java ++++ b/net/minecraft/server/WorldMap.java +@@ -6,6 +6,14 @@ + import java.util.List; + import java.util.Map; + ++// CraftBukkit start ++import java.util.UUID; ++ ++import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.map.CraftMapView; ++// CraftBukkit end ++ + public class WorldMap extends PersistentBase { + + public int centerX; +@@ -17,8 +25,18 @@ + private Map i = Maps.newHashMap(); + public Map decorations = Maps.newLinkedHashMap(); + ++ // CraftBukkit start ++ public final CraftMapView mapView; ++ private CraftServer server; ++ private UUID uniqueId = null; ++ // CraftBukkit end ++ + public WorldMap(String s) { + super(s); ++ // CraftBukkit start ++ mapView = new CraftMapView(this); ++ server = (CraftServer) org.bukkit.Bukkit.getServer(); ++ // CraftBukkit end + } + + public void a(double d0, double d1, int i) { +@@ -31,7 +49,30 @@ + } + + public void a(NBTTagCompound nbttagcompound) { +- this.map = nbttagcompound.getByte("dimension"); ++ // CraftBukkit start ++ byte dimension = nbttagcompound.getByte("dimension"); ++ ++ if (dimension >= 10) { ++ long least = nbttagcompound.getLong("UUIDLeast"); ++ long most = nbttagcompound.getLong("UUIDMost"); ++ ++ if (least != 0L && most != 0L) { ++ this.uniqueId = new UUID(most, least); ++ ++ CraftWorld world = (CraftWorld) server.getWorld(this.uniqueId); ++ // Check if the stored world details are correct. ++ if (world == null) { ++ /* All Maps which do not have their valid world loaded are set to a dimension which hopefully won't be reached. ++ This is to prevent them being corrupted with the wrong map data. */ ++ dimension = 127; ++ } else { ++ dimension = (byte) world.getHandle().dimension; ++ } ++ } ++ } ++ ++ this.map = dimension; ++ // CraftBukkit end + this.centerX = nbttagcompound.getInt("xCenter"); + this.centerZ = nbttagcompound.getInt("zCenter"); + this.scale = nbttagcompound.getByte("scale"); +@@ -66,6 +107,25 @@ + } + + public void b(NBTTagCompound nbttagcompound) { ++ // CraftBukkit start ++ if (this.map >= 10) { ++ if (this.uniqueId == null) { ++ for (org.bukkit.World world : server.getWorlds()) { ++ CraftWorld cWorld = (CraftWorld) world; ++ if (cWorld.getHandle().dimension == this.map) { ++ this.uniqueId = cWorld.getUID(); ++ break; ++ } ++ } ++ } ++ /* Perform a second check to see if a matching world was found, this is a necessary ++ change incase Maps are forcefully unlinked from a World and lack a UID.*/ ++ if (this.uniqueId != null) { ++ nbttagcompound.setLong("UUIDLeast", this.uniqueId.getLeastSignificantBits()); ++ nbttagcompound.setLong("UUIDMost", this.uniqueId.getMostSignificantBits()); ++ } ++ } ++ // CraftBukkit end + nbttagcompound.setByte("dimension", this.map); + nbttagcompound.setInt("xCenter", this.centerX); + nbttagcompound.setInt("zCenter", this.centerZ); +@@ -212,12 +272,25 @@ + } + + public Packet a(ItemStack itemstack) { ++ // CraftBukkit start ++ org.bukkit.craftbukkit.map.RenderData render = WorldMap.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.trackee.getBukkitEntity()); // CraftBukkit ++ ++ java.util.Collection icons = new java.util.ArrayList(); ++ ++ for ( org.bukkit.map.MapCursor cursor : render.cursors) { ++ ++ if (cursor.isVisible()) { ++ icons.add(new MapIcon(cursor.getRawType(), cursor.getX(), cursor.getY(), cursor.getDirection())); ++ } ++ } ++ + if (this.d) { + this.d = false; +- return new PacketPlayOutMap(itemstack.getData(), WorldMap.this.scale, WorldMap.this.decorations.values(), WorldMap.this.colors, this.e, this.f, this.g + 1 - this.e, this.h + 1 - this.f); ++ return new PacketPlayOutMap(itemstack.getData(), WorldMap.this.scale, icons, render.buffer, this.e, this.f, this.g + 1 - this.e, this.h + 1 - this.f); + } else { +- return this.i++ % 5 == 0 ? new PacketPlayOutMap(itemstack.getData(), WorldMap.this.scale, WorldMap.this.decorations.values(), WorldMap.this.colors, 0, 0, 0, 0) : null; ++ return this.i++ % 5 == 0 ? new PacketPlayOutMap(itemstack.getData(), WorldMap.this.scale, icons, render.buffer, 0, 0, 0, 0) : null; + } ++ // CraftBukkit end + } + + public void a(int i, int j) { diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldNBTStorage.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldNBTStorage.patch new file mode 100644 index 0000000..549de01 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldNBTStorage.patch @@ -0,0 +1,114 @@ +--- a/net/minecraft/server/WorldNBTStorage.java ++++ b/net/minecraft/server/WorldNBTStorage.java +@@ -11,6 +11,12 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.util.UUID; ++ ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++// CraftBukkit end ++ + public class WorldNBTStorage implements IDataManager, IPlayerFileData { + + private static final Logger a = LogManager.getLogger(); +@@ -19,6 +25,7 @@ + private final File dataDir; + private final long sessionId = MinecraftServer.az(); + private final String f; ++ private UUID uuid = null; // CraftBukkit + + public WorldNBTStorage(File file, String s, boolean flag) { + this.baseDir = new File(file, s); +@@ -202,12 +209,39 @@ + } + + if (nbttagcompound != null) { ++ // CraftBukkit start ++ if (entityhuman instanceof EntityPlayer) { ++ CraftPlayer player = (CraftPlayer) entityhuman.getBukkitEntity(); ++ // Only update first played if it is older than the one we have ++ long modified = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat").lastModified(); ++ if (modified < player.getFirstPlayed()) { ++ player.setFirstPlayed(modified); ++ } ++ } ++ // CraftBukkit end ++ + entityhuman.f(nbttagcompound); + } + + return nbttagcompound; + } + ++ // CraftBukkit start ++ public NBTTagCompound getPlayerData(String s) { ++ try { ++ File file1 = new File(this.playerDir, s + ".dat"); ++ ++ if (file1.exists()) { ++ return NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file1))); ++ } ++ } catch (Exception exception) { ++ a.warn("Failed to load player data for " + s); ++ } ++ ++ return null; ++ } ++ // CraftBukkit end ++ + public IPlayerFileData getPlayerFileData() { + return this; + } +@@ -237,4 +271,50 @@ + public String g() { + return this.f; + } ++ ++ // CraftBukkit start ++ public UUID getUUID() { ++ if (uuid != null) return uuid; ++ File file1 = new File(this.baseDir, "uid.dat"); ++ if (file1.exists()) { ++ DataInputStream dis = null; ++ try { ++ dis = new DataInputStream(new FileInputStream(file1)); ++ return uuid = new UUID(dis.readLong(), dis.readLong()); ++ } catch (IOException ex) { ++ a.warn("Failed to read " + file1 + ", generating new random UUID", ex); ++ } finally { ++ if (dis != null) { ++ try { ++ dis.close(); ++ } catch (IOException ex) { ++ // NOOP ++ } ++ } ++ } ++ } ++ uuid = UUID.randomUUID(); ++ DataOutputStream dos = null; ++ try { ++ dos = new DataOutputStream(new FileOutputStream(file1)); ++ dos.writeLong(uuid.getMostSignificantBits()); ++ dos.writeLong(uuid.getLeastSignificantBits()); ++ } catch (IOException ex) { ++ a.warn("Failed to write " + file1, ex); ++ } finally { ++ if (dos != null) { ++ try { ++ dos.close(); ++ } catch (IOException ex) { ++ // NOOP ++ } ++ } ++ } ++ return uuid; ++ } ++ ++ public File getPlayerDir() { ++ return playerDir; ++ } ++ // CraftBukkit end + } diff --git a/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldServer.patch b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldServer.patch new file mode 100644 index 0000000..5acbfbd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/nms-patches/WorldServer.patch @@ -0,0 +1,620 @@ +--- a/net/minecraft/server/WorldServer.java ++++ b/net/minecraft/server/WorldServer.java +@@ -16,14 +16,27 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.util.*; ++import java.util.logging.Level; ++ ++import org.bukkit.WeatherType; ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.util.LongHash; ++import org.bukkit.craftbukkit.util.HashTreeSet; ++ ++import org.bukkit.event.block.BlockFormEvent; ++import org.bukkit.event.weather.LightningStrikeEvent; ++// CraftBukkit end ++ + public class WorldServer extends World implements IAsyncTaskHandler { + + private static final Logger a = LogManager.getLogger(); + private final MinecraftServer server; + public EntityTracker tracker; + private final PlayerChunkMap manager; +- private final Set L = Sets.newHashSet(); +- private final TreeSet M = new TreeSet(); ++ // private final Set L = Sets.newHashSet(); // PAIL: Rename nextTickListHash ++ private final HashTreeSet M = new HashTreeSet(); // CraftBukkit - HashTreeSet // PAIL: Rename nextTickList + private final Map entitiesByUUID = Maps.newHashMap(); + public ChunkProviderServer chunkProviderServer; + public boolean savingDisabled; +@@ -37,14 +50,22 @@ + private static final List U = Lists.newArrayList(new StructurePieceTreasure[] { new StructurePieceTreasure(Items.STICK, 0, 1, 3, 10), new StructurePieceTreasure(Item.getItemOf(Blocks.PLANKS), 0, 1, 3, 10), new StructurePieceTreasure(Item.getItemOf(Blocks.LOG), 0, 1, 3, 10), new StructurePieceTreasure(Items.STONE_AXE, 0, 1, 1, 3), new StructurePieceTreasure(Items.WOODEN_AXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.STONE_PICKAXE, 0, 1, 1, 3), new StructurePieceTreasure(Items.WOODEN_PICKAXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.APPLE, 0, 2, 3, 5), new StructurePieceTreasure(Items.BREAD, 0, 2, 3, 3), new StructurePieceTreasure(Item.getItemOf(Blocks.LOG2), 0, 1, 3, 10)}); + private List V = Lists.newArrayList(); + +- public WorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, WorldData worlddata, int i, MethodProfiler methodprofiler) { +- super(idatamanager, worlddata, WorldProvider.byDimension(i), methodprofiler, false); ++ // CraftBukkit start ++ public final int dimension; ++ ++ // Add env and gen to constructor ++ public WorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, WorldData worlddata, int i, MethodProfiler methodprofiler, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { ++ super(idatamanager, worlddata, WorldProvider.byDimension(env.getId()), methodprofiler, false, gen, env); ++ this.dimension = i; ++ this.pvpMode = minecraftserver.getPVP(); ++ worlddata.world = this; ++ // CraftBukkit end + this.server = minecraftserver; + this.tracker = new EntityTracker(this); + this.manager = new PlayerChunkMap(this); + this.worldProvider.a(this); + this.chunkProvider = this.k(); +- this.Q = new PortalTravelAgent(this); ++ this.Q = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit + this.B(); + this.C(); + this.getWorldBorder().a(minecraftserver.aI()); +@@ -63,6 +84,7 @@ + this.villages.a((World) this); + } + ++ if (getServer().getScoreboardManager() == null) { // CraftBukkit + this.scoreboard = new ScoreboardServer(this.server); + PersistentScoreboard persistentscoreboard = (PersistentScoreboard) this.worldMaps.get(PersistentScoreboard.class, "scoreboard"); + +@@ -73,6 +95,11 @@ + + persistentscoreboard.a(this.scoreboard); + ((ScoreboardServer) this.scoreboard).a(persistentscoreboard); ++ // CraftBukkit start ++ } else { ++ this.scoreboard = getServer().getScoreboardManager().getMainScoreboard().getHandle(); ++ } ++ // CraftBukkit end + this.getWorldBorder().setCenter(this.worldData.C(), this.worldData.D()); + this.getWorldBorder().setDamageAmount(this.worldData.I()); + this.getWorldBorder().setDamageBuffer(this.worldData.H()); +@@ -84,9 +111,98 @@ + this.getWorldBorder().setSize(this.worldData.E()); + } + ++ // CraftBukkit start ++ if (generator != null) { ++ getWorld().getPopulators().addAll(generator.getDefaultPopulators(getWorld())); ++ } ++ // CraftBukkit end ++ + return this; + } + ++ // CraftBukkit start ++ @Override ++ public TileEntity getTileEntity(BlockPosition pos) { ++ TileEntity result = super.getTileEntity(pos); ++ Block type = getType(pos).getBlock(); ++ ++ if (type == Blocks.CHEST) { ++ if (!(result instanceof TileEntityChest)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.FURNACE) { ++ if (!(result instanceof TileEntityFurnace)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.DROPPER) { ++ if (!(result instanceof TileEntityDropper)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.DISPENSER) { ++ if (!(result instanceof TileEntityDispenser)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.JUKEBOX) { ++ if (!(result instanceof BlockJukeBox.TileEntityRecordPlayer)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.NOTEBLOCK) { ++ if (!(result instanceof TileEntityNote)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.MOB_SPAWNER) { ++ if (!(result instanceof TileEntityMobSpawner)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if ((type == Blocks.STANDING_SIGN) || (type == Blocks.WALL_SIGN)) { ++ if (!(result instanceof TileEntitySign)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.ENDER_CHEST) { ++ if (!(result instanceof TileEntityEnderChest)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.BREWING_STAND) { ++ if (!(result instanceof TileEntityBrewingStand)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.BEACON) { ++ if (!(result instanceof TileEntityBeacon)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } else if (type == Blocks.HOPPER) { ++ if (!(result instanceof TileEntityHopper)) { ++ result = fixTileEntity(pos, type, result); ++ } ++ } ++ ++ return result; ++ } ++ ++ private TileEntity fixTileEntity(BlockPosition pos, Block type, TileEntity found) { ++ this.getServer().getLogger().log(Level.SEVERE, "Block at {0},{1},{2} is {3} but has {4}" + ". " ++ + "Bukkit will attempt to fix this, but there may be additional damage that we cannot recover.", new Object[]{pos.getX(), pos.getY(), pos.getZ(), org.bukkit.Material.getMaterial(Block.getId(type)).toString(), found}); ++ ++ if (type instanceof IContainer) { ++ TileEntity replacement = ((IContainer) type).a(this, type.toLegacyData(this.getType(pos))); ++ replacement.world = this; ++ this.setTileEntity(pos, replacement); ++ return replacement; ++ } else { ++ this.getServer().getLogger().severe("Don't know how to fix for this type... Can't do anything! :("); ++ return found; ++ } ++ } ++ ++ private boolean canSpawn(int x, int z) { ++ if (this.generator != null) { ++ return this.generator.canSpawn(this.getWorld(), x, z); ++ } else { ++ return this.worldProvider.canSpawn(x, z); ++ } ++ } ++ // CraftBukkit end ++ + public void doTick() { + super.doTick(); + if (this.getWorldData().isHardcore() && this.getDifficulty() != EnumDifficulty.HARD) { +@@ -104,9 +220,11 @@ + this.e(); + } + +- this.methodProfiler.a("mobSpawner"); +- if (this.getGameRules().getBoolean("doMobSpawning") && this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { +- this.R.a(this, this.allowMonsters, this.allowAnimals, this.worldData.getTime() % 400L == 0L); ++ // 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)) { ++ this.R.a(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L); ++ // CraftBukkit end + } + + this.methodProfiler.c("chunkSource"); +@@ -135,6 +253,8 @@ + this.Q.a(this.getTime()); + this.methodProfiler.b(); + this.ak(); ++ ++ this.getWorld().processChunkGC(); // CraftBukkit + } + + public BiomeBase.BiomeMeta a(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { +@@ -161,7 +281,7 @@ + + if (entityhuman.isSpectator()) { + ++i; +- } else if (entityhuman.isSleeping()) { ++ } else if (entityhuman.isSleeping() || entityhuman.fauxSleeping) { + ++j; + } + } +@@ -187,25 +307,46 @@ + } + + private void ag() { +- this.worldData.setWeatherDuration(0); + this.worldData.setStorm(false); +- this.worldData.setThunderDuration(0); ++ // CraftBukkit start ++ // If we stop due to everyone sleeping we should reset the weather duration to some other random value. ++ // Not that everyone ever manages to get the whole server to sleep at the same time.... ++ if (!this.worldData.hasStorm()) { ++ this.worldData.setWeatherDuration(0); ++ } ++ // CraftBukkit end + this.worldData.setThundering(false); ++ // CraftBukkit start ++ // If we stop due to everyone sleeping we should reset the weather duration to some other random value. ++ // Not that everyone ever manages to get the whole server to sleep at the same time.... ++ if (!this.worldData.isThundering()) { ++ this.worldData.setThunderDuration(0); ++ } ++ // CraftBukkit end + } + + public boolean everyoneDeeplySleeping() { + if (this.O && !this.isClientSide) { + Iterator iterator = this.players.iterator(); + ++ // CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers ++ boolean foundActualSleepers = false; ++ + EntityHuman entityhuman; + + do { + if (!iterator.hasNext()) { +- return true; ++ return foundActualSleepers; + } + + entityhuman = (EntityHuman) iterator.next(); +- } while (!entityhuman.isSpectator() && entityhuman.isDeeplySleeping()); ++ ++ // CraftBukkit start ++ if (entityhuman.isDeeplySleeping()) { ++ foundActualSleepers = true; ++ } ++ } while (!entityhuman.isSpectator() || entityhuman.isDeeplySleeping() || entityhuman.fauxSleeping); ++ // CraftBukkit end + + return false; + } else { +@@ -228,13 +369,20 @@ + int i = 0; + int j = 0; + +- for (Iterator iterator1 = this.chunkTickList.iterator(); iterator1.hasNext(); this.methodProfiler.b()) { +- ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair) iterator1.next(); +- int k = chunkcoordintpair1.x * 16; +- int l = chunkcoordintpair1.z * 16; ++ // CraftBukkit start ++ //for (Iterator iterator1 = this.chunkTickList.iterator(); iterator1.hasNext(); this.methodProfiler.b()) { ++ // ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair) iterator1.next(); ++ // int k = chunkcoordintpair1.x * 16; ++ // int l = chunkcoordintpair1.z * 16; ++ for (long chunkCoord : chunkTickList.popAll()) { ++ int chunkX = LongHash.msw(chunkCoord); ++ int chunkZ = LongHash.lsw(chunkCoord); ++ int k = chunkX * 16; ++ int l = chunkZ * 16; + + this.methodProfiler.a("getChunk"); +- Chunk chunk = this.getChunkAt(chunkcoordintpair1.x, chunkcoordintpair1.z); ++ Chunk chunk = this.getChunkAt(chunkX, chunkZ); ++ // CraftBukkit end + + this.a(k, l, chunk); + this.methodProfiler.c("tickChunk"); +@@ -260,11 +408,29 @@ + BlockPosition blockposition1 = blockposition.down(); + + if (this.w(blockposition1)) { +- this.setTypeUpdate(blockposition1, Blocks.ICE.getBlockData()); ++ // CraftBukkit start ++ BlockState blockState = this.getWorld().getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()).getState(); ++ blockState.setTypeId(Block.getId(Blocks.ICE)); ++ ++ BlockFormEvent iceBlockForm = new BlockFormEvent(blockState.getBlock(), blockState); ++ this.getServer().getPluginManager().callEvent(iceBlockForm); ++ if (!iceBlockForm.isCancelled()) { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } + + if (this.S() && this.f(blockposition, true)) { +- this.setTypeUpdate(blockposition, Blocks.SNOW_LAYER.getBlockData()); ++ // CraftBukkit start ++ BlockState blockState = this.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()).getState(); ++ blockState.setTypeId(Block.getId(Blocks.SNOW_LAYER)); ++ ++ BlockFormEvent snow = new BlockFormEvent(blockState.getBlock(), blockState); ++ this.getServer().getPluginManager().callEvent(snow); ++ if (!snow.isCancelled()) { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } + + if (this.S() && this.getBiome(blockposition1).e()) { +@@ -359,8 +525,8 @@ + nextticklistentry.a(j); + } + +- if (!this.L.contains(nextticklistentry)) { +- this.L.add(nextticklistentry); ++ // CraftBukkit - use M, PAIL: Rename nextTickList ++ if (!this.M.contains(nextticklistentry)) { + this.M.add(nextticklistentry); + } + } +@@ -375,15 +541,15 @@ + nextticklistentry.a((long) i + this.worldData.getTime()); + } + +- if (!this.L.contains(nextticklistentry)) { +- this.L.add(nextticklistentry); ++ // CraftBukkit - use M, PAIL: Rename nextTickList ++ if (!this.M.contains(nextticklistentry)) { + this.M.add(nextticklistentry); + } + + } + + public void tickEntities() { +- if (this.players.isEmpty()) { ++ if (false && this.players.isEmpty()) { // CraftBukkit - this prevents entity cleanup, other issues on servers with no players + if (this.emptyTime++ >= 1200) { + return; + } +@@ -404,11 +570,17 @@ + } else { + int i = this.M.size(); + +- if (i != this.L.size()) { ++ if (false) { // CraftBukkit + throw new IllegalStateException("TickNextTick list out of synch"); + } else { + if (i > 1000) { +- i = 1000; ++ // CraftBukkit start - If the server has too much to process over time, try to alleviate that ++ if (i > 20 * 1000) { ++ i = i / 20; ++ } else { ++ i = 1000; ++ } ++ // CraftBukkit end + } + + this.methodProfiler.a("cleaning"); +@@ -421,8 +593,8 @@ + break; + } + ++ // CraftBukkit - use M, PAIL: Rename nextTickList + this.M.remove(nextticklistentry); +- this.L.remove(nextticklistentry); + this.V.add(nextticklistentry); + } + +@@ -489,7 +661,7 @@ + + if (blockposition.getX() >= structureboundingbox.a && blockposition.getX() < structureboundingbox.d && blockposition.getZ() >= structureboundingbox.c && blockposition.getZ() < structureboundingbox.f) { + if (flag) { +- this.L.remove(nextticklistentry); ++ // CraftBukkit - use M + iterator.remove(); + } + +@@ -505,6 +677,7 @@ + return arraylist; + } + ++ /* CraftBukkit start - We prevent spawning in general, so this butchering is not needed + public void entityJoinedWorld(Entity entity, boolean flag) { + if (!this.getSpawnAnimals() && (entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal)) { + entity.die(); +@@ -516,6 +689,7 @@ + + super.entityJoinedWorld(entity, flag); + } ++ // CraftBukkit end */ + + private boolean getSpawnNPCs() { + return this.server.getSpawnNPCs(); +@@ -528,13 +702,43 @@ + protected IChunkProvider k() { + IChunkLoader ichunkloader = this.dataManager.createChunkLoader(this.worldProvider); + +- this.chunkProviderServer = new ChunkProviderServer(this, ichunkloader, this.worldProvider.getChunkProvider()); ++ // CraftBukkit start ++ org.bukkit.craftbukkit.generator.InternalChunkGenerator gen; ++ ++ if (this.generator != null) { ++ gen = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, this.getSeed(), this.generator); ++ } else if (this.worldProvider instanceof WorldProviderHell) { ++ gen = new org.bukkit.craftbukkit.generator.NetherChunkGenerator(this, this.getSeed()); ++ } else if (this.worldProvider instanceof WorldProviderTheEnd) { ++ gen = new org.bukkit.craftbukkit.generator.SkyLandsChunkGenerator(this, this.getSeed()); ++ } else { ++ gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed()); ++ } ++ ++ this.chunkProviderServer = new ChunkProviderServer(this, ichunkloader, gen); ++ // CraftBukkit end + return this.chunkProviderServer; + } + + public List getTileEntities(int i, int j, int k, int l, int i1, int j1) { + ArrayList arraylist = Lists.newArrayList(); + ++ // CraftBukkit start - Get tile entities from chunks instead of world ++ for (int chunkX = (i >> 4); chunkX <= ((l - 1) >> 4); chunkX++) { ++ for (int chunkZ = (k >> 4); chunkZ <= ((j1 - 1) >> 4); chunkZ++) { ++ Chunk chunk = getChunkAt(chunkX, chunkZ); ++ if (chunk == null) { ++ continue; ++ } ++ for (Object te : chunk.tileEntities.values()) { ++ TileEntity tileentity = (TileEntity) te; ++ if ((tileentity.position.getX() >= i) && (tileentity.position.getY() >= j) && (tileentity.position.getZ() >= k) && (tileentity.position.getX() < l) && (tileentity.position.getY() < i1) && (tileentity.position.getZ() < j1)) { ++ arraylist.add(tileentity); ++ } ++ } ++ } ++ } ++ /* + for (int k1 = 0; k1 < this.h.size(); ++k1) { + TileEntity tileentity = (TileEntity) this.h.get(k1); + BlockPosition blockposition = tileentity.getPosition(); +@@ -543,6 +747,8 @@ + arraylist.add(tileentity); + } + } ++ */ ++ // CraftBukkit end + + return arraylist; + } +@@ -606,6 +812,23 @@ + int j = this.worldProvider.getSeaLevel(); + int k = 0; + ++ // CraftBukkit start ++ if (this.generator != null) { ++ Random rand = new Random(this.getSeed()); ++ org.bukkit.Location spawn = this.generator.getFixedSpawnLocation(((WorldServer) this).getWorld(), rand); ++ ++ if (spawn != null) { ++ if (spawn.getWorld() != ((WorldServer) this).getWorld()) { ++ throw new IllegalStateException("Cannot set spawn point for " + this.worldData.getName() + " to be in another world (" + spawn.getWorld().getName() + ")"); ++ } else { ++ this.worldData.setSpawn(new BlockPosition(spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ())); ++ this.isLoading = false; ++ return; ++ } ++ } ++ } ++ // CraftBukkit end ++ + if (blockposition != null) { + i = blockposition.getX(); + k = blockposition.getZ(); +@@ -615,7 +838,7 @@ + + int l = 0; + +- while (!this.worldProvider.canSpawn(i, k)) { ++ while (!this.canSpawn(i, k)) { // CraftBukkit - use our own canSpawn + i += random.nextInt(64) - random.nextInt(64); + k += random.nextInt(64) - random.nextInt(64); + ++l; +@@ -654,6 +877,7 @@ + + public void save(boolean flag, IProgressUpdate iprogressupdate) throws ExceptionWorldConflict { + if (this.chunkProvider.canSave()) { ++ org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit + if (iprogressupdate != null) { + iprogressupdate.a("Saving level"); + } +@@ -664,7 +888,8 @@ + } + + this.chunkProvider.saveChunks(flag, iprogressupdate); +- ArrayList arraylist = Lists.newArrayList(this.chunkProviderServer.a()); ++ // CraftBukkit - ArrayList -> Collection ++ Collection arraylist = this.chunkProviderServer.a(); + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { +@@ -695,8 +920,12 @@ + this.worldData.k(this.getWorldBorder().getWarningTime()); + this.worldData.b(this.getWorldBorder().j()); + this.worldData.e(this.getWorldBorder().i()); ++ // CraftBukkit start - save worldMaps once, rather than once per shared world ++ if (!(this instanceof SecondaryWorldServer)) { ++ this.worldMaps.a(); ++ } + this.dataManager.saveWorldData(this.worldData, this.server.getPlayerList().t()); +- this.worldMaps.a(); ++ // CraftBukkit end + } + + protected void a(Entity entity) { +@@ -728,8 +957,16 @@ + } + + public boolean strikeLightning(Entity entity) { ++ // CraftBukkit start ++ LightningStrikeEvent lightning = new LightningStrikeEvent(this.getWorld(), (org.bukkit.entity.LightningStrike) entity.getBukkitEntity()); ++ this.getServer().getPluginManager().callEvent(lightning); ++ ++ if (lightning.isCancelled()) { ++ return false; ++ } + if (super.strikeLightning(entity)) { +- this.server.getPlayerList().sendPacketNearby(entity.locX, entity.locY, entity.locZ, 512.0D, this.worldProvider.getDimension(), new PacketPlayOutSpawnEntityWeather(entity)); ++ this.server.getPlayerList().sendPacketNearby(entity.locX, entity.locY, entity.locZ, 512.0D, dimension, new PacketPlayOutSpawnEntityWeather(entity)); ++ // CraftBukkit end + return true; + } else { + return false; +@@ -741,10 +978,20 @@ + } + + public Explosion createExplosion(Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { ++ // CraftBukkit start ++ Explosion explosion = super.createExplosion(entity, d0, d1, d2, f, flag, flag1); ++ ++ if (explosion.wasCanceled) { ++ return explosion; ++ } ++ ++ /* Remove + Explosion explosion = new Explosion(this, entity, d0, d1, d2, f, flag, flag1); + + explosion.a(); + explosion.a(false); ++ */ ++ // CraftBukkit end - TODO: Check if explosions are still properly implemented + if (!flag1) { + explosion.clearBlocks(); + } +@@ -790,7 +1037,8 @@ + BlockActionData blockactiondata = (BlockActionData) iterator.next(); + + if (this.a(blockactiondata)) { +- this.server.getPlayerList().sendPacketNearby((double) blockactiondata.a().getX(), (double) blockactiondata.a().getY(), (double) blockactiondata.a().getZ(), 64.0D, this.worldProvider.getDimension(), new PacketPlayOutBlockAction(blockactiondata.a(), blockactiondata.d(), blockactiondata.b(), blockactiondata.c())); ++ // CraftBukkit - this.worldProvider.dimension -> this.dimension ++ this.server.getPlayerList().sendPacketNearby((double) blockactiondata.a().getX(), (double) blockactiondata.a().getY(), (double) blockactiondata.a().getZ(), 64.0D, dimension, new PacketPlayOutBlockAction(blockactiondata.a(), blockactiondata.d(), blockactiondata.b(), blockactiondata.c())); + } + } + +@@ -813,6 +1061,7 @@ + boolean flag = this.S(); + + super.p(); ++ /* CraftBukkit start + if (this.o != this.p) { + this.server.getPlayerList().a(new PacketPlayOutGameStateChange(7, this.p), this.worldProvider.getDimension()); + } +@@ -831,6 +1080,21 @@ + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(7, this.p)); + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(8, this.r)); + } ++ // */ ++ if (flag != this.S()) { ++ // Only send weather packets to those affected ++ for (int i = 0; i < this.players.size(); ++i) { ++ if (((EntityPlayer) this.players.get(i)).world == this) { ++ ((EntityPlayer) this.players.get(i)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); ++ } ++ } ++ } ++ for (int i = 0; i < this.players.size(); ++i) { ++ if (((EntityPlayer) this.players.get(i)).world == this) { ++ ((EntityPlayer) this.players.get(i)).updateWeather(this.o, this.p, this.q, this.r); ++ } ++ } ++ // CraftBukkit end + + } + +@@ -859,10 +1123,17 @@ + } + + public void a(EnumParticle enumparticle, boolean flag, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, int... aint) { ++ // CraftBukkit - visibility api support ++ sendParticles(null, enumparticle, flag, d0, d1, d2, i, d3, d4, d5, d6, aint); ++ } ++ ++ public void sendParticles(EntityPlayer sender, EnumParticle enumparticle, boolean flag, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, int... aint) { ++ // CraftBukkit end + PacketPlayOutWorldParticles packetplayoutworldparticles = new PacketPlayOutWorldParticles(enumparticle, flag, (float) d0, (float) d1, (float) d2, (float) d3, (float) d4, (float) d5, (float) d6, i, aint); + + for (int j = 0; j < this.players.size(); ++j) { + EntityPlayer entityplayer = (EntityPlayer) this.players.get(j); ++ if (sender != null && !entityplayer.getBukkitEntity().canSee(sender.getBukkitEntity())) continue; // CraftBukkit + BlockPosition blockposition = entityplayer.getChunkCoordinates(); + double d7 = blockposition.c(d0, d1, d2); + diff --git a/MythicSpigot-master/TacoSpigot-Server/pom.xml b/MythicSpigot-master/TacoSpigot-Server/pom.xml new file mode 100644 index 0000000..8064dd5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/pom.xml @@ -0,0 +1,275 @@ + + 4.0.0 + me.levansj01.mythicspigot + server + jar + 1.8.8-R0.2-SNAPSHOT + MythicSpigot-Server + verusdev.xyz + + + UTF-8 + unknown + 4.11 + 1.8.8 + 1_8_R3 + git-Bukkit- + + + 1.8 + 1.8 + + + + me.levansj01.mythicspigot + parent + dev-SNAPSHOT + ../pom.xml + + + + + net.sf.trove4j + trove4j + 3.0.3 + + + it.unimi.dsi + fastutil + 7.0.12 + + + me.levansj01.mythicspigot + api + 1.8.8-R0.2-SNAPSHOT + jar + compile + + + org.spigotmc + minecraft-server + 1.8.8-SNAPSHOT + jar + compile + + + net.sf.jopt-simple + jopt-simple + 3.2 + jar + compile + + + jline + jline + 2.12 + jar + compile + + + net.jafama + jafama + 2.3.2 + + + org.xerial + sqlite-jdbc + 3.7.2 + jar + compile + + + mysql + mysql-connector-java + 5.1.14 + jar + compile + + + + junit + junit + ${junit.version} + test + + + org.mockito + mockito-core + 1.10.19 + + + org.hamcrest + hamcrest-library + 1.3 + test + + + + + + + spigotmc-public + https://hub.spigotmc.org/nexus/content/groups/public/ + + + + destroystokyo + https://ci.destroystokyo.com/plugin/repository/everything/ + + + + + + install + + + com.lukegb.mojo + gitdescribe-maven-plugin + 1.3 + + git-TacoSpigot- + .. + + + + compile + + gitdescribe + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.5 + + true + + + org.bukkit.craftbukkit.Main + CraftBukkit + ${describe} + Bukkit Team + Bukkit + ${api.version} + Bukkit Team + + + + net/bukkit/ + + true + + + + com/bukkit/ + + true + + + + org/bukkit/ + + true + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + + package + + shade + + + + + joptsimple + org.bukkit.craftbukkit.libs.joptsimple + + + jline + org.bukkit.craftbukkit.libs.jline + + + org.ibex + org.bukkit.craftbukkit.libs.org.ibex + + + org.gjt + org.bukkit.craftbukkit.libs.org.gjt + + + org.bukkit.craftbukkit + org.bukkit.craftbukkit.v${minecraft_version} + + org.bukkit.craftbukkit.Main* + + + + net.minecraft.server + net.minecraft.server.v${minecraft_version} + + + + + + + + + net.md-5 + specialsource-maven-plugin + 1.2.1 + + + package + + remap + + + ${project.basedir}/deprecation-mappings.csrg + ${project.basedir}/deprecation-mappings.at + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + true + 1.8 + 1.8 + + + + + org.codehaus.plexus + plexus-compiler-eclipse + 2.5.0-spigotmc + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.18 + + ${basedir}/target/test-server + + org/bukkit/craftbukkit/inventory/ItemStack*Test.java + + + + + + diff --git a/MythicSpigot-master/TacoSpigot-Server/server.iml b/MythicSpigot-master/TacoSpigot-Server/server.iml new file mode 100644 index 0000000..dcecadb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/server.iml @@ -0,0 +1,50 @@ + + + + + + + MCP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/co/aikar/timings/SpigotTimings.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/co/aikar/timings/SpigotTimings.java new file mode 100644 index 0000000..b3cafaf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/co/aikar/timings/SpigotTimings.java @@ -0,0 +1,111 @@ +package co.aikar.timings; + +import net.minecraft.server.*; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; + +import org.bukkit.craftbukkit.scheduler.CraftTask; + +public final class SpigotTimings { + + public static final Timing playerListTimer = Timings.ofSafe("Player List"); + public static final Timing connectionTimer = Timings.ofSafe("Connection Handler"); + public static final Timing tickablesTimer = Timings.ofSafe("Tickables"); + public static final Timing minecraftSchedulerTimer = Timings.ofSafe("Minecraft Scheduler"); + public static final Timing bukkitSchedulerTimer = Timings.ofSafe("Bukkit Scheduler"); + public static final Timing chunkIOTickTimer = Timings.ofSafe("ChunkIOTick"); + public static final Timing timeUpdateTimer = Timings.ofSafe("Time Update"); + public static final Timing serverCommandTimer = Timings.ofSafe("Server Command"); + public static final Timing worldSaveTimer = Timings.ofSafe("World Save"); + + public static final Timing tickEntityTimer = Timings.ofSafe("## tickEntity"); + public static final Timing tickTileEntityTimer = Timings.ofSafe("## tickTileEntity"); + + public static final Timing processQueueTimer = Timings.ofSafe("processQueue"); + + public static final Timing playerCommandTimer = Timings.ofSafe("playerCommand"); + + public static final Timing entityActivationCheckTimer = Timings.ofSafe("entityActivationCheck"); + public static final Timing checkIfActiveTimer = Timings.ofSafe("checkIfActive"); + + public static final Timing antiXrayUpdateTimer = Timings.ofSafe("anti-xray - update"); + public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate"); + + private SpigotTimings() {} + + /** + * Gets a timer associated with a plugins tasks. + * @param bukkitTask + * @param period + * @return + */ + public static Timing getPluginTaskTimings(BukkitTask bukkitTask, long period) { + if (!bukkitTask.isSync()) { + return null; + } + Plugin plugin; + + Runnable task = ((CraftTask) bukkitTask).task; + + final Class taskClass = task.getClass(); + if (bukkitTask.getOwner() != null) { + plugin = bukkitTask.getOwner(); + } else { + plugin = TimingsManager.getPluginByClassloader(taskClass); + } + + final String taskname; + if (taskClass.isAnonymousClass()) { + taskname = taskClass.getName(); + } else { + taskname = taskClass.getCanonicalName(); + } + + String name = "Task: " +taskname; + if (period > 0) { + name += " (interval:" + period +")"; + } else { + name += " (Single)"; + } + + if (plugin == null) { + return Timings.ofSafe(null, name, TimingsManager.PLUGIN_GROUP_HANDLER); + } + + return Timings.ofSafe(plugin, name); + } + + /** + * Get a named timer for the specified entity type to track type specific timings. + * @param entity + * @return + */ + public static Timing getEntityTimings(Entity entity) { + String entityType = entity.getClass().getName(); + return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType, tickEntityTimer); + } + + /** + * Get a named timer for the specified tile entity type to track type specific timings. + * @param entity + * @return + */ + public static Timing getTileEntityTimings(TileEntity entity) { + String entityType = entity.getClass().getName(); + return Timings.ofSafe("Minecraft", "## tickTileEntity - " + entityType, tickTileEntityTimer); + } + public static Timing getCancelTasksTimer() { + return Timings.ofSafe("Cancel Tasks"); + } + public static Timing getCancelTasksTimer(Plugin plugin) { + return Timings.ofSafe(plugin, "Cancel Tasks"); + } + + public static void stopServer() { + TimingsManager.stopServer(); + } + + public static Timing getBlockTiming(Block block) { + return Timings.ofSafe("## Scheduled Block: " + block.getName()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/co/aikar/timings/WorldTimingsHandler.java new file mode 100644 index 0000000..9ebc710 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/co/aikar/timings/WorldTimingsHandler.java @@ -0,0 +1,69 @@ +package co.aikar.timings; + +import net.minecraft.server.World; + +/** + * Set of timers per world, to track world specific timings. + */ +public class WorldTimingsHandler { + public final Timing mobSpawn; + public final Timing doChunkUnload; + public final Timing doPortalForcer; + public final Timing scheduledBlocks; + public final Timing scheduledBlocksCleanup; + public final Timing scheduledBlocksTicking; + public final Timing chunkTicks; + public final Timing chunkTicksBlocks; + public final Timing doVillages; + public final Timing doChunkMap; + public final Timing doChunkGC; + public final Timing doSounds; + public final Timing entityRemoval; + public final Timing entityTick; + public final Timing tileEntityTick; + public final Timing tileEntityPending; + public final Timing tracker; + public final Timing doTick; + public final Timing tickEntities; + + public final Timing syncChunkLoadTimer; + public final Timing syncChunkLoadDataTimer; + public final Timing syncChunkLoadStructuresTimer; + public final Timing syncChunkLoadEntitiesTimer; + public final Timing syncChunkLoadTileEntitiesTimer; + public final Timing syncChunkLoadTileTicksTimer; + public final Timing syncChunkLoadPostTimer; + + public WorldTimingsHandler(World server) { + String name = server.worldData.getName() +" - "; + + mobSpawn = Timings.ofSafe(name + "mobSpawn"); + doChunkUnload = Timings.ofSafe(name + "doChunkUnload"); + scheduledBlocks = Timings.ofSafe(name + "Scheduled Blocks"); + scheduledBlocksCleanup = Timings.ofSafe(name + "Scheduled Blocks - Cleanup"); + scheduledBlocksTicking = Timings.ofSafe(name + "Scheduled Blocks - Ticking"); + chunkTicks = Timings.ofSafe(name + "Chunk Ticks"); + chunkTicksBlocks = Timings.ofSafe(name + "Chunk Ticks - Blocks"); + doVillages = Timings.ofSafe(name + "doVillages"); + doChunkMap = Timings.ofSafe(name + "doChunkMap"); + doSounds = Timings.ofSafe(name + "doSounds"); + doChunkGC = Timings.ofSafe(name + "doChunkGC"); + doPortalForcer = Timings.ofSafe(name + "doPortalForcer"); + entityTick = Timings.ofSafe(name + "entityTick"); + entityRemoval = Timings.ofSafe(name + "entityRemoval"); + tileEntityTick = Timings.ofSafe(name + "tileEntityTick"); + tileEntityPending = Timings.ofSafe(name + "tileEntityPending"); + + syncChunkLoadTimer = Timings.ofSafe(name + "syncChunkLoad"); + syncChunkLoadDataTimer = Timings.ofSafe(name + "syncChunkLoad - Data"); + syncChunkLoadStructuresTimer = Timings.ofSafe(name + "chunkLoad - Structures"); + syncChunkLoadEntitiesTimer = Timings.ofSafe(name + "chunkLoad - Entities"); + syncChunkLoadTileEntitiesTimer = Timings.ofSafe(name + "chunkLoad - TileEntities"); + syncChunkLoadTileTicksTimer = Timings.ofSafe(name + "chunkLoad - TileTicks"); + syncChunkLoadPostTimer = Timings.ofSafe(name + "chunkLoad - Post"); + + tracker = Timings.ofSafe(name + "tracker"); + doTick = Timings.ofSafe(name + "doTick"); + tickEntities = Timings.ofSafe(name + "tickEntities"); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/limiter/TickLimiter.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/limiter/TickLimiter.java new file mode 100644 index 0000000..0a16956 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/limiter/TickLimiter.java @@ -0,0 +1,22 @@ +package me.levansj01.mythicspigot.limiter; + +import lombok.RequiredArgsConstructor; +import net.minecraft.server.MinecraftServer; + +import java.util.function.Supplier; + +@RequiredArgsConstructor +public class TickLimiter { + private final Supplier ticks, number; + private int lastTick, current; + + public boolean test() { + int currentTick = MinecraftServer.currentTick; + if(currentTick - lastTick < ticks.get()) { + return current++ < number.get(); + } + current = 1; + lastTick = currentTick; + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/login/Login.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/login/Login.java new file mode 100644 index 0000000..d0eb92a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/login/Login.java @@ -0,0 +1,11 @@ +package me.levansj01.mythicspigot.login; + +import lombok.Data; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.NetworkManager; + +@Data +public class Login { + private final NetworkManager networkManager; + private final EntityPlayer entityPlayer; +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/util/Chat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/util/Chat.java new file mode 100644 index 0000000..207714d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/util/Chat.java @@ -0,0 +1,20 @@ +package me.levansj01.mythicspigot.util; + +import org.bukkit.ChatColor; + +/** + * @author Ghast + * @since 17-Mar-20 + */ +public class Chat { + public static String color(String s) { + return ChatColor.translateAlternateColorCodes('&', s); + } + + public static String[] color(String[] s) { + for (int i = 0; i < s.length; i++) { + s[i] = color(s[i]); + } + return s; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/util/CraftPotionUtil.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/util/CraftPotionUtil.java new file mode 100644 index 0000000..5f7e0b6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/me/levansj01/mythicspigot/util/CraftPotionUtil.java @@ -0,0 +1,25 @@ +package me.levansj01.mythicspigot.util; + +import net.minecraft.server.MobEffect; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class CraftPotionUtil { + + public static PotionEffect toBukkit(MobEffect effect) { + return new PotionEffect(PotionEffectType.getById(effect.getEffectId()), effect.getDuration(), effect.getAmplifier(), effect.isAmbient()); + } + + public static MobEffect toNMS(PotionEffect effect) { + return new MobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles()); + } + + public static MobEffect cloneWithDuration(MobEffect effect, int duration) { + return new MobEffect(effect.getEffectId(), duration, effect.getAmplifier(), effect.isAmbient(), effect.isShowParticles()); + } + + public static void extendDuration(MobEffect effect, int duration) { + effect.a(cloneWithDuration(effect, duration)); + } + +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/AttributeRanged.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/AttributeRanged.java new file mode 100644 index 0000000..838daed --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/AttributeRanged.java @@ -0,0 +1,35 @@ +package net.minecraft.server; + +public class AttributeRanged extends AttributeBase { + + private final double a; + public double b; // Spigot + private String c; + + public AttributeRanged(IAttribute iattribute, String s, double d0, double d1, double d2) { + super(iattribute, s, d0); + this.a = d1; + this.b = d2; + if (d1 > d2) { + throw new IllegalArgumentException("Minimum value cannot be bigger than maximum value!"); + } else if (d0 < d1) { + throw new IllegalArgumentException("Default value cannot be lower than minimum value!"); + } else if (d0 > d2) { + throw new IllegalArgumentException("Default value cannot be bigger than maximum value!"); + } + } + + public AttributeRanged a(String s) { + this.c = s; + return this; + } + + public String g() { + return this.c; + } + + public double a(double d0) { + d0 = MathHelper.a(d0, this.a, this.b); + return d0; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BaseBlockPosition.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BaseBlockPosition.java new file mode 100644 index 0000000..a685e08 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BaseBlockPosition.java @@ -0,0 +1,90 @@ +package net.minecraft.server; + +import com.google.common.base.Objects; + +public class BaseBlockPosition implements Comparable { + + public static final BaseBlockPosition ZERO = new BaseBlockPosition(0, 0, 0); + // PaperSpigot start - Make mutable and protected for MutableBlockPos + protected int a; + protected int c; + protected int d; + // PaperSpigot end + + public BaseBlockPosition(int i, int j, int k) { + this.a = i; + this.c = j; + this.d = k; + } + + public BaseBlockPosition(double d0, double d1, double d2) { + this(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); + } + + public boolean equals(Object object) { + if (this == object) { + return true; + } else if (!(object instanceof BaseBlockPosition)) { + return false; + } else { + BaseBlockPosition baseblockposition = (BaseBlockPosition) object; + + return this.getX() != baseblockposition.getX() ? false : (this.getY() != baseblockposition.getY() ? false : this.getZ() == baseblockposition.getZ()); + } + } + + public int hashCode() { + return (this.getY() + this.getZ() * 31) * 31 + this.getX(); + } + + public int g(BaseBlockPosition baseblockposition) { + return this.getY() == baseblockposition.getY() ? (this.getZ() == baseblockposition.getZ() ? this.getX() - baseblockposition.getX() : this.getZ() - baseblockposition.getZ()) : this.getY() - baseblockposition.getY(); + } + + // PaperSpigot start - Only allow one implementation of these methods (make final) + public final int getX() { + return this.a; + } + + public final int getY() { + return this.c; + } + + public final int getZ() { + return this.d; + } + // PaperSpigot end + + public BaseBlockPosition d(BaseBlockPosition baseblockposition) { + return new BaseBlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX()); + } + + public double c(double d0, double d1, double d2) { + double d3 = (double) this.getX() - d0; + double d4 = (double) this.getY() - d1; + double d5 = (double) this.getZ() - d2; + + return d3 * d3 + d4 * d4 + d5 * d5; + } + + public double d(double d0, double d1, double d2) { + double d3 = (double) this.getX() + 0.5D - d0; + double d4 = (double) this.getY() + 0.5D - d1; + double d5 = (double) this.getZ() + 0.5D - d2; + + return d3 * d3 + d4 * d4 + d5 * d5; + } + + public double i(BaseBlockPosition baseblockposition) { + return this.c((double) baseblockposition.getX(), (double) baseblockposition.getY(), (double) baseblockposition.getZ()); + } + + public String toString() { + return Objects.toStringHelper(this).add("x", this.getX()).add("y", this.getY()).add("z", this.getZ()).toString(); + } + + // Paperspigot - Signature change, Object -> BaseBlockPosition + public int compareTo(BaseBlockPosition object) { + return this.g((BaseBlockPosition) object); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeBase.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeBase.java new file mode 100644 index 0000000..28da136 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeBase.java @@ -0,0 +1,489 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public abstract class BiomeBase { + + private static final Logger aD = LogManager.getLogger(); + protected static final BiomeTemperature a = new BiomeTemperature(0.1F, 0.2F); + protected static final BiomeTemperature b = new BiomeTemperature(-0.5F, 0.0F); + protected static final BiomeTemperature c = new BiomeTemperature(-1.0F, 0.1F); + protected static final BiomeTemperature d = new BiomeTemperature(-1.8F, 0.1F); + protected static final BiomeTemperature e = new BiomeTemperature(0.125F, 0.05F); + protected static final BiomeTemperature f = new BiomeTemperature(0.2F, 0.2F); + protected static final BiomeTemperature g = new BiomeTemperature(0.45F, 0.3F); + protected static final BiomeTemperature h = new BiomeTemperature(1.5F, 0.025F); + protected static final BiomeTemperature i = new BiomeTemperature(1.0F, 0.5F); + protected static final BiomeTemperature j = new BiomeTemperature(0.0F, 0.025F); + protected static final BiomeTemperature k = new BiomeTemperature(0.1F, 0.8F); + protected static final BiomeTemperature l = new BiomeTemperature(0.2F, 0.3F); + protected static final BiomeTemperature m = new BiomeTemperature(-0.2F, 0.1F); + private static final BiomeBase[] biomes = new BiomeBase[256]; + public static final Set n = Sets.newHashSet(); + public static final Map o = Maps.newHashMap(); + public static final BiomeBase OCEAN = (new BiomeOcean(0)).b(112).a("Ocean").a(BiomeBase.c); + public static final BiomeBase PLAINS = (new BiomePlains(1)).b(9286496).a("Plains"); + public static final BiomeBase DESERT = (new BiomeDesert(2)).b(16421912).a("Desert").b().a(2.0F, 0.0F).a(BiomeBase.e); + public static final BiomeBase EXTREME_HILLS = (new BiomeBigHills(3, false)).b(6316128).a("Extreme Hills").a(BiomeBase.i).a(0.2F, 0.3F); + public static final BiomeBase FOREST = (new BiomeForest(4, 0)).b(353825).a("Forest"); + public static final BiomeBase TAIGA = (new BiomeTaiga(5, 0)).b(747097).a("Taiga").a(5159473).a(0.25F, 0.8F).a(BiomeBase.f); + public static final BiomeBase SWAMPLAND = (new BiomeSwamp(6)).b(522674).a("Swampland").a(9154376).a(BiomeBase.m).a(0.8F, 0.9F); + public static final BiomeBase RIVER = (new BiomeRiver(7)).b(255).a("River").a(BiomeBase.b); + public static final BiomeBase HELL = (new BiomeHell(8)).b(16711680).a("Hell").b().a(2.0F, 0.0F); + public static final BiomeBase SKY = (new BiomeTheEnd(9)).b(8421631).a("The End").b(); + public static final BiomeBase FROZEN_OCEAN = (new BiomeOcean(10)).b(9474208).a("FrozenOcean").c().a(BiomeBase.c).a(0.0F, 0.5F); + public static final BiomeBase FROZEN_RIVER = (new BiomeRiver(11)).b(10526975).a("FrozenRiver").c().a(BiomeBase.b).a(0.0F, 0.5F); + public static final BiomeBase ICE_PLAINS = (new BiomeIcePlains(12, false)).b(16777215).a("Ice Plains").c().a(0.0F, 0.5F).a(BiomeBase.e); + public static final BiomeBase ICE_MOUNTAINS = (new BiomeIcePlains(13, false)).b(10526880).a("Ice Mountains").c().a(BiomeBase.g).a(0.0F, 0.5F); + public static final BiomeBase MUSHROOM_ISLAND = (new BiomeMushrooms(14)).b(16711935).a("MushroomIsland").a(0.9F, 1.0F).a(BiomeBase.l); + public static final BiomeBase MUSHROOM_SHORE = (new BiomeMushrooms(15)).b(10486015).a("MushroomIslandShore").a(0.9F, 1.0F).a(BiomeBase.j); + public static final BiomeBase BEACH = (new BiomeBeach(16)).b(16440917).a("Beach").a(0.8F, 0.4F).a(BiomeBase.j); + public static final BiomeBase DESERT_HILLS = (new BiomeDesert(17)).b(13786898).a("DesertHills").b().a(2.0F, 0.0F).a(BiomeBase.g); + public static final BiomeBase FOREST_HILLS = (new BiomeForest(18, 0)).b(2250012).a("ForestHills").a(BiomeBase.g); + public static final BiomeBase TAIGA_HILLS = (new BiomeTaiga(19, 0)).b(1456435).a("TaigaHills").a(5159473).a(0.25F, 0.8F).a(BiomeBase.g); + public static final BiomeBase SMALL_MOUNTAINS = (new BiomeBigHills(20, true)).b(7501978).a("Extreme Hills Edge").a(BiomeBase.i.a()).a(0.2F, 0.3F); + public static final BiomeBase JUNGLE = (new BiomeJungle(21, false)).b(5470985).a("Jungle").a(5470985).a(0.95F, 0.9F); + public static final BiomeBase JUNGLE_HILLS = (new BiomeJungle(22, false)).b(2900485).a("JungleHills").a(5470985).a(0.95F, 0.9F).a(BiomeBase.g); + public static final BiomeBase JUNGLE_EDGE = (new BiomeJungle(23, true)).b(6458135).a("JungleEdge").a(5470985).a(0.95F, 0.8F); + public static final BiomeBase DEEP_OCEAN = (new BiomeOcean(24)).b(48).a("Deep Ocean").a(BiomeBase.d); + public static final BiomeBase STONE_BEACH = (new BiomeStoneBeach(25)).b(10658436).a("Stone Beach").a(0.2F, 0.3F).a(BiomeBase.k); + public static final BiomeBase COLD_BEACH = (new BiomeBeach(26)).b(16445632).a("Cold Beach").a(0.05F, 0.3F).a(BiomeBase.j).c(); + public static final BiomeBase BIRCH_FOREST = (new BiomeForest(27, 2)).a("Birch Forest").b(3175492); + public static final BiomeBase BIRCH_FOREST_HILLS = (new BiomeForest(28, 2)).a("Birch Forest Hills").b(2055986).a(BiomeBase.g); + public static final BiomeBase ROOFED_FOREST = (new BiomeForest(29, 3)).b(4215066).a("Roofed Forest"); + public static final BiomeBase COLD_TAIGA = (new BiomeTaiga(30, 0)).b(3233098).a("Cold Taiga").a(5159473).c().a(-0.5F, 0.4F).a(BiomeBase.f).c(16777215); + public static final BiomeBase COLD_TAIGA_HILLS = (new BiomeTaiga(31, 0)).b(2375478).a("Cold Taiga Hills").a(5159473).c().a(-0.5F, 0.4F).a(BiomeBase.g).c(16777215); + public static final BiomeBase MEGA_TAIGA = (new BiomeTaiga(32, 1)).b(5858897).a("Mega Taiga").a(5159473).a(0.3F, 0.8F).a(BiomeBase.f); + public static final BiomeBase MEGA_TAIGA_HILLS = (new BiomeTaiga(33, 1)).b(4542270).a("Mega Taiga Hills").a(5159473).a(0.3F, 0.8F).a(BiomeBase.g); + public static final BiomeBase EXTREME_HILLS_PLUS = (new BiomeBigHills(34, true)).b(5271632).a("Extreme Hills+").a(BiomeBase.i).a(0.2F, 0.3F); + public static final BiomeBase SAVANNA = (new BiomeSavanna(35)).b(12431967).a("Savanna").a(1.2F, 0.0F).b().a(BiomeBase.e); + public static final BiomeBase SAVANNA_PLATEAU = (new BiomeSavanna(36)).b(10984804).a("Savanna Plateau").a(1.0F, 0.0F).b().a(BiomeBase.h); + public static final BiomeBase MESA = (new BiomeMesa(37, false, false)).b(14238997).a("Mesa"); + public static final BiomeBase MESA_PLATEAU_F = (new BiomeMesa(38, false, true)).b(11573093).a("Mesa Plateau F").a(BiomeBase.h); + public static final BiomeBase MESA_PLATEAU = (new BiomeMesa(39, false, false)).b(13274213).a("Mesa Plateau").a(BiomeBase.h); + public static final BiomeBase ad = BiomeBase.OCEAN; + protected static final NoiseGenerator3 ae; + protected static final NoiseGenerator3 af; + protected static final WorldGenTallPlant ag; + public String ah; + public int ai; + public int aj; + public IBlockData ak; + public IBlockData al; + public int am; + public float an; + public float ao; + public float temperature; + public float humidity; + public int ar; + public BiomeDecorator as; + protected List at; + protected List au; + protected List av; + protected List aw; + protected boolean ax; + protected boolean ay; + public final int id; + protected WorldGenTrees aA; + protected WorldGenBigTree aB; + protected WorldGenSwampTree aC; + + protected BiomeBase(int i) { + this.ak = Blocks.GRASS.getBlockData(); + this.al = Blocks.DIRT.getBlockData(); + this.am = 5169201; + this.an = BiomeBase.a.a; + this.ao = BiomeBase.a.b; + this.temperature = 0.5F; + this.humidity = 0.5F; + this.ar = 16777215; + this.at = Lists.newArrayList(); + this.au = Lists.newArrayList(); + this.av = Lists.newArrayList(); + this.aw = Lists.newArrayList(); + this.ay = true; + this.aA = new WorldGenTrees(false); + this.aB = new WorldGenBigTree(false); + this.aC = new WorldGenSwampTree(); + this.id = i; + BiomeBase.biomes[i] = this; + this.as = this.a(); + this.au.add(new BiomeMeta(EntitySheep.class, 12, 4, 4)); + this.au.add(new BiomeMeta(EntityRabbit.class, 10, 3, 3)); + this.au.add(new BiomeMeta(EntityPig.class, 10, 4, 4)); + this.au.add(new BiomeMeta(EntityChicken.class, 10, 4, 4)); + this.au.add(new BiomeMeta(EntityCow.class, 8, 4, 4)); + this.at.add(new BiomeMeta(EntitySpider.class, 100, 4, 4)); + this.at.add(new BiomeMeta(EntityZombie.class, 100, 4, 4)); + this.at.add(new BiomeMeta(EntitySkeleton.class, 100, 4, 4)); + this.at.add(new BiomeMeta(EntityCreeper.class, 100, 4, 4)); + this.at.add(new BiomeMeta(EntitySlime.class, 100, 4, 4)); + this.at.add(new BiomeMeta(EntityEnderman.class, 10, 1, 4)); + this.at.add(new BiomeMeta(EntityWitch.class, 5, 1, 1)); + this.av.add(new BiomeMeta(EntitySquid.class, 10, 4, 4)); + this.aw.add(new BiomeMeta(EntityBat.class, 10, 8, 8)); + } + + protected BiomeDecorator a() { + return new BiomeDecorator(); + } + + protected BiomeBase a(float f, float f1) { + if (f > 0.1F && f < 0.2F) { + throw new IllegalArgumentException("Please avoid temperatures in the range 0.1 - 0.2 because of snow"); + } else { + this.temperature = f; + this.humidity = f1; + return this; + } + } + + protected final BiomeBase a(BiomeTemperature biomebase_biometemperature) { + this.an = biomebase_biometemperature.a; + this.ao = biomebase_biometemperature.b; + return this; + } + + protected BiomeBase b() { + this.ay = false; + return this; + } + + public WorldGenTreeAbstract a(Random random) { + return (WorldGenTreeAbstract) (random.nextInt(10) == 0 ? this.aB : this.aA); + } + + public WorldGenerator b(Random random) { + return new WorldGenGrass(BlockLongGrass.EnumTallGrassType.GRASS); + } + + public BlockFlowers.EnumFlowerVarient a(Random random, BlockPosition blockposition) { + return random.nextInt(3) > 0 ? BlockFlowers.EnumFlowerVarient.DANDELION : BlockFlowers.EnumFlowerVarient.POPPY; + } + + protected BiomeBase c() { + this.ax = true; + return this; + } + + protected BiomeBase a(String s) { + this.ah = s; + return this; + } + + protected BiomeBase a(int i) { + this.am = i; + return this; + } + + protected BiomeBase b(int i) { + this.a(i, false); + return this; + } + + protected BiomeBase c(int i) { + this.aj = i; + return this; + } + + protected BiomeBase a(int i, boolean flag) { + this.ai = i; + if (flag) { + this.aj = (i & 16711422) >> 1; + } else { + this.aj = i; + } + + return this; + } + + public List getMobs(EnumCreatureType enumcreaturetype) { + switch (SyntheticClass_1.switchMap[enumcreaturetype.ordinal()]) { + case 1: + return this.at; + + case 2: + return this.au; + + case 3: + return this.av; + + case 4: + return this.aw; + + default: + return Collections.emptyList(); + } + } + + public boolean d() { + return this.j(); + } + + public boolean e() { + return this.j() ? false : this.ay; + } + + public boolean f() { + return this.humidity > 0.85F; + } + + public float g() { + return 0.1F; + } + + public final int h() { + return (int) (this.humidity * 65536.0F); + } + + public final float a(BlockPosition blockposition) { + if (blockposition.getY() > 64) { + float f = (float) (BiomeBase.ae.a((double) blockposition.getX() * 1.0D / 8.0D, (double) blockposition.getZ() * 1.0D / 8.0D) * 4.0D); + + return this.temperature - (f + (float) blockposition.getY() - 64.0F) * 0.05F / 30.0F; + } else { + return this.temperature; + } + } + + public void a(World world, Random random, BlockPosition blockposition) { + this.as.a(world, random, this, blockposition); + } + + public boolean j() { + return this.ax; + } + + public void a(World world, Random random, ChunkSnapshot chunksnapshot, int i, int j, double d0) { + this.b(world, random, chunksnapshot, i, j, d0); + } + + public final void b(World world, Random random, ChunkSnapshot chunksnapshot, int i, int j, double d0) { + int k = world.F(); + IBlockData iblockdata = this.ak; + IBlockData iblockdata1 = this.al; + int l = -1; + int i1 = (int) (d0 / 3.0D + 3.0D + random.nextDouble() * 0.25D); + int j1 = i & 15; + int k1 = j & 15; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int l1 = 255; l1 >= 0; --l1) { + if (l1 <= (world.paperSpigotConfig.generateFlatBedrock ? 0 : random.nextInt(5))) { // PaperSpigot - Configurable flat bedrock + chunksnapshot.a(k1, l1, j1, Blocks.BEDROCK.getBlockData()); + } else { + IBlockData iblockdata2 = chunksnapshot.a(k1, l1, j1); + + if (iblockdata2.getBlock().getMaterial() == Material.AIR) { + l = -1; + } else if (iblockdata2.getBlock() == Blocks.STONE) { + if (l == -1) { + if (i1 <= 0) { + iblockdata = null; + iblockdata1 = Blocks.STONE.getBlockData(); + } else if (l1 >= k - 4 && l1 <= k + 1) { + iblockdata = this.ak; + iblockdata1 = this.al; + } + + if (l1 < k && (iblockdata == null || iblockdata.getBlock().getMaterial() == Material.AIR)) { + if (this.a((BlockPosition) blockposition_mutableblockposition.c(i, l1, j)) < 0.15F) { + iblockdata = Blocks.ICE.getBlockData(); + } else { + iblockdata = Blocks.WATER.getBlockData(); + } + } + + l = i1; + if (l1 >= k - 1) { + chunksnapshot.a(k1, l1, j1, iblockdata); + } else if (l1 < k - 7 - i1) { + iblockdata = null; + iblockdata1 = Blocks.STONE.getBlockData(); + chunksnapshot.a(k1, l1, j1, Blocks.GRAVEL.getBlockData()); + } else { + chunksnapshot.a(k1, l1, j1, iblockdata1); + } + } else if (l > 0) { + --l; + chunksnapshot.a(k1, l1, j1, iblockdata1); + if (l == 0 && iblockdata1.getBlock() == Blocks.SAND) { + l = random.nextInt(4) + Math.max(0, l1 - 63); + iblockdata1 = iblockdata1.get(BlockSand.VARIANT) == BlockSand.EnumSandVariant.RED_SAND ? Blocks.RED_SANDSTONE.getBlockData() : Blocks.SANDSTONE.getBlockData(); + } + } + } + } + } + + } + + protected BiomeBase k() { + return this.d(this.id + 128); + } + + protected BiomeBase d(int i) { + return new BiomeBaseSub(i, this); + } + + public Class l() { + return this.getClass(); + } + + public boolean a(BiomeBase biomebase) { + return biomebase == this ? true : (biomebase == null ? false : this.l() == biomebase.l()); + } + + public EnumTemperature m() { + return (double) this.temperature < 0.2D ? EnumTemperature.COLD : ((double) this.temperature < 1.0D ? EnumTemperature.MEDIUM : EnumTemperature.WARM); + } + + public static BiomeBase[] getBiomes() { + return BiomeBase.biomes; + } + + public static BiomeBase getBiome(int i) { + return getBiome(i, (BiomeBase) null); + } + + public static BiomeBase getBiome(int i, BiomeBase biomebase) { + if (i >= 0 && i <= BiomeBase.biomes.length) { + BiomeBase biomebase1 = BiomeBase.biomes[i]; + + return biomebase1 == null ? biomebase : biomebase1; + } else { + BiomeBase.aD.warn("Biome ID is out of bounds: " + i + ", defaulting to 0 (Ocean)"); + return BiomeBase.OCEAN; + } + } + + static { + BiomeBase.PLAINS.k(); + BiomeBase.DESERT.k(); + BiomeBase.FOREST.k(); + BiomeBase.TAIGA.k(); + BiomeBase.SWAMPLAND.k(); + BiomeBase.ICE_PLAINS.k(); + BiomeBase.JUNGLE.k(); + BiomeBase.JUNGLE_EDGE.k(); + BiomeBase.COLD_TAIGA.k(); + BiomeBase.SAVANNA.k(); + BiomeBase.SAVANNA_PLATEAU.k(); + BiomeBase.MESA.k(); + BiomeBase.MESA_PLATEAU_F.k(); + BiomeBase.MESA_PLATEAU.k(); + BiomeBase.BIRCH_FOREST.k(); + BiomeBase.BIRCH_FOREST_HILLS.k(); + BiomeBase.ROOFED_FOREST.k(); + BiomeBase.MEGA_TAIGA.k(); + BiomeBase.EXTREME_HILLS.k(); + BiomeBase.EXTREME_HILLS_PLUS.k(); + BiomeBase.MEGA_TAIGA.d(BiomeBase.MEGA_TAIGA_HILLS.id + 128).a("Redwood Taiga Hills M"); + BiomeBase[] abiomebase = BiomeBase.biomes; + int i = abiomebase.length; + + for (int j = 0; j < i; ++j) { + BiomeBase biomebase = abiomebase[j]; + + if (biomebase != null) { + if (BiomeBase.o.containsKey(biomebase.ah)) { + throw new Error("Biome \"" + biomebase.ah + "\" is defined as both ID " + ((BiomeBase) BiomeBase.o.get(biomebase.ah)).id + " and " + biomebase.id); + } + + BiomeBase.o.put(biomebase.ah, biomebase); + if (biomebase.id < 128) { + BiomeBase.n.add(biomebase); + } + } + } + + BiomeBase.n.remove(BiomeBase.HELL); + BiomeBase.n.remove(BiomeBase.SKY); + BiomeBase.n.remove(BiomeBase.FROZEN_OCEAN); + BiomeBase.n.remove(BiomeBase.SMALL_MOUNTAINS); + ae = new NoiseGenerator3(new Random(1234L), 1); + af = new NoiseGenerator3(new Random(2345L), 1); + ag = new WorldGenTallPlant(); + } + + static class SyntheticClass_1 { + + static final int[] switchMap = new int[EnumCreatureType.values().length]; + + static { + try { + SyntheticClass_1.switchMap[EnumCreatureType.MONSTER.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + SyntheticClass_1.switchMap[EnumCreatureType.CREATURE.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + SyntheticClass_1.switchMap[EnumCreatureType.WATER_CREATURE.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + SyntheticClass_1.switchMap[EnumCreatureType.AMBIENT.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + } + } + + public static class BiomeMeta extends WeightedRandom.WeightedRandomChoice { + + public Class b; + public int c; + public int d; + + public BiomeMeta(Class oclass, int i, int j, int k) { + super(i); + this.b = oclass; + this.c = j; + this.d = k; + } + + public String toString() { + return this.b.getSimpleName() + "*(" + this.c + "-" + this.d + "):" + this.a; + } + } + + public static class BiomeTemperature { + + public float a; + public float b; + + public BiomeTemperature(float f, float f1) { + this.a = f; + this.b = f1; + } + + public BiomeTemperature a() { + return new BiomeTemperature(this.a * 0.8F, this.b * 0.6F); + } + } + + public static enum EnumTemperature { + + OCEAN, COLD, MEDIUM, WARM; + + private EnumTemperature() {} + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeMesa.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeMesa.java new file mode 100644 index 0000000..65cd706 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeMesa.java @@ -0,0 +1,264 @@ +package net.minecraft.server; + +import java.util.Arrays; +import java.util.Random; + +public class BiomeMesa extends BiomeBase { + + private IBlockData[] aD; + private long aE; + private NoiseGenerator3 aF; + private NoiseGenerator3 aG; + private NoiseGenerator3 aH; + private boolean aI; + private boolean aJ; + + public BiomeMesa(int i, boolean flag, boolean flag1) { + super(i); + this.aI = flag; + this.aJ = flag1; + this.b(); + this.a(2.0F, 0.0F); + this.au.clear(); + this.ak = Blocks.SAND.getBlockData().set(BlockSand.VARIANT, BlockSand.EnumSandVariant.RED_SAND); + this.al = Blocks.STAINED_HARDENED_CLAY.getBlockData(); + this.as.A = -999; + this.as.D = 20; + this.as.F = 3; + this.as.G = 5; + this.as.B = 0; + this.au.clear(); + if (flag1) { + this.as.A = 5; + } + + } + + public WorldGenTreeAbstract a(Random random) { + return this.aA; + } + + public void a(World world, Random random, BlockPosition blockposition) { + super.a(world, random, blockposition); + } + + public void a(World world, Random random, ChunkSnapshot chunksnapshot, int i, int j, double d0) { + if (this.aD == null || this.aE != world.getSeed()) { + this.a(world.getSeed()); + } + + if (this.aF == null || this.aG == null || this.aE != world.getSeed()) { + Random random1 = new Random(this.aE); + + this.aF = new NoiseGenerator3(random1, 4); + this.aG = new NoiseGenerator3(random1, 1); + } + + this.aE = world.getSeed(); + double d1 = 0.0D; + int k; + int l; + + if (this.aI) { + k = (i & -16) + (j & 15); + l = (j & -16) + (i & 15); + double d2 = Math.min(Math.abs(d0), this.aF.a((double) k * 0.25D, (double) l * 0.25D)); + + if (d2 > 0.0D) { + double d3 = 0.001953125D; + double d4 = Math.abs(this.aG.a((double) k * d3, (double) l * d3)); + + d1 = d2 * d2 * 2.5D; + double d5 = Math.ceil(d4 * 50.0D) + 14.0D; + + if (d1 > d5) { + d1 = d5; + } + + d1 += 64.0D; + } + } + + k = i & 15; + l = j & 15; + int i1 = world.F(); + IBlockData iblockdata = Blocks.STAINED_HARDENED_CLAY.getBlockData(); + IBlockData iblockdata1 = this.al; + int j1 = (int) (d0 / 3.0D + 3.0D + random.nextDouble() * 0.25D); + boolean flag = Math.cos(d0 / 3.0D * 3.141592653589793D) > 0.0D; + int k1 = -1; + boolean flag1 = false; + + for (int l1 = 255; l1 >= 0; --l1) { + if (chunksnapshot.a(l, l1, k).getBlock().getMaterial() == Material.AIR && l1 < (int) d1) { + chunksnapshot.a(l, l1, k, Blocks.STONE.getBlockData()); + } + + if (l1 <= (world.paperSpigotConfig.generateFlatBedrock ? 0 : random.nextInt(5))) { // PaperSpigot - Configurable flat bedrock + chunksnapshot.a(l, l1, k, Blocks.BEDROCK.getBlockData()); + } else { + IBlockData iblockdata2 = chunksnapshot.a(l, l1, k); + + if (iblockdata2.getBlock().getMaterial() == Material.AIR) { + k1 = -1; + } else if (iblockdata2.getBlock() == Blocks.STONE) { + IBlockData iblockdata3; + + if (k1 == -1) { + flag1 = false; + if (j1 <= 0) { + iblockdata = null; + iblockdata1 = Blocks.STONE.getBlockData(); + } else if (l1 >= i1 - 4 && l1 <= i1 + 1) { + iblockdata = Blocks.STAINED_HARDENED_CLAY.getBlockData(); + iblockdata1 = this.al; + } + + if (l1 < i1 && (iblockdata == null || iblockdata.getBlock().getMaterial() == Material.AIR)) { + iblockdata = Blocks.WATER.getBlockData(); + } + + k1 = j1 + Math.max(0, l1 - i1); + if (l1 >= i1 - 1) { + if (this.aJ && l1 > 86 + j1 * 2) { + if (flag) { + chunksnapshot.a(l, l1, k, Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, BlockDirt.EnumDirtVariant.COARSE_DIRT)); + } else { + chunksnapshot.a(l, l1, k, Blocks.GRASS.getBlockData()); + } + } else if (l1 > i1 + 3 + j1) { + if (l1 >= 64 && l1 <= 127) { + if (flag) { + iblockdata3 = Blocks.HARDENED_CLAY.getBlockData(); + } else { + iblockdata3 = this.a(i, l1, j); + } + } else { + iblockdata3 = Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.ORANGE); + } + + chunksnapshot.a(l, l1, k, iblockdata3); + } else { + chunksnapshot.a(l, l1, k, this.ak); + flag1 = true; + } + } else { + chunksnapshot.a(l, l1, k, iblockdata1); + if (iblockdata1.getBlock() == Blocks.STAINED_HARDENED_CLAY) { + chunksnapshot.a(l, l1, k, iblockdata1.getBlock().getBlockData().set(BlockCloth.COLOR, EnumColor.ORANGE)); + } + } + } else if (k1 > 0) { + --k1; + if (flag1) { + chunksnapshot.a(l, l1, k, Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.ORANGE)); + } else { + iblockdata3 = this.a(i, l1, j); + chunksnapshot.a(l, l1, k, iblockdata3); + } + } + } + } + } + + } + + private void a(long i) { + this.aD = new IBlockData[64]; + Arrays.fill(this.aD, Blocks.HARDENED_CLAY.getBlockData()); + Random random = new Random(i); + + this.aH = new NoiseGenerator3(random, 1); + + int j; + + for (j = 0; j < 64; ++j) { + j += random.nextInt(5) + 1; + if (j < 64) { + this.aD[j] = Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.ORANGE); + } + } + + j = random.nextInt(4) + 2; + + int k; + int l; + int i1; + int j1; + + for (k = 0; k < j; ++k) { + l = random.nextInt(3) + 1; + i1 = random.nextInt(64); + + for (j1 = 0; i1 + j1 < 64 && j1 < l; ++j1) { + this.aD[i1 + j1] = Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.YELLOW); + } + } + + k = random.nextInt(4) + 2; + + int k1; + + for (l = 0; l < k; ++l) { + i1 = random.nextInt(3) + 2; + j1 = random.nextInt(64); + + for (k1 = 0; j1 + k1 < 64 && k1 < i1; ++k1) { + this.aD[j1 + k1] = Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.BROWN); + } + } + + l = random.nextInt(4) + 2; + + for (i1 = 0; i1 < l; ++i1) { + j1 = random.nextInt(3) + 1; + k1 = random.nextInt(64); + + for (int l1 = 0; k1 + l1 < 64 && l1 < j1; ++l1) { + this.aD[k1 + l1] = Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.RED); + } + } + + i1 = random.nextInt(3) + 3; + j1 = 0; + + for (k1 = 0; k1 < i1; ++k1) { + byte b0 = 1; + + j1 += random.nextInt(16) + 4; + + for (int i2 = 0; j1 + i2 < 64 && i2 < b0; ++i2) { + this.aD[j1 + i2] = Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.WHITE); + if (j1 + i2 > 1 && random.nextBoolean()) { + this.aD[j1 + i2 - 1] = Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.SILVER); + } + + if (j1 + i2 < 63 && random.nextBoolean()) { + this.aD[j1 + i2 + 1] = Blocks.STAINED_HARDENED_CLAY.getBlockData().set(BlockCloth.COLOR, EnumColor.SILVER); + } + } + } + + } + + private IBlockData a(int i, int j, int k) { + int l = (int) Math.round(this.aH.a((double) i * 1.0D / 512.0D, (double) i * 1.0D / 512.0D) * 2.0D); + + return this.aD[(j + l + 64) % 64]; + } + + protected BiomeBase d(int i) { + boolean flag = this.id == BiomeBase.MESA.id; + BiomeMesa biomemesa = new BiomeMesa(i, flag, this.aJ); + + if (!flag) { + biomemesa.a(BiomeMesa.g); + biomemesa.a(this.ah + " M"); + } else { + biomemesa.a(this.ah + " (Bryce)"); + } + + biomemesa.a(this.ai, true); + return biomemesa; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeTheEndDecorator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeTheEndDecorator.java new file mode 100644 index 0000000..4128e9c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BiomeTheEndDecorator.java @@ -0,0 +1,28 @@ +package net.minecraft.server; + +public class BiomeTheEndDecorator extends BiomeDecorator { + + protected WorldGenerator M; + + public BiomeTheEndDecorator() { + this.M = new WorldGenEnder(Blocks.END_STONE); + } + + protected void a(BiomeBase biomebase) { + this.a(); + if (this.b.nextInt(5) == 0) { + int i = this.b.nextInt(16) + 8; + int j = this.b.nextInt(16) + 8; + + this.M.generate(this.a, this.b, this.a.r(this.c.a(i, 0, j))); + } + + if (this.c.getX() == 0 && this.c.getZ() == 0) { + EntityEnderDragon entityenderdragon = new EntityEnderDragon(this.a); + + entityenderdragon.setPositionRotation(0.0D, 128.0D, 0.0D, this.b.nextFloat() * 360.0F, 0.0F); + this.a.addEntity(entityenderdragon, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Block.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Block.java new file mode 100644 index 0000000..2817389 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Block.java @@ -0,0 +1,1039 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class Block { + + private static final MinecraftKey a = new MinecraftKey("air"); + public static final RegistryBlocks REGISTRY = new RegistryBlocks(Block.a); + public static final RegistryID d = new RegistryID(); + private CreativeModeTab creativeTab; + public static final Block.StepSound e = new Block.StepSound("stone", 1.0F, 1.0F); + public static final Block.StepSound f = new Block.StepSound("wood", 1.0F, 1.0F); + public static final Block.StepSound g = new Block.StepSound("gravel", 1.0F, 1.0F); + public static final Block.StepSound h = new Block.StepSound("grass", 1.0F, 1.0F); + public static final Block.StepSound i = new Block.StepSound("stone", 1.0F, 1.0F); + public static final Block.StepSound j = new Block.StepSound("stone", 1.0F, 1.5F); + public static final Block.StepSound k = new Block.StepSound("stone", 1.0F, 1.0F) { + public String getBreakSound() { + return "dig.glass"; + } + + public String getPlaceSound() { + return "step.stone"; + } + }; + public static final Block.StepSound l = new Block.StepSound("cloth", 1.0F, 1.0F); + public static final Block.StepSound m = new Block.StepSound("sand", 1.0F, 1.0F); + public static final Block.StepSound n = new Block.StepSound("snow", 1.0F, 1.0F); + public static final Block.StepSound o = new Block.StepSound("ladder", 1.0F, 1.0F) { + public String getBreakSound() { + return "dig.wood"; + } + }; + public static final Block.StepSound p = new Block.StepSound("anvil", 0.3F, 1.0F) { + public String getBreakSound() { + return "dig.stone"; + } + + public String getPlaceSound() { + return "random.anvil_land"; + } + }; + public static final Block.StepSound q = new Block.StepSound("slime", 1.0F, 1.0F) { + public String getBreakSound() { + return "mob.slime.big"; + } + + public String getPlaceSound() { + return "mob.slime.big"; + } + + public String getStepSound() { + return "mob.slime.small"; + } + }; + protected boolean r; + protected int s; + protected boolean t; + protected int u; + protected boolean v; + protected float strength; + protected float durability; + protected boolean y; + protected boolean z; + protected boolean isTileEntity; + // Spigot start + public co.aikar.timings.Timing timing; + public co.aikar.timings.Timing getTiming() { + if (timing == null) { + timing = co.aikar.timings.SpigotTimings.getBlockTiming(this); + } + return timing; + } + // Spigot end + + protected double minX; + protected double minY; + protected double minZ; + protected double maxX; + protected double maxY; + protected double maxZ; + public Block.StepSound stepSound; + public float I; + protected final Material material; + protected final MaterialMapColor K; + public float frictionFactor; + protected final BlockStateList blockStateList; + private IBlockData blockData; + private String name; + + public static int getId(Block block) { + return Block.REGISTRY.b(block); + } + + public static int getCombinedId(IBlockData iblockdata) { + Block block = iblockdata.getBlock(); + + return getId(block) + (block.toLegacyData(iblockdata) << 12); + } + + public static Block getById(int i) { + return (Block) Block.REGISTRY.a(i); + } + + public static IBlockData getByCombinedId(int i) { + int j = i & 4095; + int k = i >> 12 & 15; + + return getById(j).fromLegacyData(k); + } + + public static Block asBlock(Item item) { + return item instanceof ItemBlock ? ((ItemBlock) item).d() : null; + } + + public static Block getByName(String s) { + MinecraftKey minecraftkey = new MinecraftKey(s); + + if (Block.REGISTRY.d(minecraftkey)) { + return (Block) Block.REGISTRY.get(minecraftkey); + } else { + try { + return (Block) Block.REGISTRY.a(Integer.parseInt(s)); + } catch (NumberFormatException numberformatexception) { + return null; + } + } + } + + public boolean o() { + return this.r; + } + + public int p() { + return this.s; + } + + public int r() { + return this.u; + } + + public boolean s() { + return this.v; + } + + public Material getMaterial() { + return this.material; + } + + public MaterialMapColor g(IBlockData iblockdata) { + return this.K; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData(); + } + + public int toLegacyData(IBlockData iblockdata) { + if (iblockdata != null && !iblockdata.a().isEmpty()) { + throw new IllegalArgumentException("Don\'t know how to convert " + iblockdata + " back into data..."); + } else { + return 0; + } + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata; + } + + public Block(Material material, MaterialMapColor materialmapcolor) { + this.y = true; + this.stepSound = Block.e; + this.I = 1.0F; + this.frictionFactor = 0.6F; + this.material = material; + this.K = materialmapcolor; + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + this.r = this.c(); + this.s = this.c() ? 255 : 0; + this.t = !material.blocksLight(); + this.blockStateList = this.getStateList(); + this.j(this.blockStateList.getBlockData()); + } + + protected Block(Material material) { + this(material, material.r()); + } + + protected Block a(Block.StepSound block_stepsound) { + this.stepSound = block_stepsound; + return this; + } + + protected Block e(int i) { + this.s = i; + return this; + } + + protected Block a(float f) { + this.u = (int) (15.0F * f); + return this; + } + + protected Block b(float f) { + this.durability = f * 3.0F; + return this; + } + + public boolean u() { + return this.material.isSolid() && this.d(); + } + + public boolean isOccluding() { + return this.material.k() && this.d() && !this.isPowerSource(); + } + + public boolean w() { + return this.material.isSolid() && this.d(); + } + + public boolean d() { + return true; + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition) { + return !this.material.isSolid(); + } + + public int b() { + return 3; + } + + public boolean a(World world, BlockPosition blockposition) { + return false; + } + + protected Block c(float f) { + this.strength = f; + if (this.durability < f * 5.0F) { + this.durability = f * 5.0F; + } + + return this; + } + + protected Block x() { + this.c(-1.0F); + return this; + } + + public float g(World world, BlockPosition blockposition) { + return this.strength; + } + + protected Block a(boolean flag) { + this.z = flag; + return this; + } + + public boolean isTicking() { + return this.z; + } + + public boolean isTileEntity() { + return this.isTileEntity; + } + + protected final void a(float f, float f1, float f2, float f3, float f4, float f5) { + this.minX = (double) f; + this.minY = (double) f1; + this.minZ = (double) f2; + this.maxX = (double) f3; + this.maxY = (double) f4; + this.maxZ = (double) f5; + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + return iblockaccess.getType(blockposition).getBlock().getMaterial().isBuildable(); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, AxisAlignedBB axisalignedbb, List list, Entity entity) { + AxisAlignedBB axisalignedbb1 = this.a(world, blockposition, iblockdata); + + if (axisalignedbb1 != null && axisalignedbb.b(axisalignedbb1)) { + list.add(axisalignedbb1); + } + + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return new AxisAlignedBB((double) blockposition.getX() + this.minX, (double) blockposition.getY() + this.minY, (double) blockposition.getZ() + this.minZ, (double) blockposition.getX() + this.maxX, (double) blockposition.getY() + this.maxY, (double) blockposition.getZ() + this.maxZ); + } + + public boolean c() { + return true; + } + + public boolean a(IBlockData iblockdata, boolean flag) { + return this.A(); + } + + public boolean A() { + return true; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + this.b(world, blockposition, iblockdata, random); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {} + + public void postBreak(World world, BlockPosition blockposition, IBlockData iblockdata) {} + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {} + + public int a(World world) { + return 10; + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + org.spigotmc.AsyncCatcher.catchOp( "block onPlace"); // Spigot + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + org.spigotmc.AsyncCatcher.catchOp( "block remove"); // Spigot + } + + public int a(Random random) { + return 1; + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Item.getItemOf(this); + } + + public float getDamage(EntityHuman entityhuman, World world, BlockPosition blockposition) { + float f = this.g(world, blockposition); + + return f < 0.0F ? 0.0F : (!entityhuman.b(this) ? entityhuman.a(this) / f / 100.0F : entityhuman.a(this) / f / 30.0F); + } + + public final void b(World world, BlockPosition blockposition, IBlockData iblockdata, int i) { + this.dropNaturally(world, blockposition, iblockdata, 1.0F, i); + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + if (!world.isClientSide) { + int j = this.getDropCount(i, world.random); + + for (int k = 0; k < j; ++k) { + // CraftBukkit - <= to < to allow for plugins to completely disable block drops from explosions + if (world.random.nextFloat() < f) { + Item item = this.getDropType(iblockdata, world.random, i); + + if (item != null) { + a(world, blockposition, new ItemStack(item, 1, this.getDropData(iblockdata))); + } + } + } + + } + } + + public static void a(World world, BlockPosition blockposition, ItemStack itemstack) { + if (!world.isClientSide && world.getGameRules().getBoolean("doTileDrops")) { + float f = 0.5F; + double d0 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; + double d1 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; + double d2 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; + EntityItem entityitem = new EntityItem(world, (double) blockposition.getX() + d0, (double) blockposition.getY() + d1, (double) blockposition.getZ() + d2, itemstack); + + entityitem.p(); + world.addEntity(entityitem); + } + } + + protected void dropExperience(World world, BlockPosition blockposition, int i) { + if (!world.isClientSide) { + while (i > 0) { + int j = EntityExperienceOrb.getOrbValue(i); + + i -= j; + world.addEntity(new EntityExperienceOrb(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, j)); + } + } + + } + + public int getDropData(IBlockData iblockdata) { + return 0; + } + + public float a(Entity entity) { + return this.durability / 5.0F; + } + + public MovingObjectPosition a(World world, BlockPosition blockposition, Vec3D vec3d, Vec3D vec3d1) { + this.updateShape(world, blockposition); + vec3d = vec3d.add((double) (-blockposition.getX()), (double) (-blockposition.getY()), (double) (-blockposition.getZ())); + vec3d1 = vec3d1.add((double) (-blockposition.getX()), (double) (-blockposition.getY()), (double) (-blockposition.getZ())); + Vec3D vec3d2 = vec3d.a(vec3d1, this.minX); + Vec3D vec3d3 = vec3d.a(vec3d1, this.maxX); + Vec3D vec3d4 = vec3d.b(vec3d1, this.minY); + Vec3D vec3d5 = vec3d.b(vec3d1, this.maxY); + Vec3D vec3d6 = vec3d.c(vec3d1, this.minZ); + Vec3D vec3d7 = vec3d.c(vec3d1, this.maxZ); + + if (!this.a(vec3d2)) { + vec3d2 = null; + } + + if (!this.a(vec3d3)) { + vec3d3 = null; + } + + if (!this.b(vec3d4)) { + vec3d4 = null; + } + + if (!this.b(vec3d5)) { + vec3d5 = null; + } + + if (!this.c(vec3d6)) { + vec3d6 = null; + } + + if (!this.c(vec3d7)) { + vec3d7 = null; + } + + Vec3D vec3d8 = null; + + if (vec3d2 != null && (vec3d8 == null || vec3d.distanceSquared(vec3d2) < vec3d.distanceSquared(vec3d8))) { + vec3d8 = vec3d2; + } + + if (vec3d3 != null && (vec3d8 == null || vec3d.distanceSquared(vec3d3) < vec3d.distanceSquared(vec3d8))) { + vec3d8 = vec3d3; + } + + if (vec3d4 != null && (vec3d8 == null || vec3d.distanceSquared(vec3d4) < vec3d.distanceSquared(vec3d8))) { + vec3d8 = vec3d4; + } + + if (vec3d5 != null && (vec3d8 == null || vec3d.distanceSquared(vec3d5) < vec3d.distanceSquared(vec3d8))) { + vec3d8 = vec3d5; + } + + if (vec3d6 != null && (vec3d8 == null || vec3d.distanceSquared(vec3d6) < vec3d.distanceSquared(vec3d8))) { + vec3d8 = vec3d6; + } + + if (vec3d7 != null && (vec3d8 == null || vec3d.distanceSquared(vec3d7) < vec3d.distanceSquared(vec3d8))) { + vec3d8 = vec3d7; + } + + if (vec3d8 == null) { + return null; + } else { + EnumDirection enumdirection = null; + + if (vec3d8 == vec3d2) { + enumdirection = EnumDirection.WEST; + } + + if (vec3d8 == vec3d3) { + enumdirection = EnumDirection.EAST; + } + + if (vec3d8 == vec3d4) { + enumdirection = EnumDirection.DOWN; + } + + if (vec3d8 == vec3d5) { + enumdirection = EnumDirection.UP; + } + + if (vec3d8 == vec3d6) { + enumdirection = EnumDirection.NORTH; + } + + if (vec3d8 == vec3d7) { + enumdirection = EnumDirection.SOUTH; + } + + return new MovingObjectPosition(vec3d8.add((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()), enumdirection, blockposition); + } + } + + private boolean a(Vec3D vec3d) { + return vec3d == null ? false : vec3d.b >= this.minY && vec3d.b <= this.maxY && vec3d.c >= this.minZ && vec3d.c <= this.maxZ; + } + + private boolean b(Vec3D vec3d) { + return vec3d == null ? false : vec3d.a >= this.minX && vec3d.a <= this.maxX && vec3d.c >= this.minZ && vec3d.c <= this.maxZ; + } + + private boolean c(Vec3D vec3d) { + return vec3d == null ? false : vec3d.a >= this.minX && vec3d.a <= this.maxX && vec3d.b >= this.minY && vec3d.b <= this.maxY; + } + + public void wasExploded(World world, BlockPosition blockposition, Explosion explosion) {} + + public boolean canPlace(World world, BlockPosition blockposition, EnumDirection enumdirection, ItemStack itemstack) { + return this.canPlace(world, blockposition, enumdirection); + } + + public boolean canPlace(World world, BlockPosition blockposition, EnumDirection enumdirection) { + return this.canPlace(world, blockposition); + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return world.getType(blockposition).getBlock().material.isReplaceable(); + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + return false; + } + + public void a(World world, BlockPosition blockposition, Entity entity) {} + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return this.fromLegacyData(i); + } + + public void attack(World world, BlockPosition blockposition, EntityHuman entityhuman) {} + + public Vec3D a(World world, BlockPosition blockposition, Entity entity, Vec3D vec3d) { + return vec3d; + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) {} + + public final double B() { + return this.minX; + } + + public final double C() { + return this.maxX; + } + + public final double D() { + return this.minY; + } + + public final double E() { + return this.maxY; + } + + public final double F() { + return this.minZ; + } + + public final double G() { + return this.maxZ; + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return 0; + } + + public boolean isPowerSource() { + return false; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) {} + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return 0; + } + + public void j() {} + + public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, TileEntity tileentity) { + entityhuman.b(StatisticList.MINE_BLOCK_COUNT[getId(this)]); + entityhuman.applyExhaustion(world.paperSpigotConfig.blockBreakExhaustion); // PaperSpigot - Configurable block break exhaustion + if (this.I() && EnchantmentManager.hasSilkTouchEnchantment(entityhuman)) { + ItemStack itemstack = this.i(iblockdata); + + if (itemstack != null) { + a(world, blockposition, itemstack); + } + } else { + int i = EnchantmentManager.getBonusBlockLootEnchantmentLevel(entityhuman); + + this.b(world, blockposition, iblockdata, i); + } + + } + + protected boolean I() { + return this.d() && !this.isTileEntity; + } + + protected ItemStack i(IBlockData iblockdata) { + int i = 0; + Item item = Item.getItemOf(this); + + if (item != null && item.k()) { + i = this.toLegacyData(iblockdata); + } + + return new ItemStack(item, 1, i); + } + + public int getDropCount(int i, Random random) { + return this.a(random); + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) {} + + public boolean g() { + return !this.material.isBuildable() && !this.material.isLiquid(); + } + + public Block c(String s) { + this.name = s; + return this; + } + + public String getName() { + return LocaleI18n.get(this.a() + ".name"); + } + + public String a() { + return "tile." + this.name; + } + + public boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, int i, int j) { + return false; + } + + public boolean J() { + return this.y; + } + + protected Block K() { + this.y = false; + return this; + } + + public int k() { + return this.material.getPushReaction(); + } + + public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { + entity.e(f, 1.0F); + } + + public void a(World world, Entity entity) { + entity.motY = 0.0D; + } + + public int getDropData(World world, BlockPosition blockposition) { + return this.getDropData(world.getType(blockposition)); + } + + public Block a(CreativeModeTab creativemodetab) { + this.creativeTab = creativemodetab; + return this; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) {} + + public void k(World world, BlockPosition blockposition) {} + + public boolean N() { + return true; + } + + public boolean a(Explosion explosion) { + return true; + } + + public boolean b(Block block) { + return this == block; + } + + public static boolean a(Block block, Block block1) { + return block != null && block1 != null ? (block == block1 ? true : block.b(block1)) : false; + } + + public boolean isComplexRedstone() { + return false; + } + + public int l(World world, BlockPosition blockposition) { + return 0; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[0]); + } + + public BlockStateList P() { + return this.blockStateList; + } + + protected final void j(IBlockData iblockdata) { + this.blockData = iblockdata; + } + + public final IBlockData getBlockData() { + return this.blockData; + } + + public String toString() { + return "Block{" + Block.REGISTRY.c(this) + "}"; + } + + public static void S() { + a(0, Block.a, (new BlockAir()).c("air")); + a(1, "stone", (new BlockStone()).c(1.5F).b(10.0F).a(Block.i).c("stone")); + a(2, "grass", (new BlockGrass()).c(0.6F).a(Block.h).c("grass")); + a(3, "dirt", (new BlockDirt()).c(0.5F).a(Block.g).c("dirt")); + Block block = (new Block(Material.STONE)).c(2.0F).b(10.0F).a(Block.i).c("stonebrick").a(CreativeModeTab.b); + + a(4, "cobblestone", block); + Block block1 = (new BlockWood()).c(2.0F).b(5.0F).a(Block.f).c("wood"); + + a(5, "planks", block1); + a(6, "sapling", (new BlockSapling()).c(0.0F).a(Block.h).c("sapling")); + a(7, "bedrock", (new Block(Material.STONE)).x().b(6000000.0F).a(Block.i).c("bedrock").K().a(CreativeModeTab.b)); + a(8, "flowing_water", (new BlockFlowing(Material.WATER)).c(100.0F).e(3).c("water").K()); + a(9, "water", (new BlockStationary(Material.WATER)).c(100.0F).e(3).c("water").K()); + a(10, "flowing_lava", (new BlockFlowing(Material.LAVA)).c(100.0F).a(1.0F).c("lava").K()); + a(11, "lava", (new BlockStationary(Material.LAVA)).c(100.0F).a(1.0F).c("lava").K()); + a(12, "sand", (new BlockSand()).c(0.5F).a(Block.m).c("sand")); + a(13, "gravel", (new BlockGravel()).c(0.6F).a(Block.g).c("gravel")); + a(14, "gold_ore", (new BlockOre()).c(3.0F).b(5.0F).a(Block.i).c("oreGold")); + a(15, "iron_ore", (new BlockOre()).c(3.0F).b(5.0F).a(Block.i).c("oreIron")); + a(16, "coal_ore", (new BlockOre()).c(3.0F).b(5.0F).a(Block.i).c("oreCoal")); + a(17, "log", (new BlockLog1()).c("log")); + a(18, "leaves", (new BlockLeaves1()).c("leaves")); + a(19, "sponge", (new BlockSponge()).c(0.6F).a(Block.h).c("sponge")); + a(20, "glass", (new BlockGlass(Material.SHATTERABLE, false)).c(0.3F).a(Block.k).c("glass")); + a(21, "lapis_ore", (new BlockOre()).c(3.0F).b(5.0F).a(Block.i).c("oreLapis")); + a(22, "lapis_block", (new Block(Material.ORE, MaterialMapColor.H)).c(3.0F).b(5.0F).a(Block.i).c("blockLapis").a(CreativeModeTab.b)); + a(23, "dispenser", (new BlockDispenser()).c(3.5F).a(Block.i).c("dispenser")); + Block block2 = (new BlockSandStone()).a(Block.i).c(0.8F).c("sandStone"); + + a(24, "sandstone", block2); + a(25, "noteblock", (new BlockNote()).c(0.8F).c("musicBlock")); + a(26, "bed", (new BlockBed()).a(Block.f).c(0.2F).c("bed").K()); + a(27, "golden_rail", (new BlockPoweredRail()).c(0.7F).a(Block.j).c("goldenRail")); + a(28, "detector_rail", (new BlockMinecartDetector()).c(0.7F).a(Block.j).c("detectorRail")); + a(29, "sticky_piston", (new BlockPiston(true)).c("pistonStickyBase")); + a(30, "web", (new BlockWeb()).e(1).c(4.0F).c("web")); + a(31, "tallgrass", (new BlockLongGrass()).c(0.0F).a(Block.h).c("tallgrass")); + a(32, "deadbush", (new BlockDeadBush()).c(0.0F).a(Block.h).c("deadbush")); + a(33, "piston", (new BlockPiston(false)).c("pistonBase")); + a(34, "piston_head", (new BlockPistonExtension()).c("pistonBase")); + a(35, "wool", (new BlockCloth(Material.CLOTH)).c(0.8F).a(Block.l).c("cloth")); + a(36, "piston_extension", new BlockPistonMoving()); + a(37, "yellow_flower", (new BlockYellowFlowers()).c(0.0F).a(Block.h).c("flower1")); + a(38, "red_flower", (new BlockRedFlowers()).c(0.0F).a(Block.h).c("flower2")); + Block block3 = (new BlockMushroom()).c(0.0F).a(Block.h).a(0.125F).c("mushroom"); + + a(39, "brown_mushroom", block3); + Block block4 = (new BlockMushroom()).c(0.0F).a(Block.h).c("mushroom"); + + a(40, "red_mushroom", block4); + a(41, "gold_block", (new Block(Material.ORE, MaterialMapColor.F)).c(3.0F).b(10.0F).a(Block.j).c("blockGold").a(CreativeModeTab.b)); + a(42, "iron_block", (new Block(Material.ORE, MaterialMapColor.h)).c(5.0F).b(10.0F).a(Block.j).c("blockIron").a(CreativeModeTab.b)); + a(43, "double_stone_slab", (new BlockDoubleStep()).c(2.0F).b(10.0F).a(Block.i).c("stoneSlab")); + a(44, "stone_slab", (new BlockStep()).c(2.0F).b(10.0F).a(Block.i).c("stoneSlab")); + Block block5 = (new Block(Material.STONE, MaterialMapColor.D)).c(2.0F).b(10.0F).a(Block.i).c("brick").a(CreativeModeTab.b); + + a(45, "brick_block", block5); + a(46, "tnt", (new BlockTNT()).c(0.0F).a(Block.h).c("tnt")); + a(47, "bookshelf", (new BlockBookshelf()).c(1.5F).a(Block.f).c("bookshelf")); + a(48, "mossy_cobblestone", (new Block(Material.STONE)).c(2.0F).b(10.0F).a(Block.i).c("stoneMoss").a(CreativeModeTab.b)); + a(49, "obsidian", (new BlockObsidian()).c(50.0F).b(2000.0F).a(Block.i).c("obsidian")); + a(50, "torch", (new BlockTorch()).c(0.0F).a(0.9375F).a(Block.f).c("torch")); + a(51, "fire", (new BlockFire()).c(0.0F).a(1.0F).a(Block.l).c("fire").K()); + a(52, "mob_spawner", (new BlockMobSpawner()).c(5.0F).a(Block.j).c("mobSpawner").K()); + a(53, "oak_stairs", (new BlockStairs(block1.getBlockData().set(BlockWood.VARIANT, BlockWood.EnumLogVariant.OAK))).c("stairsWood")); + a(54, "chest", (new BlockChest(0)).c(2.5F).a(Block.f).c("chest")); + a(55, "redstone_wire", (new BlockRedstoneWire()).c(0.0F).a(Block.e).c("redstoneDust").K()); + a(56, "diamond_ore", (new BlockOre()).c(3.0F).b(5.0F).a(Block.i).c("oreDiamond")); + a(57, "diamond_block", (new Block(Material.ORE, MaterialMapColor.G)).c(5.0F).b(10.0F).a(Block.j).c("blockDiamond").a(CreativeModeTab.b)); + a(58, "crafting_table", (new BlockWorkbench()).c(2.5F).a(Block.f).c("workbench")); + a(59, "wheat", (new BlockCrops()).c("crops")); + Block block6 = (new BlockSoil()).c(0.6F).a(Block.g).c("farmland"); + + a(60, "farmland", block6); + a(61, "furnace", (new BlockFurnace(false)).c(3.5F).a(Block.i).c("furnace").a(CreativeModeTab.c)); + a(62, "lit_furnace", (new BlockFurnace(true)).c(3.5F).a(Block.i).a(0.875F).c("furnace")); + a(63, "standing_sign", (new BlockFloorSign()).c(1.0F).a(Block.f).c("sign").K()); + a(64, "wooden_door", (new BlockDoor(Material.WOOD)).c(3.0F).a(Block.f).c("doorOak").K()); + a(65, "ladder", (new BlockLadder()).c(0.4F).a(Block.o).c("ladder")); + a(66, "rail", (new BlockMinecartTrack()).c(0.7F).a(Block.j).c("rail")); + a(67, "stone_stairs", (new BlockStairs(block.getBlockData())).c("stairsStone")); + a(68, "wall_sign", (new BlockWallSign()).c(1.0F).a(Block.f).c("sign").K()); + a(69, "lever", (new BlockLever()).c(0.5F).a(Block.f).c("lever")); + a(70, "stone_pressure_plate", (new BlockPressurePlateBinary(Material.STONE, BlockPressurePlateBinary.EnumMobType.MOBS)).c(0.5F).a(Block.i).c("pressurePlateStone")); + a(71, "iron_door", (new BlockDoor(Material.ORE)).c(5.0F).a(Block.j).c("doorIron").K()); + a(72, "wooden_pressure_plate", (new BlockPressurePlateBinary(Material.WOOD, BlockPressurePlateBinary.EnumMobType.EVERYTHING)).c(0.5F).a(Block.f).c("pressurePlateWood")); + a(73, "redstone_ore", (new BlockRedstoneOre(false)).c(3.0F).b(5.0F).a(Block.i).c("oreRedstone").a(CreativeModeTab.b)); + a(74, "lit_redstone_ore", (new BlockRedstoneOre(true)).a(0.625F).c(3.0F).b(5.0F).a(Block.i).c("oreRedstone")); + a(75, "unlit_redstone_torch", (new BlockRedstoneTorch(false)).c(0.0F).a(Block.f).c("notGate")); + a(76, "redstone_torch", (new BlockRedstoneTorch(true)).c(0.0F).a(0.5F).a(Block.f).c("notGate").a(CreativeModeTab.d)); + a(77, "stone_button", (new BlockStoneButton()).c(0.5F).a(Block.i).c("button")); + a(78, "snow_layer", (new BlockSnow()).c(0.1F).a(Block.n).c("snow").e(0)); + a(79, "ice", (new BlockIce()).c(0.5F).e(3).a(Block.k).c("ice")); + a(80, "snow", (new BlockSnowBlock()).c(0.2F).a(Block.n).c("snow")); + a(81, "cactus", (new BlockCactus()).c(0.4F).a(Block.l).c("cactus")); + a(82, "clay", (new BlockClay()).c(0.6F).a(Block.g).c("clay")); + a(83, "reeds", (new BlockReed()).c(0.0F).a(Block.h).c("reeds").K()); + a(84, "jukebox", (new BlockJukeBox()).c(2.0F).b(10.0F).a(Block.i).c("jukebox")); + a(85, "fence", (new BlockFence(Material.WOOD, BlockWood.EnumLogVariant.OAK.c())).c(2.0F).b(5.0F).a(Block.f).c("fence")); + Block block7 = (new BlockPumpkin()).c(1.0F).a(Block.f).c("pumpkin"); + + a(86, "pumpkin", block7); + a(87, "netherrack", (new BlockBloodStone()).c(0.4F).a(Block.i).c("hellrock")); + a(88, "soul_sand", (new BlockSlowSand()).c(0.5F).a(Block.m).c("hellsand")); + a(89, "glowstone", (new BlockLightStone(Material.SHATTERABLE)).c(0.3F).a(Block.k).a(1.0F).c("lightgem")); + a(90, "portal", (new BlockPortal()).c(-1.0F).a(Block.k).a(0.75F).c("portal")); + a(91, "lit_pumpkin", (new BlockPumpkin()).c(1.0F).a(Block.f).a(1.0F).c("litpumpkin")); + a(92, "cake", (new BlockCake()).c(0.5F).a(Block.l).c("cake").K()); + a(93, "unpowered_repeater", (new BlockRepeater(false)).c(0.0F).a(Block.f).c("diode").K()); + a(94, "powered_repeater", (new BlockRepeater(true)).c(0.0F).a(Block.f).c("diode").K()); + a(95, "stained_glass", (new BlockStainedGlass(Material.SHATTERABLE)).c(0.3F).a(Block.k).c("stainedGlass")); + a(96, "trapdoor", (new BlockTrapdoor(Material.WOOD)).c(3.0F).a(Block.f).c("trapdoor").K()); + a(97, "monster_egg", (new BlockMonsterEggs()).c(0.75F).c("monsterStoneEgg")); + Block block8 = (new BlockSmoothBrick()).c(1.5F).b(10.0F).a(Block.i).c("stonebricksmooth"); + + a(98, "stonebrick", block8); + a(99, "brown_mushroom_block", (new BlockHugeMushroom(Material.WOOD, MaterialMapColor.l, block3)).c(0.2F).a(Block.f).c("mushroom")); + a(100, "red_mushroom_block", (new BlockHugeMushroom(Material.WOOD, MaterialMapColor.D, block4)).c(0.2F).a(Block.f).c("mushroom")); + a(101, "iron_bars", (new BlockThin(Material.ORE, true)).c(5.0F).b(10.0F).a(Block.j).c("fenceIron")); + a(102, "glass_pane", (new BlockThin(Material.SHATTERABLE, false)).c(0.3F).a(Block.k).c("thinGlass")); + Block block9 = (new BlockMelon()).c(1.0F).a(Block.f).c("melon"); + + a(103, "melon_block", block9); + a(104, "pumpkin_stem", (new BlockStem(block7)).c(0.0F).a(Block.f).c("pumpkinStem")); + a(105, "melon_stem", (new BlockStem(block9)).c(0.0F).a(Block.f).c("pumpkinStem")); + a(106, "vine", (new BlockVine()).c(0.2F).a(Block.h).c("vine")); + a(107, "fence_gate", (new BlockFenceGate(BlockWood.EnumLogVariant.OAK)).c(2.0F).b(5.0F).a(Block.f).c("fenceGate")); + a(108, "brick_stairs", (new BlockStairs(block5.getBlockData())).c("stairsBrick")); + a(109, "stone_brick_stairs", (new BlockStairs(block8.getBlockData().set(BlockSmoothBrick.VARIANT, BlockSmoothBrick.EnumStonebrickType.DEFAULT))).c("stairsStoneBrickSmooth")); + a(110, "mycelium", (new BlockMycel()).c(0.6F).a(Block.h).c("mycel")); + a(111, "waterlily", (new BlockWaterLily()).c(0.0F).a(Block.h).c("waterlily")); + Block block10 = (new BlockNetherbrick()).c(2.0F).b(10.0F).a(Block.i).c("netherBrick").a(CreativeModeTab.b); + + a(112, "nether_brick", block10); + a(113, "nether_brick_fence", (new BlockFence(Material.STONE, MaterialMapColor.K)).c(2.0F).b(10.0F).a(Block.i).c("netherFence")); + a(114, "nether_brick_stairs", (new BlockStairs(block10.getBlockData())).c("stairsNetherBrick")); + a(115, "nether_wart", (new BlockNetherWart()).c("netherStalk")); + a(116, "enchanting_table", (new BlockEnchantmentTable()).c(5.0F).b(2000.0F).c("enchantmentTable")); + a(117, "brewing_stand", (new BlockBrewingStand()).c(0.5F).a(0.125F).c("brewingStand")); + a(118, "cauldron", (new BlockCauldron()).c(2.0F).c("cauldron")); + a(119, "end_portal", (new BlockEnderPortal(Material.PORTAL)).c(-1.0F).b(6000000.0F)); + a(120, "end_portal_frame", (new BlockEnderPortalFrame()).a(Block.k).a(0.125F).c(-1.0F).c("endPortalFrame").b(6000000.0F).a(CreativeModeTab.c)); + a(121, "end_stone", (new Block(Material.STONE, MaterialMapColor.d)).c(3.0F).b(15.0F).a(Block.i).c("whiteStone").a(CreativeModeTab.b)); + a(122, "dragon_egg", (new BlockDragonEgg()).c(3.0F).b(15.0F).a(Block.i).a(0.125F).c("dragonEgg")); + a(123, "redstone_lamp", (new BlockRedstoneLamp(false)).c(0.3F).a(Block.k).c("redstoneLight").a(CreativeModeTab.d)); + a(124, "lit_redstone_lamp", (new BlockRedstoneLamp(true)).c(0.3F).a(Block.k).c("redstoneLight")); + a(125, "double_wooden_slab", (new BlockDoubleWoodStep()).c(2.0F).b(5.0F).a(Block.f).c("woodSlab")); + a(126, "wooden_slab", (new BlockWoodStep()).c(2.0F).b(5.0F).a(Block.f).c("woodSlab")); + a(127, "cocoa", (new BlockCocoa()).c(0.2F).b(5.0F).a(Block.f).c("cocoa")); + a(128, "sandstone_stairs", (new BlockStairs(block2.getBlockData().set(BlockSandStone.TYPE, BlockSandStone.EnumSandstoneVariant.SMOOTH))).c("stairsSandStone")); + a(129, "emerald_ore", (new BlockOre()).c(3.0F).b(5.0F).a(Block.i).c("oreEmerald")); + a(130, "ender_chest", (new BlockEnderChest()).c(22.5F).b(1000.0F).a(Block.i).c("enderChest").a(0.5F)); + a(131, "tripwire_hook", (new BlockTripwireHook()).c("tripWireSource")); + a(132, "tripwire", (new BlockTripwire()).c("tripWire")); + a(133, "emerald_block", (new Block(Material.ORE, MaterialMapColor.I)).c(5.0F).b(10.0F).a(Block.j).c("blockEmerald").a(CreativeModeTab.b)); + a(134, "spruce_stairs", (new BlockStairs(block1.getBlockData().set(BlockWood.VARIANT, BlockWood.EnumLogVariant.SPRUCE))).c("stairsWoodSpruce")); + a(135, "birch_stairs", (new BlockStairs(block1.getBlockData().set(BlockWood.VARIANT, BlockWood.EnumLogVariant.BIRCH))).c("stairsWoodBirch")); + a(136, "jungle_stairs", (new BlockStairs(block1.getBlockData().set(BlockWood.VARIANT, BlockWood.EnumLogVariant.JUNGLE))).c("stairsWoodJungle")); + a(137, "command_block", (new BlockCommand()).x().b(6000000.0F).c("commandBlock")); + a(138, "beacon", (new BlockBeacon()).c("beacon").a(1.0F)); + a(139, "cobblestone_wall", (new BlockCobbleWall(block)).c("cobbleWall")); + a(140, "flower_pot", (new BlockFlowerPot()).c(0.0F).a(Block.e).c("flowerPot")); + a(141, "carrots", (new BlockCarrots()).c("carrots")); + a(142, "potatoes", (new BlockPotatoes()).c("potatoes")); + a(143, "wooden_button", (new BlockWoodButton()).c(0.5F).a(Block.f).c("button")); + a(144, "skull", (new BlockSkull()).c(1.0F).a(Block.i).c("skull")); + a(145, "anvil", (new BlockAnvil()).c(5.0F).a(Block.p).b(2000.0F).c("anvil")); + a(146, "trapped_chest", (new BlockChest(1)).c(2.5F).a(Block.f).c("chestTrap")); + a(147, "light_weighted_pressure_plate", (new BlockPressurePlateWeighted(Material.ORE, 15, MaterialMapColor.F)).c(0.5F).a(Block.f).c("weightedPlate_light")); + a(148, "heavy_weighted_pressure_plate", (new BlockPressurePlateWeighted(Material.ORE, 150)).c(0.5F).a(Block.f).c("weightedPlate_heavy")); + a(149, "unpowered_comparator", (new BlockRedstoneComparator(false)).c(0.0F).a(Block.f).c("comparator").K()); + a(150, "powered_comparator", (new BlockRedstoneComparator(true)).c(0.0F).a(0.625F).a(Block.f).c("comparator").K()); + a(151, "daylight_detector", new BlockDaylightDetector(false)); + a(152, "redstone_block", (new BlockPowered(Material.ORE, MaterialMapColor.f)).c(5.0F).b(10.0F).a(Block.j).c("blockRedstone").a(CreativeModeTab.d)); + a(153, "quartz_ore", (new BlockOre(MaterialMapColor.K)).c(3.0F).b(5.0F).a(Block.i).c("netherquartz")); + a(154, "hopper", (new BlockHopper()).c(3.0F).b(8.0F).a(Block.j).c("hopper")); + Block block11 = (new BlockQuartz()).a(Block.i).c(0.8F).c("quartzBlock"); + + a(155, "quartz_block", block11); + a(156, "quartz_stairs", (new BlockStairs(block11.getBlockData().set(BlockQuartz.VARIANT, BlockQuartz.EnumQuartzVariant.DEFAULT))).c("stairsQuartz")); + a(157, "activator_rail", (new BlockPoweredRail()).c(0.7F).a(Block.j).c("activatorRail")); + a(158, "dropper", (new BlockDropper()).c(3.5F).a(Block.i).c("dropper")); + a(159, "stained_hardened_clay", (new BlockCloth(Material.STONE)).c(1.25F).b(7.0F).a(Block.i).c("clayHardenedStained")); + a(160, "stained_glass_pane", (new BlockStainedGlassPane()).c(0.3F).a(Block.k).c("thinStainedGlass")); + a(161, "leaves2", (new BlockLeaves2()).c("leaves")); + a(162, "log2", (new BlockLog2()).c("log")); + a(163, "acacia_stairs", (new BlockStairs(block1.getBlockData().set(BlockWood.VARIANT, BlockWood.EnumLogVariant.ACACIA))).c("stairsWoodAcacia")); + a(164, "dark_oak_stairs", (new BlockStairs(block1.getBlockData().set(BlockWood.VARIANT, BlockWood.EnumLogVariant.DARK_OAK))).c("stairsWoodDarkOak")); + a(165, "slime", (new BlockSlime()).c("slime").a(Block.q)); + a(166, "barrier", (new BlockBarrier()).c("barrier")); + a(167, "iron_trapdoor", (new BlockTrapdoor(Material.ORE)).c(5.0F).a(Block.j).c("ironTrapdoor").K()); + a(168, "prismarine", (new BlockPrismarine()).c(1.5F).b(10.0F).a(Block.i).c("prismarine")); + a(169, "sea_lantern", (new BlockSeaLantern(Material.SHATTERABLE)).c(0.3F).a(Block.k).a(1.0F).c("seaLantern")); + a(170, "hay_block", (new BlockHay()).c(0.5F).a(Block.h).c("hayBlock").a(CreativeModeTab.b)); + a(171, "carpet", (new BlockCarpet()).c(0.1F).a(Block.l).c("woolCarpet").e(0)); + a(172, "hardened_clay", (new BlockHardenedClay()).c(1.25F).b(7.0F).a(Block.i).c("clayHardened")); + a(173, "coal_block", (new Block(Material.STONE, MaterialMapColor.E)).c(5.0F).b(10.0F).a(Block.i).c("blockCoal").a(CreativeModeTab.b)); + a(174, "packed_ice", (new BlockPackedIce()).c(0.5F).a(Block.k).c("icePacked")); + a(175, "double_plant", new BlockTallPlant()); + a(176, "standing_banner", (new BlockBanner.BlockStandingBanner()).c(1.0F).a(Block.f).c("banner").K()); + a(177, "wall_banner", (new BlockBanner.BlockWallBanner()).c(1.0F).a(Block.f).c("banner").K()); + a(178, "daylight_detector_inverted", new BlockDaylightDetector(true)); + Block block12 = (new BlockRedSandstone()).a(Block.i).c(0.8F).c("redSandStone"); + + a(179, "red_sandstone", block12); + a(180, "red_sandstone_stairs", (new BlockStairs(block12.getBlockData().set(BlockRedSandstone.TYPE, BlockRedSandstone.EnumRedSandstoneVariant.SMOOTH))).c("stairsRedSandStone")); + a(181, "double_stone_slab2", (new BlockDoubleStoneStep2()).c(2.0F).b(10.0F).a(Block.i).c("stoneSlab2")); + a(182, "stone_slab2", (new BlockStoneStep2()).c(2.0F).b(10.0F).a(Block.i).c("stoneSlab2")); + a(183, "spruce_fence_gate", (new BlockFenceGate(BlockWood.EnumLogVariant.SPRUCE)).c(2.0F).b(5.0F).a(Block.f).c("spruceFenceGate")); + a(184, "birch_fence_gate", (new BlockFenceGate(BlockWood.EnumLogVariant.BIRCH)).c(2.0F).b(5.0F).a(Block.f).c("birchFenceGate")); + a(185, "jungle_fence_gate", (new BlockFenceGate(BlockWood.EnumLogVariant.JUNGLE)).c(2.0F).b(5.0F).a(Block.f).c("jungleFenceGate")); + a(186, "dark_oak_fence_gate", (new BlockFenceGate(BlockWood.EnumLogVariant.DARK_OAK)).c(2.0F).b(5.0F).a(Block.f).c("darkOakFenceGate")); + a(187, "acacia_fence_gate", (new BlockFenceGate(BlockWood.EnumLogVariant.ACACIA)).c(2.0F).b(5.0F).a(Block.f).c("acaciaFenceGate")); + a(188, "spruce_fence", (new BlockFence(Material.WOOD, BlockWood.EnumLogVariant.SPRUCE.c())).c(2.0F).b(5.0F).a(Block.f).c("spruceFence")); + a(189, "birch_fence", (new BlockFence(Material.WOOD, BlockWood.EnumLogVariant.BIRCH.c())).c(2.0F).b(5.0F).a(Block.f).c("birchFence")); + a(190, "jungle_fence", (new BlockFence(Material.WOOD, BlockWood.EnumLogVariant.JUNGLE.c())).c(2.0F).b(5.0F).a(Block.f).c("jungleFence")); + a(191, "dark_oak_fence", (new BlockFence(Material.WOOD, BlockWood.EnumLogVariant.DARK_OAK.c())).c(2.0F).b(5.0F).a(Block.f).c("darkOakFence")); + a(192, "acacia_fence", (new BlockFence(Material.WOOD, BlockWood.EnumLogVariant.ACACIA.c())).c(2.0F).b(5.0F).a(Block.f).c("acaciaFence")); + a(193, "spruce_door", (new BlockDoor(Material.WOOD)).c(3.0F).a(Block.f).c("doorSpruce").K()); + a(194, "birch_door", (new BlockDoor(Material.WOOD)).c(3.0F).a(Block.f).c("doorBirch").K()); + a(195, "jungle_door", (new BlockDoor(Material.WOOD)).c(3.0F).a(Block.f).c("doorJungle").K()); + a(196, "acacia_door", (new BlockDoor(Material.WOOD)).c(3.0F).a(Block.f).c("doorAcacia").K()); + a(197, "dark_oak_door", (new BlockDoor(Material.WOOD)).c(3.0F).a(Block.f).c("doorDarkOak").K()); + Block.REGISTRY.a(); + Iterator iterator = Block.REGISTRY.iterator(); + + Block block13; + + while (iterator.hasNext()) { + block13 = (Block) iterator.next(); + if (block13.material == Material.AIR) { + block13.v = false; + } else { + boolean flag = false; + boolean flag1 = block13 instanceof BlockStairs; + boolean flag2 = block13 instanceof BlockStepAbstract; + boolean flag3 = block13 == block6; + boolean flag4 = block13.t; + boolean flag5 = block13.s == 0; + + if (flag1 || flag2 || flag3 || flag4 || flag5) { + flag = true; + } + + block13.v = flag; + } + } + + iterator = Block.REGISTRY.iterator(); + + while (iterator.hasNext()) { + block13 = (Block) iterator.next(); + Iterator iterator1 = block13.P().a().iterator(); + + while (iterator1.hasNext()) { + IBlockData iblockdata = (IBlockData) iterator1.next(); + int i = Block.REGISTRY.b(block13) << 4 | block13.toLegacyData(iblockdata); + // TacoSpigot start + + Block.d.a(iblockdata, i); + } + } + + } + + private static void a(int i, MinecraftKey minecraftkey, Block block) { + Block.REGISTRY.a(i, minecraftkey, block); + } + + private static void a(int i, String s, Block block) { + a(i, new MinecraftKey(s), block); + } + + public static class StepSound { + + public final String a; + public final float b; + public final float c; + + public StepSound(String s, float f, float f1) { + this.a = s; + this.b = f; + this.c = f1; + } + + public float getVolume1() { + return this.b; + } + + public float getVolume2() { + return this.c; + } + + public String getBreakSound() { + return "dig." + this.a; + } + + public String getStepSound() { + return "step." + this.a; + } + + public String getPlaceSound() { + return this.getBreakSound(); + } + } + + // CraftBukkit start + public int getExpDrop(World world, IBlockData data, int enchantmentLevel) { + return 0; + } + // CraftBukkit end + + // Spigot start + public static float range(float min, float value, float max) { + if (value < min) { + return min; + } + if (value > max) { + return max; + } + return value; + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockAnvil.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockAnvil.java new file mode 100644 index 0000000..43b1d00 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockAnvil.java @@ -0,0 +1,108 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; + +public class BlockAnvil extends BlockFalling { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirection.EnumDirectionLimit.HORIZONTAL); + public static final BlockStateInteger DAMAGE = BlockStateInteger.of("damage", 0, 2); + + protected BlockAnvil() { + super(Material.HEAVY); + this.j(this.blockStateList.getBlockData().set(BlockAnvil.FACING, EnumDirection.NORTH).set(BlockAnvil.DAMAGE, Integer.valueOf(0))); + this.e(0); + this.a(CreativeModeTab.c); + } + + public boolean d() { + return false; + } + + public boolean c() { + return false; + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + EnumDirection enumdirection1 = entityliving.getDirection().e(); + + return super.getPlacedState(world, blockposition, enumdirection, f, f1, f2, i, entityliving).set(BlockAnvil.FACING, enumdirection1).set(BlockAnvil.DAMAGE, Integer.valueOf(i >> 2)); + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (!world.isClientSide) { + entityhuman.openTileEntity(new BlockAnvil.TileEntityContainerAnvil(world, blockposition)); + } + + return true; + } + + public int getDropData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockAnvil.DAMAGE)).intValue(); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + EnumDirection enumdirection = (EnumDirection) iblockaccess.getType(blockposition).get(BlockAnvil.FACING); + + if (enumdirection.k() == EnumDirection.EnumAxis.X) { + this.a(0.0F, 0.0F, 0.125F, 1.0F, 1.0F, 0.875F); + } else { + this.a(0.125F, 0.0F, 0.0F, 0.875F, 1.0F, 1.0F); + } + + } + + protected void a(EntityFallingBlock entityfallingblock) { + entityfallingblock.a(true); + } + + public void a_(World world, BlockPosition blockposition) { + world.triggerEffect(1022, blockposition, 0); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockAnvil.FACING, EnumDirection.fromType2(i & 3)).set(BlockAnvil.DAMAGE, Integer.valueOf((i & 15) >> 2)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((EnumDirection) iblockdata.get(BlockAnvil.FACING)).b(); + + i |= ((Integer) iblockdata.get(BlockAnvil.DAMAGE)).intValue() << 2; + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockAnvil.FACING, BlockAnvil.DAMAGE}); + } + + public static class TileEntityContainerAnvil implements ITileEntityContainer { + + private final World a; + private final BlockPosition b; + + public TileEntityContainerAnvil(World world, BlockPosition blockposition) { + this.a = world; + this.b = blockposition; + } + + public String getName() { + return "anvil"; + } + + public boolean hasCustomName() { + return false; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return new ChatMessage(Blocks.ANVIL.a() + ".name", new Object[0]); + } + + public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerAnvil(playerinventory, this.a, this.b, entityhuman); + } + + public String getContainerName() { + return "minecraft:anvil"; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockBloodStone.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockBloodStone.java new file mode 100644 index 0000000..0158497 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockBloodStone.java @@ -0,0 +1,28 @@ +package net.minecraft.server; + +import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + +public class BlockBloodStone extends Block { + + public BlockBloodStone() { + super(Material.STONE); + this.a(CreativeModeTab.b); + } + + public MaterialMapColor g(IBlockData iblockdata) { + return MaterialMapColor.K; + } + + // CraftBukkit start + //@Override // PaperSpigot - Remove completely invalid Redstone event for Netherrack + public void doPhysics_nvmplsdont(World world, BlockPosition position, IBlockData iblockdata, Block block) { + if (block != null && block.isPowerSource()) { + org.bukkit.block.Block bl = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()); + int power = bl.getBlockPower(); + + BlockRedstoneEvent event = new BlockRedstoneEvent(bl, power, power); + world.getServer().getPluginManager().callEvent(event); + } + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockBrewingStand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockBrewingStand.java new file mode 100644 index 0000000..0bb2b50 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockBrewingStand.java @@ -0,0 +1,119 @@ +package net.minecraft.server; + +import java.util.List; +import java.util.Random; + +public class BlockBrewingStand extends BlockContainer { + + public static final BlockStateBoolean[] HAS_BOTTLE = new BlockStateBoolean[] { BlockStateBoolean.of("has_bottle_0"), BlockStateBoolean.of("has_bottle_1"), BlockStateBoolean.of("has_bottle_2")}; + + public BlockBrewingStand() { + super(Material.ORE); + this.j(this.blockStateList.getBlockData().set(BlockBrewingStand.HAS_BOTTLE[0], Boolean.valueOf(false)).set(BlockBrewingStand.HAS_BOTTLE[1], Boolean.valueOf(false)).set(BlockBrewingStand.HAS_BOTTLE[2], Boolean.valueOf(false))); + } + + public String getName() { + return LocaleI18n.get("item.brewingStand.name"); + } + + public boolean c() { + return false; + } + + public int b() { + return 3; + } + + public TileEntity a(World world, int i) { + return new TileEntityBrewingStand(); + } + + public boolean d() { + return false; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, AxisAlignedBB axisalignedbb, List list, Entity entity) { + this.a(0.4375F, 0.0F, 0.4375F, 0.5625F, 0.875F, 0.5625F); + super.a(world, blockposition, iblockdata, axisalignedbb, list, entity); + this.j(); + super.a(world, blockposition, iblockdata, axisalignedbb, list, entity); + } + + public void j() { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (world.isClientSide) { + return true; + } else { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityBrewingStand) { + entityhuman.openContainer((TileEntityBrewingStand) tileentity); + entityhuman.b(StatisticList.M); + } + + return true; + } + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + if (itemstack.hasName()) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityBrewingStand) { + ((TileEntityBrewingStand) tileentity).a(itemstack.getName()); + } + } + + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityBrewingStand) { + InventoryUtils.dropInventory(world, blockposition, (TileEntityBrewingStand) tileentity); + } + + super.remove(world, blockposition, iblockdata); + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Items.BREWING_STAND; + } + + public boolean isComplexRedstone() { + return true; + } + + public int l(World world, BlockPosition blockposition) { + return Container.a(world.getTileEntity(blockposition)); + } + + public IBlockData fromLegacyData(int i) { + IBlockData iblockdata = this.getBlockData(); + + for (int j = 0; j < 3; ++j) { + iblockdata = iblockdata.set(BlockBrewingStand.HAS_BOTTLE[j], Boolean.valueOf((i & 1 << j) > 0)); + } + + return iblockdata; + } + + public int toLegacyData(IBlockData iblockdata) { + int i = 0; + + for (int j = 0; j < 3; ++j) { + if (((Boolean) iblockdata.get(BlockBrewingStand.HAS_BOTTLE[j])).booleanValue()) { + i |= 1 << j; + } + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockBrewingStand.HAS_BOTTLE[0], BlockBrewingStand.HAS_BOTTLE[1], BlockBrewingStand.HAS_BOTTLE[2]}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockButtonAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockButtonAbstract.java new file mode 100644 index 0000000..0cccb53 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockButtonAbstract.java @@ -0,0 +1,410 @@ +package net.minecraft.server; + +import java.util.List; +import java.util.Random; + +// CraftBukkit start +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.entity.EntityInteractEvent; +// CraftBukkit end + +public abstract class BlockButtonAbstract extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing"); + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); + private final boolean N; + + protected BlockButtonAbstract(boolean flag) { + super(Material.ORIENTABLE); + this.j(this.blockStateList.getBlockData().set(BlockButtonAbstract.FACING, EnumDirection.NORTH).set(BlockButtonAbstract.POWERED, Boolean.valueOf(false))); + this.a(true); + this.a(CreativeModeTab.d); + this.N = flag; + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public int a(World world) { + return this.N ? 30 : 20; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public boolean canPlace(World world, BlockPosition blockposition, EnumDirection enumdirection) { + return a(world, blockposition, enumdirection.opposite()); + } + + public boolean canPlace(World world, BlockPosition blockposition) { + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + if (a(world, blockposition, enumdirection)) { + return true; + } + } + + return false; + } + + protected static boolean a(World world, BlockPosition blockposition, EnumDirection enumdirection) { + BlockPosition blockposition1 = blockposition.shift(enumdirection); + + return enumdirection == EnumDirection.DOWN ? World.a((IBlockAccess) world, blockposition1) : world.getType(blockposition1).getBlock().isOccluding(); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return a(world, blockposition, enumdirection.opposite()) ? this.getBlockData().set(BlockButtonAbstract.FACING, enumdirection).set(BlockButtonAbstract.POWERED, Boolean.valueOf(false)) : this.getBlockData().set(BlockButtonAbstract.FACING, EnumDirection.DOWN).set(BlockButtonAbstract.POWERED, Boolean.valueOf(false)); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (this.e(world, blockposition, iblockdata) && !a(world, blockposition, ((EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)).opposite())) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + + } + + private boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (this.canPlace(world, blockposition)) { + return true; + } else { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + return false; + } + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + this.d(iblockaccess.getType(blockposition)); + } + + private void d(IBlockData iblockdata) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING); + boolean flag = ((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue(); + float f = 0.25F; + float f1 = 0.375F; + float f2 = (float) (flag ? 1 : 2) / 16.0F; + float f3 = 0.125F; + float f4 = 0.1875F; + + switch (BlockButtonAbstract.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + this.a(0.0F, 0.375F, 0.3125F, f2, 0.625F, 0.6875F); + break; + + case 2: + this.a(1.0F - f2, 0.375F, 0.3125F, 1.0F, 0.625F, 0.6875F); + break; + + case 3: + this.a(0.3125F, 0.375F, 0.0F, 0.6875F, 0.625F, f2); + break; + + case 4: + this.a(0.3125F, 0.375F, 1.0F - f2, 0.6875F, 0.625F, 1.0F); + break; + + case 5: + this.a(0.3125F, 0.0F, 0.375F, 0.6875F, 0.0F + f2, 0.625F); + break; + + case 6: + this.a(0.3125F, 1.0F - f2, 0.375F, 0.6875F, 1.0F, 0.625F); + } + + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue()) { + return true; + } else { + // CraftBukkit start + boolean powered = ((Boolean) iblockdata.get(POWERED)); + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + int old = (powered) ? 15 : 0; + int current = (!powered) ? 15 : 0; + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); + world.getServer().getPluginManager().callEvent(eventRedstone); + + if ((eventRedstone.getNewCurrent() > 0) != (!powered)) { + return true; + } + // CraftBukkit end + world.setTypeAndData(blockposition, iblockdata.set(BlockButtonAbstract.POWERED, Boolean.valueOf(true)), 3); + world.b(blockposition, blockposition); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, 0.6F); + this.c(world, blockposition, (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)); + world.a(blockposition, (Block) this, this.a(world)); + return true; + } + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue()) { + this.c(world, blockposition, (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)); + } + + super.remove(world, blockposition, iblockdata); + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return ((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue() ? 15 : 0; + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return !((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue() ? 0 : (iblockdata.get(BlockButtonAbstract.FACING) == enumdirection ? 15 : 0); + } + + public boolean isPowerSource() { + return true; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {} + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue()) { + if (this.N) { + this.f(world, blockposition, iblockdata); + } else { + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); + world.getServer().getPluginManager().callEvent(eventRedstone); + + if (eventRedstone.getNewCurrent() > 0) { + return; + } + // CraftBukkit end + world.setTypeUpdate(blockposition, iblockdata.set(BlockButtonAbstract.POWERED, Boolean.valueOf(false))); + this.c(world, blockposition, (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, 0.5F); + world.b(blockposition, blockposition); + } + + } + } + } + + public void j() { + float f = 0.1875F; + float f1 = 0.125F; + float f2 = 0.125F; + + this.a(0.5F - f, 0.5F - f1, 0.5F - f2, 0.5F + f, 0.5F + f1, 0.5F + f2); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (!world.isClientSide) { + if (this.N) { + if (!((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue()) { + this.f(world, blockposition, iblockdata); + } + } + } + } + + private void f(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.d(iblockdata); + List list = world.a(EntityArrow.class, new AxisAlignedBB((double) blockposition.getX() + this.minX, (double) blockposition.getY() + this.minY, (double) blockposition.getZ() + this.minZ, (double) blockposition.getX() + this.maxX, (double) blockposition.getY() + this.maxY, (double) blockposition.getZ() + this.maxZ)); + boolean flag = !list.isEmpty(); + boolean flag1 = ((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue(); + + // CraftBukkit start - Call interact event when arrows turn on wooden buttons + if (flag1 != flag && flag) { + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + boolean allowed = false; + + // If all of the events are cancelled block the button press, else allow + for (Object object : list) { + if (object != null) { + EntityInteractEvent event = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block); + world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + allowed = true; + break; + } + } + } + + if (!allowed) { + return; + } + } + // CraftBukkit end + + if (flag && !flag1) { + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 0, 15); + world.getServer().getPluginManager().callEvent(eventRedstone); + + if (eventRedstone.getNewCurrent() <= 0) { + return; + } + // CraftBukkit end + world.setTypeUpdate(blockposition, iblockdata.set(BlockButtonAbstract.POWERED, Boolean.valueOf(true))); + this.c(world, blockposition, (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)); + world.b(blockposition, blockposition); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, 0.6F); + } + + if (!flag && flag1) { + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); + world.getServer().getPluginManager().callEvent(eventRedstone); + + if (eventRedstone.getNewCurrent() > 0) { + return; + } + // CraftBukkit end + world.setTypeUpdate(blockposition, iblockdata.set(BlockButtonAbstract.POWERED, Boolean.valueOf(false))); + this.c(world, blockposition, (EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)); + world.b(blockposition, blockposition); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, 0.5F); + } + + if (flag) { + world.a(blockposition, (Block) this, this.a(world)); + } + + } + + private void c(World world, BlockPosition blockposition, EnumDirection enumdirection) { + world.applyPhysics(blockposition, this); + world.applyPhysics(blockposition.shift(enumdirection.opposite()), this); + } + + public IBlockData fromLegacyData(int i) { + EnumDirection enumdirection; + + switch (i & 7) { + case 0: + enumdirection = EnumDirection.DOWN; + break; + + case 1: + enumdirection = EnumDirection.EAST; + break; + + case 2: + enumdirection = EnumDirection.WEST; + break; + + case 3: + enumdirection = EnumDirection.SOUTH; + break; + + case 4: + enumdirection = EnumDirection.NORTH; + break; + + case 5: + default: + enumdirection = EnumDirection.UP; + } + + return this.getBlockData().set(BlockButtonAbstract.FACING, enumdirection).set(BlockButtonAbstract.POWERED, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + int i; + + switch (BlockButtonAbstract.SyntheticClass_1.a[((EnumDirection) iblockdata.get(BlockButtonAbstract.FACING)).ordinal()]) { + case 1: + i = 1; + break; + + case 2: + i = 2; + break; + + case 3: + i = 3; + break; + + case 4: + i = 4; + break; + + case 5: + default: + i = 5; + break; + + case 6: + i = 0; + } + + if (((Boolean) iblockdata.get(BlockButtonAbstract.POWERED)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockButtonAbstract.FACING, BlockButtonAbstract.POWERED}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + BlockButtonAbstract.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockButtonAbstract.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockButtonAbstract.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockButtonAbstract.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockButtonAbstract.SyntheticClass_1.a[EnumDirection.UP.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + try { + BlockButtonAbstract.SyntheticClass_1.a[EnumDirection.DOWN.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror5) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCactus.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCactus.java new file mode 100644 index 0000000..ddc2135 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCactus.java @@ -0,0 +1,105 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Random; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class BlockCactus extends Block { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 15); + + protected BlockCactus() { + super(Material.CACTUS); + this.j(this.blockStateList.getBlockData().set(BlockCactus.AGE, Integer.valueOf(0))); + this.a(true); + this.a(CreativeModeTab.c); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + BlockPosition blockposition1 = blockposition.up(); + + if (world.isEmpty(blockposition1)) { + int i; + + for (i = 1; world.getType(blockposition.down(i)).getBlock() == this; ++i) { + ; + } + + if (i < world.paperSpigotConfig.cactusMaxHeight) { // PaperSpigot - Configurable max growth height for cactus blocks) { + int j = ((Integer) iblockdata.get(BlockCactus.AGE)).intValue(); + + if (j >= (byte) range(3, (world.growthOdds / world.spigotConfig.cactusModifier * 15) + 0.5F, 15)) { // Spigot + // world.setTypeUpdate(blockposition1, this.getBlockData()); // CraftBukkit + IBlockData iblockdata1 = iblockdata.set(BlockCactus.AGE, Integer.valueOf(0)); + + CraftEventFactory.handleBlockGrowEvent(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), this, 0); // CraftBukkit + world.setTypeAndData(blockposition, iblockdata1, 4); + this.doPhysics(world, blockposition1, iblockdata1, this); + } else { + world.setTypeAndData(blockposition, iblockdata.set(BlockCactus.AGE, Integer.valueOf(j + 1)), 4); + } + + } + } + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + float f = 0.0625F; + + return new AxisAlignedBB((double) ((float) blockposition.getX() + f), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + f), (double) ((float) (blockposition.getX() + 1) - f), (double) ((float) (blockposition.getY() + 1) - f), (double) ((float) (blockposition.getZ() + 1) - f)); + } + + public boolean d() { + return false; + } + + public boolean c() { + return false; + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return super.canPlace(world, blockposition) ? this.e(world, blockposition) : false; + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!this.e(world, blockposition)) { + world.setAir(blockposition, true); + } + + } + + public boolean e(World world, BlockPosition blockposition) { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + + if (world.getType(blockposition.shift(enumdirection)).getBlock().getMaterial().isBuildable()) { + return false; + } + } + + Block block = world.getType(blockposition.down()).getBlock(); + + return block == Blocks.CACTUS || block == Blocks.SAND; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + CraftEventFactory.blockDamage = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); // CraftBukkit + entity.damageEntity(DamageSource.CACTUS, 1.0F); + CraftEventFactory.blockDamage = null; // CraftBukkit + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockCactus.AGE, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockCactus.AGE)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockCactus.AGE}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCake.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCake.java new file mode 100644 index 0000000..11a7eaf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCake.java @@ -0,0 +1,123 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockCake extends Block { + + public static final BlockStateInteger BITES = BlockStateInteger.of("bites", 0, 6); + + protected BlockCake() { + super(Material.CAKE); + this.j(this.blockStateList.getBlockData().set(BlockCake.BITES, Integer.valueOf(0))); + this.a(true); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + float f = 0.0625F; + float f1 = (float) (1 + ((Integer) iblockaccess.getType(blockposition).get(BlockCake.BITES)).intValue() * 2) / 16.0F; + float f2 = 0.5F; + + this.a(f1, 0.0F, f, 1.0F - f, f2, 1.0F - f); + } + + public void j() { + float f = 0.0625F; + float f1 = 0.5F; + + this.a(f, 0.0F, f, 1.0F - f, f1, 1.0F - f); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + float f = 0.0625F; + float f1 = (float) (1 + ((Integer) iblockdata.get(BlockCake.BITES)).intValue() * 2) / 16.0F; + float f2 = 0.5F; + + return new AxisAlignedBB((double) ((float) blockposition.getX() + f1), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + f), (double) ((float) (blockposition.getX() + 1) - f), (double) ((float) blockposition.getY() + f2), (double) ((float) (blockposition.getZ() + 1) - f)); + } + + public boolean d() { + return false; + } + + public boolean c() { + return false; + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + this.b(world, blockposition, iblockdata, entityhuman); + return true; + } + + public void attack(World world, BlockPosition blockposition, EntityHuman entityhuman) { + this.b(world, blockposition, world.getType(blockposition), entityhuman); + } + + private void b(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { + if (entityhuman.j(false)) { + entityhuman.b(StatisticList.H); + // CraftBukkit start + // entityhuman.getFoodData().eat(2, 0.1F); + int oldFoodLevel = entityhuman.getFoodData().foodLevel; + + org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, 2 + oldFoodLevel); + + if (!event.isCancelled()) { + entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 0.1F); + } + + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel)); + // CraftBukkit end + int i = ((Integer) iblockdata.get(BlockCake.BITES)).intValue(); + + if (i < 6) { + world.setTypeAndData(blockposition, iblockdata.set(BlockCake.BITES, Integer.valueOf(i + 1)), 3); + } else { + world.setAir(blockposition); + } + + } + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return super.canPlace(world, blockposition) ? this.e(world, blockposition) : false; + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!this.e(world, blockposition)) { + world.setAir(blockposition); + } + + } + + private boolean e(World world, BlockPosition blockposition) { + return world.getType(blockposition.down()).getBlock().getMaterial().isBuildable(); + } + + public int a(Random random) { + return 0; + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return null; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockCake.BITES, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockCake.BITES)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockCake.BITES}); + } + + public int l(World world, BlockPosition blockposition) { + return (7 - ((Integer) world.getType(blockposition).get(BlockCake.BITES)).intValue()) * 2; + } + + public boolean isComplexRedstone() { + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockChest.java new file mode 100644 index 0000000..eed516e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockChest.java @@ -0,0 +1,460 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.Iterator; + +public class BlockChest extends BlockContainer { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirection.EnumDirectionLimit.HORIZONTAL); + public final int b; + + protected BlockChest(int i) { + super(Material.WOOD); + this.j(this.blockStateList.getBlockData().set(BlockChest.FACING, EnumDirection.NORTH)); + this.b = i; + this.a(CreativeModeTab.c); + this.a(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public int b() { + return 2; + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + if (iblockaccess.getType(blockposition.north()).getBlock() == this) { + this.a(0.0625F, 0.0F, 0.0F, 0.9375F, 0.875F, 0.9375F); + } else if (iblockaccess.getType(blockposition.south()).getBlock() == this) { + this.a(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 1.0F); + } else if (iblockaccess.getType(blockposition.west()).getBlock() == this) { + this.a(0.0F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } else if (iblockaccess.getType(blockposition.east()).getBlock() == this) { + this.a(0.0625F, 0.0F, 0.0625F, 1.0F, 0.875F, 0.9375F); + } else { + this.a(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.875F, 0.9375F); + } + + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.e(world, blockposition, iblockdata); + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + IBlockData iblockdata1 = world.getType(blockposition1); + + if (iblockdata1.getBlock() == this) { + this.e(world, blockposition1, iblockdata1); + } + } + + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return this.getBlockData().set(BlockChest.FACING, entityliving.getDirection()); + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + EnumDirection enumdirection = EnumDirection.fromType2(MathHelper.floor((double) (entityliving.yaw * 4.0F / 360.0F) + 0.5D) & 3).opposite(); + + iblockdata = iblockdata.set(BlockChest.FACING, enumdirection); + BlockPosition blockposition1 = blockposition.north(); + BlockPosition blockposition2 = blockposition.south(); + BlockPosition blockposition3 = blockposition.west(); + BlockPosition blockposition4 = blockposition.east(); + boolean flag = this == world.getType(blockposition1).getBlock(); + boolean flag1 = this == world.getType(blockposition2).getBlock(); + boolean flag2 = this == world.getType(blockposition3).getBlock(); + boolean flag3 = this == world.getType(blockposition4).getBlock(); + + if (!flag && !flag1 && !flag2 && !flag3) { + world.setTypeAndData(blockposition, iblockdata, 3); + } else if (enumdirection.k() == EnumDirection.EnumAxis.X && (flag || flag1)) { + if (flag) { + world.setTypeAndData(blockposition1, iblockdata, 3); + } else { + world.setTypeAndData(blockposition2, iblockdata, 3); + } + + world.setTypeAndData(blockposition, iblockdata, 3); + } else if (enumdirection.k() == EnumDirection.EnumAxis.Z && (flag2 || flag3)) { + if (flag2) { + world.setTypeAndData(blockposition3, iblockdata, 3); + } else { + world.setTypeAndData(blockposition4, iblockdata, 3); + } + + world.setTypeAndData(blockposition, iblockdata, 3); + } + + if (itemstack.hasName()) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityChest) { + ((TileEntityChest) tileentity).a(itemstack.getName()); + } + } + + } + + public IBlockData e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (world.isClientSide) { + return iblockdata; + } else { + IBlockData iblockdata1 = world.getType(blockposition.north()); + IBlockData iblockdata2 = world.getType(blockposition.south()); + IBlockData iblockdata3 = world.getType(blockposition.west()); + IBlockData iblockdata4 = world.getType(blockposition.east()); + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockChest.FACING); + Block block = iblockdata1.getBlock(); + Block block1 = iblockdata2.getBlock(); + Block block2 = iblockdata3.getBlock(); + Block block3 = iblockdata4.getBlock(); + + if (block != this && block1 != this) { + boolean flag = block.o(); + boolean flag1 = block1.o(); + + if (block2 == this || block3 == this) { + BlockPosition blockposition1 = block2 == this ? blockposition.west() : blockposition.east(); + IBlockData iblockdata5 = world.getType(blockposition1.north()); + IBlockData iblockdata6 = world.getType(blockposition1.south()); + + enumdirection = EnumDirection.SOUTH; + EnumDirection enumdirection1; + + if (block2 == this) { + enumdirection1 = (EnumDirection) iblockdata3.get(BlockChest.FACING); + } else { + enumdirection1 = (EnumDirection) iblockdata4.get(BlockChest.FACING); + } + + if (enumdirection1 == EnumDirection.NORTH) { + enumdirection = EnumDirection.NORTH; + } + + Block block4 = iblockdata5.getBlock(); + Block block5 = iblockdata6.getBlock(); + + if ((flag || block4.o()) && !flag1 && !block5.o()) { + enumdirection = EnumDirection.SOUTH; + } + + if ((flag1 || block5.o()) && !flag && !block4.o()) { + enumdirection = EnumDirection.NORTH; + } + } + } else { + BlockPosition blockposition2 = block == this ? blockposition.north() : blockposition.south(); + IBlockData iblockdata7 = world.getType(blockposition2.west()); + IBlockData iblockdata8 = world.getType(blockposition2.east()); + + enumdirection = EnumDirection.EAST; + EnumDirection enumdirection2; + + if (block == this) { + enumdirection2 = (EnumDirection) iblockdata1.get(BlockChest.FACING); + } else { + enumdirection2 = (EnumDirection) iblockdata2.get(BlockChest.FACING); + } + + if (enumdirection2 == EnumDirection.WEST) { + enumdirection = EnumDirection.WEST; + } + + Block block6 = iblockdata7.getBlock(); + Block block7 = iblockdata8.getBlock(); + + if ((block2.o() || block6.o()) && !block3.o() && !block7.o()) { + enumdirection = EnumDirection.EAST; + } + + if ((block3.o() || block7.o()) && !block2.o() && !block6.o()) { + enumdirection = EnumDirection.WEST; + } + } + + iblockdata = iblockdata.set(BlockChest.FACING, enumdirection); + world.setTypeAndData(blockposition, iblockdata, 3); + return iblockdata; + } + } + + public IBlockData f(World world, BlockPosition blockposition, IBlockData iblockdata) { + EnumDirection enumdirection = null; + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection1 = (EnumDirection) iterator.next(); + IBlockData iblockdata1 = world.getType(blockposition.shift(enumdirection1)); + + if (iblockdata1.getBlock() == this) { + return iblockdata; + } + + if (iblockdata1.getBlock().o()) { + if (enumdirection != null) { + enumdirection = null; + break; + } + + enumdirection = enumdirection1; + } + } + + if (enumdirection != null) { + return iblockdata.set(BlockChest.FACING, enumdirection.opposite()); + } else { + EnumDirection enumdirection2 = (EnumDirection) iblockdata.get(BlockChest.FACING); + + if (world.getType(blockposition.shift(enumdirection2)).getBlock().o()) { + enumdirection2 = enumdirection2.opposite(); + } + + if (world.getType(blockposition.shift(enumdirection2)).getBlock().o()) { + enumdirection2 = enumdirection2.e(); + } + + if (world.getType(blockposition.shift(enumdirection2)).getBlock().o()) { + enumdirection2 = enumdirection2.opposite(); + } + + return iblockdata.set(BlockChest.FACING, enumdirection2); + } + } + + public boolean canPlace(World world, BlockPosition blockposition) { + int i = 0; + BlockPosition blockposition1 = blockposition.west(); + BlockPosition blockposition2 = blockposition.east(); + BlockPosition blockposition3 = blockposition.north(); + BlockPosition blockposition4 = blockposition.south(); + + if (world.getType(blockposition1).getBlock() == this) { + if (this.m(world, blockposition1)) { + return false; + } + + ++i; + } + + if (world.getType(blockposition2).getBlock() == this) { + if (this.m(world, blockposition2)) { + return false; + } + + ++i; + } + + if (world.getType(blockposition3).getBlock() == this) { + if (this.m(world, blockposition3)) { + return false; + } + + ++i; + } + + if (world.getType(blockposition4).getBlock() == this) { + if (this.m(world, blockposition4)) { + return false; + } + + ++i; + } + + return i <= 1; + } + + private boolean m(World world, BlockPosition blockposition) { + if (world.getType(blockposition).getBlock() != this) { + return false; + } else { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + EnumDirection enumdirection; + + do { + if (!iterator.hasNext()) { + return false; + } + + enumdirection = (EnumDirection) iterator.next(); + } while (world.getType(blockposition.shift(enumdirection)).getBlock() != this); + + return true; + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + super.doPhysics(world, blockposition, iblockdata, block); + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityChest) { + tileentity.E(); + } + + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof IInventory) { + InventoryUtils.dropInventory(world, blockposition, (IInventory) tileentity); + world.updateAdjacentComparators(blockposition, this); + } + + super.remove(world, blockposition, iblockdata); + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (world.isClientSide) { + return true; + } else { + ITileInventory itileinventory = this.f(world, blockposition); + + if (itileinventory != null) { + entityhuman.openContainer(itileinventory); + if (this.b == 0) { + entityhuman.b(StatisticList.aa); + } else if (this.b == 1) { + entityhuman.b(StatisticList.U); + } + } + + return true; + } + } + + public ITileInventory f(World world, BlockPosition blockposition) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (!(tileentity instanceof TileEntityChest)) { + return null; + } else { + Object object = (TileEntityChest) tileentity; + + if (this.n(world, blockposition)) { + return null; + } else { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + Block block = world.getType(blockposition1).getBlock(); + + if (block == this) { + if (this.n(world, blockposition1)) { + return null; + } + + TileEntity tileentity1 = world.getTileEntity(blockposition1); + + if (tileentity1 instanceof TileEntityChest) { + if (enumdirection != EnumDirection.WEST && enumdirection != EnumDirection.NORTH) { + object = new InventoryLargeChest("container.chestDouble", (ITileInventory) object, (TileEntityChest) tileentity1); + } else { + object = new InventoryLargeChest("container.chestDouble", (TileEntityChest) tileentity1, (ITileInventory) object); + } + } + } + } + + return (ITileInventory) object; + } + } + } + + public TileEntity a(World world, int i) { + return new TileEntityChest(); + } + + public boolean isPowerSource() { + return this.b == 1; + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + if (!this.isPowerSource()) { + return 0; + } else { + int i = 0; + TileEntity tileentity = iblockaccess.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityChest) { + i = ((TileEntityChest) tileentity).l; + } + + return MathHelper.clamp(i, 0, 15); + } + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return enumdirection == EnumDirection.UP ? this.a(iblockaccess, blockposition, iblockdata, enumdirection) : 0; + } + + private boolean n(World world, BlockPosition blockposition) { + return this.o(world, blockposition) || this.p(world, blockposition); + } + + private boolean o(World world, BlockPosition blockposition) { + return world.getType(blockposition.up()).getBlock().isOccluding(); + } + + private boolean p(World world, BlockPosition blockposition) { + // PaperSpigot start - Option to disable chest's cat detection (Performance++) + if (world.paperSpigotConfig.disableChestCatDetection) { + return false; + } + // PaperSpigot end + Iterator iterator = world.a(EntityOcelot.class, new AxisAlignedBB((double) blockposition.getX(), (double) (blockposition.getY() + 1), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 2), (double) (blockposition.getZ() + 1))).iterator(); + + EntityOcelot entityocelot; + + do { + if (!iterator.hasNext()) { + return false; + } + + Entity entity = (Entity) iterator.next(); + + entityocelot = (EntityOcelot) entity; + } while (!entityocelot.isSitting()); + + return true; + } + + public boolean isComplexRedstone() { + return true; + } + + public int l(World world, BlockPosition blockposition) { + return Container.b((IInventory) this.f(world, blockposition)); + } + + public IBlockData fromLegacyData(int i) { + EnumDirection enumdirection = EnumDirection.fromType1(i); + + if (enumdirection.k() == EnumDirection.EnumAxis.Y) { + enumdirection = EnumDirection.NORTH; + } + + return this.getBlockData().set(BlockChest.FACING, enumdirection); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((EnumDirection) iblockdata.get(BlockChest.FACING)).a(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockChest.FACING}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCocoa.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCocoa.java new file mode 100644 index 0000000..8eb1beb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCocoa.java @@ -0,0 +1,186 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class BlockCocoa extends BlockDirectional implements IBlockFragilePlantElement { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 2); + + public BlockCocoa() { + super(Material.PLANT); + this.j(this.blockStateList.getBlockData().set(BlockCocoa.FACING, EnumDirection.NORTH).set(BlockCocoa.AGE, Integer.valueOf(0))); + this.a(true); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!this.e(world, blockposition, iblockdata)) { + this.f(world, blockposition, iblockdata); + } else if (world.random.nextInt(5) == 0) { + int i = ((Integer) iblockdata.get(BlockCocoa.AGE)).intValue(); + + if (i < 2) { + // CraftBukkit start + IBlockData data = iblockdata.set(AGE, Integer.valueOf(i + 1)); + CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data)); + // CraftBukkit end + } + } + + } + + public boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + blockposition = blockposition.shift((EnumDirection) iblockdata.get(BlockCocoa.FACING)); + IBlockData iblockdata1 = world.getType(blockposition); + + return iblockdata1.getBlock() == Blocks.LOG && iblockdata1.get(BlockWood.VARIANT) == BlockWood.EnumLogVariant.JUNGLE; + } + + public boolean d() { + return false; + } + + public boolean c() { + return false; + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.updateShape(world, blockposition); + return super.a(world, blockposition, iblockdata); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockCocoa.FACING); + int i = ((Integer) iblockdata.get(BlockCocoa.AGE)).intValue(); + int j = 4 + i * 2; + int k = 5 + i * 2; + float f = (float) j / 2.0F; + + switch (BlockCocoa.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + this.a((8.0F - f) / 16.0F, (12.0F - (float) k) / 16.0F, (15.0F - (float) j) / 16.0F, (8.0F + f) / 16.0F, 0.75F, 0.9375F); + break; + + case 2: + this.a((8.0F - f) / 16.0F, (12.0F - (float) k) / 16.0F, 0.0625F, (8.0F + f) / 16.0F, 0.75F, (1.0F + (float) j) / 16.0F); + break; + + case 3: + this.a(0.0625F, (12.0F - (float) k) / 16.0F, (8.0F - f) / 16.0F, (1.0F + (float) j) / 16.0F, 0.75F, (8.0F + f) / 16.0F); + break; + + case 4: + this.a((15.0F - (float) j) / 16.0F, (12.0F - (float) k) / 16.0F, (8.0F - f) / 16.0F, 0.9375F, 0.75F, (8.0F + f) / 16.0F); + } + + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + EnumDirection enumdirection = EnumDirection.fromAngle((double) entityliving.yaw); + + world.setTypeAndData(blockposition, iblockdata.set(BlockCocoa.FACING, enumdirection), 2); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + if (!enumdirection.k().c()) { + enumdirection = EnumDirection.NORTH; + } + + return this.getBlockData().set(BlockCocoa.FACING, enumdirection.opposite()).set(BlockCocoa.AGE, Integer.valueOf(0)); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!this.e(world, blockposition, iblockdata)) { + this.f(world, blockposition, iblockdata); + } + + } + + private void f(World world, BlockPosition blockposition, IBlockData iblockdata) { + world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); + this.b(world, blockposition, iblockdata, 0); + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + int j = ((Integer) iblockdata.get(BlockCocoa.AGE)).intValue(); + byte b0 = 1; + + if (j >= 2) { + b0 = 3; + } + + for (int k = 0; k < b0; ++k) { + a(world, blockposition, new ItemStack(Items.DYE, 1, EnumColor.BROWN.getInvColorIndex())); + } + + } + + public int getDropData(World world, BlockPosition blockposition) { + return EnumColor.BROWN.getInvColorIndex(); + } + + public boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return ((Integer) iblockdata.get(BlockCocoa.AGE)).intValue() < 2; + } + + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return true; + } + + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + // CraftBukkit start + IBlockData data = iblockdata.set(AGE, Integer.valueOf(((Integer) iblockdata.get(AGE)).intValue() + 1)); + CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data)); + // CraftBukkit end + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockCocoa.FACING, EnumDirection.fromType2(i)).set(BlockCocoa.AGE, Integer.valueOf((i & 15) >> 2)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((EnumDirection) iblockdata.get(BlockCocoa.FACING)).b(); + + i |= ((Integer) iblockdata.get(BlockCocoa.AGE)).intValue() << 2; + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockCocoa.FACING, BlockCocoa.AGE}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + BlockCocoa.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockCocoa.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockCocoa.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockCocoa.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCommand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCommand.java new file mode 100644 index 0000000..2630616 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCommand.java @@ -0,0 +1,120 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + +public class BlockCommand extends BlockContainer { + + public static final BlockStateBoolean TRIGGERED = BlockStateBoolean.of("triggered"); + + public BlockCommand() { + super(Material.ORE, MaterialMapColor.q); + this.j(this.blockStateList.getBlockData().set(BlockCommand.TRIGGERED, Boolean.valueOf(false))); + } + + public TileEntity a(World world, int i) { + return new TileEntityCommand(); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!world.isClientSide) { + boolean flag = world.isBlockIndirectlyPowered(blockposition); + boolean flag1 = ((Boolean) iblockdata.get(BlockCommand.TRIGGERED)).booleanValue(); + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + int old = flag1 ? 15 : 0; + int current = flag ? 15 : 0; + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, old, current); + world.getServer().getPluginManager().callEvent(eventRedstone); + // CraftBukkit end + + if (eventRedstone.getNewCurrent() > 0 && !(eventRedstone.getOldCurrent() > 0)) { // CraftBukkit + world.setTypeAndData(blockposition, iblockdata.set(BlockCommand.TRIGGERED, Boolean.valueOf(true)), 4); + world.a(blockposition, (Block) this, this.a(world)); + } else if (!(eventRedstone.getNewCurrent() > 0) && eventRedstone.getOldCurrent() > 0) { // CraftBukkit + world.setTypeAndData(blockposition, iblockdata.set(BlockCommand.TRIGGERED, Boolean.valueOf(false)), 4); + } + } + + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityCommand) { + ((TileEntityCommand) tileentity).getCommandBlock().a(world); + world.updateAdjacentComparators(blockposition, this); + } + + } + + public int a(World world) { + return 1; + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + TileEntity tileentity = world.getTileEntity(blockposition); + + return tileentity instanceof TileEntityCommand ? ((TileEntityCommand) tileentity).getCommandBlock().a(entityhuman) : false; + } + + public boolean isComplexRedstone() { + return true; + } + + public int l(World world, BlockPosition blockposition) { + TileEntity tileentity = world.getTileEntity(blockposition); + + return tileentity instanceof TileEntityCommand ? ((TileEntityCommand) tileentity).getCommandBlock().j() : 0; + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityCommand) { + CommandBlockListenerAbstract commandblocklistenerabstract = ((TileEntityCommand) tileentity).getCommandBlock(); + + if (itemstack.hasName()) { + commandblocklistenerabstract.setName(itemstack.getName()); + } + + if (!world.isClientSide) { + commandblocklistenerabstract.a(world.getGameRules().getBoolean("sendCommandFeedback")); + } + + } + } + + public int a(Random random) { + return 0; + } + + public int b() { + return 3; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockCommand.TRIGGERED, Boolean.valueOf((i & 1) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + int i = 0; + + if (((Boolean) iblockdata.get(BlockCommand.TRIGGERED)).booleanValue()) { + i |= 1; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockCommand.TRIGGERED}); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return this.getBlockData().set(BlockCommand.TRIGGERED, Boolean.valueOf(false)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCrops.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCrops.java new file mode 100644 index 0000000..b91b220 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockCrops.java @@ -0,0 +1,159 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 7); + + protected BlockCrops() { + this.j(this.blockStateList.getBlockData().set(BlockCrops.AGE, Integer.valueOf(0))); + this.a(true); + float f = 0.5F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f); + this.a((CreativeModeTab) null); + this.c(0.0F); + this.a(BlockCrops.h); + this.K(); + } + + protected boolean c(Block block) { + return block == Blocks.FARMLAND; + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + super.b(world, blockposition, iblockdata, random); + if (world.getLightLevel(blockposition.up()) >= 9) { + int i = ((Integer) iblockdata.get(BlockCrops.AGE)).intValue(); + + if (i < 7) { + float f = a((Block) this, world, blockposition); + + if (random.nextInt((int) (world.growthOdds / world.spigotConfig.wheatModifier * (25.0F / f)) + 1) == 0) { // Spigot // CraftBukkit start + IBlockData data = iblockdata.set(AGE, Integer.valueOf(i + 1)); + CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data)); + // CraftBukkit end + } + } + } + + } + + public void g(World world, BlockPosition blockposition, IBlockData iblockdata) { + int i = ((Integer) iblockdata.get(BlockCrops.AGE)).intValue() + MathHelper.nextInt(world.random, 2, 5); + + if (i > 7) { + i = 7; + } + + // CraftBukkit start + IBlockData data = iblockdata.set(AGE, Integer.valueOf(i)); + CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data)); + // CraftBukkit end + } + + protected static float a(Block block, World world, BlockPosition blockposition) { + float f = 1.0F; + BlockPosition blockposition1 = blockposition.down(); + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + float f1 = 0.0F; + IBlockData iblockdata = world.getType(blockposition1.a(i, 0, j)); + + if (iblockdata.getBlock() == Blocks.FARMLAND) { + f1 = 1.0F; + if (((Integer) iblockdata.get(BlockSoil.MOISTURE)).intValue() > 0) { + f1 = 3.0F; + } + } + + if (i != 0 || j != 0) { + f1 /= 4.0F; + } + + f += f1; + } + } + + BlockPosition blockposition2 = blockposition.north(); + BlockPosition blockposition3 = blockposition.south(); + BlockPosition blockposition4 = blockposition.west(); + BlockPosition blockposition5 = blockposition.east(); + boolean flag = block == world.getType(blockposition4).getBlock() || block == world.getType(blockposition5).getBlock(); + boolean flag1 = block == world.getType(blockposition2).getBlock() || block == world.getType(blockposition3).getBlock(); + + if (flag && flag1) { + f /= 2.0F; + } else { + boolean flag2 = block == world.getType(blockposition4.north()).getBlock() || block == world.getType(blockposition5.north()).getBlock() || block == world.getType(blockposition5.south()).getBlock() || block == world.getType(blockposition4.south()).getBlock(); + + if (flag2) { + f /= 2.0F; + } + } + + return f; + } + + public boolean f(World world, BlockPosition blockposition, IBlockData iblockdata) { + return (world.k(blockposition) >= 8 || world.i(blockposition)) && this.c(world.getType(blockposition.down()).getBlock()); + } + + protected Item l() { + return Items.WHEAT_SEEDS; + } + + protected Item n() { + return Items.WHEAT; + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + super.dropNaturally(world, blockposition, iblockdata, f, 0); + if (!world.isClientSide) { + int j = ((Integer) iblockdata.get(BlockCrops.AGE)).intValue(); + + if (j >= 7) { + int k = 3 + i; + + for (int l = 0; l < k; ++l) { + if (world.random.nextInt(15) <= j) { + a(world, blockposition, new ItemStack(this.l(), 1, 0)); + } + } + } + + } + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return ((Integer) iblockdata.get(BlockCrops.AGE)).intValue() == 7 ? this.n() : this.l(); + } + + public boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return ((Integer) iblockdata.get(BlockCrops.AGE)).intValue() < 7; + } + + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return true; + } + + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + this.g(world, blockposition, iblockdata); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockCrops.AGE, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockCrops.AGE)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockCrops.AGE}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDaylightDetector.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDaylightDetector.java new file mode 100644 index 0000000..45df7c9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDaylightDetector.java @@ -0,0 +1,106 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockDaylightDetector extends BlockContainer { + + public static final BlockStateInteger POWER = BlockStateInteger.of("power", 0, 15); + private final boolean b; + + public BlockDaylightDetector(boolean flag) { + super(Material.WOOD); + this.b = flag; + this.j(this.blockStateList.getBlockData().set(BlockDaylightDetector.POWER, Integer.valueOf(0))); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F); + this.a(CreativeModeTab.d); + this.c(0.2F); + this.a(BlockDaylightDetector.f); + this.c("daylightDetector"); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.375F, 1.0F); + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return ((Integer) iblockdata.get(BlockDaylightDetector.POWER)).intValue(); + } + + public void f(World world, BlockPosition blockposition) { + if (!world.worldProvider.o()) { + IBlockData iblockdata = world.getType(blockposition); + int i = world.b(EnumSkyBlock.SKY, blockposition) - world.ab(); + float f = world.d(1.0F); + float f1 = f < 3.1415927F ? 0.0F : 6.2831855F; + + f += (f1 - f) * 0.2F; + i = Math.round((float) i * MathHelper.cos(f)); + i = MathHelper.clamp(i, 0, 15); + if (this.b) { + i = 15 - i; + } + + if (((Integer) iblockdata.get(BlockDaylightDetector.POWER)).intValue() != i) { + i = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), ((Integer) iblockdata.get(POWER)), i).getNewCurrent(); // CraftBukkit - Call BlockRedstoneEvent + world.setTypeAndData(blockposition, iblockdata.set(BlockDaylightDetector.POWER, Integer.valueOf(i)), 3); + } + + } + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (entityhuman.cn()) { + if (world.isClientSide) { + return true; + } else { + if (this.b) { + world.setTypeAndData(blockposition, Blocks.DAYLIGHT_DETECTOR.getBlockData().set(BlockDaylightDetector.POWER, iblockdata.get(BlockDaylightDetector.POWER)), 4); + Blocks.DAYLIGHT_DETECTOR.f(world, blockposition); + } else { + world.setTypeAndData(blockposition, Blocks.DAYLIGHT_DETECTOR_INVERTED.getBlockData().set(BlockDaylightDetector.POWER, iblockdata.get(BlockDaylightDetector.POWER)), 4); + Blocks.DAYLIGHT_DETECTOR_INVERTED.f(world, blockposition); + } + + return true; + } + } else { + return super.interact(world, blockposition, iblockdata, entityhuman, enumdirection, f, f1, f2); + } + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Item.getItemOf(Blocks.DAYLIGHT_DETECTOR); + } + + public boolean d() { + return false; + } + + public boolean c() { + return false; + } + + public int b() { + return 3; + } + + public boolean isPowerSource() { + return true; + } + + public TileEntity a(World world, int i) { + return new TileEntityLightDetector(); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockDaylightDetector.POWER, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockDaylightDetector.POWER)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockDaylightDetector.POWER}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDiodeAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDiodeAbstract.java new file mode 100644 index 0000000..2350af8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDiodeAbstract.java @@ -0,0 +1,248 @@ +package net.minecraft.server; + +import java.util.Random; + +import net.jafama.FastMath; +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public abstract class BlockDiodeAbstract extends BlockDirectional { + + protected final boolean N; + + protected BlockDiodeAbstract(boolean flag) { + super(Material.ORIENTABLE); + this.N = flag; + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + public boolean d() { + return false; + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return World.a((IBlockAccess) world, blockposition.down()) ? super.canPlace(world, blockposition) : false; + } + + public boolean e(World world, BlockPosition blockposition) { + return World.a((IBlockAccess) world, blockposition.down()); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {} + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!this.b(world, blockposition, iblockdata)) { + boolean flag = this.e(world, blockposition, iblockdata); + + if (this.N && !flag) { + // CraftBukkit start + if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 15, 0).getNewCurrent() != 0) { + return; + } + // CraftBukkit end + world.setTypeAndData(blockposition, this.k(iblockdata), 2); + } else if (!this.N) { + // CraftBukkit start + if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 0, 15).getNewCurrent() != 15) { + return; + } + // CraftBukkit end + world.setTypeAndData(blockposition, this.e(iblockdata), 2); + if (!flag) { + world.a(blockposition, this.e(iblockdata).getBlock(), this.m(iblockdata), -1); + } + } + + } + } + + protected boolean l(IBlockData iblockdata) { + return this.N; + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return this.a(iblockaccess, blockposition, iblockdata, enumdirection); + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return !this.l(iblockdata) ? 0 : (iblockdata.get(BlockDiodeAbstract.FACING) == enumdirection ? this.a(iblockaccess, blockposition, iblockdata) : 0); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (this.e(world, blockposition)) { + this.g(world, blockposition, iblockdata); + } else { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + // PaperSpigot start - Fix cannons + if (world.paperSpigotConfig.fixCannons) { + world.applyPhysics(blockposition.shift(EnumDirection.EAST), this); + world.applyPhysics(blockposition.shift(EnumDirection.WEST), this); + world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this); + world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this); + world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this); + world.applyPhysics(blockposition.shift(EnumDirection.UP), this); + return; + } + // PaperSpigot end + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + world.applyPhysics(blockposition.shift(enumdirection), this); + } + + } + } + + protected void g(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!this.b(world, blockposition, iblockdata)) { + boolean flag = this.e(world, blockposition, iblockdata); + + if ((this.N && !flag || !this.N && flag) && !world.a(blockposition, (Block) this)) { + byte b0 = -1; + + if (this.i(world, blockposition, iblockdata)) { + b0 = -3; + } else if (this.N) { + b0 = -2; + } + + world.a(blockposition, this, this.d(iblockdata), b0); + } + + } + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { + return false; + } + + protected boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + return this.f(world, blockposition, iblockdata) > 0; + } + + protected int f(World world, BlockPosition blockposition, IBlockData iblockdata) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockDiodeAbstract.FACING); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + int i = world.getBlockFacePower(blockposition1, enumdirection); + + if (i >= 15) { + return i; + } else { + IBlockData iblockdata1 = world.getType(blockposition1); + + return FastMath.max(i, iblockdata1.getBlock() == Blocks.REDSTONE_WIRE ? ((Integer) iblockdata1.get(BlockRedstoneWire.POWER)).intValue() : 0); + } + } + + protected int c(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockDiodeAbstract.FACING); + EnumDirection enumdirection1 = enumdirection.e(); + EnumDirection enumdirection2 = enumdirection.f(); + + return FastMath.max(this.c(iblockaccess, blockposition.shift(enumdirection1), enumdirection1), this.c(iblockaccess, blockposition.shift(enumdirection2), enumdirection2)); + } + + protected int c(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + Block block = iblockdata.getBlock(); + + return this.c(block) ? (block == Blocks.REDSTONE_WIRE ? ((Integer) iblockdata.get(BlockRedstoneWire.POWER)).intValue() : iblockaccess.getBlockPower(blockposition, enumdirection)) : 0; + } + + public boolean isPowerSource() { + return true; + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return this.getBlockData().set(BlockDiodeAbstract.FACING, entityliving.getDirection().opposite()); + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + if (this.e(world, blockposition, iblockdata)) { + world.a(blockposition, (Block) this, 1); + } + + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.h(world, blockposition, iblockdata); + } + + protected void h(World world, BlockPosition blockposition, IBlockData iblockdata) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockDiodeAbstract.FACING); + BlockPosition blockposition1 = blockposition.shift(enumdirection.opposite()); + + world.d(blockposition1, this); + world.a(blockposition1, (Block) this, enumdirection); + } + + public void postBreak(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (this.N) { + // PaperSpigot start - Fix cannons + if (world.paperSpigotConfig.fixCannons) { + world.applyPhysics(blockposition.shift(EnumDirection.EAST), this); + world.applyPhysics(blockposition.shift(EnumDirection.WEST), this); + world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this); + world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this); + world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this); + world.applyPhysics(blockposition.shift(EnumDirection.UP), this); + return; + } + // PaperSpigot end + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + world.applyPhysics(blockposition.shift(enumdirection), this); + } + } + + super.postBreak(world, blockposition, iblockdata); + } + + public boolean c() { + return false; + } + + protected boolean c(Block block) { + return block.isPowerSource(); + } + + protected int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata) { + return 15; + } + + public static boolean d(Block block) { + return Blocks.UNPOWERED_REPEATER.e(block) || Blocks.UNPOWERED_COMPARATOR.e(block); + } + + public boolean e(Block block) { + return block == this.e(this.getBlockData()).getBlock() || block == this.k(this.getBlockData()).getBlock(); + } + + public boolean i(World world, BlockPosition blockposition, IBlockData iblockdata) { + EnumDirection enumdirection = ((EnumDirection) iblockdata.get(BlockDiodeAbstract.FACING)).opposite(); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + + return d(world.getType(blockposition1).getBlock()) ? world.getType(blockposition1).get(BlockDiodeAbstract.FACING) != enumdirection : false; + } + + protected int m(IBlockData iblockdata) { + return this.d(iblockdata); + } + + protected abstract int d(IBlockData iblockdata); + + protected abstract IBlockData e(IBlockData iblockdata); + + protected abstract IBlockData k(IBlockData iblockdata); + + public boolean b(Block block) { + return this.e(block); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDispenser.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDispenser.java new file mode 100644 index 0000000..010d7c6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDispenser.java @@ -0,0 +1,194 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockDispenser extends BlockContainer { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing"); + public static final BlockStateBoolean TRIGGERED = BlockStateBoolean.of("triggered"); + public static final RegistryDefault REGISTRY = new RegistryDefault(new DispenseBehaviorItem()); + protected Random O = new Random(); + public static boolean eventFired = false; // CraftBukkit + + protected BlockDispenser() { + super(Material.STONE); + this.j(this.blockStateList.getBlockData().set(BlockDispenser.FACING, EnumDirection.NORTH).set(BlockDispenser.TRIGGERED, Boolean.valueOf(false))); + this.a(CreativeModeTab.d); + } + + public int a(World world) { + return 4; + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + super.onPlace(world, blockposition, iblockdata); + this.e(world, blockposition, iblockdata); + } + + private void e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!world.isClientSide) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockDispenser.FACING); + boolean flag = world.getType(blockposition.north()).getBlock().o(); + boolean flag1 = world.getType(blockposition.south()).getBlock().o(); + + if (enumdirection == EnumDirection.NORTH && flag && !flag1) { + enumdirection = EnumDirection.SOUTH; + } else if (enumdirection == EnumDirection.SOUTH && flag1 && !flag) { + enumdirection = EnumDirection.NORTH; + } else { + boolean flag2 = world.getType(blockposition.west()).getBlock().o(); + boolean flag3 = world.getType(blockposition.east()).getBlock().o(); + + if (enumdirection == EnumDirection.WEST && flag2 && !flag3) { + enumdirection = EnumDirection.EAST; + } else if (enumdirection == EnumDirection.EAST && flag3 && !flag2) { + enumdirection = EnumDirection.WEST; + } + } + + world.setTypeAndData(blockposition, iblockdata.set(BlockDispenser.FACING, enumdirection).set(BlockDispenser.TRIGGERED, Boolean.valueOf(false)), 2); + } + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (world.isClientSide) { + return true; + } else { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityDispenser) { + entityhuman.openContainer((TileEntityDispenser) tileentity); + if (tileentity instanceof TileEntityDropper) { + entityhuman.b(StatisticList.O); + } else { + entityhuman.b(StatisticList.Q); + } + } + + return true; + } + } + + public void dispense(World world, BlockPosition blockposition) { + SourceBlock sourceblock = new SourceBlock(world, blockposition); + TileEntityDispenser tileentitydispenser = (TileEntityDispenser) sourceblock.getTileEntity(); + + if (tileentitydispenser != null) { + int i = tileentitydispenser.m(); + + if (i < 0) { + world.triggerEffect(1001, blockposition, 0); + } else { + ItemStack itemstack = tileentitydispenser.getItem(i); + IDispenseBehavior idispensebehavior = this.a(itemstack); + + if (idispensebehavior != IDispenseBehavior.NONE) { + ItemStack itemstack1 = idispensebehavior.a(sourceblock, itemstack); + eventFired = false; // CraftBukkit - reset event status + + tileentitydispenser.setItem(i, itemstack1.count <= 0 ? null : itemstack1); + } + + } + } + } + + protected IDispenseBehavior a(ItemStack itemstack) { + return (IDispenseBehavior) BlockDispenser.REGISTRY.get(itemstack == null ? null : itemstack.getItem()); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + boolean flag = world.isBlockIndirectlyPowered(blockposition) || world.isBlockIndirectlyPowered(blockposition.up()); + boolean flag1 = ((Boolean) iblockdata.get(BlockDispenser.TRIGGERED)).booleanValue(); + + if (flag && !flag1) { + world.a(blockposition, (Block) this, this.a(world)); + world.setTypeAndData(blockposition, iblockdata.set(BlockDispenser.TRIGGERED, Boolean.valueOf(true)), 4); + } else if (!flag && flag1) { + world.setTypeAndData(blockposition, iblockdata.set(BlockDispenser.TRIGGERED, Boolean.valueOf(false)), 4); + } + + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + this.dispense(world, blockposition); + } + + } + + public TileEntity a(World world, int i) { + return new TileEntityDispenser(); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return this.getBlockData().set(BlockDispenser.FACING, BlockPiston.a(world, blockposition, entityliving)).set(BlockDispenser.TRIGGERED, Boolean.valueOf(false)); + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + world.setTypeAndData(blockposition, iblockdata.set(BlockDispenser.FACING, BlockPiston.a(world, blockposition, entityliving)), 2); + if (itemstack.hasName()) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityDispenser) { + ((TileEntityDispenser) tileentity).a(itemstack.getName()); + } + } + + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityDispenser) { + InventoryUtils.dropInventory(world, blockposition, (TileEntityDispenser) tileentity); + world.updateAdjacentComparators(blockposition, this); + } + + super.remove(world, blockposition, iblockdata); + } + + public static IPosition a(ISourceBlock isourceblock) { + EnumDirection enumdirection = b(isourceblock.f()); + double d0 = isourceblock.getX() + 0.7D * (double) enumdirection.getAdjacentX(); + double d1 = isourceblock.getY() + 0.7D * (double) enumdirection.getAdjacentY(); + double d2 = isourceblock.getZ() + 0.7D * (double) enumdirection.getAdjacentZ(); + + return new Position(d0, d1, d2); + } + + public static EnumDirection b(int i) { + return EnumDirection.fromType1(i & 7); + } + + public boolean isComplexRedstone() { + return true; + } + + public int l(World world, BlockPosition blockposition) { + return Container.a(world.getTileEntity(blockposition)); + } + + public int b() { + return 3; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockDispenser.FACING, b(i)).set(BlockDispenser.TRIGGERED, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((EnumDirection) iblockdata.get(BlockDispenser.FACING)).a(); + + if (((Boolean) iblockdata.get(BlockDispenser.TRIGGERED)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockDispenser.FACING, BlockDispenser.TRIGGERED}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDoor.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDoor.java new file mode 100644 index 0000000..bbaa2b5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDoor.java @@ -0,0 +1,341 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.Random; + +import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + +public class BlockDoor extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirection.EnumDirectionLimit.HORIZONTAL); + public static final BlockStateBoolean OPEN = BlockStateBoolean.of("open"); + public static final BlockStateEnum HINGE = BlockStateEnum.of("hinge", BlockDoor.EnumDoorHinge.class); + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); + public static final BlockStateEnum HALF = BlockStateEnum.of("half", BlockDoor.EnumDoorHalf.class); + + protected BlockDoor(Material material) { + super(material); + this.j(this.blockStateList.getBlockData().set(BlockDoor.FACING, EnumDirection.NORTH).set(BlockDoor.OPEN, Boolean.valueOf(false)).set(BlockDoor.HINGE, BlockDoor.EnumDoorHinge.LEFT).set(BlockDoor.POWERED, Boolean.valueOf(false)).set(BlockDoor.HALF, BlockDoor.EnumDoorHalf.LOWER)); + } + + public String getName() { + return LocaleI18n.get((this.a() + ".name").replaceAll("tile", "item")); + } + + public boolean c() { + return false; + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition) { + return g(e(iblockaccess, blockposition)); + } + + public boolean d() { + return false; + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.updateShape(world, blockposition); + return super.a(world, blockposition, iblockdata); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + this.k(e(iblockaccess, blockposition)); + } + + private void k(int i) { + float f = 0.1875F; + + this.a(0.0F, 0.0F, 0.0F, 1.0F, 2.0F, 1.0F); + EnumDirection enumdirection = f(i); + boolean flag = g(i); + boolean flag1 = j(i); + + if (flag) { + if (enumdirection == EnumDirection.EAST) { + if (!flag1) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f); + } else { + this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F); + } + } else if (enumdirection == EnumDirection.SOUTH) { + if (!flag1) { + this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F); + } + } else if (enumdirection == EnumDirection.WEST) { + if (!flag1) { + this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F); + } else { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f); + } + } else if (enumdirection == EnumDirection.NORTH) { + if (!flag1) { + this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F); + } else { + this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + } + } else if (enumdirection == EnumDirection.EAST) { + this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F); + } else if (enumdirection == EnumDirection.SOUTH) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f); + } else if (enumdirection == EnumDirection.WEST) { + this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } else if (enumdirection == EnumDirection.NORTH) { + this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F); + } + + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (this.material == Material.ORE) { + return true; + } else { + BlockPosition blockposition1 = iblockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER ? blockposition : blockposition.down(); + IBlockData iblockdata1 = blockposition.equals(blockposition1) ? iblockdata : world.getType(blockposition1); + + if (iblockdata1.getBlock() != this) { + return false; + } else { + iblockdata = iblockdata1.a(BlockDoor.OPEN); + world.setTypeAndData(blockposition1, iblockdata, 2); + world.b(blockposition1, blockposition); + world.a(entityhuman, ((Boolean) iblockdata.get(BlockDoor.OPEN)).booleanValue() ? 1003 : 1006, blockposition, 0); + return true; + } + } + } + + public void setDoor(World world, BlockPosition blockposition, boolean flag) { + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock() == this) { + BlockPosition blockposition1 = iblockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER ? blockposition : blockposition.down(); + IBlockData iblockdata1 = blockposition == blockposition1 ? iblockdata : world.getType(blockposition1); + + if (iblockdata1.getBlock() == this && ((Boolean) iblockdata1.get(BlockDoor.OPEN)).booleanValue() != flag) { + world.setTypeAndData(blockposition1, iblockdata1.set(BlockDoor.OPEN, Boolean.valueOf(flag)), 2); + world.b(blockposition1, blockposition); + world.a((EntityHuman) null, flag ? 1003 : 1006, blockposition, 0); + } + + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (iblockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.UPPER) { + BlockPosition blockposition1 = blockposition.down(); + IBlockData iblockdata1 = world.getType(blockposition1); + + if (iblockdata1.getBlock() != this) { + world.setAir(blockposition); + } else if (block != this) { + this.doPhysics(world, blockposition1, iblockdata1, block); + } + } else { + boolean flag = false; + BlockPosition blockposition2 = blockposition.up(); + IBlockData iblockdata2 = world.getType(blockposition2); + + if (iblockdata2.getBlock() != this) { + world.setAir(blockposition); + flag = true; + } + + if (!World.a((IBlockAccess) world, blockposition.down())) { + world.setAir(blockposition); + flag = true; + if (iblockdata2.getBlock() == this) { + world.setAir(blockposition2); + } + } + + if (flag) { + if (!world.isClientSide) { + this.b(world, blockposition, iblockdata, 0); + } + } else { + + // CraftBukkit start + org.bukkit.World bworld = world.getWorld(); + org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block blockTop = bworld.getBlockAt(blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()); + + int power = bukkitBlock.getBlockPower(); + int powerTop = blockTop.getBlockPower(); + if (powerTop > power) power = powerTop; + int oldPower = (Boolean)iblockdata2.get(POWERED) ? 15 : 0; + + if (oldPower == 0 ^ power == 0) { + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, oldPower, power); + world.getServer().getPluginManager().callEvent(eventRedstone); + + boolean flag1 = eventRedstone.getNewCurrent() > 0; + world.setTypeAndData(blockposition2, iblockdata2.set(BlockDoor.POWERED, Boolean.valueOf(flag1)), 2); + if (flag1 != ((Boolean) iblockdata.get(BlockDoor.OPEN)).booleanValue()) { + world.setTypeAndData(blockposition, iblockdata.set(BlockDoor.OPEN, Boolean.valueOf(flag1)), 2); + world.b(blockposition, blockposition); + world.a((EntityHuman) null, flag1 ? 1003 : 1006, blockposition, 0); + } + } + // CraftBukkit end + } + } + + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return iblockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.UPPER ? null : this.l(); + } + + public MovingObjectPosition a(World world, BlockPosition blockposition, Vec3D vec3d, Vec3D vec3d1) { + this.updateShape(world, blockposition); + return super.a(world, blockposition, vec3d, vec3d1); + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return blockposition.getY() >= 255 ? false : World.a((IBlockAccess) world, blockposition.down()) && super.canPlace(world, blockposition) && super.canPlace(world, blockposition.up()); + } + + public int k() { + return 1; + } + + public static int e(IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + int i = iblockdata.getBlock().toLegacyData(iblockdata); + boolean flag = i(i); + IBlockData iblockdata1 = iblockaccess.getType(blockposition.down()); + int j = iblockdata1.getBlock().toLegacyData(iblockdata1); + int k = flag ? j : i; + IBlockData iblockdata2 = iblockaccess.getType(blockposition.up()); + int l = iblockdata2.getBlock().toLegacyData(iblockdata2); + int i1 = flag ? i : l; + boolean flag1 = (i1 & 1) != 0; + boolean flag2 = (i1 & 2) != 0; + + return b(k) | (flag ? 8 : 0) | (flag1 ? 16 : 0) | (flag2 ? 32 : 0); + } + + private Item l() { + return this == Blocks.IRON_DOOR ? Items.IRON_DOOR : (this == Blocks.SPRUCE_DOOR ? Items.SPRUCE_DOOR : (this == Blocks.BIRCH_DOOR ? Items.BIRCH_DOOR : (this == Blocks.JUNGLE_DOOR ? Items.JUNGLE_DOOR : (this == Blocks.ACACIA_DOOR ? Items.ACACIA_DOOR : (this == Blocks.DARK_OAK_DOOR ? Items.DARK_OAK_DOOR : Items.WOODEN_DOOR))))); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { + BlockPosition blockposition1 = blockposition.down(); + + if (entityhuman.abilities.canInstantlyBuild && iblockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.UPPER && world.getType(blockposition1).getBlock() == this) { + world.setAir(blockposition1); + } + + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata1; + + if (iblockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER) { + iblockdata1 = iblockaccess.getType(blockposition.up()); + if (iblockdata1.getBlock() == this) { + iblockdata = iblockdata.set(BlockDoor.HINGE, iblockdata1.get(BlockDoor.HINGE)).set(BlockDoor.POWERED, iblockdata1.get(BlockDoor.POWERED)); + } + } else { + iblockdata1 = iblockaccess.getType(blockposition.down()); + if (iblockdata1.getBlock() == this) { + iblockdata = iblockdata.set(BlockDoor.FACING, iblockdata1.get(BlockDoor.FACING)).set(BlockDoor.OPEN, iblockdata1.get(BlockDoor.OPEN)); + } + } + + return iblockdata; + } + + public IBlockData fromLegacyData(int i) { + return (i & 8) > 0 ? this.getBlockData().set(BlockDoor.HALF, BlockDoor.EnumDoorHalf.UPPER).set(BlockDoor.HINGE, (i & 1) > 0 ? BlockDoor.EnumDoorHinge.RIGHT : BlockDoor.EnumDoorHinge.LEFT).set(BlockDoor.POWERED, Boolean.valueOf((i & 2) > 0)) : this.getBlockData().set(BlockDoor.HALF, BlockDoor.EnumDoorHalf.LOWER).set(BlockDoor.FACING, EnumDirection.fromType2(i & 3).f()).set(BlockDoor.OPEN, Boolean.valueOf((i & 4) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i; + + if (iblockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.UPPER) { + i = b0 | 8; + if (iblockdata.get(BlockDoor.HINGE) == BlockDoor.EnumDoorHinge.RIGHT) { + i |= 1; + } + + if (((Boolean) iblockdata.get(BlockDoor.POWERED)).booleanValue()) { + i |= 2; + } + } else { + i = b0 | ((EnumDirection) iblockdata.get(BlockDoor.FACING)).e().b(); + if (((Boolean) iblockdata.get(BlockDoor.OPEN)).booleanValue()) { + i |= 4; + } + } + + return i; + } + + protected static int b(int i) { + return i & 7; + } + + public static boolean f(IBlockAccess iblockaccess, BlockPosition blockposition) { + return g(e(iblockaccess, blockposition)); + } + + public static EnumDirection h(IBlockAccess iblockaccess, BlockPosition blockposition) { + return f(e(iblockaccess, blockposition)); + } + + public static EnumDirection f(int i) { + return EnumDirection.fromType2(i & 3).f(); + } + + protected static boolean g(int i) { + return (i & 4) != 0; + } + + protected static boolean i(int i) { + return (i & 8) != 0; + } + + protected static boolean j(int i) { + return (i & 16) != 0; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockDoor.HALF, BlockDoor.FACING, BlockDoor.OPEN, BlockDoor.HINGE, BlockDoor.POWERED}); + } + + public static enum EnumDoorHinge implements INamable { + + LEFT, RIGHT; + + private EnumDoorHinge() {} + + public String toString() { + return this.getName(); + } + + public String getName() { + return this == BlockDoor.EnumDoorHinge.LEFT ? "left" : "right"; + } + } + + public static enum EnumDoorHalf implements INamable { + + UPPER, LOWER; + + private EnumDoorHalf() {} + + public String toString() { + return this.getName(); + } + + public String getName() { + return this == BlockDoor.EnumDoorHalf.UPPER ? "upper" : "lower"; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDragonEgg.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDragonEgg.java new file mode 100644 index 0000000..76a6272 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDragonEgg.java @@ -0,0 +1,116 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.event.block.BlockFromToEvent; // CraftBukkit + +public class BlockDragonEgg extends Block { + + public BlockDragonEgg() { + super(Material.DRAGON_EGG, MaterialMapColor.E); + this.a(0.0625F, 0.0F, 0.0625F, 0.9375F, 1.0F, 0.9375F); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + world.a(blockposition, (Block) this, this.a(world)); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + world.a(blockposition, (Block) this, this.a(world)); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + this.e(world, blockposition); + } + + private void e(World world, BlockPosition blockposition) { + if (BlockFalling.canFall(world, blockposition.down()) && blockposition.getY() >= 0) { + byte b0 = 32; + + if (!BlockFalling.instaFall && world.areChunksLoadedBetween(blockposition.a(-b0, -b0, -b0), blockposition.a(b0, b0, b0))) { + // PaperSpigot start - Add FallingBlock source location API + org.bukkit.Location loc = new org.bukkit.Location(world.getWorld(), (double) ((float) blockposition.getX() + 0.5F), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + 0.5F)); + world.addEntity(new EntityFallingBlock(loc, world, (double) ((float) blockposition.getX() + 0.5F), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + 0.5F), this.getBlockData())); + // PaperSpigot end + } else { + world.setAir(blockposition); + + BlockPosition blockposition1; + + for (blockposition1 = blockposition; BlockFalling.canFall(world, blockposition1) && blockposition1.getY() > 0; blockposition1 = blockposition1.down()) { + ; + } + + if (blockposition1.getY() > 0) { + world.setTypeAndData(blockposition1, this.getBlockData(), 2); + } + } + + } + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + this.f(world, blockposition); + return true; + } + + public void attack(World world, BlockPosition blockposition, EntityHuman entityhuman) { + this.f(world, blockposition); + } + + private void f(World world, BlockPosition blockposition) { + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock() == this) { + for (int i = 0; i < 1000; ++i) { + BlockPosition blockposition1 = blockposition.a(world.random.nextInt(16) - world.random.nextInt(16), world.random.nextInt(8) - world.random.nextInt(8), world.random.nextInt(16) - world.random.nextInt(16)); + + if (world.getType(blockposition1).getBlock().material == Material.AIR) { + // CraftBukkit start + org.bukkit.block.Block from = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block to = world.getWorld().getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); + BlockFromToEvent event = new BlockFromToEvent(from, to); + org.bukkit.Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + + blockposition1 = new BlockPosition(event.getToBlock().getX(), event.getToBlock().getY(), event.getToBlock().getZ()); + // CraftBukkit end + if (world.isClientSide) { + for (int j = 0; j < 128; ++j) { + double d0 = world.random.nextDouble(); + float f = (world.random.nextFloat() - 0.5F) * 0.2F; + float f1 = (world.random.nextFloat() - 0.5F) * 0.2F; + float f2 = (world.random.nextFloat() - 0.5F) * 0.2F; + double d1 = (double) blockposition1.getX() + (double) (blockposition.getX() - blockposition1.getX()) * d0 + (world.random.nextDouble() - 0.5D) * 1.0D + 0.5D; + 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, (double) f, (double) f1, (double) f2, new int[0]); + } + } else { + world.setTypeAndData(blockposition1, iblockdata, 2); + world.setAir(blockposition); + } + + return; + } + } + + } + } + + public int a(World world) { + return 5; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDropper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDropper.java new file mode 100644 index 0000000..f3e1e72 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockDropper.java @@ -0,0 +1,79 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +// CraftBukkit end + +public class BlockDropper extends BlockDispenser { + + private final IDispenseBehavior P = new DispenseBehaviorItem(); + + public BlockDropper() {} + + protected IDispenseBehavior a(ItemStack itemstack) { + return this.P; + } + + public TileEntity a(World world, int i) { + return new TileEntityDropper(); + } + + public void dispense(World world, BlockPosition blockposition) { + SourceBlock sourceblock = new SourceBlock(world, blockposition); + TileEntityDispenser tileentitydispenser = (TileEntityDispenser) sourceblock.getTileEntity(); + + if (tileentitydispenser != null) { + int i = tileentitydispenser.m(); + + if (i < 0) { + world.triggerEffect(1001, blockposition, 0); + } else { + ItemStack itemstack = tileentitydispenser.getItem(i); + + if (itemstack != null) { + EnumDirection enumdirection = (EnumDirection) world.getType(blockposition).get(BlockDropper.FACING); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + IInventory iinventory = TileEntityHopper.b(world, (double) blockposition1.getX(), (double) blockposition1.getY(), (double) blockposition1.getZ()); + ItemStack itemstack1; + + if (iinventory == null) { + itemstack1 = this.P.a(sourceblock, itemstack); + if (itemstack1 != null && itemstack1.count <= 0) { + itemstack1 = null; + } + } else { + // CraftBukkit start - Fire event when pushing items into other inventories + CraftItemStack oitemstack = CraftItemStack.asCraftMirror(itemstack.cloneItemStack().cloneAndSubtract(1)); + + org.bukkit.inventory.Inventory destinationInventory; + // Have to special case large chests as they work oddly + if (iinventory instanceof InventoryLargeChest) { + destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); + } else { + destinationInventory = iinventory.getOwner().getInventory(); + } + + InventoryMoveItemEvent event = new InventoryMoveItemEvent(tileentitydispenser.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); + world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + itemstack1 = TileEntityHopper.addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), enumdirection.opposite()); + if (event.getItem().equals(oitemstack) && itemstack1 == null) { + // CraftBukkit end + itemstack1 = itemstack.cloneItemStack(); + if (--itemstack1.count <= 0) { + itemstack1 = null; + } + } else { + itemstack1 = itemstack.cloneItemStack(); + } + } + + tileentitydispenser.setItem(i, itemstack1); + } + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockEnderPortal.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockEnderPortal.java new file mode 100644 index 0000000..77bee15 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockEnderPortal.java @@ -0,0 +1,53 @@ +package net.minecraft.server; + +import java.util.List; +import java.util.Random; + +import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit + +public class BlockEnderPortal extends BlockContainer { + + protected BlockEnderPortal(Material material) { + super(material); + this.a(1.0F); + } + + public TileEntity a(World world, int i) { + return new TileEntityEnderPortal(); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + float f = 0.0625F; + + this.a(0.0F, 0.0F, 0.0F, 1.0F, f, 1.0F); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, AxisAlignedBB axisalignedbb, List list, Entity entity) {} + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public int a(Random random) { + return 0; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (entity.vehicle == null && entity.passenger == null && !world.isClientSide) { + // CraftBukkit start - Entity in portal + EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ())); + world.getServer().getPluginManager().callEvent(event); + // CraftBukkit end + entity.c(1); + } + + } + + public MaterialMapColor g(IBlockData iblockdata) { + return MaterialMapColor.E; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFalling.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFalling.java new file mode 100644 index 0000000..1d952b8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFalling.java @@ -0,0 +1,78 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockFalling extends Block { + + public static boolean instaFall; + + public BlockFalling() { + super(Material.SAND); + this.a(CreativeModeTab.b); + } + + public BlockFalling(Material material) { + super(material); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + world.a(blockposition, (Block) this, this.a(world)); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + world.a(blockposition, (Block) this, this.a(world)); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + this.f(world, blockposition); + } + + } + + private void f(World world, BlockPosition blockposition) { + if (canFall(world, blockposition.down()) && blockposition.getY() >= 0) { + byte b0 = 32; + + if (!BlockFalling.instaFall && world.areChunksLoadedBetween(blockposition.a(-b0, -b0, -b0), blockposition.a(b0, b0, b0))) { + if (!world.isClientSide) { + // PaperSpigot start - Add FallingBlock source location API + org.bukkit.Location loc = new org.bukkit.Location(world.getWorld(), (double) ((float) blockposition.getX() + 0.5F), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + 0.5F)); + EntityFallingBlock entityfallingblock = new EntityFallingBlock(loc, world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, world.getType(blockposition)); + // PaperSpigot end + + this.a(entityfallingblock); + world.addEntity(entityfallingblock); + } + } else { + world.setAir(blockposition); + + BlockPosition blockposition1; + + for (blockposition1 = blockposition.down(); canFall(world, blockposition1) && blockposition1.getY() > 0; blockposition1 = blockposition1.down()) { + ; + } + + if (blockposition1.getY() > 0) { + world.setTypeUpdate(blockposition1.up(), this.getBlockData()); + } + } + + } + } + + protected void a(EntityFallingBlock entityfallingblock) {} + + public int a(World world) { + return 2; + } + + public static boolean canFall(World world, BlockPosition blockposition) { + Block block = world.getType(blockposition).getBlock(); + Material material = block.material; + + return block == Blocks.FIRE || material == Material.AIR || material == Material.WATER || material == Material.LAVA; + } + + public void a_(World world, BlockPosition blockposition) {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFire.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFire.java new file mode 100644 index 0000000..76cd512 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFire.java @@ -0,0 +1,367 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Map; +import java.util.Random; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockSpreadEvent; +// CraftBukkit end + +public class BlockFire extends Block { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 15); + public static final BlockStateBoolean FLIP = BlockStateBoolean.of("flip"); + public static final BlockStateBoolean ALT = BlockStateBoolean.of("alt"); + public static final BlockStateBoolean NORTH = BlockStateBoolean.of("north"); + public static final BlockStateBoolean EAST = BlockStateBoolean.of("east"); + public static final BlockStateBoolean SOUTH = BlockStateBoolean.of("south"); + public static final BlockStateBoolean WEST = BlockStateBoolean.of("west"); + public static final BlockStateInteger UPPER = BlockStateInteger.of("upper", 0, 2); + private final Map flameChances = Maps.newIdentityHashMap(); + private final Map U = Maps.newIdentityHashMap(); + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + int i = blockposition.getX(); + int j = blockposition.getY(); + int k = blockposition.getZ(); + + if (!World.a(iblockaccess, blockposition.down()) && !Blocks.FIRE.e(iblockaccess, blockposition.down())) { + boolean flag = (i + j + k & 1) == 1; + boolean flag1 = (i / 2 + j / 2 + k / 2 & 1) == 1; + int l = 0; + + if (this.e(iblockaccess, blockposition.up())) { + l = flag ? 1 : 2; + } + + return iblockdata.set(BlockFire.NORTH, Boolean.valueOf(this.e(iblockaccess, blockposition.north()))).set(BlockFire.EAST, Boolean.valueOf(this.e(iblockaccess, blockposition.east()))).set(BlockFire.SOUTH, Boolean.valueOf(this.e(iblockaccess, blockposition.south()))).set(BlockFire.WEST, Boolean.valueOf(this.e(iblockaccess, blockposition.west()))).set(BlockFire.UPPER, Integer.valueOf(l)).set(BlockFire.FLIP, Boolean.valueOf(flag1)).set(BlockFire.ALT, Boolean.valueOf(flag)); + } else { + return this.getBlockData(); + } + } + + protected BlockFire() { + super(Material.FIRE); + this.j(this.blockStateList.getBlockData().set(BlockFire.AGE, Integer.valueOf(0)).set(BlockFire.FLIP, Boolean.valueOf(false)).set(BlockFire.ALT, Boolean.valueOf(false)).set(BlockFire.NORTH, Boolean.valueOf(false)).set(BlockFire.EAST, Boolean.valueOf(false)).set(BlockFire.SOUTH, Boolean.valueOf(false)).set(BlockFire.WEST, Boolean.valueOf(false)).set(BlockFire.UPPER, Integer.valueOf(0))); + this.a(true); + } + + public static void l() { + Blocks.FIRE.a(Blocks.PLANKS, 5, 20); + Blocks.FIRE.a(Blocks.DOUBLE_WOODEN_SLAB, 5, 20); + Blocks.FIRE.a(Blocks.WOODEN_SLAB, 5, 20); + Blocks.FIRE.a(Blocks.FENCE_GATE, 5, 20); + Blocks.FIRE.a(Blocks.SPRUCE_FENCE_GATE, 5, 20); + Blocks.FIRE.a(Blocks.BIRCH_FENCE_GATE, 5, 20); + Blocks.FIRE.a(Blocks.JUNGLE_FENCE_GATE, 5, 20); + Blocks.FIRE.a(Blocks.DARK_OAK_FENCE_GATE, 5, 20); + Blocks.FIRE.a(Blocks.ACACIA_FENCE_GATE, 5, 20); + Blocks.FIRE.a(Blocks.FENCE, 5, 20); + Blocks.FIRE.a(Blocks.SPRUCE_FENCE, 5, 20); + Blocks.FIRE.a(Blocks.BIRCH_FENCE, 5, 20); + Blocks.FIRE.a(Blocks.JUNGLE_FENCE, 5, 20); + Blocks.FIRE.a(Blocks.DARK_OAK_FENCE, 5, 20); + Blocks.FIRE.a(Blocks.ACACIA_FENCE, 5, 20); + Blocks.FIRE.a(Blocks.OAK_STAIRS, 5, 20); + Blocks.FIRE.a(Blocks.BIRCH_STAIRS, 5, 20); + Blocks.FIRE.a(Blocks.SPRUCE_STAIRS, 5, 20); + Blocks.FIRE.a(Blocks.JUNGLE_STAIRS, 5, 20); + Blocks.FIRE.a(Blocks.LOG, 5, 5); + Blocks.FIRE.a(Blocks.LOG2, 5, 5); + Blocks.FIRE.a(Blocks.LEAVES, 30, 60); + Blocks.FIRE.a(Blocks.LEAVES2, 30, 60); + Blocks.FIRE.a(Blocks.BOOKSHELF, 30, 20); + Blocks.FIRE.a(Blocks.TNT, 15, 100); + Blocks.FIRE.a(Blocks.TALLGRASS, 60, 100); + Blocks.FIRE.a(Blocks.DOUBLE_PLANT, 60, 100); + Blocks.FIRE.a(Blocks.YELLOW_FLOWER, 60, 100); + Blocks.FIRE.a(Blocks.RED_FLOWER, 60, 100); + Blocks.FIRE.a(Blocks.DEADBUSH, 60, 100); + Blocks.FIRE.a(Blocks.WOOL, 30, 60); + Blocks.FIRE.a(Blocks.VINE, 15, 100); + Blocks.FIRE.a(Blocks.COAL_BLOCK, 5, 5); + Blocks.FIRE.a(Blocks.HAY_BLOCK, 60, 20); + Blocks.FIRE.a(Blocks.CARPET, 60, 20); + } + + public void a(Block block, int i, int j) { + this.flameChances.put(block, Integer.valueOf(i)); + this.U.put(block, Integer.valueOf(j)); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public int a(Random random) { + return 0; + } + + public int a(World world) { + return 30; + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (world.getGameRules().getBoolean("doFireTick")) { + if (!this.canPlace(world, blockposition)) { + fireExtinguished(world, blockposition); // CraftBukkit - invalid place location + } + + Block block = world.getType(blockposition.down()).getBlock(); + boolean flag = block == Blocks.NETHERRACK; + + if (world.worldProvider instanceof WorldProviderTheEnd && block == Blocks.BEDROCK) { + flag = true; + } + + if (!flag && world.S() && this.e(world, blockposition)) { + fireExtinguished(world, blockposition); // CraftBukkit - extinguished by rain + } else { + int i = ((Integer) iblockdata.get(BlockFire.AGE)).intValue(); + + if (i < 15) { + iblockdata = iblockdata.set(BlockFire.AGE, Integer.valueOf(i + random.nextInt(3) / 2)); + world.setTypeAndData(blockposition, iblockdata, 4); + } + + world.a(blockposition, (Block) this, this.a(world) + random.nextInt(10)); + if (!flag) { + if (!this.f(world, blockposition)) { + if (!World.a((IBlockAccess) world, blockposition.down()) || i > 3) { + fireExtinguished(world, blockposition); // CraftBukkit + } + + return; + } + + if (!this.e((IBlockAccess) world, blockposition.down()) && i == 15 && random.nextInt(4) == 0) { + fireExtinguished(world, blockposition); // CraftBukkit + return; + } + } + + boolean flag1 = world.D(blockposition); + byte b0 = 0; + + if (flag1) { + b0 = -50; + } + + this.a(world, blockposition.east(), 300 + b0, random, i); + this.a(world, blockposition.west(), 300 + b0, random, i); + this.a(world, blockposition.down(), 250 + b0, random, i); + this.a(world, blockposition.up(), 250 + b0, random, i); + this.a(world, blockposition.north(), 300 + b0, random, i); + this.a(world, blockposition.south(), 300 + b0, random, i); + + for (int j = -1; j <= 1; ++j) { + for (int k = -1; k <= 1; ++k) { + for (int l = -1; l <= 4; ++l) { + if (j != 0 || l != 0 || k != 0) { + int i1 = 100; + + if (l > 1) { + i1 += (l - 1) * 100; + } + + BlockPosition blockposition1 = blockposition.a(j, l, k); + int j1 = this.m(world, blockposition1); + + if (j1 > 0) { + int k1 = (j1 + 40 + world.getDifficulty().a() * 7) / (i + 30); + + if (flag1) { + k1 /= 2; + } + + if (k1 > 0 && random.nextInt(i1) <= k1 && (!world.S() || !this.e(world, blockposition1))) { + int l1 = i + random.nextInt(5) / 4; + + if (l1 > 15) { + l1 = 15; + } + + // CraftBukkit start - Call to stop spread of fire + if (world.getType(blockposition1) != Blocks.FIRE) { + if (CraftEventFactory.callBlockIgniteEvent(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), blockposition.getX(), blockposition.getY(), blockposition.getZ()).isCancelled()) { + continue; + } + + org.bukkit.Server server = world.getServer(); + org.bukkit.World bworld = world.getWorld(); + org.bukkit.block.BlockState blockState = bworld.getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()).getState(); + blockState.setTypeId(Block.getId(this)); + blockState.setData(new org.bukkit.material.MaterialData(Block.getId(this), (byte) l1)); + + BlockSpreadEvent spreadEvent = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), blockState); + server.getPluginManager().callEvent(spreadEvent); + + if (!spreadEvent.isCancelled()) { + blockState.update(true); + } + } + // CraftBukkit end + } + } + } + } + } + } + + } + } + } + + protected boolean e(World world, BlockPosition blockposition) { + return world.isRainingAt(blockposition) || world.isRainingAt(blockposition.west()) || world.isRainingAt(blockposition.east()) || world.isRainingAt(blockposition.north()) || world.isRainingAt(blockposition.south()); + } + + public boolean N() { + return false; + } + + private int c(Block block) { + Integer integer = (Integer) this.U.get(block); + + return integer == null ? 0 : integer.intValue(); + } + + private int d(Block block) { + Integer integer = (Integer) this.flameChances.get(block); + + return integer == null ? 0 : integer.intValue(); + } + + private void a(World world, BlockPosition blockposition, int i, Random random, int j) { + int k = this.c(world.getType(blockposition).getBlock()); + + if (random.nextInt(i) < k) { + IBlockData iblockdata = world.getType(blockposition); + + // CraftBukkit start + org.bukkit.block.Block theBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + BlockBurnEvent event = new BlockBurnEvent(theBlock); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + // CraftBukkit end + + if (random.nextInt(j + 10) < 5 && !world.isRainingAt(blockposition)) { + int l = j + random.nextInt(5) / 4; + + if (l > 15) { + l = 15; + } + + world.setTypeAndData(blockposition, this.getBlockData().set(BlockFire.AGE, Integer.valueOf(l)), 3); + } else { + fireExtinguished(world, blockposition); // CraftBukkit + } + + if (iblockdata.getBlock() == Blocks.TNT) { + Blocks.TNT.postBreak(world, blockposition, iblockdata.set(BlockTNT.EXPLODE, Boolean.valueOf(true))); + } + } + + } + + private boolean f(World world, BlockPosition blockposition) { + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + if (this.e((IBlockAccess) world, blockposition.shift(enumdirection))) { + return true; + } + } + + return false; + } + + private int m(World world, BlockPosition blockposition) { + if (!world.isEmpty(blockposition)) { + return 0; + } else { + int i = 0; + EnumDirection[] aenumdirection = EnumDirection.values(); + int j = aenumdirection.length; + + for (int k = 0; k < j; ++k) { + EnumDirection enumdirection = aenumdirection[k]; + + i = Math.max(this.d(world.getType(blockposition.shift(enumdirection)).getBlock()), i); + } + + return i; + } + } + + public boolean A() { + return false; + } + + public boolean e(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.d(iblockaccess.getType(blockposition).getBlock()) > 0; + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return World.a((IBlockAccess) world, blockposition.down()) || this.f(world, blockposition); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!World.a((IBlockAccess) world, blockposition.down()) && !this.f(world, blockposition)) { + fireExtinguished(world, blockposition); // CraftBukkit - fuel block gone + } + + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (world.worldProvider.getDimension() > 0 || !Blocks.PORTAL.e(world, blockposition)) { + if (!World.a((IBlockAccess) world, blockposition.down()) && !this.f(world, blockposition)) { + fireExtinguished(world, blockposition); // CraftBukkit - fuel block broke + } else { + world.a(blockposition, (Block) this, this.a(world) + world.random.nextInt(10)); + } + } + } + + public MaterialMapColor g(IBlockData iblockdata) { + return MaterialMapColor.f; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockFire.AGE, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockFire.AGE)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockFire.AGE, BlockFire.NORTH, BlockFire.EAST, BlockFire.SOUTH, BlockFire.WEST, BlockFire.UPPER, BlockFire.FLIP, BlockFire.ALT}); + } + + // CraftBukkit start + private void fireExtinguished(World world, BlockPosition position) { + if (!CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), Blocks.AIR).isCancelled()) { + world.setAir(position); + } + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFlowerPot.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFlowerPot.java new file mode 100644 index 0000000..ce46138 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFlowerPot.java @@ -0,0 +1,433 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockFlowerPot extends BlockContainer { + + public static final BlockStateInteger LEGACY_DATA = BlockStateInteger.of("legacy_data", 0, 15); + public static final BlockStateEnum CONTENTS = BlockStateEnum.of("contents", BlockFlowerPot.EnumFlowerPotContents.class); + + public BlockFlowerPot() { + super(Material.ORIENTABLE); + this.j(this.blockStateList.getBlockData().set(BlockFlowerPot.CONTENTS, BlockFlowerPot.EnumFlowerPotContents.EMPTY).set(BlockFlowerPot.LEGACY_DATA, Integer.valueOf(0))); + this.j(); + } + + public String getName() { + return LocaleI18n.get("item.flowerPot.name"); + } + + public void j() { + float f = 0.375F; + float f1 = f / 2.0F; + + this.a(0.5F - f1, 0.0F, 0.5F - f1, 0.5F + f1, f, 0.5F + f1); + } + + public boolean c() { + return false; + } + + public int b() { + return 3; + } + + public boolean d() { + return false; + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() instanceof ItemBlock) { + TileEntityFlowerPot tileentityflowerpot = this.f(world, blockposition); + + if (tileentityflowerpot == null) { + return false; + } else if (tileentityflowerpot.b() != null) { + return false; + } else { + Block block = Block.asBlock(itemstack.getItem()); + + if (!this.a(block, itemstack.getData())) { + return false; + } else { + tileentityflowerpot.a(itemstack.getItem(), itemstack.getData()); + tileentityflowerpot.update(); + world.notify(blockposition); + entityhuman.b(StatisticList.T); + if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + + return true; + } + } + } else { + return false; + } + } + + private boolean a(Block block, int i) { + return block != Blocks.YELLOW_FLOWER && block != Blocks.RED_FLOWER && block != Blocks.CACTUS && block != Blocks.BROWN_MUSHROOM && block != Blocks.RED_MUSHROOM && block != Blocks.SAPLING && block != Blocks.DEADBUSH ? block == Blocks.TALLGRASS && i == BlockLongGrass.EnumTallGrassType.FERN.a() : true; + } + + public int getDropData(World world, BlockPosition blockposition) { + TileEntityFlowerPot tileentityflowerpot = this.f(world, blockposition); + + return tileentityflowerpot != null && tileentityflowerpot.b() != null ? tileentityflowerpot.c() : 0; + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return super.canPlace(world, blockposition) && World.a((IBlockAccess) world, blockposition.down()); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!World.a((IBlockAccess) world, blockposition.down())) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + TileEntityFlowerPot tileentityflowerpot = this.f(world, blockposition); + + if (tileentityflowerpot != null && tileentityflowerpot.b() != null) { + a(world, blockposition, new ItemStack(tileentityflowerpot.b(), 1, tileentityflowerpot.c())); + tileentityflowerpot.a( null, 0 ); // Spigot + } + + super.remove(world, blockposition, iblockdata); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { + super.a(world, blockposition, iblockdata, entityhuman); + if (entityhuman.abilities.canInstantlyBuild) { + TileEntityFlowerPot tileentityflowerpot = this.f(world, blockposition); + + if (tileentityflowerpot != null) { + tileentityflowerpot.a((Item) null, 0); + } + } + + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Items.FLOWER_POT; + } + + private TileEntityFlowerPot f(World world, BlockPosition blockposition) { + TileEntity tileentity = world.getTileEntity(blockposition); + + return tileentity instanceof TileEntityFlowerPot ? (TileEntityFlowerPot) tileentity : null; + } + + public TileEntity a(World world, int i) { + Object object = null; + int j = 0; + + switch (i) { + case 1: + object = Blocks.RED_FLOWER; + j = BlockFlowers.EnumFlowerVarient.POPPY.b(); + break; + + case 2: + object = Blocks.YELLOW_FLOWER; + break; + + case 3: + object = Blocks.SAPLING; + j = BlockWood.EnumLogVariant.OAK.a(); + break; + + case 4: + object = Blocks.SAPLING; + j = BlockWood.EnumLogVariant.SPRUCE.a(); + break; + + case 5: + object = Blocks.SAPLING; + j = BlockWood.EnumLogVariant.BIRCH.a(); + break; + + case 6: + object = Blocks.SAPLING; + j = BlockWood.EnumLogVariant.JUNGLE.a(); + break; + + case 7: + object = Blocks.RED_MUSHROOM; + break; + + case 8: + object = Blocks.BROWN_MUSHROOM; + break; + + case 9: + object = Blocks.CACTUS; + break; + + case 10: + object = Blocks.DEADBUSH; + break; + + case 11: + object = Blocks.TALLGRASS; + j = BlockLongGrass.EnumTallGrassType.FERN.a(); + break; + + case 12: + object = Blocks.SAPLING; + j = BlockWood.EnumLogVariant.ACACIA.a(); + break; + + case 13: + object = Blocks.SAPLING; + j = BlockWood.EnumLogVariant.DARK_OAK.a(); + } + + return new TileEntityFlowerPot(Item.getItemOf((Block) object), j); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockFlowerPot.CONTENTS, BlockFlowerPot.LEGACY_DATA}); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockFlowerPot.LEGACY_DATA)).intValue(); + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + BlockFlowerPot.EnumFlowerPotContents blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.EMPTY; + TileEntity tileentity = iblockaccess.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityFlowerPot) { + TileEntityFlowerPot tileentityflowerpot = (TileEntityFlowerPot) tileentity; + Item item = tileentityflowerpot.b(); + + if (item instanceof ItemBlock) { + int i = tileentityflowerpot.c(); + Block block = Block.asBlock(item); + + if (block == Blocks.SAPLING) { + switch (BlockFlowerPot.SyntheticClass_1.a[BlockWood.EnumLogVariant.a(i).ordinal()]) { + case 1: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.OAK_SAPLING; + break; + + case 2: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.SPRUCE_SAPLING; + break; + + case 3: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.BIRCH_SAPLING; + break; + + case 4: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.JUNGLE_SAPLING; + break; + + case 5: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.ACACIA_SAPLING; + break; + + case 6: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.DARK_OAK_SAPLING; + break; + + default: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.EMPTY; + } + } else if (block == Blocks.TALLGRASS) { + switch (i) { + case 0: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.DEAD_BUSH; + break; + + case 2: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.FERN; + break; + + default: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.EMPTY; + } + } else if (block == Blocks.YELLOW_FLOWER) { + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.DANDELION; + } else if (block == Blocks.RED_FLOWER) { + switch (BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.a(BlockFlowers.EnumFlowerType.RED, i).ordinal()]) { + case 1: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.POPPY; + break; + + case 2: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.BLUE_ORCHID; + break; + + case 3: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.ALLIUM; + break; + + case 4: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.HOUSTONIA; + break; + + case 5: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.RED_TULIP; + break; + + case 6: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.ORANGE_TULIP; + break; + + case 7: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.WHITE_TULIP; + break; + + case 8: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.PINK_TULIP; + break; + + case 9: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.OXEYE_DAISY; + break; + + default: + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.EMPTY; + } + } else if (block == Blocks.RED_MUSHROOM) { + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.MUSHROOM_RED; + } else if (block == Blocks.BROWN_MUSHROOM) { + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.MUSHROOM_BROWN; + } else if (block == Blocks.DEADBUSH) { + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.DEAD_BUSH; + } else if (block == Blocks.CACTUS) { + blockflowerpot_enumflowerpotcontents = BlockFlowerPot.EnumFlowerPotContents.CACTUS; + } + } + } + + return iblockdata.set(BlockFlowerPot.CONTENTS, blockflowerpot_enumflowerpotcontents); + } + + static class SyntheticClass_1 { + + static final int[] a; + static final int[] b = new int[BlockFlowers.EnumFlowerVarient.values().length]; + + static { + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.POPPY.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.BLUE_ORCHID.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.ALLIUM.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.HOUSTONIA.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.RED_TULIP.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.ORANGE_TULIP.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror5) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.WHITE_TULIP.ordinal()] = 7; + } catch (NoSuchFieldError nosuchfielderror6) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.PINK_TULIP.ordinal()] = 8; + } catch (NoSuchFieldError nosuchfielderror7) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.b[BlockFlowers.EnumFlowerVarient.OXEYE_DAISY.ordinal()] = 9; + } catch (NoSuchFieldError nosuchfielderror8) { + ; + } + + a = new int[BlockWood.EnumLogVariant.values().length]; + + try { + BlockFlowerPot.SyntheticClass_1.a[BlockWood.EnumLogVariant.OAK.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror9) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.a[BlockWood.EnumLogVariant.SPRUCE.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror10) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.a[BlockWood.EnumLogVariant.BIRCH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror11) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.a[BlockWood.EnumLogVariant.JUNGLE.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror12) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.a[BlockWood.EnumLogVariant.ACACIA.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror13) { + ; + } + + try { + BlockFlowerPot.SyntheticClass_1.a[BlockWood.EnumLogVariant.DARK_OAK.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror14) { + ; + } + + } + } + + public static enum EnumFlowerPotContents implements INamable { + + EMPTY("empty"), POPPY("rose"), BLUE_ORCHID("blue_orchid"), ALLIUM("allium"), HOUSTONIA("houstonia"), RED_TULIP("red_tulip"), ORANGE_TULIP("orange_tulip"), WHITE_TULIP("white_tulip"), PINK_TULIP("pink_tulip"), OXEYE_DAISY("oxeye_daisy"), DANDELION("dandelion"), OAK_SAPLING("oak_sapling"), SPRUCE_SAPLING("spruce_sapling"), BIRCH_SAPLING("birch_sapling"), JUNGLE_SAPLING("jungle_sapling"), ACACIA_SAPLING("acacia_sapling"), DARK_OAK_SAPLING("dark_oak_sapling"), MUSHROOM_RED("mushroom_red"), MUSHROOM_BROWN("mushroom_brown"), DEAD_BUSH("dead_bush"), FERN("fern"), CACTUS("cactus"); + + private final String w; + + private EnumFlowerPotContents(String s) { + this.w = s; + } + + public String toString() { + return this.w; + } + + public String getName() { + return this.w; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFlowing.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFlowing.java new file mode 100644 index 0000000..23130ba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFlowing.java @@ -0,0 +1,339 @@ +package net.minecraft.server; + +import java.util.EnumSet; +import java.util.Iterator; +import java.util.Random; +import java.util.Set; + +// CraftBukkit start +import org.bukkit.block.BlockFace; +import org.bukkit.event.block.BlockFromToEvent; +// CraftBukkit end + +public class BlockFlowing extends BlockFluids { + + int a; + + protected BlockFlowing(Material material) { + super(material); + } + + private void f(World world, BlockPosition blockposition, IBlockData iblockdata) { + world.setTypeAndData(blockposition, b(this.material).getBlockData().set(BlockFlowing.LEVEL, iblockdata.get(BlockFlowing.LEVEL)), 2); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + // CraftBukkit start + org.bukkit.World bworld = world.getWorld(); + org.bukkit.Server server = world.getServer(); + org.bukkit.block.Block source = bworld == null ? null : bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + // CraftBukkit end + int i = ((Integer) iblockdata.get(BlockFlowing.LEVEL)).intValue(); + byte b0 = 1; + + if (this.material == Material.LAVA && !world.worldProvider.n()) { + b0 = 2; + } + + int j = this.getFlowSpeed(world, blockposition); // PaperSpigot + int k; + + if (i > 0) { + int l = -100; + + this.a = 0; + + EnumDirection enumdirection; + + for (Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); iterator.hasNext(); l = this.a(world, blockposition.shift(enumdirection), l)) { + enumdirection = (EnumDirection) iterator.next(); + } + + int i1 = l + b0; + + if (i1 >= 8 || l < 0) { + i1 = -1; + } + + if (this.e(world, blockposition.up()) >= 0) { + k = this.e(world, blockposition.up()); + if (k >= 8) { + i1 = k; + } else { + i1 = k + 8; + } + } + + if (this.a >= 2 && this.material == Material.WATER) { + IBlockData iblockdata1 = world.getType(blockposition.down()); + + if (iblockdata1.getBlock().getMaterial().isBuildable()) { + i1 = 0; + } else if (iblockdata1.getBlock().getMaterial() == this.material && ((Integer) iblockdata1.get(BlockFlowing.LEVEL)).intValue() == 0) { + i1 = 0; + } + } + + if (!world.paperSpigotConfig.fastDrainLava && this.material == Material.LAVA && i < 8 && i1 < 8 && i1 > i && random.nextInt(4) != 0) { // PaperSpigot + j *= 4; + } + + if (i1 == i) { + this.f(world, blockposition, iblockdata); + } else { + i = i1; + if (i1 < 0 || canFastDrain(world, blockposition)) { // PaperSpigot - Fast draining + world.setAir(blockposition); + } else { + iblockdata = iblockdata.set(BlockFlowing.LEVEL, Integer.valueOf(i1)); + world.setTypeAndData(blockposition, iblockdata, 2); + world.a(blockposition, (Block) this, j); + // PaperSpigot start - Optimize draining + world.d(blockposition.west(), this); + world.d(blockposition.east(), this); + world.d(blockposition.up(), this); + world.d(blockposition.north(), this); + world.d(blockposition.south(), this); + world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, blockposition); // Spigot + // PaperSpigot end + } + } + } else { + this.f(world, blockposition, iblockdata); + } + + if (world.getType(blockposition).getBlock().getMaterial() != material) return; // PaperSpigot - Stop updating flowing block if material has changed + IBlockData iblockdata2 = world.getType(blockposition.down()); + + if (this.h(world, blockposition.down(), iblockdata2)) { + // CraftBukkit start - Send "down" to the server + BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN); + if (server != null) { + server.getPluginManager().callEvent(event); + } + if (!event.isCancelled()) { + if (this.material == Material.LAVA && world.getType(blockposition.down()).getBlock().getMaterial() == Material.WATER) { + world.setTypeUpdate(blockposition.down(), Blocks.STONE.getBlockData()); + this.fizz(world, blockposition.down()); + return; + } + + if (i >= 8) { + this.flow(world, blockposition.down(), iblockdata2, i); + } else { + this.flow(world, blockposition.down(), iblockdata2, i + 8); + } + } + // CraftBukkit end + } else if (i >= 0 && (i == 0 || this.g(world, blockposition.down(), iblockdata2))) { + Set set = this.f(world, blockposition); + + k = i + b0; + if (i >= 8) { + k = 1; + } + + if (k >= 8) { + return; + } + + Iterator iterator1 = set.iterator(); + + while (iterator1.hasNext()) { + EnumDirection enumdirection1 = (EnumDirection) iterator1.next(); + + // CraftBukkit start + BlockFromToEvent event = new BlockFromToEvent(source, org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection1)); + if (server != null) { + server.getPluginManager().callEvent(event); + } + + if (!event.isCancelled()) { + this.flow(world, blockposition.shift(enumdirection1), world.getType(blockposition.shift(enumdirection1)), k); + } + // CraftBukkit end + } + } + + } + + private void flow(World world, BlockPosition blockposition, IBlockData iblockdata, int i) { + if (world.isLoaded(blockposition) && this.h(world, blockposition, iblockdata)) { // CraftBukkit - add isLoaded check + if (iblockdata.getBlock() != Blocks.AIR) { + if (this.material == Material.LAVA) { + this.fizz(world, blockposition); + } else { + iblockdata.getBlock().b(world, blockposition, iblockdata, 0); + } + } + + world.setTypeAndData(blockposition, this.getBlockData().set(BlockFlowing.LEVEL, Integer.valueOf(i)), 3); + } + + } + + private int a(World world, BlockPosition blockposition, int i, EnumDirection enumdirection) { + int j = 1000; + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection1 = (EnumDirection) iterator.next(); + + if (enumdirection1 != enumdirection) { + BlockPosition blockposition1 = blockposition.shift(enumdirection1); + IBlockData iblockdata = world.getType(blockposition1); + + if (!this.g(world, blockposition1, iblockdata) && (iblockdata.getBlock().getMaterial() != this.material || ((Integer) iblockdata.get(BlockFlowing.LEVEL)).intValue() > 0)) { + if (!this.g(world, blockposition1.down(), iblockdata)) { + return i; + } + + if (i < 4) { + int k = this.a(world, blockposition1, i + 1, enumdirection1.opposite()); + + if (k < j) { + j = k; + } + } + } + } + } + + return j; + } + + private Set f(World world, BlockPosition blockposition) { + int i = 1000; + EnumSet enumset = EnumSet.noneOf(EnumDirection.class); + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + IBlockData iblockdata = world.getType(blockposition1); + + if (!this.g(world, blockposition1, iblockdata) && (iblockdata.getBlock().getMaterial() != this.material || ((Integer) iblockdata.get(BlockFlowing.LEVEL)).intValue() > 0)) { + int j; + + if (this.g(world, blockposition1.down(), world.getType(blockposition1.down()))) { + j = this.a(world, blockposition1, 1, enumdirection.opposite()); + } else { + j = 0; + } + + if (j < i) { + enumset.clear(); + } + + if (j <= i) { + enumset.add(enumdirection); + i = j; + } + } + } + + return enumset; + } + + private boolean g(World world, BlockPosition blockposition, IBlockData iblockdata) { + Block block = world.getType(blockposition).getBlock(); + + return !(block instanceof BlockDoor) && block != Blocks.STANDING_SIGN && block != Blocks.LADDER && block != Blocks.REEDS ? (block.material == Material.PORTAL ? true : block.material.isSolid()) : true; + } + + protected int a(World world, BlockPosition blockposition, int i) { + int j = this.e(world, blockposition); + + if (j < 0) { + return i; + } else { + if (j == 0) { + ++this.a; + } + + if (j >= 8) { + j = 0; + } + + return i >= 0 && j >= i ? i : j; + } + } + + private boolean h(World world, BlockPosition blockposition, IBlockData iblockdata) { + Material material = iblockdata.getBlock().getMaterial(); + + return material != this.material && material != Material.LAVA && !this.g(world, blockposition, iblockdata); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!this.e(world, blockposition, iblockdata)) { + world.a(blockposition, (Block) this, this.getFlowSpeed(world, blockposition)); // PaperSpigot + } + + } + + /** + * PaperSpigot - Get flow speed. Throttle if its water and flowing adjacent to lava + */ + public int getFlowSpeed(World world, BlockPosition blockposition) { + if (this.getMaterial() == Material.LAVA) { + return world.worldProvider.o() ? world.paperSpigotConfig.lavaFlowSpeedNether : world.paperSpigotConfig.lavaFlowSpeedNormal; + } + if (this.getMaterial() == Material.WATER && ( + world.getType(blockposition.north(1)).getBlock().getMaterial() == Material.LAVA || + world.getType(blockposition.south(1)).getBlock().getMaterial() == Material.LAVA || + world.getType(blockposition.west(1)).getBlock().getMaterial() == Material.LAVA || + world.getType(blockposition.east(1)).getBlock().getMaterial() == Material.LAVA)) { + return world.paperSpigotConfig.waterOverLavaFlowSpeed; + } + return super.a(world); + } + + /** + * PaperSpigot - Data check method for fast draining + */ + public int getData(World world, BlockPosition position) { + int data = this.e(world, position); + return data < 8 ? data : 0; + } + + /** + * PaperSpigot - Checks surrounding blocks to determine if block can be fast drained + */ + public boolean canFastDrain(World world, BlockPosition position) { + boolean result = false; + int data = getData(world, position); + if (this.material == Material.WATER) { + if (world.paperSpigotConfig.fastDrainWater) { + result = true; + if (getData(world, position.down()) < 0) { + result = false; + } else if (world.getType(position.north()).getBlock().getMaterial() == Material.WATER && getData(world, position.north()) < data) { + result = false; + } else if (world.getType(position.south()).getBlock().getMaterial() == Material.WATER && getData(world, position.south()) < data) { + result = false; + } else if (world.getType(position.west()).getBlock().getMaterial() == Material.WATER && getData(world, position.west()) < data) { + result = false; + } else if (world.getType(position.east()).getBlock().getMaterial() == Material.WATER && getData(world, position.east()) < data) { + result = false; + } + } + } else if (this.material == Material.LAVA) { + if (world.paperSpigotConfig.fastDrainLava) { + result = true; + if (getData(world, position.down()) < 0 || world.getType(position.up()).getBlock().getMaterial() != Material.AIR) { + result = false; + } else if (world.getType(position.north()).getBlock().getMaterial() == Material.LAVA && getData(world, position.north()) < data) { + result = false; + } else if (world.getType(position.south()).getBlock().getMaterial() == Material.LAVA && getData(world, position.south()) < data) { + result = false; + } else if (world.getType(position.west()).getBlock().getMaterial() == Material.LAVA && getData(world, position.west()) < data) { + result = false; + } else if (world.getType(position.east()).getBlock().getMaterial() == Material.LAVA && getData(world, position.east()) < data) { + result = false; + } + } + } + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFluids.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFluids.java new file mode 100644 index 0000000..db73f5d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockFluids.java @@ -0,0 +1,212 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Random; + +public abstract class BlockFluids extends Block { + + public static final BlockStateInteger LEVEL = BlockStateInteger.of("level", 0, 15); + + protected BlockFluids(Material material) { + super(material); + this.j(this.blockStateList.getBlockData().set(BlockFluids.LEVEL, Integer.valueOf(0))); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + this.a(true); + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition) { + return this.material != Material.LAVA; + } + + public static float b(int i) { + if (i >= 8) { + i = 0; + } + + return (float) (i + 1) / 9.0F; + } + + protected int e(IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockaccess.getType(blockposition).getBlock().getMaterial() == this.material ? ((Integer) iblockaccess.getType(blockposition).get(BlockFluids.LEVEL)).intValue() : -1; + } + + protected int f(IBlockAccess iblockaccess, BlockPosition blockposition) { + int i = this.e(iblockaccess, blockposition); + + return i >= 8 ? 0 : i; + } + + public boolean d() { + return false; + } + + public boolean c() { + return false; + } + + public boolean a(IBlockData iblockdata, boolean flag) { + return flag && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0; + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + Material material = iblockaccess.getType(blockposition).getBlock().getMaterial(); + + return material == this.material ? false : (enumdirection == EnumDirection.UP ? true : (material == Material.ICE ? false : super.b(iblockaccess, blockposition, enumdirection))); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public int b() { + return 1; + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return null; + } + + public int a(Random random) { + return 0; + } + + protected Vec3D h(IBlockAccess iblockaccess, BlockPosition blockposition) { + Vec3D vec3d = new Vec3D(0.0D, 0.0D, 0.0D); + int i = this.f(iblockaccess, blockposition); + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + EnumDirection enumdirection; + BlockPosition blockposition1; + + while (iterator.hasNext()) { + enumdirection = (EnumDirection) iterator.next(); + blockposition1 = blockposition.shift(enumdirection); + int j = this.f(iblockaccess, blockposition1); + int k; + + if (j < 0) { + if (!iblockaccess.getType(blockposition1).getBlock().getMaterial().isSolid()) { + j = this.f(iblockaccess, blockposition1.down()); + if (j >= 0) { + k = j - (i - 8); + vec3d = vec3d.add((double) ((blockposition1.getX() - blockposition.getX()) * k), (double) ((blockposition1.getY() - blockposition.getY()) * k), (double) ((blockposition1.getZ() - blockposition.getZ()) * k)); + } + } + } else if (j >= 0) { + k = j - i; + vec3d = vec3d.add((double) ((blockposition1.getX() - blockposition.getX()) * k), (double) ((blockposition1.getY() - blockposition.getY()) * k), (double) ((blockposition1.getZ() - blockposition.getZ()) * k)); + } + } + + if (((Integer) iblockaccess.getType(blockposition).get(BlockFluids.LEVEL)).intValue() >= 8) { + iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + enumdirection = (EnumDirection) iterator.next(); + blockposition1 = blockposition.shift(enumdirection); + if (this.b(iblockaccess, blockposition1, enumdirection) || this.b(iblockaccess, blockposition1.up(), enumdirection)) { + vec3d = vec3d.a().add(0.0D, -6.0D, 0.0D); + break; + } + } + } + + return vec3d.a(); + } + + public Vec3D a(World world, BlockPosition blockposition, Entity entity, Vec3D vec3d) { + return vec3d.e(this.h(world, blockposition)); + } + + public int a(World world) { + return this.material == Material.WATER ? 5 : (this.material == Material.LAVA ? (world.worldProvider.o() ? 10 : 30) : 0); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.e(world, blockposition, iblockdata); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + this.e(world, blockposition, iblockdata); + } + + public boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (this.material == Material.LAVA) { + boolean flag = false; + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + if (enumdirection != EnumDirection.DOWN && world.getType(blockposition.shift(enumdirection)).getBlock().getMaterial() == Material.WATER) { + flag = true; + break; + } + } + + if (flag) { + Integer integer = (Integer) iblockdata.get(BlockFluids.LEVEL); + + if (integer.intValue() == 0) { + world.setTypeUpdate(blockposition, Blocks.OBSIDIAN.getBlockData()); + this.fizz(world, blockposition); + return true; + } + + if (integer.intValue() > 0) { // PaperSpigot + world.setTypeUpdate(blockposition, Blocks.COBBLESTONE.getBlockData()); + this.fizz(world, blockposition); + return true; + } + } + } + + return false; + } + + protected void fizz(World world, BlockPosition blockposition) { + double d0 = (double) blockposition.getX(); + double d1 = (double) blockposition.getY(); + double d2 = (double) blockposition.getZ(); + + 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]); + } + + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockFluids.LEVEL, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockFluids.LEVEL}); + } + + public static BlockFlowing a(Material material) { + if (material == Material.WATER) { + return Blocks.FLOWING_WATER; + } else if (material == Material.LAVA) { + return Blocks.FLOWING_LAVA; + } else { + throw new IllegalArgumentException("Invalid material"); + } + } + + public static BlockStationary b(Material material) { + if (material == Material.WATER) { + return Blocks.WATER; + } else if (material == Material.LAVA) { + return Blocks.LAVA; + } else { + throw new IllegalArgumentException("Invalid material"); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockGrass.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockGrass.java new file mode 100644 index 0000000..557e357 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockGrass.java @@ -0,0 +1,136 @@ +package net.minecraft.server; + +import java.util.Random; + +// CraftBukkit start +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.BlockFadeEvent; +// CraftBukkit end + +public class BlockGrass extends Block implements IBlockFragilePlantElement { + + public static final BlockStateBoolean SNOWY = BlockStateBoolean.of("snowy"); + + protected BlockGrass() { + super(Material.GRASS); + this.j(this.blockStateList.getBlockData().set(BlockGrass.SNOWY, Boolean.valueOf(false))); + this.a(true); + this.a(CreativeModeTab.b); + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + Block block = iblockaccess.getType(blockposition.up()).getBlock(); + + return iblockdata.set(BlockGrass.SNOWY, Boolean.valueOf(block == Blocks.SNOW || block == Blocks.SNOW_LAYER)); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (world.getLightLevel(blockposition.up()) < 4 && world.getType(blockposition.up()).getBlock().p() > 2) { + // CraftBukkit start + // world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); + org.bukkit.World bworld = world.getWorld(); + BlockState blockState = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()).getState(); + blockState.setType(CraftMagicNumbers.getMaterial(Blocks.DIRT)); + + BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); + world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + blockState.update(true); + } + // CraftBukkit end + } else { + if (world.tacoSpigotConfig.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(); + IBlockData iblockdata1 = world.getType(blockposition1); + + if (iblockdata1.getBlock() == Blocks.DIRT && iblockdata1.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.DIRT && world.getLightLevel(blockposition1.up()) >= 4 && block.p() <= 2) { + // CraftBukkit start + // world.setTypeUpdate(blockposition1, Blocks.GRASS.getBlockData()); + org.bukkit.World bworld = world.getWorld(); + BlockState blockState = bworld.getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()).getState(); + blockState.setType(CraftMagicNumbers.getMaterial(Blocks.GRASS)); + + BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), blockState); + world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + blockState.update(true); + } + // CraftBukkit end + } + } + } + + } + } + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Blocks.DIRT.getDropType(Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, BlockDirt.EnumDirtVariant.DIRT), random, i); + } + + public boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return true; + } + + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return true; + } + + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + BlockPosition blockposition1 = blockposition.up(); + int i = 0; + + while (i < 128) { + BlockPosition blockposition2 = blockposition1; + int j = 0; + + while (true) { + if (j < i / 16) { + blockposition2 = blockposition2.a(random.nextInt(3) - 1, (random.nextInt(3) - 1) * random.nextInt(3) / 2, random.nextInt(3) - 1); + if (world.getType(blockposition2.down()).getBlock() == Blocks.GRASS && !world.getType(blockposition2).getBlock().isOccluding()) { + ++j; + continue; + } + } else if (world.getType(blockposition2).getBlock().material == Material.AIR) { + if (random.nextInt(8) == 0) { + BlockFlowers.EnumFlowerVarient blockflowers_enumflowervarient = world.getBiome(blockposition2).a(random, blockposition2); + BlockFlowers blockflowers = blockflowers_enumflowervarient.a().a(); + IBlockData iblockdata1 = blockflowers.getBlockData().set(blockflowers.n(), blockflowers_enumflowervarient); + + if (blockflowers.f(world, blockposition2, iblockdata1)) { + // world.setTypeAndData(blockposition2, iblockdata1, 3); // CraftBukkit + CraftEventFactory.handleBlockGrowEvent(world, blockposition2.getX(), blockposition2.getY(), blockposition2.getZ(), iblockdata1.getBlock(), iblockdata1.getBlock().toLegacyData(iblockdata1)); // CraftBukkit + } + } else { + IBlockData iblockdata2 = Blocks.TALLGRASS.getBlockData().set(BlockLongGrass.TYPE, BlockLongGrass.EnumTallGrassType.GRASS); + + if (Blocks.TALLGRASS.f(world, blockposition2, iblockdata2)) { + // world.setTypeAndData(blockposition2, iblockdata2, 3); // CraftBukkit + CraftEventFactory.handleBlockGrowEvent(world, blockposition2.getX(), blockposition2.getY(), blockposition2.getZ(), iblockdata2.getBlock(), iblockdata2.getBlock().toLegacyData(iblockdata2)); // CraftBukkit + } + } + } + + ++i; + break; + } + } + + } + + public int toLegacyData(IBlockData iblockdata) { + return 0; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockGrass.SNOWY}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockHopper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockHopper.java new file mode 100644 index 0000000..9f9b45d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockHopper.java @@ -0,0 +1,161 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.List; + +public class BlockHopper extends BlockContainer { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", new Predicate() { + public boolean a(EnumDirection enumdirection) { + return enumdirection != EnumDirection.UP; + } + + public boolean apply(Object object) { + return this.a((EnumDirection) object); + } + }); + public static final BlockStateBoolean ENABLED = BlockStateBoolean.of("enabled"); + + public BlockHopper() { + super(Material.ORE, MaterialMapColor.m); + this.j(this.blockStateList.getBlockData().set(BlockHopper.FACING, EnumDirection.DOWN).set(BlockHopper.ENABLED, Boolean.valueOf(true))); + this.a(CreativeModeTab.d); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, AxisAlignedBB axisalignedbb, List list, Entity entity) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F); + super.a(world, blockposition, iblockdata, axisalignedbb, list, entity); + float f = 0.125F; + + this.a(0.0F, 0.0F, 0.0F, f, 1.0F, 1.0F); + super.a(world, blockposition, iblockdata, axisalignedbb, list, entity); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, f); + super.a(world, blockposition, iblockdata, axisalignedbb, list, entity); + this.a(1.0F - f, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.a(world, blockposition, iblockdata, axisalignedbb, list, entity); + this.a(0.0F, 0.0F, 1.0F - f, 1.0F, 1.0F, 1.0F); + super.a(world, blockposition, iblockdata, axisalignedbb, list, entity); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + EnumDirection enumdirection1 = enumdirection.opposite(); + + if (enumdirection1 == EnumDirection.UP) { + enumdirection1 = EnumDirection.DOWN; + } + + return this.getBlockData().set(BlockHopper.FACING, enumdirection1).set(BlockHopper.ENABLED, Boolean.valueOf(true)); + } + + public TileEntity a(World world, int i) { + return new TileEntityHopper(); + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + super.postPlace(world, blockposition, iblockdata, entityliving, itemstack); + if (itemstack.hasName()) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityHopper) { + ((TileEntityHopper) tileentity).a(itemstack.getName()); + } + } + + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.e(world, blockposition, iblockdata); + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (world.isClientSide) { + return true; + } else { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityHopper) { + entityhuman.openContainer((TileEntityHopper) tileentity); + entityhuman.b(StatisticList.P); + } + + return true; + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + this.e(world, blockposition, iblockdata); + } + + private void e(World world, BlockPosition blockposition, IBlockData iblockdata) { + boolean flag = !world.isBlockIndirectlyPowered(blockposition); + + if (flag != ((Boolean) iblockdata.get(BlockHopper.ENABLED)).booleanValue()) { + world.setTypeAndData(blockposition, iblockdata.set(BlockHopper.ENABLED, Boolean.valueOf(flag)), 4); + } + + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityHopper) { + InventoryUtils.dropInventory(world, blockposition, (TileEntityHopper) tileentity); + world.updateAdjacentComparators(blockposition, this); + } + + super.remove(world, blockposition, iblockdata); + } + + public int b() { + return 3; + } + + public boolean d() { + return false; + } + + public boolean c() { + return false; + } + + public static EnumDirection b(int i) { + return EnumDirection.fromType1(i & 7); + } + + public static boolean f(int i) { + return (i & 8) != 8; + } + + public boolean isComplexRedstone() { + return true; + } + + public int l(World world, BlockPosition blockposition) { + return Container.a(world.getTileEntity(blockposition)); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockHopper.FACING, b(i)).set(BlockHopper.ENABLED, Boolean.valueOf(f(i))); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((EnumDirection) iblockdata.get(BlockHopper.FACING)).a(); + + if (!((Boolean) iblockdata.get(BlockHopper.ENABLED)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockHopper.FACING, BlockHopper.ENABLED}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockIce.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockIce.java new file mode 100644 index 0000000..be8bb5b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockIce.java @@ -0,0 +1,65 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockIce extends BlockHalfTransparent { + + public BlockIce() { + super(Material.ICE, false); + this.frictionFactor = 0.98F; + this.a(true); + this.a(CreativeModeTab.b); + } + + public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, TileEntity tileentity) { + entityhuman.b(StatisticList.MINE_BLOCK_COUNT[Block.getId(this)]); + entityhuman.applyExhaustion(0.025F); + if (this.I() && EnchantmentManager.hasSilkTouchEnchantment(entityhuman)) { + ItemStack itemstack = this.i(iblockdata); + + if (itemstack != null) { + a(world, blockposition, itemstack); + } + } else { + if (world.worldProvider.n()) { + world.setAir(blockposition); + return; + } + + int i = EnchantmentManager.getBonusBlockLootEnchantmentLevel(entityhuman); + + this.b(world, blockposition, iblockdata, i); + Material material = world.getType(blockposition.down()).getBlock().getMaterial(); + + if (material.isSolid() || material.isLiquid()) { + world.setTypeUpdate(blockposition, Blocks.FLOWING_WATER.getBlockData()); + } + } + + } + + public int a(Random random) { + return 0; + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (world.b(EnumSkyBlock.BLOCK, blockposition) > 11 - this.p()) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), world.worldProvider.n() ? Blocks.AIR : Blocks.WATER).isCancelled()) { + return; + } + // CraftBukkit end + + if (world.worldProvider.n()) { + world.setAir(blockposition); + } else { + this.b(world, blockposition, world.getType(blockposition), 0); + world.setTypeUpdate(blockposition, Blocks.WATER.getBlockData()); + } + } + } + + public int k() { + return 0; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockJukeBox.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockJukeBox.java new file mode 100644 index 0000000..b1bfb7e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockJukeBox.java @@ -0,0 +1,148 @@ +package net.minecraft.server; + +public class BlockJukeBox extends BlockContainer { + + public static final BlockStateBoolean HAS_RECORD = BlockStateBoolean.of("has_record"); + + protected BlockJukeBox() { + super(Material.WOOD, MaterialMapColor.l); + this.j(this.blockStateList.getBlockData().set(BlockJukeBox.HAS_RECORD, Boolean.valueOf(false))); + this.a(CreativeModeTab.c); + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (((Boolean) iblockdata.get(BlockJukeBox.HAS_RECORD)).booleanValue()) { + this.dropRecord(world, blockposition, iblockdata); + iblockdata = iblockdata.set(BlockJukeBox.HAS_RECORD, Boolean.valueOf(false)); + world.setTypeAndData(blockposition, iblockdata, 2); + return true; + } else { + return false; + } + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, ItemStack itemstack) { + if (!world.isClientSide) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof BlockJukeBox.TileEntityRecordPlayer) { + ((BlockJukeBox.TileEntityRecordPlayer) tileentity).setRecord(new ItemStack(itemstack.getItem(), 1, itemstack.getData())); + world.setTypeAndData(blockposition, iblockdata.set(BlockJukeBox.HAS_RECORD, Boolean.valueOf(true)), 2); + } + } + } + + public void dropRecord(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!world.isClientSide) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof BlockJukeBox.TileEntityRecordPlayer) { + BlockJukeBox.TileEntityRecordPlayer blockjukebox_tileentityrecordplayer = (BlockJukeBox.TileEntityRecordPlayer) tileentity; + ItemStack itemstack = blockjukebox_tileentityrecordplayer.getRecord(); + + if (itemstack != null) { + world.triggerEffect(1005, blockposition, 0); + world.a(blockposition, (String) null); + blockjukebox_tileentityrecordplayer.setRecord((ItemStack) null); + float f = 0.7F; + double d0 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; + double d1 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.2D + 0.6D; + double d2 = (double) (world.random.nextFloat() * f) + (double) (1.0F - f) * 0.5D; + ItemStack itemstack1 = itemstack.cloneItemStack(); + EntityItem entityitem = new EntityItem(world, (double) blockposition.getX() + d0, (double) blockposition.getY() + d1, (double) blockposition.getZ() + d2, itemstack1); + + entityitem.p(); + world.addEntity(entityitem); + } + } + } + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.dropRecord(world, blockposition, iblockdata); + super.remove(world, blockposition, iblockdata); + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + if (!world.isClientSide) { + super.dropNaturally(world, blockposition, iblockdata, f, 0); + } + } + + public TileEntity a(World world, int i) { + return new BlockJukeBox.TileEntityRecordPlayer(); + } + + public boolean isComplexRedstone() { + return true; + } + + public int l(World world, BlockPosition blockposition) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof BlockJukeBox.TileEntityRecordPlayer) { + ItemStack itemstack = ((BlockJukeBox.TileEntityRecordPlayer) tileentity).getRecord(); + + if (itemstack != null) { + return Item.getId(itemstack.getItem()) + 1 - Item.getId(Items.RECORD_13); + } + } + + return 0; + } + + public int b() { + return 3; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockJukeBox.HAS_RECORD, Boolean.valueOf(i > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Boolean) iblockdata.get(BlockJukeBox.HAS_RECORD)).booleanValue() ? 1 : 0; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockJukeBox.HAS_RECORD}); + } + + public static class TileEntityRecordPlayer extends TileEntity { + + private ItemStack record; + + public TileEntityRecordPlayer() {} + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("RecordItem", 10)) { + this.setRecord(ItemStack.createStack(nbttagcompound.getCompound("RecordItem"))); + } else if (nbttagcompound.getInt("Record") > 0) { + this.setRecord(new ItemStack(Item.getById(nbttagcompound.getInt("Record")), 1, 0)); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + if (this.getRecord() != null) { + nbttagcompound.set("RecordItem", this.getRecord().save(new NBTTagCompound())); + } + + } + + public ItemStack getRecord() { + return this.record; + } + + public void setRecord(ItemStack itemstack) { + // CraftBukkit start - There can only be one + if (itemstack != null) { + itemstack.count = 1; + } + // CraftBukkit end + this.record = itemstack; + this.update(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockLeaves.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockLeaves.java new file mode 100644 index 0000000..c9619df --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockLeaves.java @@ -0,0 +1,200 @@ +package net.minecraft.server; + +import org.bukkit.event.block.LeavesDecayEvent; + +import java.util.Random; + +public abstract class BlockLeaves extends BlockTransparent { + + public static final BlockStateBoolean DECAYABLE = BlockStateBoolean.of("decayable"); + public static final BlockStateBoolean CHECK_DECAY = BlockStateBoolean.of("check_decay"); + int[] N; + + public BlockLeaves() { + super(Material.LEAVES, false); + this.a(true); + this.a(CreativeModeTab.c); + this.c(0.2F); + this.e(1); + this.a(BlockLeaves.h); + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + byte b0 = 1; + int i = b0 + 1; + int j = blockposition.getX(); + int k = blockposition.getY(); + int l = blockposition.getZ(); + + if (world.areChunksLoadedBetween(j - i, k - i, l - i, j + i, k + i, l + i)) { + for (int i1 = -b0; i1 <= b0; ++i1) { + for (int j1 = -b0; j1 <= b0; ++j1) { + for (int k1 = -b0; k1 <= b0; ++k1) { + BlockPosition blockposition1 = blockposition.a(i1, j1, k1); + IBlockData iblockdata1 = world.getType(blockposition1); + + if (iblockdata1.getBlock().getMaterial() == Material.LEAVES && !iblockdata1.get(BlockLeaves.CHECK_DECAY).booleanValue()) { + world.setTypeAndData(blockposition1, iblockdata1.set(BlockLeaves.CHECK_DECAY, Boolean.valueOf(true)), 4); + } + } + } + } + } + + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (iblockdata.get(BlockLeaves.CHECK_DECAY).booleanValue() && iblockdata.get(BlockLeaves.DECAYABLE).booleanValue()) { + byte b0 = 4; + int i = b0 + 1; + int j = blockposition.getX(); + int k = blockposition.getY(); + int l = blockposition.getZ(); + byte b1 = 32; + int i1 = b1 * b1; + int j1 = b1 / 2; + + if (this.N == null) { + this.N = new int[b1 * b1 * b1]; + } + + if (world.areChunksLoadedBetween(j - i, k - i, l - i, j + i, k + i, l + i)) { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + int k1; + int l1; + int i2; + + for (k1 = -b0; k1 <= b0; ++k1) { + for (l1 = -b0; l1 <= b0; ++l1) { + for (i2 = -b0; i2 <= b0; ++i2) { + Block block = world.getType(blockposition_mutableblockposition.c(j + k1, k + l1, l + i2)).getBlock(); + + if (block != Blocks.LOG && block != Blocks.LOG2) { + if (block.getMaterial() == Material.LEAVES) { + this.N[(k1 + j1) * i1 + (l1 + j1) * b1 + i2 + j1] = -2; + } else { + this.N[(k1 + j1) * i1 + (l1 + j1) * b1 + i2 + j1] = -1; + } + } else { + this.N[(k1 + j1) * i1 + (l1 + j1) * b1 + i2 + j1] = 0; + } + } + } + } + + for (k1 = 1; k1 <= 4; ++k1) { + for (l1 = -b0; l1 <= b0; ++l1) { + for (i2 = -b0; i2 <= b0; ++i2) { + for (int j2 = -b0; j2 <= b0; ++j2) { + if (this.N[(l1 + j1) * i1 + (i2 + j1) * b1 + j2 + j1] == k1 - 1) { + if (this.N[(l1 + j1 - 1) * i1 + (i2 + j1) * b1 + j2 + j1] == -2) { + this.N[(l1 + j1 - 1) * i1 + (i2 + j1) * b1 + j2 + j1] = k1; + } + + if (this.N[(l1 + j1 + 1) * i1 + (i2 + j1) * b1 + j2 + j1] == -2) { + this.N[(l1 + j1 + 1) * i1 + (i2 + j1) * b1 + j2 + j1] = k1; + } + + if (this.N[(l1 + j1) * i1 + (i2 + j1 - 1) * b1 + j2 + j1] == -2) { + this.N[(l1 + j1) * i1 + (i2 + j1 - 1) * b1 + j2 + j1] = k1; + } + + if (this.N[(l1 + j1) * i1 + (i2 + j1 + 1) * b1 + j2 + j1] == -2) { + this.N[(l1 + j1) * i1 + (i2 + j1 + 1) * b1 + j2 + j1] = k1; + } + + if (this.N[(l1 + j1) * i1 + (i2 + j1) * b1 + (j2 + j1 - 1)] == -2) { + this.N[(l1 + j1) * i1 + (i2 + j1) * b1 + (j2 + j1 - 1)] = k1; + } + + if (this.N[(l1 + j1) * i1 + (i2 + j1) * b1 + j2 + j1 + 1] == -2) { + this.N[(l1 + j1) * i1 + (i2 + j1) * b1 + j2 + j1 + 1] = k1; + } + } + } + } + } + } + } + + int k2 = this.N[j1 * i1 + j1 * b1 + j1]; + + if (k2 >= 0) { + world.setTypeAndData(blockposition, iblockdata.set(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)), 4); + } else { + this.e(world, blockposition); + } + } + + } + } + + private void e(World world, BlockPosition blockposition) { + // CraftBukkit start + LeavesDecayEvent event = new LeavesDecayEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled() || world.getType(blockposition).getBlock() != this) { + return; + } + // CraftBukkit end + this.b(world, blockposition, world.getType(blockposition), 0); + world.setAir(blockposition); + } + + public int a(Random random) { + return random.nextInt(20) == 0 ? 1 : 0; + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Item.getItemOf(Blocks.SAPLING); + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + if (!world.isClientSide) { + int j = this.d(iblockdata); + + if (i > 0) { + j -= 2 << i; + if (j < 10) { + j = 10; + } + } + + if (world.random.nextInt(j) == 0) { + Item item = this.getDropType(iblockdata, world.random, i); + + a(world, blockposition, new ItemStack(item, 1, this.getDropData(iblockdata))); + } + + j = 200; + if (i > 0) { + j -= 10 << i; + if (j < 40) { + j = 40; + } + } + + this.a(world, blockposition, iblockdata, j); + } + + } + + protected void a(World world, BlockPosition blockposition, IBlockData iblockdata, int i) {} + + protected int d(IBlockData iblockdata) { + return 20; + } + + public boolean c() { + return !this.R; + } + + public boolean w() { + return false; + } + + public abstract BlockWood.EnumLogVariant b(int i); +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockLever.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockLever.java new file mode 100644 index 0000000..c9015eb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockLever.java @@ -0,0 +1,431 @@ +package net.minecraft.server; + +import java.util.Iterator; + +import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + +public class BlockLever extends Block { + + public static final BlockStateEnum FACING = BlockStateEnum.of("facing", BlockLever.EnumLeverPosition.class); + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); + + protected BlockLever() { + super(Material.ORIENTABLE); + this.j(this.blockStateList.getBlockData().set(BlockLever.FACING, BlockLever.EnumLeverPosition.NORTH).set(BlockLever.POWERED, Boolean.valueOf(false))); + this.a(CreativeModeTab.d); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public boolean canPlace(World world, BlockPosition blockposition, EnumDirection enumdirection) { + return a(world, blockposition, enumdirection.opposite()); + } + + public boolean canPlace(World world, BlockPosition blockposition) { + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + if (a(world, blockposition, enumdirection)) { + return true; + } + } + + return false; + } + + protected static boolean a(World world, BlockPosition blockposition, EnumDirection enumdirection) { + return BlockButtonAbstract.a(world, blockposition, enumdirection); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + IBlockData iblockdata = this.getBlockData().set(BlockLever.POWERED, Boolean.valueOf(false)); + + if (a(world, blockposition, enumdirection.opposite())) { + return iblockdata.set(BlockLever.FACING, BlockLever.EnumLeverPosition.a(enumdirection, entityliving.getDirection())); + } else { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + EnumDirection enumdirection1; + + do { + if (!iterator.hasNext()) { + if (World.a((IBlockAccess) world, blockposition.down())) { + return iblockdata.set(BlockLever.FACING, BlockLever.EnumLeverPosition.a(EnumDirection.UP, entityliving.getDirection())); + } + + return iblockdata; + } + + enumdirection1 = (EnumDirection) iterator.next(); + } while (enumdirection1 == enumdirection || !a(world, blockposition, enumdirection1.opposite())); + + return iblockdata.set(BlockLever.FACING, BlockLever.EnumLeverPosition.a(enumdirection1, entityliving.getDirection())); + } + } + + public static int a(EnumDirection enumdirection) { + switch (BlockLever.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + return 0; + + case 2: + return 5; + + case 3: + return 4; + + case 4: + return 3; + + case 5: + return 2; + + case 6: + return 1; + + default: + return -1; + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (this.e(world, blockposition, iblockdata) && !a(world, blockposition, ((BlockLever.EnumLeverPosition) iblockdata.get(BlockLever.FACING)).c().opposite())) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + + } + + private boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (this.canPlace(world, blockposition)) { + return true; + } else { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + return false; + } + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + float f = 0.1875F; + + switch (BlockLever.SyntheticClass_1.b[((BlockLever.EnumLeverPosition) iblockaccess.getType(blockposition).get(BlockLever.FACING)).ordinal()]) { + case 1: + this.a(0.0F, 0.2F, 0.5F - f, f * 2.0F, 0.8F, 0.5F + f); + break; + + case 2: + this.a(1.0F - f * 2.0F, 0.2F, 0.5F - f, 1.0F, 0.8F, 0.5F + f); + break; + + case 3: + this.a(0.5F - f, 0.2F, 0.0F, 0.5F + f, 0.8F, f * 2.0F); + break; + + case 4: + this.a(0.5F - f, 0.2F, 1.0F - f * 2.0F, 0.5F + f, 0.8F, 1.0F); + break; + + case 5: + case 6: + f = 0.25F; + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.6F, 0.5F + f); + break; + + case 7: + case 8: + f = 0.25F; + this.a(0.5F - f, 0.4F, 0.5F - f, 0.5F + f, 1.0F, 0.5F + f); + } + + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (world.isClientSide) { + return true; + } else { + // CraftBukkit start - Interact Lever + boolean powered = iblockdata.get(POWERED); + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + int old = (powered) ? 15 : 0; + int current = (!powered) ? 15 : 0; + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); + world.getServer().getPluginManager().callEvent(eventRedstone); + + if ((eventRedstone.getNewCurrent() > 0) != (!powered)) { + return true; + } + // CraftBukkit end + + iblockdata = iblockdata.a(BlockLever.POWERED); + world.setTypeAndData(blockposition, iblockdata, 3); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, ((Boolean) iblockdata.get(BlockLever.POWERED)).booleanValue() ? 0.6F : 0.5F); + world.applyPhysics(blockposition, this); + EnumDirection enumdirection1 = ((BlockLever.EnumLeverPosition) iblockdata.get(BlockLever.FACING)).c(); + + world.applyPhysics(blockposition.shift(enumdirection1.opposite()), this); + return true; + } + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (((Boolean) iblockdata.get(BlockLever.POWERED)).booleanValue()) { + world.applyPhysics(blockposition, this); + EnumDirection enumdirection = ((BlockLever.EnumLeverPosition) iblockdata.get(BlockLever.FACING)).c(); + + world.applyPhysics(blockposition.shift(enumdirection.opposite()), this); + } + + super.remove(world, blockposition, iblockdata); + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return ((Boolean) iblockdata.get(BlockLever.POWERED)).booleanValue() ? 15 : 0; + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return !((Boolean) iblockdata.get(BlockLever.POWERED)).booleanValue() ? 0 : (((BlockLever.EnumLeverPosition) iblockdata.get(BlockLever.FACING)).c() == enumdirection ? 15 : 0); + } + + public boolean isPowerSource() { + return true; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockLever.FACING, BlockLever.EnumLeverPosition.a(i & 7)).set(BlockLever.POWERED, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((BlockLever.EnumLeverPosition) iblockdata.get(BlockLever.FACING)).a(); + + if (((Boolean) iblockdata.get(BlockLever.POWERED)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockLever.FACING, BlockLever.POWERED}); + } + + static class SyntheticClass_1 { + + static final int[] a; + static final int[] b; + static final int[] c = new int[EnumDirection.EnumAxis.values().length]; + + static { + try { + BlockLever.SyntheticClass_1.c[EnumDirection.EnumAxis.X.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockLever.SyntheticClass_1.c[EnumDirection.EnumAxis.Z.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + b = new int[BlockLever.EnumLeverPosition.values().length]; + + try { + BlockLever.SyntheticClass_1.b[BlockLever.EnumLeverPosition.EAST.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockLever.SyntheticClass_1.b[BlockLever.EnumLeverPosition.WEST.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockLever.SyntheticClass_1.b[BlockLever.EnumLeverPosition.SOUTH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + try { + BlockLever.SyntheticClass_1.b[BlockLever.EnumLeverPosition.NORTH.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror5) { + ; + } + + try { + BlockLever.SyntheticClass_1.b[BlockLever.EnumLeverPosition.UP_Z.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror6) { + ; + } + + try { + BlockLever.SyntheticClass_1.b[BlockLever.EnumLeverPosition.UP_X.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror7) { + ; + } + + try { + BlockLever.SyntheticClass_1.b[BlockLever.EnumLeverPosition.DOWN_X.ordinal()] = 7; + } catch (NoSuchFieldError nosuchfielderror8) { + ; + } + + try { + BlockLever.SyntheticClass_1.b[BlockLever.EnumLeverPosition.DOWN_Z.ordinal()] = 8; + } catch (NoSuchFieldError nosuchfielderror9) { + ; + } + + a = new int[EnumDirection.values().length]; + + try { + BlockLever.SyntheticClass_1.a[EnumDirection.DOWN.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror10) { + ; + } + + try { + BlockLever.SyntheticClass_1.a[EnumDirection.UP.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror11) { + ; + } + + try { + BlockLever.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror12) { + ; + } + + try { + BlockLever.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror13) { + ; + } + + try { + BlockLever.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror14) { + ; + } + + try { + BlockLever.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror15) { + ; + } + + } + } + + public static enum EnumLeverPosition implements INamable { + + DOWN_X(0, "down_x", EnumDirection.DOWN), EAST(1, "east", EnumDirection.EAST), WEST(2, "west", EnumDirection.WEST), SOUTH(3, "south", EnumDirection.SOUTH), NORTH(4, "north", EnumDirection.NORTH), UP_Z(5, "up_z", EnumDirection.UP), UP_X(6, "up_x", EnumDirection.UP), DOWN_Z(7, "down_z", EnumDirection.DOWN); + + private static final BlockLever.EnumLeverPosition[] i = new BlockLever.EnumLeverPosition[values().length]; + private final int j; + private final String k; + private final EnumDirection l; + + private EnumLeverPosition(int i, String s, EnumDirection enumdirection) { + this.j = i; + this.k = s; + this.l = enumdirection; + } + + public int a() { + return this.j; + } + + public EnumDirection c() { + return this.l; + } + + public String toString() { + return this.k; + } + + public static BlockLever.EnumLeverPosition a(int i) { + if (i < 0 || i >= BlockLever.EnumLeverPosition.i.length) { + i = 0; + } + + return BlockLever.EnumLeverPosition.i[i]; + } + + public static BlockLever.EnumLeverPosition a(EnumDirection enumdirection, EnumDirection enumdirection1) { + switch (BlockLever.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + switch (BlockLever.SyntheticClass_1.c[enumdirection1.k().ordinal()]) { + case 1: + return BlockLever.EnumLeverPosition.DOWN_X; + + case 2: + return BlockLever.EnumLeverPosition.DOWN_Z; + + default: + throw new IllegalArgumentException("Invalid entityFacing " + enumdirection1 + " for facing " + enumdirection); + } + + case 2: + switch (BlockLever.SyntheticClass_1.c[enumdirection1.k().ordinal()]) { + case 1: + return BlockLever.EnumLeverPosition.UP_X; + + case 2: + return BlockLever.EnumLeverPosition.UP_Z; + + default: + throw new IllegalArgumentException("Invalid entityFacing " + enumdirection1 + " for facing " + enumdirection); + } + + case 3: + return BlockLever.EnumLeverPosition.NORTH; + + case 4: + return BlockLever.EnumLeverPosition.SOUTH; + + case 5: + return BlockLever.EnumLeverPosition.WEST; + + case 6: + return BlockLever.EnumLeverPosition.EAST; + + default: + throw new IllegalArgumentException("Invalid facing: " + enumdirection); + } + } + + public String getName() { + return this.k; + } + + static { + BlockLever.EnumLeverPosition[] ablocklever_enumleverposition = values(); + int i = ablocklever_enumleverposition.length; + + for (int j = 0; j < i; ++j) { + BlockLever.EnumLeverPosition blocklever_enumleverposition = ablocklever_enumleverposition[j]; + + BlockLever.EnumLeverPosition.i[blocklever_enumleverposition.a()] = blocklever_enumleverposition; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMinecartDetector.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMinecartDetector.java new file mode 100644 index 0000000..f3ce4a9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMinecartDetector.java @@ -0,0 +1,162 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.List; +import java.util.Random; + +import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + +public class BlockMinecartDetector extends BlockMinecartTrackAbstract { + + public static final BlockStateEnum SHAPE = BlockStateEnum.a("shape", BlockMinecartTrackAbstract.EnumTrackPosition.class, new Predicate() { + public boolean a(BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition) { + return blockminecarttrackabstract_enumtrackposition != BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_EAST && blockminecarttrackabstract_enumtrackposition != BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_WEST && blockminecarttrackabstract_enumtrackposition != BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_EAST && blockminecarttrackabstract_enumtrackposition != BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_WEST; + } + + public boolean apply(Object object) { + return this.a((BlockMinecartTrackAbstract.EnumTrackPosition) object); + } + }); + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); + + public BlockMinecartDetector() { + super(true); + this.j(this.blockStateList.getBlockData().set(BlockMinecartDetector.POWERED, Boolean.valueOf(false)).set(BlockMinecartDetector.SHAPE, BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH)); + this.a(true); + } + + public int a(World world) { + return 20; + } + + public boolean isPowerSource() { + return true; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (!world.isClientSide) { + if (!((Boolean) iblockdata.get(BlockMinecartDetector.POWERED)).booleanValue()) { + this.e(world, blockposition, iblockdata); + } + } + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {} + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide && ((Boolean) iblockdata.get(BlockMinecartDetector.POWERED)).booleanValue()) { + this.e(world, blockposition, iblockdata); + } + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return ((Boolean) iblockdata.get(BlockMinecartDetector.POWERED)).booleanValue() ? 15 : 0; + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return !((Boolean) iblockdata.get(BlockMinecartDetector.POWERED)).booleanValue() ? 0 : (enumdirection == EnumDirection.UP ? 15 : 0); + } + + private void e(World world, BlockPosition blockposition, IBlockData iblockdata) { + boolean flag = ((Boolean) iblockdata.get(BlockMinecartDetector.POWERED)).booleanValue(); + boolean flag1 = false; + List list = this.a(world, blockposition, EntityMinecartAbstract.class, new Predicate[0]); + + if (!list.isEmpty()) { + flag1 = true; + } + + // CraftBukkit start + if (flag != flag1) { + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, flag ? 15 : 0, flag1 ? 15 : 0); + world.getServer().getPluginManager().callEvent(eventRedstone); + + flag1 = eventRedstone.getNewCurrent() > 0; + } + // CraftBukkit end + + if (flag1 && !flag) { + world.setTypeAndData(blockposition, iblockdata.set(BlockMinecartDetector.POWERED, Boolean.valueOf(true)), 3); + world.applyPhysics(blockposition, this); + world.applyPhysics(blockposition.down(), this); + world.b(blockposition, blockposition); + } + + if (!flag1 && flag) { + world.setTypeAndData(blockposition, iblockdata.set(BlockMinecartDetector.POWERED, Boolean.valueOf(false)), 3); + world.applyPhysics(blockposition, this); + world.applyPhysics(blockposition.down(), this); + world.b(blockposition, blockposition); + } + + if (flag1) { + world.a(blockposition, (Block) this, this.a(world)); + } + + world.updateAdjacentComparators(blockposition, this); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + super.onPlace(world, blockposition, iblockdata); + this.e(world, blockposition, iblockdata); + } + + public IBlockState n() { + return BlockMinecartDetector.SHAPE; + } + + public boolean isComplexRedstone() { + return true; + } + + public int l(World world, BlockPosition blockposition) { + if (((Boolean) world.getType(blockposition).get(BlockMinecartDetector.POWERED)).booleanValue()) { + List list = this.a(world, blockposition, EntityMinecartCommandBlock.class, new Predicate[0]); + + if (!list.isEmpty()) { + return ((EntityMinecartCommandBlock) list.get(0)).getCommandBlock().j(); + } + + List list1 = this.a(world, blockposition, EntityMinecartAbstract.class, new Predicate[] { IEntitySelector.c}); + + if (!list1.isEmpty()) { + return Container.b((IInventory) list1.get(0)); + } + } + + return 0; + } + + protected List a(World world, BlockPosition blockposition, Class oclass, Predicate... apredicate) { + AxisAlignedBB axisalignedbb = this.a(blockposition); + + return apredicate.length != 1 ? world.a(oclass, axisalignedbb) : world.a(oclass, axisalignedbb, apredicate[0]); + } + + private AxisAlignedBB a(BlockPosition blockposition) { + float f = 0.2F; + + return new AxisAlignedBB((double) ((float) blockposition.getX() + 0.2F), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + 0.2F), (double) ((float) (blockposition.getX() + 1) - 0.2F), (double) ((float) (blockposition.getY() + 1) - 0.2F), (double) ((float) (blockposition.getZ() + 1) - 0.2F)); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockMinecartDetector.SHAPE, BlockMinecartTrackAbstract.EnumTrackPosition.a(i & 7)).set(BlockMinecartDetector.POWERED, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(BlockMinecartDetector.SHAPE)).a(); + + if (((Boolean) iblockdata.get(BlockMinecartDetector.POWERED)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockMinecartDetector.SHAPE, BlockMinecartDetector.POWERED}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMinecartTrackAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMinecartTrackAbstract.java new file mode 100644 index 0000000..ec42421 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMinecartTrackAbstract.java @@ -0,0 +1,597 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; + +public abstract class BlockMinecartTrackAbstract extends Block { + + protected final boolean a; + + public static boolean e(World world, BlockPosition blockposition) { + return d(world.getType(blockposition)); + } + + public static boolean d(IBlockData iblockdata) { + Block block = iblockdata.getBlock(); + + return block == Blocks.RAIL || block == Blocks.GOLDEN_RAIL || block == Blocks.DETECTOR_RAIL || block == Blocks.ACTIVATOR_RAIL; + } + + protected BlockMinecartTrackAbstract(boolean flag) { + super(Material.ORIENTABLE); + this.a = flag; + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + this.a(CreativeModeTab.e); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean c() { + return false; + } + + public MovingObjectPosition a(World world, BlockPosition blockposition, Vec3D vec3d, Vec3D vec3d1) { + this.updateShape(world, blockposition); + return super.a(world, blockposition, vec3d, vec3d1); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = iblockdata.getBlock() == this ? (BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(this.n()) : null; + + if (blockminecarttrackabstract_enumtrackposition != null && blockminecarttrackabstract_enumtrackposition.c()) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.625F, 1.0F); + } else { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + } + + } + + public boolean d() { + return false; + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return World.a((IBlockAccess) world, blockposition.down()); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!world.isClientSide) { + iblockdata = this.a(world, blockposition, iblockdata, true); + if (this.a) { + this.doPhysics(world, blockposition, iblockdata, this); + } + } + + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!world.isClientSide) { + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = (BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(this.n()); + boolean flag = false; + + if (!World.a((IBlockAccess) world, blockposition.down())) { + flag = true; + } + + if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_EAST && !World.a((IBlockAccess) world, blockposition.east())) { + flag = true; + } else if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_WEST && !World.a((IBlockAccess) world, blockposition.west())) { + flag = true; + } else if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_NORTH && !World.a((IBlockAccess) world, blockposition.north())) { + flag = true; + } else if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_SOUTH && !World.a((IBlockAccess) world, blockposition.south())) { + flag = true; + } + + if (flag && !world.isEmpty(blockposition)) { // CraftBukkit - SPIGOT-424, MC-73474 + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } else { + this.b(world, blockposition, iblockdata, block); + } + + } + } + + protected void b(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) {} + + protected IBlockData a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return world.isClientSide ? iblockdata : (new BlockMinecartTrackAbstract.MinecartTrackLogic(world, blockposition, iblockdata)).a(world.isBlockIndirectlyPowered(blockposition), flag).b(); + } + + public int k() { + return 0; + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + super.remove(world, blockposition, iblockdata); + if (((BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(this.n())).c()) { + world.applyPhysics(blockposition.up(), this); + } + + if (this.a) { + world.applyPhysics(blockposition, this); + world.applyPhysics(blockposition.down(), this); + } + + } + + public abstract IBlockState n(); + + static class SyntheticClass_1 { + + static final int[] a = new int[BlockMinecartTrackAbstract.EnumTrackPosition.values().length]; + + static { + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_EAST.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_WEST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_NORTH.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_SOUTH.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror5) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_EAST.ordinal()] = 7; + } catch (NoSuchFieldError nosuchfielderror6) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_WEST.ordinal()] = 8; + } catch (NoSuchFieldError nosuchfielderror7) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_WEST.ordinal()] = 9; + } catch (NoSuchFieldError nosuchfielderror8) { + ; + } + + try { + BlockMinecartTrackAbstract.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_EAST.ordinal()] = 10; + } catch (NoSuchFieldError nosuchfielderror9) { + ; + } + + } + } + + public static enum EnumTrackPosition implements INamable { + + NORTH_SOUTH(0, "north_south"), EAST_WEST(1, "east_west"), ASCENDING_EAST(2, "ascending_east"), ASCENDING_WEST(3, "ascending_west"), ASCENDING_NORTH(4, "ascending_north"), ASCENDING_SOUTH(5, "ascending_south"), SOUTH_EAST(6, "south_east"), SOUTH_WEST(7, "south_west"), NORTH_WEST(8, "north_west"), NORTH_EAST(9, "north_east"); + + private static final BlockMinecartTrackAbstract.EnumTrackPosition[] k = new BlockMinecartTrackAbstract.EnumTrackPosition[values().length]; + private final int l; + private final String m; + + private EnumTrackPosition(int i, String s) { + this.l = i; + this.m = s; + } + + public int a() { + return this.l; + } + + public String toString() { + return this.m; + } + + public boolean c() { + return this == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_NORTH || this == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_EAST || this == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_SOUTH || this == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_WEST; + } + + public static BlockMinecartTrackAbstract.EnumTrackPosition a(int i) { + if (i < 0 || i >= BlockMinecartTrackAbstract.EnumTrackPosition.k.length) { + i = 0; + } + + return BlockMinecartTrackAbstract.EnumTrackPosition.k[i]; + } + + public String getName() { + return this.m; + } + + static { + BlockMinecartTrackAbstract.EnumTrackPosition[] ablockminecarttrackabstract_enumtrackposition = values(); + int i = ablockminecarttrackabstract_enumtrackposition.length; + + for (int j = 0; j < i; ++j) { + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = ablockminecarttrackabstract_enumtrackposition[j]; + + BlockMinecartTrackAbstract.EnumTrackPosition.k[blockminecarttrackabstract_enumtrackposition.a()] = blockminecarttrackabstract_enumtrackposition; + } + + } + } + + public class MinecartTrackLogic { + + private final World b; + private final BlockPosition c; + private final BlockMinecartTrackAbstract d; + private IBlockData e; + private final boolean f; + private final List g = Lists.newArrayList(); + + public MinecartTrackLogic(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.b = world; + this.c = blockposition; + this.e = iblockdata; + this.d = (BlockMinecartTrackAbstract) iblockdata.getBlock(); + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = (BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(BlockMinecartTrackAbstract.this.n()); + + this.f = this.d.a; + this.a(blockminecarttrackabstract_enumtrackposition); + } + + private void a(BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition) { + this.g.clear(); + switch (BlockMinecartTrackAbstract.SyntheticClass_1.a[blockminecarttrackabstract_enumtrackposition.ordinal()]) { + case 1: + this.g.add(this.c.north()); + this.g.add(this.c.south()); + break; + + case 2: + this.g.add(this.c.west()); + this.g.add(this.c.east()); + break; + + case 3: + this.g.add(this.c.west()); + this.g.add(this.c.east().up()); + break; + + case 4: + this.g.add(this.c.west().up()); + this.g.add(this.c.east()); + break; + + case 5: + this.g.add(this.c.north().up()); + this.g.add(this.c.south()); + break; + + case 6: + this.g.add(this.c.north()); + this.g.add(this.c.south().up()); + break; + + case 7: + this.g.add(this.c.east()); + this.g.add(this.c.south()); + break; + + case 8: + this.g.add(this.c.west()); + this.g.add(this.c.south()); + break; + + case 9: + this.g.add(this.c.west()); + this.g.add(this.c.north()); + break; + + case 10: + this.g.add(this.c.east()); + this.g.add(this.c.north()); + } + + } + + private void c() { + for (int i = 0; i < this.g.size(); ++i) { + BlockMinecartTrackAbstract.MinecartTrackLogic blockminecarttrackabstract_minecarttracklogic = this.b((BlockPosition) this.g.get(i)); + + if (blockminecarttrackabstract_minecarttracklogic != null && blockminecarttrackabstract_minecarttracklogic.a(this)) { + this.g.set(i, blockminecarttrackabstract_minecarttracklogic.c); + } else { + this.g.remove(i--); + } + } + + } + + private boolean a(BlockPosition blockposition) { + return BlockMinecartTrackAbstract.e(this.b, blockposition) || BlockMinecartTrackAbstract.e(this.b, blockposition.up()) || BlockMinecartTrackAbstract.e(this.b, blockposition.down()); + } + + private BlockMinecartTrackAbstract.MinecartTrackLogic b(BlockPosition blockposition) { + IBlockData iblockdata = this.b.getType(blockposition); + + if (BlockMinecartTrackAbstract.d(iblockdata)) { + return BlockMinecartTrackAbstract.this.new MinecartTrackLogic(this.b, blockposition, iblockdata); + } else { + BlockPosition blockposition1 = blockposition.up(); + + iblockdata = this.b.getType(blockposition1); + if (BlockMinecartTrackAbstract.d(iblockdata)) { + return BlockMinecartTrackAbstract.this.new MinecartTrackLogic(this.b, blockposition1, iblockdata); + } else { + blockposition1 = blockposition.down(); + iblockdata = this.b.getType(blockposition1); + return BlockMinecartTrackAbstract.d(iblockdata) ? BlockMinecartTrackAbstract.this.new MinecartTrackLogic(this.b, blockposition1, iblockdata) : null; + } + } + } + + private boolean a(BlockMinecartTrackAbstract.MinecartTrackLogic blockminecarttrackabstract_minecarttracklogic) { + return this.c(blockminecarttrackabstract_minecarttracklogic.c); + } + + private boolean c(BlockPosition blockposition) { + for (int i = 0; i < this.g.size(); ++i) { + BlockPosition blockposition1 = (BlockPosition) this.g.get(i); + + if (blockposition1.getX() == blockposition.getX() && blockposition1.getZ() == blockposition.getZ()) { + return true; + } + } + + return false; + } + + protected int a() { + int i = 0; + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + + if (this.a(this.c.shift(enumdirection))) { + ++i; + } + } + + return i; + } + + private boolean b(BlockMinecartTrackAbstract.MinecartTrackLogic blockminecarttrackabstract_minecarttracklogic) { + return this.a(blockminecarttrackabstract_minecarttracklogic) || this.g.size() != 2; + } + + private void c(BlockMinecartTrackAbstract.MinecartTrackLogic blockminecarttrackabstract_minecarttracklogic) { + this.g.add(blockminecarttrackabstract_minecarttracklogic.c); + BlockPosition blockposition = this.c.north(); + BlockPosition blockposition1 = this.c.south(); + BlockPosition blockposition2 = this.c.west(); + BlockPosition blockposition3 = this.c.east(); + boolean flag = this.c(blockposition); + boolean flag1 = this.c(blockposition1); + boolean flag2 = this.c(blockposition2); + boolean flag3 = this.c(blockposition3); + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = null; + + if (flag || flag1) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + } + + if (flag2 || flag3) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST; + } + + if (!this.f) { + if (flag1 && flag3 && !flag && !flag2) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_EAST; + } + + if (flag1 && flag2 && !flag && !flag3) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_WEST; + } + + if (flag && flag2 && !flag1 && !flag3) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_WEST; + } + + if (flag && flag3 && !flag1 && !flag2) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_EAST; + } + } + + if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH) { + if (BlockMinecartTrackAbstract.e(this.b, blockposition.up())) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_NORTH; + } + + if (BlockMinecartTrackAbstract.e(this.b, blockposition1.up())) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_SOUTH; + } + } + + if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST) { + if (BlockMinecartTrackAbstract.e(this.b, blockposition3.up())) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_EAST; + } + + if (BlockMinecartTrackAbstract.e(this.b, blockposition2.up())) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_WEST; + } + } + + if (blockminecarttrackabstract_enumtrackposition == null) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + } + + this.e = this.e.set(this.d.n(), blockminecarttrackabstract_enumtrackposition); + this.b.setTypeAndData(this.c, this.e, 3); + } + + private boolean d(BlockPosition blockposition) { + BlockMinecartTrackAbstract.MinecartTrackLogic blockminecarttrackabstract_minecarttracklogic = this.b(blockposition); + + if (blockminecarttrackabstract_minecarttracklogic == null) { + return false; + } else { + blockminecarttrackabstract_minecarttracklogic.c(); + return blockminecarttrackabstract_minecarttracklogic.b(this); + } + } + + public BlockMinecartTrackAbstract.MinecartTrackLogic a(boolean flag, boolean flag1) { + BlockPosition blockposition = this.c.north(); + BlockPosition blockposition1 = this.c.south(); + BlockPosition blockposition2 = this.c.west(); + BlockPosition blockposition3 = this.c.east(); + boolean flag2 = this.d(blockposition); + boolean flag3 = this.d(blockposition1); + boolean flag4 = this.d(blockposition2); + boolean flag5 = this.d(blockposition3); + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = null; + + if ((flag2 || flag3) && !flag4 && !flag5) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + } + + if ((flag4 || flag5) && !flag2 && !flag3) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST; + } + + if (!this.f) { + if (flag3 && flag5 && !flag2 && !flag4) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_EAST; + } + + if (flag3 && flag4 && !flag2 && !flag5) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_WEST; + } + + if (flag2 && flag4 && !flag3 && !flag5) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_WEST; + } + + if (flag2 && flag5 && !flag3 && !flag4) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_EAST; + } + } + + if (blockminecarttrackabstract_enumtrackposition == null) { + if (flag2 || flag3) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + } + + if (flag4 || flag5) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST; + } + + if (!this.f) { + if (flag) { + if (flag3 && flag5) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_EAST; + } + + if (flag4 && flag3) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_WEST; + } + + if (flag5 && flag2) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_EAST; + } + + if (flag2 && flag4) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_WEST; + } + } else { + if (flag2 && flag4) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_WEST; + } + + if (flag5 && flag2) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_EAST; + } + + if (flag4 && flag3) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_WEST; + } + + if (flag3 && flag5) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_EAST; + } + } + } + } + + if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH) { + if (BlockMinecartTrackAbstract.e(this.b, blockposition.up())) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_NORTH; + } + + if (BlockMinecartTrackAbstract.e(this.b, blockposition1.up())) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_SOUTH; + } + } + + if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST) { + if (BlockMinecartTrackAbstract.e(this.b, blockposition3.up())) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_EAST; + } + + if (BlockMinecartTrackAbstract.e(this.b, blockposition2.up())) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_WEST; + } + } + + if (blockminecarttrackabstract_enumtrackposition == null) { + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + } + + this.a(blockminecarttrackabstract_enumtrackposition); + this.e = this.e.set(this.d.n(), blockminecarttrackabstract_enumtrackposition); + if (flag1 || this.b.getType(this.c) != this.e) { + this.b.setTypeAndData(this.c, this.e, 3); + + for (int i = 0; i < this.g.size(); ++i) { + BlockMinecartTrackAbstract.MinecartTrackLogic blockminecarttrackabstract_minecarttracklogic = this.b((BlockPosition) this.g.get(i)); + + if (blockminecarttrackabstract_minecarttracklogic != null) { + blockminecarttrackabstract_minecarttracklogic.c(); + if (blockminecarttrackabstract_minecarttracklogic.b(this)) { + blockminecarttrackabstract_minecarttracklogic.c(this); + } + } + } + } + + return this; + } + + public IBlockData b() { + return this.e; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMobSpawner.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMobSpawner.java new file mode 100644 index 0000000..4bf4df8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMobSpawner.java @@ -0,0 +1,47 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockMobSpawner extends BlockContainer { + + protected BlockMobSpawner() { + super(Material.STONE); + } + + public TileEntity a(World world, int i) { + return new TileEntityMobSpawner(); + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return null; + } + + public int a(Random random) { + return 0; + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + super.dropNaturally(world, blockposition, iblockdata, f, i); + /* CraftBukkit start - Delegate to getExpDrop + int j = 15 + world.random.nextInt(15) + world.random.nextInt(15); + + this.dropExperience(world, blockposition, j); + */ + } + + @Override + public int getExpDrop(World world, IBlockData iblockdata, int enchantmentLevel) { + int j = 15 + world.random.nextInt(15) + world.random.nextInt(15); + + return j; + // CraftBukkit end + } + + public boolean c() { + return false; + } + + public int b() { + return 3; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMonsterEggs.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMonsterEggs.java new file mode 100644 index 0000000..0b58e4f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMonsterEggs.java @@ -0,0 +1,221 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; // CraftBukkit + +public class BlockMonsterEggs extends Block { + + public static final BlockStateEnum VARIANT = BlockStateEnum.of("variant", BlockMonsterEggs.EnumMonsterEggVarient.class); + + public BlockMonsterEggs() { + super(Material.CLAY); + this.j(this.blockStateList.getBlockData().set(BlockMonsterEggs.VARIANT, BlockMonsterEggs.EnumMonsterEggVarient.STONE)); + this.c(0.0F); + this.a(CreativeModeTab.c); + } + + public int a(Random random) { + return 0; + } + + public static boolean d(IBlockData iblockdata) { + Block block = iblockdata.getBlock(); + + return iblockdata == Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.STONE) || block == Blocks.COBBLESTONE || block == Blocks.STONEBRICK; + } + + protected ItemStack i(IBlockData iblockdata) { + switch (BlockMonsterEggs.SyntheticClass_1.a[((BlockMonsterEggs.EnumMonsterEggVarient) iblockdata.get(BlockMonsterEggs.VARIANT)).ordinal()]) { + case 1: + return new ItemStack(Blocks.COBBLESTONE); + + case 2: + return new ItemStack(Blocks.STONEBRICK); + + case 3: + return new ItemStack(Blocks.STONEBRICK, 1, BlockSmoothBrick.EnumStonebrickType.MOSSY.a()); + + case 4: + return new ItemStack(Blocks.STONEBRICK, 1, BlockSmoothBrick.EnumStonebrickType.CRACKED.a()); + + case 5: + return new ItemStack(Blocks.STONEBRICK, 1, BlockSmoothBrick.EnumStonebrickType.CHISELED.a()); + + default: + return new ItemStack(Blocks.STONE); + } + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + if (!world.isClientSide && world.getGameRules().getBoolean("doTileDrops")) { + EntitySilverfish entitysilverfish = new EntitySilverfish(world); + + entitysilverfish.setPositionRotation((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, 0.0F, 0.0F); + world.addEntity(entitysilverfish, SpawnReason.SILVERFISH_BLOCK); // CraftBukkit - add SpawnReason + entitysilverfish.y(); + } + + } + + public int getDropData(World world, BlockPosition blockposition) { + IBlockData iblockdata = world.getType(blockposition); + + return iblockdata.getBlock().toLegacyData(iblockdata); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockMonsterEggs.VARIANT, BlockMonsterEggs.EnumMonsterEggVarient.a(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((BlockMonsterEggs.EnumMonsterEggVarient) iblockdata.get(BlockMonsterEggs.VARIANT)).a(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockMonsterEggs.VARIANT}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[BlockMonsterEggs.EnumMonsterEggVarient.values().length]; + + static { + try { + BlockMonsterEggs.SyntheticClass_1.a[BlockMonsterEggs.EnumMonsterEggVarient.COBBLESTONE.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockMonsterEggs.SyntheticClass_1.a[BlockMonsterEggs.EnumMonsterEggVarient.STONEBRICK.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockMonsterEggs.SyntheticClass_1.a[BlockMonsterEggs.EnumMonsterEggVarient.MOSSY_STONEBRICK.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockMonsterEggs.SyntheticClass_1.a[BlockMonsterEggs.EnumMonsterEggVarient.CRACKED_STONEBRICK.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockMonsterEggs.SyntheticClass_1.a[BlockMonsterEggs.EnumMonsterEggVarient.CHISELED_STONEBRICK.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + } + } + + public static enum EnumMonsterEggVarient implements INamable { + + STONE(0, "stone") {; + public IBlockData d() { + return Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.STONE); + } + }, COBBLESTONE(1, "cobblestone", "cobble") {; + public IBlockData d() { + return Blocks.COBBLESTONE.getBlockData(); + } +}, STONEBRICK(2, "stone_brick", "brick") {; + public IBlockData d() { + return Blocks.STONEBRICK.getBlockData().set(BlockSmoothBrick.VARIANT, BlockSmoothBrick.EnumStonebrickType.DEFAULT); + } +}, MOSSY_STONEBRICK(3, "mossy_brick", "mossybrick") {; + public IBlockData d() { + return Blocks.STONEBRICK.getBlockData().set(BlockSmoothBrick.VARIANT, BlockSmoothBrick.EnumStonebrickType.MOSSY); + } +}, CRACKED_STONEBRICK(4, "cracked_brick", "crackedbrick") {; + public IBlockData d() { + return Blocks.STONEBRICK.getBlockData().set(BlockSmoothBrick.VARIANT, BlockSmoothBrick.EnumStonebrickType.CRACKED); + } +}, CHISELED_STONEBRICK(5, "chiseled_brick", "chiseledbrick") {; + public IBlockData d() { + return Blocks.STONEBRICK.getBlockData().set(BlockSmoothBrick.VARIANT, BlockSmoothBrick.EnumStonebrickType.CHISELED); + } +}; + + private static final BlockMonsterEggs.EnumMonsterEggVarient[] g = new BlockMonsterEggs.EnumMonsterEggVarient[values().length]; + private final int h; + private final String i; + private final String j; + + private EnumMonsterEggVarient(int i, String s) { + this(i, s, s); + } + + private EnumMonsterEggVarient(int i, String s, String s1) { + this.h = i; + this.i = s; + this.j = s1; + } + + public int a() { + return this.h; + } + + public String toString() { + return this.i; + } + + public static BlockMonsterEggs.EnumMonsterEggVarient a(int i) { + if (i < 0 || i >= BlockMonsterEggs.EnumMonsterEggVarient.g.length) { + i = 0; + } + + return BlockMonsterEggs.EnumMonsterEggVarient.g[i]; + } + + public String getName() { + return this.i; + } + + public String c() { + return this.j; + } + + public abstract IBlockData d(); + + public static BlockMonsterEggs.EnumMonsterEggVarient a(IBlockData iblockdata) { + BlockMonsterEggs.EnumMonsterEggVarient[] ablockmonstereggs_enummonstereggvarient = values(); + int i = ablockmonstereggs_enummonstereggvarient.length; + + for (int j = 0; j < i; ++j) { + BlockMonsterEggs.EnumMonsterEggVarient blockmonstereggs_enummonstereggvarient = ablockmonstereggs_enummonstereggvarient[j]; + + if (iblockdata == blockmonstereggs_enummonstereggvarient.d()) { + return blockmonstereggs_enummonstereggvarient; + } + } + + return BlockMonsterEggs.EnumMonsterEggVarient.STONE; + } + + EnumMonsterEggVarient(int i, String s, BlockMonsterEggs.SyntheticClass_1 blockmonstereggs_syntheticclass_1) { + this(i, s); + } + + EnumMonsterEggVarient(int i, String s, String s1, BlockMonsterEggs.SyntheticClass_1 blockmonstereggs_syntheticclass_1) { + this(i, s, s1); + } + + static { + BlockMonsterEggs.EnumMonsterEggVarient[] ablockmonstereggs_enummonstereggvarient = values(); + int i = ablockmonstereggs_enummonstereggvarient.length; + + for (int j = 0; j < i; ++j) { + BlockMonsterEggs.EnumMonsterEggVarient blockmonstereggs_enummonstereggvarient = ablockmonstereggs_enummonstereggvarient[j]; + + BlockMonsterEggs.EnumMonsterEggVarient.g[blockmonstereggs_enummonstereggvarient.a()] = blockmonstereggs_enummonstereggvarient; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMushroom.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMushroom.java new file mode 100644 index 0000000..7cf7a08 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMushroom.java @@ -0,0 +1,117 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Random; + +// CraftBukkit start +import org.bukkit.TreeType; +import org.bukkit.block.BlockState; +import org.bukkit.event.block.BlockSpreadEvent; +// CraftBukkit end + +public class BlockMushroom extends BlockPlant implements IBlockFragilePlantElement { + + protected BlockMushroom() { + float f = 0.2F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f); + this.a(true); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + final int sourceX = blockposition.getX(), sourceY = blockposition.getY(), sourceZ = blockposition.getZ(); // CraftBukkit + if (random.nextInt(Math.max(1, (int) world.growthOdds / world.spigotConfig.mushroomModifier * 25)) == 0) { // Spigot int i = 5; + int i = 5; + boolean flag = true; + Iterator iterator = BlockPosition.b(blockposition.a(-4, -1, -4), blockposition.a(4, 1, 4)).iterator(); + + while (iterator.hasNext()) { + BlockPosition blockposition1 = (BlockPosition) iterator.next(); + + if (world.getType(blockposition1).getBlock() == this) { + --i; + if (i <= 0) { + return; + } + } + } + + BlockPosition blockposition2 = blockposition.a(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1); + + for (int j = 0; j < 4; ++j) { + if (world.isEmpty(blockposition2) && this.f(world, blockposition2, this.getBlockData())) { + blockposition = blockposition2; + } + + blockposition2 = blockposition.a(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1); + } + + if (world.isEmpty(blockposition2) && this.f(world, blockposition2, this.getBlockData())) { + // CraftBukkit start + // world.setTypeAndData(blockposition2, this.getBlockData(), 2); + org.bukkit.World bworld = world.getWorld(); + BlockState blockState = bworld.getBlockAt(blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()).getState(); + blockState.setType(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(this)); // nms: this.id, 0, 2 + + BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(sourceX, sourceY, sourceZ), blockState); + world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + blockState.update(true); + } + // CraftBukkit end + } + } + + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return super.canPlace(world, blockposition) && this.f(world, blockposition, this.getBlockData()); + } + + protected boolean c(Block block) { + return block.o(); + } + + public boolean f(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (blockposition.getY() >= 0 && blockposition.getY() < 256) { + IBlockData iblockdata1 = world.getType(blockposition.down()); + + return iblockdata1.getBlock() == Blocks.MYCELIUM ? true : (iblockdata1.getBlock() == Blocks.DIRT && iblockdata1.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.PODZOL ? true : world.k(blockposition) < 13 && this.c(iblockdata1.getBlock())); + } else { + return false; + } + } + + public boolean d(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + world.setAir(blockposition); + WorldGenHugeMushroom worldgenhugemushroom = null; + + if (this == Blocks.BROWN_MUSHROOM) { + BlockSapling.treeType = TreeType.BROWN_MUSHROOM; // CraftBukkit + worldgenhugemushroom = new WorldGenHugeMushroom(Blocks.BROWN_MUSHROOM_BLOCK); + } else if (this == Blocks.RED_MUSHROOM) { + BlockSapling.treeType = TreeType.RED_MUSHROOM; // CraftBukkit + worldgenhugemushroom = new WorldGenHugeMushroom(Blocks.RED_MUSHROOM_BLOCK); + } + + if (worldgenhugemushroom != null && worldgenhugemushroom.generate(world, random, blockposition)) { + return true; + } else { + world.setTypeAndData(blockposition, iblockdata, 3); + return false; + } + } + + public boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return true; + } + + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return (double) random.nextFloat() < 0.4D; + } + + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + this.d(world, blockposition, iblockdata, random); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMycel.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMycel.java new file mode 100644 index 0000000..d2bd4dd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockMycel.java @@ -0,0 +1,85 @@ +package net.minecraft.server; + +import java.util.Random; + +// CraftBukkit start +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockSpreadEvent; +// CraftBukkit end + +public class BlockMycel extends Block { + + public static final BlockStateBoolean SNOWY = BlockStateBoolean.of("snowy"); + + protected BlockMycel() { + super(Material.GRASS, MaterialMapColor.z); + this.j(this.blockStateList.getBlockData().set(BlockMycel.SNOWY, Boolean.valueOf(false))); + this.a(true); + this.a(CreativeModeTab.b); + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + Block block = iblockaccess.getType(blockposition.up()).getBlock(); + + return iblockdata.set(BlockMycel.SNOWY, Boolean.valueOf(block == Blocks.SNOW || block == Blocks.SNOW_LAYER)); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (world.getLightLevel(blockposition.up()) < 4 && world.getType(blockposition.up()).getBlock().p() > 2) { + // CraftBukkit start + // world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, EnumDirtVariant.DIRT)); + org.bukkit.World bworld = world.getWorld(); + BlockState blockState = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()).getState(); + blockState.setType(CraftMagicNumbers.getMaterial(Blocks.DIRT)); + + BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); + world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + blockState.update(true); + } + // CraftBukkit end + } else { + if (world.getLightLevel(blockposition.up()) >= 9) { + 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); + IBlockData iblockdata1 = world.getType(blockposition1); + Block block = world.getType(blockposition1.up()).getBlock(); + + if (iblockdata1.getBlock() == Blocks.DIRT && iblockdata1.get(BlockDirt.VARIANT) == BlockDirt.EnumDirtVariant.DIRT && world.getLightLevel(blockposition1.up()) >= 4 && block.p() <= 2) { + // CraftBukkit start + // world.setTypeUpdate(blockposition1, this.getBlockData()); + org.bukkit.World bworld = world.getWorld(); + BlockState blockState = bworld.getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()).getState(); + blockState.setType(CraftMagicNumbers.getMaterial(this)); + + BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), blockState); + world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + blockState.update(true); + } + // CraftBukkit end + } + } + } + + } + } + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Blocks.DIRT.getDropType(Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, BlockDirt.EnumDirtVariant.DIRT), random, i); + } + + public int toLegacyData(IBlockData iblockdata) { + return 0; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockMycel.SNOWY}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockNetherWart.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockNetherWart.java new file mode 100644 index 0000000..374f06c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockNetherWart.java @@ -0,0 +1,76 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockNetherWart extends BlockPlant { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 3); + + protected BlockNetherWart() { + super(Material.PLANT, MaterialMapColor.D); + this.j(this.blockStateList.getBlockData().set(BlockNetherWart.AGE, Integer.valueOf(0))); + this.a(true); + float f = 0.5F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f); + this.a((CreativeModeTab) null); + } + + protected boolean c(Block block) { + return block == Blocks.SOUL_SAND; + } + + public boolean f(World world, BlockPosition blockposition, IBlockData iblockdata) { + return this.c(world.getType(blockposition.down()).getBlock()); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + int i = ((Integer) iblockdata.get(BlockNetherWart.AGE)).intValue(); + + if (i < 3 && random.nextInt(Math.max(1, (int) world.growthOdds / world.spigotConfig.wartModifier * 10)) == 0) { // Spigot + iblockdata = iblockdata.set(BlockNetherWart.AGE, Integer.valueOf(i + 1)); + // world.setTypeAndData(blockposition, iblockdata, 2); // CraftBukkit + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(iblockdata)); // CraftBukkit + } + + super.b(world, blockposition, iblockdata, random); + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + if (!world.isClientSide) { + int j = 1; + + if (((Integer) iblockdata.get(BlockNetherWart.AGE)).intValue() >= 3) { + j = 2 + world.random.nextInt(3); + if (i > 0) { + j += world.random.nextInt(i + 1); + } + } + + for (int k = 0; k < j; ++k) { + a(world, blockposition, new ItemStack(Items.NETHER_WART)); + } + + } + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return null; + } + + public int a(Random random) { + return 0; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockNetherWart.AGE, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockNetherWart.AGE)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockNetherWart.AGE}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockOre.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockOre.java new file mode 100644 index 0000000..4d97cdf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockOre.java @@ -0,0 +1,93 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockOre extends Block { + + public BlockOre() { + this(Material.STONE.r()); + } + + public BlockOre(MaterialMapColor materialmapcolor) { + super(Material.STONE, materialmapcolor); + this.a(CreativeModeTab.b); + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return this == Blocks.COAL_ORE ? Items.COAL : (this == Blocks.DIAMOND_ORE ? Items.DIAMOND : (this == Blocks.LAPIS_ORE ? Items.DYE : (this == Blocks.EMERALD_ORE ? Items.EMERALD : (this == Blocks.QUARTZ_ORE ? Items.QUARTZ : Item.getItemOf(this))))); + } + + public int a(Random random) { + return this == Blocks.LAPIS_ORE ? 4 + random.nextInt(5) : 1; + } + + public int getDropCount(int i, Random random) { + if (i > 0 && Item.getItemOf(this) != this.getDropType((IBlockData) this.P().a().iterator().next(), random, i)) { + int j = random.nextInt(i + 2) - 1; + + if (j < 0) { + j = 0; + } + + return this.a(random) * (j + 1); + } else { + return this.a(random); + } + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + super.dropNaturally(world, blockposition, iblockdata, f, i); + /* CraftBukkit start - Delegated to getExpDrop + if (this.getDropType(iblockdata, world.random, i) != Item.getItemOf(this)) { + int j = 0; + + if (this == Blocks.COAL_ORE) { + j = MathHelper.nextInt(world.random, 0, 2); + } else if (this == Blocks.DIAMOND_ORE) { + j = MathHelper.nextInt(world.random, 3, 7); + } else if (this == Blocks.EMERALD_ORE) { + j = MathHelper.nextInt(world.random, 3, 7); + } else if (this == Blocks.LAPIS_ORE) { + j = MathHelper.nextInt(world.random, 2, 5); + } else if (this == Blocks.QUARTZ_ORE) { + j = MathHelper.nextInt(world.random, 2, 5); + } + + this.dropExperience(world, blockposition, j); + } + // */ + + } + + @Override + public int getExpDrop(World world, IBlockData iblockdata, int i) { + if (this.getDropType(iblockdata, world.random, i) != Item.getItemOf(this)) { + int j = 0; + + if (this == Blocks.COAL_ORE) { + j = MathHelper.nextInt(world.random, 0, 2); + } else if (this == Blocks.DIAMOND_ORE) { + j = MathHelper.nextInt(world.random, 3, 7); + } else if (this == Blocks.EMERALD_ORE) { + j = MathHelper.nextInt(world.random, 3, 7); + } else if (this == Blocks.LAPIS_ORE) { + j = MathHelper.nextInt(world.random, 2, 5); + } else if (this == Blocks.QUARTZ_ORE) { + j = MathHelper.nextInt(world.random, 2, 5); + } + + return j; + } + + return 0; + // CraftBukkit end + } + + public int getDropData(World world, BlockPosition blockposition) { + return 0; + } + + public int getDropData(IBlockData iblockdata) { + return this == Blocks.LAPIS_ORE ? EnumColor.BLUE.getInvColorIndex() : 0; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPiston.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPiston.java new file mode 100644 index 0000000..b582f4b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPiston.java @@ -0,0 +1,481 @@ +package net.minecraft.server; + +import java.util.List; + +// CraftBukkit start +import java.util.AbstractList; +import java.util.Collection; +import java.util.Iterator; +import java.util.ListIterator; + +import com.google.common.collect.ImmutableList; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +// CraftBukkit end + +public class BlockPiston extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing"); + public static final BlockStateBoolean EXTENDED = BlockStateBoolean.of("extended"); + private final boolean sticky; + + public BlockPiston(boolean flag) { + super(Material.PISTON); + this.j(this.blockStateList.getBlockData().set(BlockPiston.FACING, EnumDirection.NORTH).set(BlockPiston.EXTENDED, Boolean.valueOf(false))); + this.sticky = flag; + this.a(BlockPiston.i); + this.c(0.5F); + this.a(CreativeModeTab.d); + } + + public boolean c() { + return false; + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + world.setTypeAndData(blockposition, iblockdata.set(BlockPiston.FACING, a(world, blockposition, entityliving)), 2); + if (!world.isClientSide) { + this.e(world, blockposition, iblockdata); + } + + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!world.isClientSide) { + this.e(world, blockposition, iblockdata); + } + + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!world.isClientSide && world.getTileEntity(blockposition) == null) { + this.e(world, blockposition, iblockdata); + } + + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return this.getBlockData().set(BlockPiston.FACING, a(world, blockposition, entityliving)).set(BlockPiston.EXTENDED, Boolean.valueOf(false)); + } + + private void e(World world, BlockPosition blockposition, IBlockData iblockdata) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockPiston.FACING); + boolean flag = this.a(world, blockposition, enumdirection); + + if (flag && !((Boolean) iblockdata.get(BlockPiston.EXTENDED)).booleanValue()) { + if ((new PistonExtendsChecker(world, blockposition, enumdirection, true)).a()) { + world.playBlockAction(blockposition, this, 0, enumdirection.a()); + } + } else if (!flag && ((Boolean) iblockdata.get(BlockPiston.EXTENDED)).booleanValue()) { + // CraftBukkit start + if (!this.sticky) { + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.of(), CraftBlock.notchToBlockFace(enumdirection)); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + } + // CraftBukkit end + world.setTypeAndData(blockposition, iblockdata.set(BlockPiston.EXTENDED, Boolean.valueOf(false)), 2); + world.playBlockAction(blockposition, this, 1, enumdirection.a()); + } + + } + + private boolean a(World world, BlockPosition blockposition, EnumDirection enumdirection) { + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + int j; + + for (j = 0; j < i; ++j) { + EnumDirection enumdirection1 = aenumdirection[j]; + + if (enumdirection1 != enumdirection && world.isBlockFacePowered(blockposition.shift(enumdirection1), enumdirection1)) { + return true; + } + } + + if (world.isBlockFacePowered(blockposition, EnumDirection.DOWN)) { + return true; + } else { + BlockPosition blockposition1 = blockposition.up(); + EnumDirection[] aenumdirection1 = EnumDirection.values(); + + j = aenumdirection1.length; + + for (int k = 0; k < j; ++k) { + EnumDirection enumdirection2 = aenumdirection1[k]; + + if (enumdirection2 != EnumDirection.DOWN && world.isBlockFacePowered(blockposition1.shift(enumdirection2), enumdirection2)) { + return true; + } + } + + return false; + } + } + + public boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, int i, int j) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockPiston.FACING); + + if (!world.isClientSide) { + boolean flag = this.a(world, blockposition, enumdirection); + + if (flag && i == 1) { + world.setTypeAndData(blockposition, iblockdata.set(BlockPiston.EXTENDED, Boolean.valueOf(true)), 2); + return false; + } + + if (!flag && i == 0) { + return false; + } + } + + if (i == 0) { + if (!this.a(world, blockposition, enumdirection, true)) { + return false; + } + + world.setTypeAndData(blockposition, iblockdata.set(BlockPiston.EXTENDED, Boolean.valueOf(true)), 2); + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "tile.piston.out", 0.5F, world.random.nextFloat() * 0.25F + 0.6F); + } else if (i == 1) { + TileEntity tileentity = world.getTileEntity(blockposition.shift(enumdirection)); + + if (tileentity instanceof TileEntityPiston) { + ((TileEntityPiston) tileentity).h(); + } + + world.setTypeAndData(blockposition, Blocks.PISTON_EXTENSION.getBlockData().set(BlockPistonMoving.FACING, enumdirection).set(BlockPistonMoving.TYPE, this.sticky ? BlockPistonExtension.EnumPistonType.STICKY : BlockPistonExtension.EnumPistonType.DEFAULT), 3); + world.setTileEntity(blockposition, BlockPistonMoving.a(this.fromLegacyData(j), enumdirection, false, true)); + if (this.sticky) { + BlockPosition blockposition1 = blockposition.a(enumdirection.getAdjacentX() * 2, enumdirection.getAdjacentY() * 2, enumdirection.getAdjacentZ() * 2); + Block block = world.getType(blockposition1).getBlock(); + boolean flag1 = false; + + if (block == Blocks.PISTON_EXTENSION) { + TileEntity tileentity1 = world.getTileEntity(blockposition1); + + if (tileentity1 instanceof TileEntityPiston) { + TileEntityPiston tileentitypiston = (TileEntityPiston) tileentity1; + + if (tileentitypiston.e() == enumdirection && tileentitypiston.d()) { + tileentitypiston.h(); + flag1 = true; + } + } + } + + if (!flag1 && a(block, world, blockposition1, enumdirection.opposite(), false) && (block.k() == 0 || block == Blocks.PISTON || block == Blocks.STICKY_PISTON)) { // CraftBukkit - remove 'block.getMaterial() != Material.AIR' condition + this.a(world, blockposition, enumdirection, false); + } + } else { + world.setAir(blockposition.shift(enumdirection)); + } + + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "tile.piston.in", 0.5F, world.random.nextFloat() * 0.15F + 0.6F); + } + + return true; + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + + if (iblockdata.getBlock() == this && ((Boolean) iblockdata.get(BlockPiston.EXTENDED)).booleanValue()) { + float f = 0.25F; + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockPiston.FACING); + + if (enumdirection != null) { + switch (BlockPiston.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + this.a(0.0F, 0.25F, 0.0F, 1.0F, 1.0F, 1.0F); + break; + + case 2: + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); + break; + + case 3: + this.a(0.0F, 0.0F, 0.25F, 1.0F, 1.0F, 1.0F); + break; + + case 4: + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.75F); + break; + + case 5: + this.a(0.25F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + break; + + case 6: + this.a(0.0F, 0.0F, 0.0F, 0.75F, 1.0F, 1.0F); + } + } + } else { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + } + + public void j() { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, AxisAlignedBB axisalignedbb, List list, Entity entity) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + super.a(world, blockposition, iblockdata, axisalignedbb, list, entity); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.updateShape(world, blockposition); + return super.a(world, blockposition, iblockdata); + } + + public boolean d() { + return false; + } + + public static EnumDirection b(int i) { + int j = i & 7; + + return j > 5 ? null : EnumDirection.fromType1(j); + } + + public static EnumDirection a(World world, BlockPosition blockposition, EntityLiving entityliving) { + if (MathHelper.e((float) entityliving.locX - (float) blockposition.getX()) < 2.0F && MathHelper.e((float) entityliving.locZ - (float) blockposition.getZ()) < 2.0F) { + double d0 = entityliving.locY + (double) entityliving.getHeadHeight(); + + if (d0 - (double) blockposition.getY() > 2.0D) { + return EnumDirection.UP; + } + + if ((double) blockposition.getY() - d0 > 0.0D) { + return EnumDirection.DOWN; + } + } + + return entityliving.getDirection().opposite(); + } + + public static boolean a(Block block, World world, BlockPosition blockposition, EnumDirection enumdirection, boolean flag) { + if (block == Blocks.OBSIDIAN) { + return false; + } else if (!world.getWorldBorder().a(blockposition)) { + return false; + } else if (blockposition.getY() >= 0 && (enumdirection != EnumDirection.DOWN || blockposition.getY() != 0)) { + if (blockposition.getY() <= world.getHeight() - 1 && (enumdirection != EnumDirection.UP || blockposition.getY() != world.getHeight() - 1)) { + if (block != Blocks.PISTON && block != Blocks.STICKY_PISTON) { + if (block.g(world, blockposition) == -1.0F) { + return false; + } + + if (block.k() == 2) { + return false; + } + + if (block.k() == 1) { + if (!flag) { + return false; + } + + return true; + } + } else if (((Boolean) world.getType(blockposition).get(BlockPiston.EXTENDED)).booleanValue()) { + return false; + } + + return !(block instanceof IContainer); + } else { + return false; + } + } else { + return false; + } + } + + private boolean a(World world, BlockPosition blockposition, EnumDirection enumdirection, boolean flag) { + if (!flag) { + world.setAir(blockposition.shift(enumdirection)); + } + + PistonExtendsChecker pistonextendschecker = new PistonExtendsChecker(world, blockposition, enumdirection, flag); + List list = pistonextendschecker.getMovedBlocks(); + List list1 = pistonextendschecker.getBrokenBlocks(); + + if (!pistonextendschecker.a()) { + return false; + } else { + // CraftBukkit start + final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + final List moved = pistonextendschecker.getMovedBlocks(); + final List broken = pistonextendschecker.getBrokenBlocks(); + + List blocks = new AbstractList() { + + @Override + public int size() { + return moved.size() + broken.size(); + } + + @Override + public org.bukkit.block.Block get(int index) { + if (index >= size() || index < 0) { + throw new ArrayIndexOutOfBoundsException(index); + } + BlockPosition pos = (BlockPosition) (index < moved.size() ? moved.get(index) : broken.get(index - moved.size())); + return bblock.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); + } + }; + + int i = list.size() + list1.size(); + Block[] ablock = new Block[i]; + EnumDirection enumdirection1 = flag ? enumdirection : enumdirection.opposite(); + + org.bukkit.event.block.BlockPistonEvent event; + if (flag) { + event = new BlockPistonExtendEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1)); + } else { + event = new BlockPistonRetractEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1)); + } + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + for (BlockPosition b : broken) { + world.notify(b); + } + for (BlockPosition b : moved) { + world.notify(b); + world.notify(b.shift(enumdirection1)); + } + return false; + } + // CraftBukkit end + + int j; + BlockPosition blockposition1; + + for (j = list1.size() - 1; j >= 0; --j) { + blockposition1 = (BlockPosition) list1.get(j); + Block block = world.getType(blockposition1).getBlock(); + + block.b(world, blockposition1, world.getType(blockposition1), 0); + world.setAir(blockposition1); + --i; + ablock[i] = block; + } + + IBlockData iblockdata; + + for (j = list.size() - 1; j >= 0; --j) { + blockposition1 = (BlockPosition) list.get(j); + iblockdata = world.getType(blockposition1); + Block block1 = iblockdata.getBlock(); + + block1.toLegacyData(iblockdata); + world.setAir(blockposition1); + blockposition1 = blockposition1.shift(enumdirection1); + world.setTypeAndData(blockposition1, Blocks.PISTON_EXTENSION.getBlockData().set(BlockPiston.FACING, enumdirection), 4); + world.setTileEntity(blockposition1, BlockPistonMoving.a(iblockdata, enumdirection, flag, false)); + --i; + ablock[i] = block1; + } + + BlockPosition blockposition2 = blockposition.shift(enumdirection); + + if (flag) { + BlockPistonExtension.EnumPistonType blockpistonextension_enumpistontype = this.sticky ? BlockPistonExtension.EnumPistonType.STICKY : BlockPistonExtension.EnumPistonType.DEFAULT; + + iblockdata = Blocks.PISTON_HEAD.getBlockData().set(BlockPistonExtension.FACING, enumdirection).set(BlockPistonExtension.TYPE, blockpistonextension_enumpistontype); + IBlockData iblockdata1 = Blocks.PISTON_EXTENSION.getBlockData().set(BlockPistonMoving.FACING, enumdirection).set(BlockPistonMoving.TYPE, this.sticky ? BlockPistonExtension.EnumPistonType.STICKY : BlockPistonExtension.EnumPistonType.DEFAULT); + + world.setTypeAndData(blockposition2, iblockdata1, 4); + world.setTileEntity(blockposition2, BlockPistonMoving.a(iblockdata, enumdirection, true, false)); + } + + int k; + + for (k = list1.size() - 1; k >= 0; --k) { + world.applyPhysics((BlockPosition) list1.get(k), ablock[i++]); + } + + for (k = list.size() - 1; k >= 0; --k) { + world.applyPhysics((BlockPosition) list.get(k), ablock[i++]); + } + + if (flag) { + world.applyPhysics(blockposition2, Blocks.PISTON_HEAD); + world.applyPhysics(blockposition, this); + } + + return true; + } + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockPiston.FACING, b(i)).set(BlockPiston.EXTENDED, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((EnumDirection) iblockdata.get(BlockPiston.FACING)).a(); + + if (((Boolean) iblockdata.get(BlockPiston.EXTENDED)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockPiston.FACING, BlockPiston.EXTENDED}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + BlockPiston.SyntheticClass_1.a[EnumDirection.DOWN.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockPiston.SyntheticClass_1.a[EnumDirection.UP.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockPiston.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockPiston.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockPiston.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + try { + BlockPiston.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror5) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPlant.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPlant.java new file mode 100644 index 0000000..c111024 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPlant.java @@ -0,0 +1,77 @@ +package net.minecraft.server; + +import java.util.Random; +// CraftBukkit start +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.event.block.BlockPhysicsEvent; +// CraftBukkit end + +public class BlockPlant extends Block { + + protected BlockPlant() { + this(Material.PLANT); + } + + protected BlockPlant(Material material) { + this(material, material.r()); + } + + protected BlockPlant(Material material, MaterialMapColor materialmapcolor) { + super(material, materialmapcolor); + this.a(true); + float f = 0.2F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 3.0F, 0.5F + f); + this.a(CreativeModeTab.c); + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return super.canPlace(world, blockposition) && this.c(world.getType(blockposition.down()).getBlock()); + } + + protected boolean c(Block block) { + return block == Blocks.GRASS || block == Blocks.DIRT || block == Blocks.FARMLAND; + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + super.doPhysics(world, blockposition, iblockdata, block); + this.e(world, blockposition, iblockdata); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + this.e(world, blockposition, iblockdata); + } + + protected void e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!this.f(world, blockposition, iblockdata)) { + // CraftBukkit Start + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + BlockPhysicsEvent event = new BlockPhysicsEvent(block, block.getTypeId()); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + // CraftBukkit end + this.b(world, blockposition, iblockdata, 0); + world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); + } + + } + + public boolean f(World world, BlockPosition blockposition, IBlockData iblockdata) { + return this.c(world.getType(blockposition.down()).getBlock()); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPortal.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPortal.java new file mode 100644 index 0000000..170f776 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPortal.java @@ -0,0 +1,363 @@ +package net.minecraft.server; + +import com.google.common.cache.LoadingCache; +import java.util.Random; + +import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit +import org.bukkit.event.world.PortalCreateEvent; // CraftBukkit + +public class BlockPortal extends BlockHalfTransparent { + + public static final BlockStateEnum AXIS = BlockStateEnum.of("axis", EnumDirection.EnumAxis.class, new EnumDirection.EnumAxis[] { EnumDirection.EnumAxis.X, EnumDirection.EnumAxis.Z}); + + public BlockPortal() { + super(Material.PORTAL, false); + this.j(this.blockStateList.getBlockData().set(BlockPortal.AXIS, EnumDirection.EnumAxis.X)); + this.a(true); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + super.b(world, blockposition, iblockdata, random); + if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.worldProvider.d() && world.getGameRules().getBoolean("doMobSpawning") && random.nextInt(2000) < world.getDifficulty().a()) { // Spigot + int i = blockposition.getY(); + + BlockPosition blockposition1; + + for (blockposition1 = blockposition; !World.a((IBlockAccess) world, blockposition1) && blockposition1.getY() > 0; blockposition1 = blockposition1.down()) { + ; + } + + if (i > 0 && !world.getType(blockposition1.up()).getBlock().isOccluding()) { + // CraftBukkit - set spawn reason to NETHER_PORTAL + Entity entity = ItemMonsterEgg.spawnCreature(world, 57, (double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 1.1D, (double) blockposition1.getZ() + 0.5D, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); + + if (entity != null) { + entity.portalCooldown = entity.aq(); + } + } + } + + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + EnumDirection.EnumAxis enumdirection_enumaxis = (EnumDirection.EnumAxis) iblockaccess.getType(blockposition).get(BlockPortal.AXIS); + float f = 0.125F; + float f1 = 0.125F; + + if (enumdirection_enumaxis == EnumDirection.EnumAxis.X) { + f = 0.5F; + } + + if (enumdirection_enumaxis == EnumDirection.EnumAxis.Z) { + f1 = 0.5F; + } + + this.a(0.5F - f, 0.0F, 0.5F - f1, 0.5F + f, 1.0F, 0.5F + f1); + } + + public static int a(EnumDirection.EnumAxis enumdirection_enumaxis) { + return enumdirection_enumaxis == EnumDirection.EnumAxis.X ? 1 : (enumdirection_enumaxis == EnumDirection.EnumAxis.Z ? 2 : 0); + } + + public boolean d() { + return false; + } + + public boolean e(World world, BlockPosition blockposition) { + BlockPortal.Shape blockportal_shape = new BlockPortal.Shape(world, blockposition, EnumDirection.EnumAxis.X); + + if (blockportal_shape.d() && blockportal_shape.e == 0) { + // CraftBukkit start - return portalcreator + return blockportal_shape.createPortal(); + // return true; + } else { + BlockPortal.Shape blockportal_shape1 = new BlockPortal.Shape(world, blockposition, EnumDirection.EnumAxis.Z); + + if (blockportal_shape1.d() && blockportal_shape1.e == 0) { + return blockportal_shape1.createPortal(); + // return true; + // CraftBukkit end + } else { + return false; + } + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + EnumDirection.EnumAxis enumdirection_enumaxis = (EnumDirection.EnumAxis) iblockdata.get(BlockPortal.AXIS); + BlockPortal.Shape blockportal_shape; + + if (enumdirection_enumaxis == EnumDirection.EnumAxis.X) { + blockportal_shape = new BlockPortal.Shape(world, blockposition, EnumDirection.EnumAxis.X); + if (!blockportal_shape.d() || blockportal_shape.e < blockportal_shape.width * blockportal_shape.height) { + world.setTypeUpdate(blockposition, Blocks.AIR.getBlockData()); + } + } else if (enumdirection_enumaxis == EnumDirection.EnumAxis.Z) { + blockportal_shape = new BlockPortal.Shape(world, blockposition, EnumDirection.EnumAxis.Z); + if (!blockportal_shape.d() || blockportal_shape.e < blockportal_shape.width * blockportal_shape.height) { + world.setTypeUpdate(blockposition, Blocks.AIR.getBlockData()); + } + } + + } + + public int a(Random random) { + return 0; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (entity.vehicle == null && entity.passenger == null) { + // CraftBukkit start - Entity in portal + EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ())); + world.getServer().getPluginManager().callEvent(event); + // CraftBukkit end + entity.d(blockposition); + } + + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockPortal.AXIS, (i & 3) == 2 ? EnumDirection.EnumAxis.Z : EnumDirection.EnumAxis.X); + } + + public int toLegacyData(IBlockData iblockdata) { + return a((EnumDirection.EnumAxis) iblockdata.get(BlockPortal.AXIS)); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockPortal.AXIS}); + } + + public ShapeDetector.ShapeDetectorCollection f(World world, BlockPosition blockposition) { + EnumDirection.EnumAxis enumdirection_enumaxis = EnumDirection.EnumAxis.Z; + BlockPortal.Shape blockportal_shape = new BlockPortal.Shape(world, blockposition, EnumDirection.EnumAxis.X); + LoadingCache loadingcache = ShapeDetector.a(world, true); + + if (!blockportal_shape.d()) { + enumdirection_enumaxis = EnumDirection.EnumAxis.X; + blockportal_shape = new BlockPortal.Shape(world, blockposition, EnumDirection.EnumAxis.Z); + } + + if (!blockportal_shape.d()) { + return new ShapeDetector.ShapeDetectorCollection(blockposition, EnumDirection.NORTH, EnumDirection.UP, loadingcache, 1, 1, 1); + } else { + int[] aint = new int[EnumDirection.EnumAxisDirection.values().length]; + EnumDirection enumdirection = blockportal_shape.c.f(); + BlockPosition blockposition1 = blockportal_shape.position.up(blockportal_shape.a() - 1); + EnumDirection.EnumAxisDirection[] aenumdirection_enumaxisdirection = EnumDirection.EnumAxisDirection.values(); + int i = aenumdirection_enumaxisdirection.length; + + int j; + + for (j = 0; j < i; ++j) { + EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection = aenumdirection_enumaxisdirection[j]; + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = new ShapeDetector.ShapeDetectorCollection(enumdirection.c() == enumdirection_enumaxisdirection ? blockposition1 : blockposition1.shift(blockportal_shape.c, blockportal_shape.b() - 1), EnumDirection.a(enumdirection_enumaxisdirection, enumdirection_enumaxis), EnumDirection.UP, loadingcache, blockportal_shape.b(), blockportal_shape.a(), 1); + + for (int k = 0; k < blockportal_shape.b(); ++k) { + for (int l = 0; l < blockportal_shape.a(); ++l) { + ShapeDetectorBlock shapedetectorblock = shapedetector_shapedetectorcollection.a(k, l, 1); + + if (shapedetectorblock.a() != null && shapedetectorblock.a().getBlock().getMaterial() != Material.AIR) { + ++aint[enumdirection_enumaxisdirection.ordinal()]; + } + } + } + } + + EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection1 = EnumDirection.EnumAxisDirection.POSITIVE; + EnumDirection.EnumAxisDirection[] aenumdirection_enumaxisdirection1 = EnumDirection.EnumAxisDirection.values(); + + j = aenumdirection_enumaxisdirection1.length; + + for (int i1 = 0; i1 < j; ++i1) { + EnumDirection.EnumAxisDirection enumdirection_enumaxisdirection2 = aenumdirection_enumaxisdirection1[i1]; + + if (aint[enumdirection_enumaxisdirection2.ordinal()] < aint[enumdirection_enumaxisdirection1.ordinal()]) { + enumdirection_enumaxisdirection1 = enumdirection_enumaxisdirection2; + } + } + + return new ShapeDetector.ShapeDetectorCollection(enumdirection.c() == enumdirection_enumaxisdirection1 ? blockposition1 : blockposition1.shift(blockportal_shape.c, blockportal_shape.b() - 1), EnumDirection.a(enumdirection_enumaxisdirection1, enumdirection_enumaxis), EnumDirection.UP, loadingcache, blockportal_shape.b(), blockportal_shape.a(), 1); + } + } + + public static class Shape { + + private final World a; + private final EnumDirection.EnumAxis b; + private final EnumDirection c; + private final EnumDirection d; + private int e = 0; + private BlockPosition position; + private int height; + private int width; + java.util.Collection blocks = new java.util.HashSet(); // CraftBukkit - add field + + public Shape(World world, BlockPosition blockposition, EnumDirection.EnumAxis enumdirection_enumaxis) { + this.a = world; + this.b = enumdirection_enumaxis; + if (enumdirection_enumaxis == EnumDirection.EnumAxis.X) { + this.d = EnumDirection.EAST; + this.c = EnumDirection.WEST; + } else { + this.d = EnumDirection.NORTH; + this.c = EnumDirection.SOUTH; + } + + for (BlockPosition blockposition1 = blockposition; blockposition.getY() > blockposition1.getY() - 21 && blockposition.getY() > 0 && this.a(world.getType(blockposition.down()).getBlock()); blockposition = blockposition.down()) { + ; + } + + int i = this.a(blockposition, this.d) - 1; + + if (i >= 0) { + this.position = blockposition.shift(this.d, i); + this.width = this.a(this.position, this.c); + if (this.width < 2 || this.width > 21) { + this.position = null; + this.width = 0; + } + } + + if (this.position != null) { + this.height = this.c(); + } + + } + + protected int a(BlockPosition blockposition, EnumDirection enumdirection) { + int i; + + for (i = 0; i < 22; ++i) { + BlockPosition blockposition1 = blockposition.shift(enumdirection, i); + + if (!this.a(this.a.getType(blockposition1).getBlock()) || this.a.getType(blockposition1.down()).getBlock() != Blocks.OBSIDIAN) { + break; + } + } + + Block block = this.a.getType(blockposition.shift(enumdirection, i)).getBlock(); + + return block == Blocks.OBSIDIAN ? i : 0; + } + + public int a() { + return this.height; + } + + public int b() { + return this.width; + } + + protected int c() { + // CraftBukkit start + this.blocks.clear(); + org.bukkit.World bworld = this.a.getWorld(); + // CraftBukkit end + int i; + + label56: + for (this.height = 0; this.height < 21; ++this.height) { + for (i = 0; i < this.width; ++i) { + BlockPosition blockposition = this.position.shift(this.c, i).up(this.height); + Block block = this.a.getType(blockposition).getBlock(); + + if (!this.a(block)) { + break label56; + } + + if (block == Blocks.PORTAL) { + ++this.e; + } + + if (i == 0) { + block = this.a.getType(blockposition.shift(this.d)).getBlock(); + if (block != Blocks.OBSIDIAN) { + break label56; + // CraftBukkit start - add the block to our list + } else { + BlockPosition pos = blockposition.shift(this.d); + blocks.add(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); + // CraftBukkit end + } + } else if (i == this.width - 1) { + block = this.a.getType(blockposition.shift(this.c)).getBlock(); + if (block != Blocks.OBSIDIAN) { + break label56; + // CraftBukkit start - add the block to our list + } else { + BlockPosition pos = blockposition.shift(this.c); + blocks.add(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); + // CraftBukkit end + } + } + } + } + + for (i = 0; i < this.width; ++i) { + if (this.a.getType(this.position.shift(this.c, i).up(this.height)).getBlock() != Blocks.OBSIDIAN) { + this.height = 0; + break; + // CraftBukkit start - add the block to our list + } else { + BlockPosition pos = this.position.shift(this.c, i).up(this.height); + blocks.add(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); + // CraftBukkit end + } + } + + if (this.height <= 21 && this.height >= 3) { + return this.height; + } else { + this.position = null; + this.width = 0; + this.height = 0; + return 0; + } + } + + protected boolean a(Block block) { + return block.material == Material.AIR || block == Blocks.FIRE || block == Blocks.PORTAL; + } + + public boolean d() { + return this.position != null && this.width >= 2 && this.width <= 21 && this.height >= 3 && this.height <= 21; + } + + // CraftBukkit start - return boolean + public boolean createPortal() { + org.bukkit.World bworld = this.a.getWorld(); + + // Copy below for loop + for (int i = 0; i < this.width; ++i) { + BlockPosition blockposition = this.position.shift(this.c, i); + + for (int j = 0; j < this.height; ++j) { + BlockPosition pos = blockposition.up(j); + blocks.add(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); + } + } + + PortalCreateEvent event = new PortalCreateEvent(blocks, bworld, PortalCreateEvent.CreateReason.FIRE); + this.a.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return false; + } + // CraftBukkit end + for (int i = 0; i < this.width; ++i) { + BlockPosition blockposition = this.position.shift(this.c, i); + + for (int j = 0; j < this.height; ++j) { + this.a.setTypeAndData(blockposition.up(j), Blocks.PORTAL.getBlockData().set(BlockPortal.AXIS, this.b), 2); + } + } + + return true; // CraftBukkit + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPosition.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPosition.java new file mode 100644 index 0000000..7fac7a2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPosition.java @@ -0,0 +1,290 @@ +package net.minecraft.server; + +import com.google.common.collect.AbstractIterator; +import net.jafama.FastMath; + +import java.util.Iterator; + +public class BlockPosition extends BaseBlockPosition { + + public static final BlockPosition ZERO = new BlockPosition(0, 0, 0); + private static final int c = 1 + MathHelper.c(MathHelper.b(30000000)); + private static final int d = BlockPosition.c; + private static final int e = 64 - BlockPosition.c - BlockPosition.d; + private static final int f = 0 + BlockPosition.d; + private static final int g = BlockPosition.f + BlockPosition.e; + private static final long h = (1L << BlockPosition.c) - 1L; + private static final long i = (1L << BlockPosition.e) - 1L; + private static final long j = (1L << BlockPosition.d) - 1L; + + public BlockPosition(int i, int j, int k) { + super(i, j, k); + } + + public BlockPosition(double d0, double d1, double d2) { + super(d0, d1, d2); + } + + public BlockPosition(Entity entity) { + this(entity.locX, entity.locY, entity.locZ); + } + + public BlockPosition(Vec3D vec3d) { + this(vec3d.a, vec3d.b, vec3d.c); + } + + public BlockPosition(BaseBlockPosition baseblockposition) { + this(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ()); + } + + public BlockPosition a(double d0, double d1, double d2) { + return d0 == 0.0D && d1 == 0.0D && d2 == 0.0D ? this : new BlockPosition((double) this.getX() + d0, (double) this.getY() + d1, (double) this.getZ() + d2); + } + + public BlockPosition a(int i, int j, int k) { + return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k); + } + + public BlockPosition a(BaseBlockPosition baseblockposition) { + return baseblockposition.getX() == 0 && baseblockposition.getY() == 0 && baseblockposition.getZ() == 0 ? this : new BlockPosition(this.getX() + baseblockposition.getX(), this.getY() + baseblockposition.getY(), this.getZ() + baseblockposition.getZ()); + } + + public BlockPosition b(BaseBlockPosition baseblockposition) { + return baseblockposition.getX() == 0 && baseblockposition.getY() == 0 && baseblockposition.getZ() == 0 ? this : new BlockPosition(this.getX() - baseblockposition.getX(), this.getY() - baseblockposition.getY(), this.getZ() - baseblockposition.getZ()); + } + + public BlockPosition up() { + return this.up(1); + } + + public BlockPosition up(int i) { + return this.shift(EnumDirection.UP, i); + } + + public BlockPosition down() { + return this.down(1); + } + + public BlockPosition down(int i) { + return this.shift(EnumDirection.DOWN, i); + } + + public BlockPosition north() { + return this.north(1); + } + + public BlockPosition north(int i) { + return this.shift(EnumDirection.NORTH, i); + } + + public BlockPosition south() { + return this.south(1); + } + + public BlockPosition south(int i) { + return this.shift(EnumDirection.SOUTH, i); + } + + public BlockPosition west() { + return this.west(1); + } + + public BlockPosition west(int i) { + return this.shift(EnumDirection.WEST, i); + } + + public BlockPosition east() { + return this.east(1); + } + + public BlockPosition east(int i) { + return this.shift(EnumDirection.EAST, i); + } + + public BlockPosition shift(EnumDirection enumdirection) { + return this.shift(enumdirection, 1); + } + + public BlockPosition shift(EnumDirection enumdirection, int i) { + return i == 0 ? this : new BlockPosition(this.getX() + enumdirection.getAdjacentX() * i, this.getY() + enumdirection.getAdjacentY() * i, this.getZ() + enumdirection.getAdjacentZ() * i); + } + + public BlockPosition c(BaseBlockPosition baseblockposition) { + return new BlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX()); + } + + public long asLong() { + return ((long) this.getX() & BlockPosition.h) << BlockPosition.g | ((long) this.getY() & BlockPosition.i) << BlockPosition.f | ((long) this.getZ() & BlockPosition.j) << 0; + } + + public static BlockPosition fromLong(long i) { + int j = (int) (i << 64 - BlockPosition.g - BlockPosition.c >> 64 - BlockPosition.c); + int k = (int) (i << 64 - BlockPosition.f - BlockPosition.e >> 64 - BlockPosition.e); + int l = (int) (i << 64 - BlockPosition.d >> 64 - BlockPosition.d); + + return new BlockPosition(j, k, l); + } + + public static Iterable a(BlockPosition blockposition, BlockPosition blockposition1) { + final BlockPosition blockposition2 = new BlockPosition(FastMath.min(blockposition.getX(), blockposition1.getX()), FastMath.min(blockposition.getY(), blockposition1.getY()), FastMath.min(blockposition.getZ(), blockposition1.getZ())); + final BlockPosition blockposition3 = new BlockPosition(FastMath.max(blockposition.getX(), blockposition1.getX()), FastMath.max(blockposition.getY(), blockposition1.getY()), FastMath.max(blockposition.getZ(), blockposition1.getZ())); + + return new Iterable() { + public Iterator iterator() { + return new AbstractIterator() { + private BlockPosition b = null; + + protected BlockPosition a() { + if (this.b == null) { + this.b = blockposition; + return this.b; + } else if (this.b.equals(blockposition1)) { + return (BlockPosition) this.endOfData(); + } else { + int i = this.b.getX(); + int j = this.b.getY(); + int k = this.b.getZ(); + + if (i < blockposition1.getX()) { + ++i; + } else if (j < blockposition1.getY()) { + i = blockposition.getX(); + ++j; + } else if (k < blockposition1.getZ()) { + i = blockposition.getX(); + j = blockposition.getY(); + ++k; + } + + this.b = new BlockPosition(i, j, k); + return this.b; + } + } + + protected Object computeNext() { + return this.a(); + } + }; + } + }; + } + + public static Iterable b(BlockPosition blockposition, BlockPosition blockposition1) { + final BlockPosition blockposition2 = new BlockPosition(FastMath.min(blockposition.getX(), blockposition1.getX()), FastMath.min(blockposition.getY(), blockposition1.getY()), FastMath.min(blockposition.getZ(), blockposition1.getZ())); + final BlockPosition blockposition3 = new BlockPosition(FastMath.max(blockposition.getX(), blockposition1.getX()), FastMath.max(blockposition.getY(), blockposition1.getY()), FastMath.max(blockposition.getZ(), blockposition1.getZ())); + + return new Iterable() { + public Iterator iterator() { + return new AbstractIterator() { + private BlockPosition.MutableBlockPosition b = null; + + protected BlockPosition.MutableBlockPosition a() { + if (this.b == null) { + this.b = new BlockPosition.MutableBlockPosition(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + return this.b; + } else if (this.b.equals(blockposition1)) { + return (BlockPosition.MutableBlockPosition) this.endOfData(); + } else { + int i = this.b.getX(); + int j = this.b.getY(); + int k = this.b.getZ(); + + if (i < blockposition1.getX()) { + ++i; + } else if (j < blockposition1.getY()) { + i = blockposition.getX(); + ++j; + } else if (k < blockposition1.getZ()) { + i = blockposition.getX(); + j = blockposition.getY(); + ++k; + } + + // PaperSpigot start + this.b.setX(i); + this.b.setY(j); + this.b.setZ(k); + // PaperSpigot stop + return this.b; + } + } + + protected Object computeNext() { + return this.a(); + } + }; + } + }; + } + + public BaseBlockPosition d(BaseBlockPosition baseblockposition) { + return this.c(baseblockposition); + } + + public static final class MutableBlockPosition extends BlockPosition { + + // PaperSpigot start - remove our overriding variables + /* + private int c; + private int d; + private int e; + */ + + public void setX(int x) { + ((BaseBlockPosition) this).a = x; + } + + public void setY(int y) { + ((BaseBlockPosition) this).c = y; + } + + public void setZ(int z) { + ((BaseBlockPosition) this).d = z; + } + // PaperSpigot end + + public MutableBlockPosition() { + this(0, 0, 0); + } + + public MutableBlockPosition(int i, int j, int k) { + super(0, 0, 0); + // PaperSpigot start - modify base x,y,z + this.setX(i); + this.setY(j); + this.setZ(k); + } + + /* + public int getX() { + return this.c; + } + + public int getY() { + return this.d; + } + + public int getZ() { + return this.e; + } + */ + + // TacoSpigot start - OBFHELPER + public BlockPosition.MutableBlockPosition setValues(int x, int y, int z) { + return c(x, y, z); + } + // TacoSpigot end + + public BlockPosition.MutableBlockPosition c(int i, int j, int k) { + setX(i); + setY(j); + setZ(k); + // PaperSpigot end + return this; + } + + public BaseBlockPosition d(BaseBlockPosition baseblockposition) { + return super.c(baseblockposition); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPoweredRail.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPoweredRail.java new file mode 100644 index 0000000..43a400f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPoweredRail.java @@ -0,0 +1,203 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class BlockPoweredRail extends BlockMinecartTrackAbstract { + + public static final BlockStateEnum SHAPE = BlockStateEnum.a("shape", BlockMinecartTrackAbstract.EnumTrackPosition.class, new Predicate() { + public boolean a(BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition) { + return blockminecarttrackabstract_enumtrackposition != BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_EAST && blockminecarttrackabstract_enumtrackposition != BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_WEST && blockminecarttrackabstract_enumtrackposition != BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_EAST && blockminecarttrackabstract_enumtrackposition != BlockMinecartTrackAbstract.EnumTrackPosition.SOUTH_WEST; + } + + public boolean apply(Object object) { + return this.a((BlockMinecartTrackAbstract.EnumTrackPosition) object); + } + }); + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); + + protected BlockPoweredRail() { + super(true); + this.j(this.blockStateList.getBlockData().set(BlockPoweredRail.SHAPE, BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH).set(BlockPoweredRail.POWERED, Boolean.valueOf(false))); + } + + protected boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag, int i) { + if (i >= 8) { + return false; + } else { + int j = blockposition.getX(); + int k = blockposition.getY(); + int l = blockposition.getZ(); + boolean flag1 = true; + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = (BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE); + + switch (BlockPoweredRail.SyntheticClass_1.a[blockminecarttrackabstract_enumtrackposition.ordinal()]) { + case 1: + if (flag) { + ++l; + } else { + --l; + } + break; + + case 2: + if (flag) { + --j; + } else { + ++j; + } + break; + + case 3: + if (flag) { + --j; + } else { + ++j; + ++k; + flag1 = false; + } + + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST; + break; + + case 4: + if (flag) { + --j; + ++k; + flag1 = false; + } else { + ++j; + } + + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST; + break; + + case 5: + if (flag) { + ++l; + } else { + --l; + ++k; + flag1 = false; + } + + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + break; + + case 6: + if (flag) { + ++l; + ++k; + flag1 = false; + } else { + --l; + } + + blockminecarttrackabstract_enumtrackposition = BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + } + + return this.a(world, new BlockPosition(j, k, l), flag, i, blockminecarttrackabstract_enumtrackposition) ? true : flag1 && this.a(world, new BlockPosition(j, k - 1, l), flag, i, blockminecarttrackabstract_enumtrackposition); + } + } + + protected boolean a(World world, BlockPosition blockposition, boolean flag, int i, BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition) { + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock() != this) { + return false; + } else { + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition1 = (BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE); + + return blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST && (blockminecarttrackabstract_enumtrackposition1 == BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH || blockminecarttrackabstract_enumtrackposition1 == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_NORTH || blockminecarttrackabstract_enumtrackposition1 == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_SOUTH) ? false : (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH && (blockminecarttrackabstract_enumtrackposition1 == BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST || blockminecarttrackabstract_enumtrackposition1 == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_EAST || blockminecarttrackabstract_enumtrackposition1 == BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_WEST) ? false : (((Boolean) iblockdata.get(BlockPoweredRail.POWERED)).booleanValue() ? (world.isBlockIndirectlyPowered(blockposition) ? true : this.a(world, blockposition, iblockdata, flag, i + 1)) : false)); + } + } + + protected void b(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + boolean flag = ((Boolean) iblockdata.get(BlockPoweredRail.POWERED)).booleanValue(); + boolean flag1 = world.isBlockIndirectlyPowered(blockposition) || this.a(world, blockposition, iblockdata, true, 0) || this.a(world, blockposition, iblockdata, false, 0); + + if (flag1 != flag) { + // CraftBukkit start + int power = (Boolean)iblockdata.get(POWERED) ? 15 : 0; + int newPower = CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), power, 15 - power).getNewCurrent(); + if (newPower == power) { + return; + } + // CraftBukkit end + world.setTypeAndData(blockposition, iblockdata.set(BlockPoweredRail.POWERED, Boolean.valueOf(flag1)), 3); + world.applyPhysics(blockposition.down(), this); + if (((BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)).c()) { + world.applyPhysics(blockposition.up(), this); + } + } + + } + + public IBlockState n() { + return BlockPoweredRail.SHAPE; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockPoweredRail.SHAPE, BlockMinecartTrackAbstract.EnumTrackPosition.a(i & 7)).set(BlockPoweredRail.POWERED, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(BlockPoweredRail.SHAPE)).a(); + + if (((Boolean) iblockdata.get(BlockPoweredRail.POWERED)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockPoweredRail.SHAPE, BlockPoweredRail.POWERED}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[BlockMinecartTrackAbstract.EnumTrackPosition.values().length]; + + static { + try { + BlockPoweredRail.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockPoweredRail.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockPoweredRail.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_EAST.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockPoweredRail.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_WEST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockPoweredRail.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_NORTH.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + try { + BlockPoweredRail.SyntheticClass_1.a[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_SOUTH.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror5) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateAbstract.java new file mode 100644 index 0000000..6da1fcc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateAbstract.java @@ -0,0 +1,184 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + +public abstract class BlockPressurePlateAbstract extends Block { + + protected BlockPressurePlateAbstract(Material material) { + this(material, material.r()); + } + + protected BlockPressurePlateAbstract(Material material, MaterialMapColor materialmapcolor) { + super(material, materialmapcolor); + this.a(CreativeModeTab.d); + this.a(true); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + this.d(iblockaccess.getType(blockposition)); + } + + protected void d(IBlockData iblockdata) { + boolean flag = this.e(iblockdata) > 0; + float f = 0.0625F; + + if (flag) { + this.a(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.03125F, 0.9375F); + } else { + this.a(0.0625F, 0.0F, 0.0625F, 0.9375F, 0.0625F, 0.9375F); + } + + } + + public int a(World world) { + return 20; + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition) { + return true; + } + + public boolean g() { + return true; + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return this.m(world, blockposition.down()); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!this.m(world, blockposition.down())) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + + } + + private boolean m(World world, BlockPosition blockposition) { + return World.a((IBlockAccess) world, blockposition) || world.getType(blockposition).getBlock() instanceof BlockFence; + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {} + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + int i = this.e(iblockdata); + + if (i > 0) { + this.a(world, blockposition, iblockdata, i); + } + + } + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (!world.isClientSide) { + int i = this.e(iblockdata); + + if (i == 0) { + this.a(world, blockposition, iblockdata, i); + } + + } + } + + protected void a(World world, BlockPosition blockposition, IBlockData iblockdata, int i) { + int j = this.f(world, blockposition); + boolean flag = i > 0; + boolean flag1 = j > 0; + + // CraftBukkit start - Interact Pressure Plate + org.bukkit.World bworld = world.getWorld(); + org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); + + if (flag != flag1) { + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), i, j); + manager.callEvent(eventRedstone); + + flag1 = eventRedstone.getNewCurrent() > 0; + j = eventRedstone.getNewCurrent(); + } + // CraftBukkit end + + if (i != j) { + iblockdata = this.a(iblockdata, j); + world.setTypeAndData(blockposition, iblockdata, 2); + this.e(world, blockposition); + world.b(blockposition, blockposition); + } + + if (!flag1 && flag) { + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.1D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, 0.5F); + } else if (flag1 && !flag) { + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.1D, (double) blockposition.getZ() + 0.5D, "random.click", 0.3F, 0.6F); + } + + if (flag1) { + world.a(blockposition, (Block) this, this.a(world)); + } + + } + + protected AxisAlignedBB getBoundingBox(BlockPosition blockposition) { + float f = 0.125F; + + return new AxisAlignedBB((double) ((float) blockposition.getX() + 0.125F), (double) blockposition.getY(), (double) ((float) blockposition.getZ() + 0.125F), (double) ((float) (blockposition.getX() + 1) - 0.125F), (double) blockposition.getY() + 0.25D, (double) ((float) (blockposition.getZ() + 1) - 0.125F)); + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (this.e(iblockdata) > 0) { + this.e(world, blockposition); + } + + super.remove(world, blockposition, iblockdata); + } + + protected void e(World world, BlockPosition blockposition) { + world.applyPhysics(blockposition, this); + world.applyPhysics(blockposition.down(), this); + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return this.e(iblockdata); + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return enumdirection == EnumDirection.UP ? this.e(iblockdata) : 0; + } + + public boolean isPowerSource() { + return true; + } + + public void j() { + float f = 0.5F; + float f1 = 0.125F; + float f2 = 0.5F; + + this.a(0.0F, 0.375F, 0.0F, 1.0F, 0.625F, 1.0F); + } + + public int k() { + return 1; + } + + protected abstract int f(World world, BlockPosition blockposition); + + protected abstract int e(IBlockData iblockdata); + + protected abstract IBlockData a(IBlockData iblockdata, int i); +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateBinary.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateBinary.java new file mode 100644 index 0000000..ada3875 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateBinary.java @@ -0,0 +1,117 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit + +public class BlockPressurePlateBinary extends BlockPressurePlateAbstract { + + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); + private final BlockPressurePlateBinary.EnumMobType b; + + protected BlockPressurePlateBinary(Material material, BlockPressurePlateBinary.EnumMobType blockpressureplatebinary_enummobtype) { + super(material); + this.j(this.blockStateList.getBlockData().set(BlockPressurePlateBinary.POWERED, Boolean.valueOf(false))); + this.b = blockpressureplatebinary_enummobtype; + } + + protected int e(IBlockData iblockdata) { + return ((Boolean) iblockdata.get(BlockPressurePlateBinary.POWERED)).booleanValue() ? 15 : 0; + } + + protected IBlockData a(IBlockData iblockdata, int i) { + return iblockdata.set(BlockPressurePlateBinary.POWERED, Boolean.valueOf(i > 0)); + } + + protected int f(World world, BlockPosition blockposition) { + AxisAlignedBB axisalignedbb = this.getBoundingBox(blockposition); + List list; + + switch (BlockPressurePlateBinary.SyntheticClass_1.a[this.b.ordinal()]) { + case 1: + list = world.getEntities((Entity) null, axisalignedbb); + break; + + case 2: + list = world.a(EntityLiving.class, axisalignedbb); + break; + + default: + return 0; + } + + if (!list.isEmpty()) { + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + // CraftBukkit start - Call interact event when turning on a pressure plate + if (this.e(world.getType(blockposition)) == 0) { + org.bukkit.World bworld = world.getWorld(); + org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); + org.bukkit.event.Cancellable cancellable; + + if (entity instanceof EntityHuman) { + cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); + } else { + cancellable = new EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + manager.callEvent((EntityInteractEvent) cancellable); + } + + // We only want to block turning the plate on if all events are cancelled + if (cancellable.isCancelled()) { + continue; + } + } + // CraftBukkit end + + if (!entity.aI()) { + return 15; + } + } + } + + return 0; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockPressurePlateBinary.POWERED, Boolean.valueOf(i == 1)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Boolean) iblockdata.get(BlockPressurePlateBinary.POWERED)).booleanValue() ? 1 : 0; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockPressurePlateBinary.POWERED}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[BlockPressurePlateBinary.EnumMobType.values().length]; + + static { + try { + BlockPressurePlateBinary.SyntheticClass_1.a[BlockPressurePlateBinary.EnumMobType.EVERYTHING.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockPressurePlateBinary.SyntheticClass_1.a[BlockPressurePlateBinary.EnumMobType.MOBS.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + } + } + + public static enum EnumMobType { + + EVERYTHING, MOBS; + + private EnumMobType() {} + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateWeighted.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateWeighted.java new file mode 100644 index 0000000..5e96f9b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPressurePlateWeighted.java @@ -0,0 +1,79 @@ +package net.minecraft.server; + +import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit + +public class BlockPressurePlateWeighted extends BlockPressurePlateAbstract { + + public static final BlockStateInteger POWER = BlockStateInteger.of("power", 0, 15); + private final int weight; + + protected BlockPressurePlateWeighted(Material material, int i) { + this(material, i, material.r()); + } + + protected BlockPressurePlateWeighted(Material material, int i, MaterialMapColor materialmapcolor) { + super(material, materialmapcolor); + this.j(this.blockStateList.getBlockData().set(BlockPressurePlateWeighted.POWER, Integer.valueOf(0))); + this.weight = i; + } + + protected int f(World world, BlockPosition blockposition) { + // CraftBukkit start + //int i = Math.min(world.a(Entity.class, this.a(blockposition)).size(), this.b); + int i = 0; + java.util.Iterator iterator = world.a(Entity.class, this.getBoundingBox(blockposition)).iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + org.bukkit.event.Cancellable cancellable; + + if (entity instanceof EntityHuman) { + cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); + } else { + cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + world.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); + } + + // We only want to block turning the plate on if all events are cancelled + if (!cancellable.isCancelled()) { + i++; + } + } + + i = Math.min(i, this.weight); + // CraftBukkit end + + if (i > 0) { + float f = (float) Math.min(this.weight, i) / (float) this.weight; + + return MathHelper.f(f * 15.0F); + } else { + return 0; + } + } + + protected int e(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockPressurePlateWeighted.POWER)).intValue(); + } + + protected IBlockData a(IBlockData iblockdata, int i) { + return iblockdata.set(BlockPressurePlateWeighted.POWER, Integer.valueOf(i)); + } + + public int a(World world) { + return 10; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockPressurePlateWeighted.POWER, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockPressurePlateWeighted.POWER)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockPressurePlateWeighted.POWER}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPumpkin.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPumpkin.java new file mode 100644 index 0000000..1295820 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockPumpkin.java @@ -0,0 +1,167 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; + +// CraftBukkit start +import org.bukkit.craftbukkit.util.BlockStateListPopulator; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +// CraftBukkit end + +public class BlockPumpkin extends BlockDirectional { + + private ShapeDetector snowGolemPart; + private ShapeDetector snowGolem; + private ShapeDetector ironGolemPart; + private ShapeDetector ironGolem; + private static final Predicate Q = new Predicate() { + public boolean a(IBlockData iblockdata) { + return iblockdata != null && (iblockdata.getBlock() == Blocks.PUMPKIN || iblockdata.getBlock() == Blocks.LIT_PUMPKIN); + } + + public boolean apply(Object object) { + return this.a((IBlockData) object); + } + }; + + protected BlockPumpkin() { + super(Material.PUMPKIN, MaterialMapColor.q); + this.j(this.blockStateList.getBlockData().set(BlockPumpkin.FACING, EnumDirection.NORTH)); + this.a(true); + this.a(CreativeModeTab.b); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + super.onPlace(world, blockposition, iblockdata); + this.f(world, blockposition); + } + + public boolean e(World world, BlockPosition blockposition) { + return this.getDetectorSnowGolemPart().a(world, blockposition) != null || this.getDetectorIronGolemPart().a(world, blockposition) != null; + } + + private void f(World world, BlockPosition blockposition) { + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection; + int i; + int j; + + if ((shapedetector_shapedetectorcollection = this.getDetectorSnowGolem().a(world, blockposition)) != null) { + BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld()); // CraftBukkit - Use BlockStateListPopulator + for (i = 0; i < this.getDetectorSnowGolem().b(); ++i) { + ShapeDetectorBlock shapedetectorblock = shapedetector_shapedetectorcollection.a(0, i, 0); + + // CraftBukkit start + // world.setTypeAndData(shapedetectorblock.d(), Blocks.AIR.getBlockData(), 2); + BlockPosition pos = shapedetectorblock.getPosition(); + blockList.setTypeId(pos.getX(), pos.getY(), pos.getZ(), 0); + // CraftBukkit end + } + + EntitySnowman entitysnowman = new EntitySnowman(world); + BlockPosition blockposition1 = shapedetector_shapedetectorcollection.a(0, 2, 0).getPosition(); + + entitysnowman.setPositionRotation((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.05D, (double) blockposition1.getZ() + 0.5D, 0.0F, 0.0F); + // CraftBukkit start + if (world.addEntity(entitysnowman, SpawnReason.BUILD_SNOWMAN)) { + 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]); + } + + for (j = 0; j < this.getDetectorSnowGolem().b(); ++j) { + ShapeDetectorBlock shapedetectorblock1 = shapedetector_shapedetectorcollection.a(0, j, 0); + + world.update(shapedetectorblock1.getPosition(), Blocks.AIR); + } + } // CraftBukkit end + } else if ((shapedetector_shapedetectorcollection = this.getDetectorIronGolem().a(world, blockposition)) != null) { + BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld()); // CraftBukkit - Use BlockStateListPopulator + for (i = 0; i < this.getDetectorIronGolem().c(); ++i) { + for (int k = 0; k < this.getDetectorIronGolem().b(); ++k) { + // CraftBukkit start + // world.setTypeAndData(shapedetectorcollection.a(i, k, 0).d(), Blocks.AIR.getBlockData(), 2); + BlockPosition pos = shapedetector_shapedetectorcollection.a(i, k, 0).getPosition(); + blockList.setTypeId(pos.getX(), pos.getY(), pos.getZ(), 0); + // CraftBukkit end + } + } + + BlockPosition blockposition2 = shapedetector_shapedetectorcollection.a(1, 2, 0).getPosition(); + EntityIronGolem entityirongolem = new EntityIronGolem(world); + + entityirongolem.setPlayerCreated(true); + entityirongolem.setPositionRotation((double) blockposition2.getX() + 0.5D, (double) blockposition2.getY() + 0.05D, (double) blockposition2.getZ() + 0.5D, 0.0F, 0.0F); + + // CraftBukkit start + if (world.addEntity(entityirongolem, SpawnReason.BUILD_IRONGOLEM)) { + 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]); + } + + for (j = 0; j < this.getDetectorIronGolem().c(); ++j) { + for (int l = 0; l < this.getDetectorIronGolem().b(); ++l) { + ShapeDetectorBlock shapedetectorblock2 = shapedetector_shapedetectorcollection.a(j, l, 0); + + world.update(shapedetectorblock2.getPosition(), Blocks.AIR); + } + } + } // CraftBukkit end + } + + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return world.getType(blockposition).getBlock().material.isReplaceable() && World.a((IBlockAccess) world, blockposition.down()); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return this.getBlockData().set(BlockPumpkin.FACING, entityliving.getDirection().opposite()); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockPumpkin.FACING, EnumDirection.fromType2(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((EnumDirection) iblockdata.get(BlockPumpkin.FACING)).b(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockPumpkin.FACING}); + } + + protected ShapeDetector getDetectorSnowGolemPart() { + if (this.snowGolemPart == null) { + this.snowGolemPart = ShapeDetectorBuilder.a().a(new String[] { " ", "#", "#"}).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SNOW))).b(); + } + + return this.snowGolemPart; + } + + protected ShapeDetector getDetectorSnowGolem() { + if (this.snowGolem == null) { + this.snowGolem = ShapeDetectorBuilder.a().a(new String[] { "^", "#", "#"}).a('^', ShapeDetectorBlock.a(BlockPumpkin.Q)).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SNOW))).b(); + } + + return this.snowGolem; + } + + protected ShapeDetector getDetectorIronGolemPart() { + if (this.ironGolemPart == null) { + this.ironGolemPart = ShapeDetectorBuilder.a().a(new String[] { "~ ~", "###", "~#~"}).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.IRON_BLOCK))).a('~', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.AIR))).b(); + } + + return this.ironGolemPart; + } + + protected ShapeDetector getDetectorIronGolem() { + if (this.ironGolem == null) { + this.ironGolem = ShapeDetectorBuilder.a().a(new String[] { "~^~", "###", "~#~"}).a('^', ShapeDetectorBlock.a(BlockPumpkin.Q)).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.IRON_BLOCK))).a('~', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.AIR))).b(); + } + + return this.ironGolem; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneLamp.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneLamp.java new file mode 100644 index 0000000..4542b49 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneLamp.java @@ -0,0 +1,73 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class BlockRedstoneLamp extends Block { + + private final boolean a; + + public BlockRedstoneLamp(boolean flag) { + super(Material.BUILDABLE_GLASS); + this.a = flag; + if (flag) { + this.a(1.0F); + } + + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!world.isClientSide) { + if (this.a && !world.isBlockIndirectlyPowered(blockposition)) { + world.setTypeAndData(blockposition, Blocks.REDSTONE_LAMP.getBlockData(), 2); + } else if (!this.a && world.isBlockIndirectlyPowered(blockposition)) { + // CraftBukkit start + if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 0, 15).getNewCurrent() != 15) { + return; + } + // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.LIT_REDSTONE_LAMP.getBlockData(), 2); + } + + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!world.isClientSide) { + if (this.a && !world.isBlockIndirectlyPowered(blockposition)) { + world.a(blockposition, (Block) this, 4); + } else if (!this.a && world.isBlockIndirectlyPowered(blockposition)) { + // CraftBukkit start + if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 0, 15).getNewCurrent() != 15) { + return; + } + // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.LIT_REDSTONE_LAMP.getBlockData(), 2); + } + + } + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (this.a && !world.isBlockIndirectlyPowered(blockposition)) { + // CraftBukkit start + if (CraftEventFactory.callRedstoneChange(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), 15, 0).getNewCurrent() != 0) { + return; + } + // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.REDSTONE_LAMP.getBlockData(), 2); + } + + } + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Item.getItemOf(Blocks.REDSTONE_LAMP); + } + + protected ItemStack i(IBlockData iblockdata) { + return new ItemStack(Blocks.REDSTONE_LAMP); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneOre.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneOre.java new file mode 100644 index 0000000..119354a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneOre.java @@ -0,0 +1,160 @@ +package net.minecraft.server; + +import java.util.Random; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityInteractEvent; +// CraftBukkit end + +public class BlockRedstoneOre extends Block { + + private final boolean a; + + public BlockRedstoneOre(boolean flag) { + super(Material.STONE); + if (flag) { + this.a(true); + } + + this.a = flag; + } + + public int a(World world) { + return 30; + } + + public void attack(World world, BlockPosition blockposition, EntityHuman entityhuman) { + this.e(world, blockposition, entityhuman); // CraftBukkit - add entityhuman + super.attack(world, blockposition, entityhuman); + } + + public void a(World world, BlockPosition blockposition, Entity entity) { + // CraftBukkit start + // this.e(world, blockposition); + // super.a(world, blockposition, entity); + if (entity instanceof EntityHuman) { + org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); + if (!event.isCancelled()) { + this.e(world, blockposition, entity); // add entity + super.a(world, blockposition, entity); + } + } else { + EntityInteractEvent event = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + world.getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) { + this.e(world, blockposition, entity); // add entity + super.a(world, blockposition, entity); + } + } + // CraftBukkit end + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + this.e(world, blockposition, entityhuman); // CraftBukkit - add entityhuman + return super.interact(world, blockposition, iblockdata, entityhuman, enumdirection, f, f1, f2); + } + + private void e(World world, BlockPosition blockposition, Entity entity) { // CraftBukkit - add Entity + this.f(world, blockposition); + if (this == Blocks.REDSTONE_ORE) { + // CraftBukkit start + if (CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.LIT_REDSTONE_ORE, 0).isCancelled()) { + return; + } + // CraftBukkit end + world.setTypeUpdate(blockposition, Blocks.LIT_REDSTONE_ORE.getBlockData()); + } + + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (this == Blocks.LIT_REDSTONE_ORE) { + // CraftBukkit start + if (CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), Blocks.REDSTONE_ORE).isCancelled()) { + return; + } + // CraftBukkit end + world.setTypeUpdate(blockposition, Blocks.REDSTONE_ORE.getBlockData()); + } + + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Items.REDSTONE; + } + + public int getDropCount(int i, Random random) { + return this.a(random) + random.nextInt(i + 1); + } + + public int a(Random random) { + return 4 + random.nextInt(2); + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + super.dropNaturally(world, blockposition, iblockdata, f, i); + /* CraftBukkit start - Delegated to getExpDrop + if (this.getDropType(iblockdata, world.random, i) != Item.getItemOf(this)) { + int j = 1 + world.random.nextInt(5); + + this.dropExperience(world, blockposition, j); + } + // */ + } + + @Override + public int getExpDrop(World world, IBlockData data, int i) { + if (this.getDropType(data, world.random, i) != Item.getItemOf(this)) { + int j = 1 + world.random.nextInt(5); + + return j; + } + return 0; + // CraftBukkit end + } + + private void f(World world, BlockPosition blockposition) { + Random random = world.random; + double d0 = 0.0625D; + + for (int i = 0; i < 6; ++i) { + double d1 = (double) ((float) blockposition.getX() + random.nextFloat()); + double d2 = (double) ((float) blockposition.getY() + random.nextFloat()); + double d3 = (double) ((float) blockposition.getZ() + random.nextFloat()); + + if (i == 0 && !world.getType(blockposition.up()).getBlock().c()) { + d2 = (double) blockposition.getY() + d0 + 1.0D; + } + + if (i == 1 && !world.getType(blockposition.down()).getBlock().c()) { + d2 = (double) blockposition.getY() - d0; + } + + if (i == 2 && !world.getType(blockposition.south()).getBlock().c()) { + d3 = (double) blockposition.getZ() + d0 + 1.0D; + } + + if (i == 3 && !world.getType(blockposition.north()).getBlock().c()) { + d3 = (double) blockposition.getZ() - d0; + } + + if (i == 4 && !world.getType(blockposition.east()).getBlock().c()) { + d1 = (double) blockposition.getX() + d0 + 1.0D; + } + + if (i == 5 && !world.getType(blockposition.west()).getBlock().c()) { + d1 = (double) blockposition.getX() - d0; + } + + 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]); + } + } + + } + + protected ItemStack i(IBlockData iblockdata) { + return new ItemStack(Blocks.REDSTONE_ORE); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneTorch.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneTorch.java new file mode 100644 index 0000000..da484c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneTorch.java @@ -0,0 +1,206 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import org.bukkit.event.block.BlockRedstoneEvent; + +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class BlockRedstoneTorch extends BlockTorch { + + private static Map> b = new java.util.WeakHashMap(); // Spigot + private final boolean isOn; + + private boolean a(World world, BlockPosition blockposition, boolean flag) { + if (!BlockRedstoneTorch.b.containsKey(world)) { + BlockRedstoneTorch.b.put(world, Lists.newArrayList()); // CraftBukkit - fix decompile error + } + + List list = BlockRedstoneTorch.b.get(world); + + if (flag) { + list.add(new BlockRedstoneTorch.RedstoneUpdateInfo(blockposition, world.getTime())); + } + + int i = 0; + + for (int j = 0; j < list.size(); ++j) { + BlockRedstoneTorch.RedstoneUpdateInfo blockredstonetorch_redstoneupdateinfo = (BlockRedstoneTorch.RedstoneUpdateInfo) list.get(j); + + if (blockredstonetorch_redstoneupdateinfo.a.equals(blockposition)) { + ++i; + if (i >= 8) { + return true; + } + } + } + + return false; + } + + protected BlockRedstoneTorch(boolean flag) { + this.isOn = flag; + this.a(true); + this.a((CreativeModeTab) null); + } + + public int a(World world) { + return 2; + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (this.isOn) { + // PaperSpigot start - Fix cannons + if (world.paperSpigotConfig.fixCannons) { + world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this); + world.applyPhysics(blockposition.shift(EnumDirection.UP), this); + world.applyPhysics(blockposition.shift(EnumDirection.WEST), this); + world.applyPhysics(blockposition.shift(EnumDirection.EAST), this); + world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this); + world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this); + return; + } + // PaperSpigot end + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + if(!world.applyPhysics(blockposition.shift(enumdirection), this)) break; + } + } + + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (this.isOn) { + // PaperSpigot start - Fix cannons + if (world.paperSpigotConfig.fixCannons) { + world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this); + world.applyPhysics(blockposition.shift(EnumDirection.UP), this); + world.applyPhysics(blockposition.shift(EnumDirection.WEST), this); + world.applyPhysics(blockposition.shift(EnumDirection.EAST), this); + world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this); + world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this); + return; + } + // PaperSpigot end + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + if(!world.applyPhysics(blockposition.shift(enumdirection), this)) break; + } + } + + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return this.isOn && iblockdata.get(BlockRedstoneTorch.FACING) != enumdirection ? 15 : 0; + } + + private boolean g(World world, BlockPosition blockposition, IBlockData iblockdata) { + EnumDirection enumdirection = iblockdata.get(BlockRedstoneTorch.FACING).opposite(); + + return world.isBlockFacePowered(blockposition.shift(enumdirection), enumdirection); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {} + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + boolean flag = this.g(world, blockposition, iblockdata); + List list = BlockRedstoneTorch.b.get(world); + + while (list != null && !list.isEmpty() && world.getTime() - ((BlockRedstoneTorch.RedstoneUpdateInfo) list.get(0)).b > 60L) { + list.remove(0); + } + + // CraftBukkit start + org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + int oldCurrent = this.isOn ? 15 : 0; + + BlockRedstoneEvent event = new BlockRedstoneEvent(block, oldCurrent, oldCurrent); + // CraftBukkit end + + if (this.isOn) { + if (flag) { + // CraftBukkit start + if (oldCurrent != 0) { + event.setNewCurrent(0); + manager.callEvent(event); + if (event.getNewCurrent() != 0) { + return; + } + } + // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.UNLIT_REDSTONE_TORCH.getBlockData().set(BlockRedstoneTorch.FACING, iblockdata.get(BlockRedstoneTorch.FACING)), 3); + if (this.a(world, blockposition, true)) { + world.makeSound((float) blockposition.getX() + 0.5F, (float) blockposition.getY() + 0.5F, (float) blockposition.getZ() + 0.5F, "random.fizz", 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); + + for (int i = 0; i < 5; ++i) { + double d0 = (double) blockposition.getX() + random.nextDouble() * 0.6D + 0.2D; + double d1 = (double) blockposition.getY() + random.nextDouble() * 0.6D + 0.2D; + double d2 = (double) blockposition.getZ() + random.nextDouble() * 0.6D + 0.2D; + + world.addParticle(EnumParticle.SMOKE_NORMAL, d0, d1, d2, 0.0D, 0.0D, 0.0D); + } + + world.a(blockposition, world.getType(blockposition).getBlock(), 160); + } + } + } else if (!flag && !this.a(world, blockposition, false)) { + // CraftBukkit start + if (oldCurrent != 15) { + event.setNewCurrent(15); + manager.callEvent(event); + if (event.getNewCurrent() != 15) { + return; + } + } + // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.REDSTONE_TORCH.getBlockData().set(BlockRedstoneTorch.FACING, iblockdata.get(BlockRedstoneTorch.FACING)), 3); + } + + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!this.e(world, blockposition, iblockdata)) { + if (this.isOn == this.g(world, blockposition, iblockdata)) { + world.a(blockposition, this, this.a(world)); + } + + } + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return enumdirection == EnumDirection.DOWN ? this.a(iblockaccess, blockposition, iblockdata, enumdirection) : 0; + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Item.getItemOf(Blocks.REDSTONE_TORCH); + } + + public boolean isPowerSource() { + return true; + } + + public boolean b(Block block) { + return block == Blocks.UNLIT_REDSTONE_TORCH || block == Blocks.REDSTONE_TORCH; + } + + static class RedstoneUpdateInfo { + + BlockPosition a; + long b; + + public RedstoneUpdateInfo(BlockPosition blockposition, long i) { + this.a = blockposition; + this.b = i; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneWire.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneWire.java new file mode 100644 index 0000000..9984af4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockRedstoneWire.java @@ -0,0 +1,393 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.bukkit.event.block.BlockRedstoneEvent; + +import java.util.*; + +public class BlockRedstoneWire extends Block { + + public static final BlockStateEnum NORTH = BlockStateEnum.of("north", BlockRedstoneWire.EnumRedstoneWireConnection.class); + public static final BlockStateEnum EAST = BlockStateEnum.of("east", BlockRedstoneWire.EnumRedstoneWireConnection.class); + public static final BlockStateEnum SOUTH = BlockStateEnum.of("south", BlockRedstoneWire.EnumRedstoneWireConnection.class); + public static final BlockStateEnum WEST = BlockStateEnum.of("west", BlockRedstoneWire.EnumRedstoneWireConnection.class); + public static final BlockStateInteger POWER = BlockStateInteger.of("power", 0, 15); + private boolean Q = true; + private final Set R = Sets.newHashSet(); + + public BlockRedstoneWire() { + super(Material.ORIENTABLE); + this.j(this.blockStateList.getBlockData().set(BlockRedstoneWire.NORTH, BlockRedstoneWire.EnumRedstoneWireConnection.NONE).set(BlockRedstoneWire.EAST, BlockRedstoneWire.EnumRedstoneWireConnection.NONE).set(BlockRedstoneWire.SOUTH, BlockRedstoneWire.EnumRedstoneWireConnection.NONE).set(BlockRedstoneWire.WEST, BlockRedstoneWire.EnumRedstoneWireConnection.NONE).set(BlockRedstoneWire.POWER, Integer.valueOf(0))); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.0625F, 1.0F); + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + iblockdata = iblockdata.set(BlockRedstoneWire.WEST, this.c(iblockaccess, blockposition, EnumDirection.WEST)); + iblockdata = iblockdata.set(BlockRedstoneWire.EAST, this.c(iblockaccess, blockposition, EnumDirection.EAST)); + iblockdata = iblockdata.set(BlockRedstoneWire.NORTH, this.c(iblockaccess, blockposition, EnumDirection.NORTH)); + iblockdata = iblockdata.set(BlockRedstoneWire.SOUTH, this.c(iblockaccess, blockposition, EnumDirection.SOUTH)); + return iblockdata; + } + + private BlockRedstoneWire.EnumRedstoneWireConnection c(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + BlockPosition blockposition1 = blockposition.shift(enumdirection); + Block block = iblockaccess.getType(blockposition.shift(enumdirection)).getBlock(); + + if (!a(iblockaccess.getType(blockposition1), enumdirection) && (block.u() || !d(iblockaccess.getType(blockposition1.down())))) { + Block block1 = iblockaccess.getType(blockposition.up()).getBlock(); + + return !block1.u() && block.u() && d(iblockaccess.getType(blockposition1.up())) ? BlockRedstoneWire.EnumRedstoneWireConnection.UP : BlockRedstoneWire.EnumRedstoneWireConnection.NONE; + } else { + return BlockRedstoneWire.EnumRedstoneWireConnection.SIDE; + } + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public boolean canPlace(World world, BlockPosition blockposition) { + return World.a(world, blockposition.down()) || world.getType(blockposition.down()).getBlock() == Blocks.GLOWSTONE; + } + + private IBlockData e(World world, BlockPosition blockposition, IBlockData iblockdata) { + iblockdata = this.a(world, blockposition, blockposition, iblockdata); + ArrayList arraylist = Lists.newArrayList(this.R); + + this.R.clear(); + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + BlockPosition blockposition1 = (BlockPosition) iterator.next(); + + if(!world.applyPhysics(blockposition1, this)) break; + } + + return iblockdata; + } + + private IBlockData a(World world, BlockPosition blockposition, BlockPosition blockposition1, IBlockData iblockdata) { + IBlockData iblockdata1 = iblockdata; + int i = iblockdata.get(BlockRedstoneWire.POWER).intValue(); + byte b0 = 0; + int j = this.getPower(world, blockposition1, b0); + + this.Q = false; + int k = world.A(blockposition); + + this.Q = true; + if (k > 0 && k > j - 1) { + j = k; + } + + int l = 0; + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + BlockPosition blockposition2 = blockposition.shift(enumdirection); + boolean flag = blockposition2.getX() != blockposition1.getX() || blockposition2.getZ() != blockposition1.getZ(); + + if (flag) { + l = this.getPower(world, blockposition2, l); + } + + if (world.getType(blockposition2).getBlock().isOccluding() && !world.getType(blockposition.up()).getBlock().isOccluding()) { + if (flag && blockposition.getY() >= blockposition1.getY()) { + l = this.getPower(world, blockposition2.up(), l); + } + } else if (!world.getType(blockposition2).getBlock().isOccluding() && flag && blockposition.getY() <= blockposition1.getY()) { + l = this.getPower(world, blockposition2.down(), l); + } + } + + if (l > j) { + j = l - 1; + } else if (j > 0) { + --j; + } else { + j = 0; + } + + if (k > j - 1) { + j = k; + } + + // CraftBukkit start + if (i != j) { + BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), i, j); + world.getServer().getPluginManager().callEvent(event); + + j = event.getNewCurrent(); + } + // CraftBukkit end + + if (i != j) { + iblockdata = iblockdata.set(BlockRedstoneWire.POWER, Integer.valueOf(j)); + if (world.getType(blockposition) == iblockdata1) { + world.setTypeAndData(blockposition, iblockdata, 2); + } + + this.R.add(blockposition); + // PaperSpigot start - Fix cannons + if (world.paperSpigotConfig.fixCannons) { + this.R.add(blockposition.shift(EnumDirection.WEST)); + this.R.add(blockposition.shift(EnumDirection.EAST)); + this.R.add(blockposition.shift(EnumDirection.DOWN)); + this.R.add(blockposition.shift(EnumDirection.UP)); + this.R.add(blockposition.shift(EnumDirection.NORTH)); + this.R.add(blockposition.shift(EnumDirection.SOUTH)); + return iblockdata; + } + // PaperSpigot end + EnumDirection[] aenumdirection = EnumDirection.values(); + int i1 = aenumdirection.length; + + for (int j1 = 0; j1 < i1; ++j1) { + EnumDirection enumdirection1 = aenumdirection[j1]; + + this.R.add(blockposition.shift(enumdirection1)); + } + } + + return iblockdata; + } + + private void e(World world, BlockPosition blockposition) { + if (world.getType(blockposition).getBlock() == this) { + world.applyPhysics(blockposition, this); + // PaperSpigot start - Fix cannons + if (world.paperSpigotConfig.fixCannons) { + world.applyPhysics(blockposition.shift(EnumDirection.WEST), this); + world.applyPhysics(blockposition.shift(EnumDirection.EAST), this); + world.applyPhysics(blockposition.shift(EnumDirection.NORTH), this); + world.applyPhysics(blockposition.shift(EnumDirection.SOUTH), this); + world.applyPhysics(blockposition.shift(EnumDirection.DOWN), this); + world.applyPhysics(blockposition.shift(EnumDirection.UP), this); + return; + } + // PaperSpigot end + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + world.applyPhysics(blockposition.shift(enumdirection), this); + } + + } + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!world.isClientSide) { + this.e(world, blockposition, iblockdata); + Iterator iterator = EnumDirection.EnumDirectionLimit.VERTICAL.iterator(); + + EnumDirection enumdirection; + + while (iterator.hasNext()) { + enumdirection = (EnumDirection) iterator.next(); + world.applyPhysics(blockposition.shift(enumdirection), this); + } + + iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + enumdirection = (EnumDirection) iterator.next(); + this.e(world, blockposition.shift(enumdirection)); + } + + iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + enumdirection = (EnumDirection) iterator.next(); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + + if (world.getType(blockposition1).getBlock().isOccluding()) { + this.e(world, blockposition1.up()); + } else { + this.e(world, blockposition1.down()); + } + } + + } + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + super.remove(world, blockposition, iblockdata); + if (!world.isClientSide) { + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + world.applyPhysics(blockposition.shift(enumdirection), this); + } + + this.e(world, blockposition, iblockdata); + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + EnumDirection enumdirection1; + + while (iterator.hasNext()) { + enumdirection1 = (EnumDirection) iterator.next(); + this.e(world, blockposition.shift(enumdirection1)); + } + + iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + enumdirection1 = (EnumDirection) iterator.next(); + BlockPosition blockposition1 = blockposition.shift(enumdirection1); + + if (world.getType(blockposition1).getBlock().isOccluding()) { + this.e(world, blockposition1.up()); + } else { + this.e(world, blockposition1.down()); + } + } + + } + } + + public int getPower(World world, BlockPosition blockposition, int i) { + if (world.getType(blockposition).getBlock() != this) { + return i; + } else { + int j = world.getType(blockposition).get(BlockRedstoneWire.POWER).intValue(); + + return j > i ? j : i; + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!world.isClientSide) { + if (this.canPlace(world, blockposition)) { + this.e(world, blockposition, iblockdata); + } else { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + + } + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Items.REDSTONE; + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return !this.Q ? 0 : this.a(iblockaccess, blockposition, iblockdata, enumdirection); + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + if (!this.Q) { + return 0; + } else { + int i = iblockdata.get(BlockRedstoneWire.POWER).intValue(); + + if (i == 0) { + return 0; + } else if (enumdirection == EnumDirection.UP) { + return i; + } else { + EnumSet enumset = EnumSet.noneOf(EnumDirection.class); + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection1 = (EnumDirection) iterator.next(); + + if (this.d(iblockaccess, blockposition, enumdirection1)) { + enumset.add(enumdirection1); + } + } + + if (enumdirection.k().c() && enumset.isEmpty()) { + return i; + } else if (enumset.contains(enumdirection) && !enumset.contains(enumdirection.f()) && !enumset.contains(enumdirection.e())) { + return i; + } else { + return 0; + } + } + } + } + + private boolean d(IBlockAccess iblockaccess, BlockPosition blockposition, EnumDirection enumdirection) { + BlockPosition blockposition1 = blockposition.shift(enumdirection); + IBlockData iblockdata = iblockaccess.getType(blockposition1); + Block block = iblockdata.getBlock(); + boolean flag = block.isOccluding(); + boolean flag1 = iblockaccess.getType(blockposition.up()).getBlock().isOccluding(); + + return !flag1 && flag && e(iblockaccess, blockposition1.up()) || (a(iblockdata, enumdirection) || (block == Blocks.POWERED_REPEATER && iblockdata.get(BlockDiodeAbstract.FACING) == enumdirection || !flag && e(iblockaccess, blockposition1.down()))); + } + + protected static boolean e(IBlockAccess iblockaccess, BlockPosition blockposition) { + return d(iblockaccess.getType(blockposition)); + } + + protected static boolean d(IBlockData iblockdata) { + return a(iblockdata, null); + } + + protected static boolean a(IBlockData iblockdata, EnumDirection enumdirection) { + Block block = iblockdata.getBlock(); + + if (block == Blocks.REDSTONE_WIRE) { + return true; + } else if (Blocks.UNPOWERED_REPEATER.e(block)) { + EnumDirection enumdirection1 = iblockdata.get(BlockRepeater.FACING); + + return enumdirection1 == enumdirection || enumdirection1.opposite() == enumdirection; + } else { + return block.isPowerSource() && enumdirection != null; + } + } + + public boolean isPowerSource() { + return this.Q; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockRedstoneWire.POWER, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return iblockdata.get(BlockRedstoneWire.POWER).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, BlockRedstoneWire.NORTH, BlockRedstoneWire.EAST, BlockRedstoneWire.SOUTH, BlockRedstoneWire.WEST, BlockRedstoneWire.POWER); + } + + enum EnumRedstoneWireConnection implements INamable { + + UP("up"), SIDE("side"), NONE("none"); + + private final String d; + + EnumRedstoneWireConnection(String s) { + this.d = s; + } + + public String toString() { + return this.getName(); + } + + public String getName() { + return this.d; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockReed.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockReed.java new file mode 100644 index 0000000..337f2c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockReed.java @@ -0,0 +1,116 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Random; + +public class BlockReed extends Block { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 15); + + protected BlockReed() { + super(Material.PLANT); + this.j(this.blockStateList.getBlockData().set(BlockReed.AGE, Integer.valueOf(0))); + float f = 0.375F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 1.0F, 0.5F + f); + this.a(true); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (world.getType(blockposition.down()).getBlock() == Blocks.REEDS || this.e(world, blockposition, iblockdata)) { + if (world.isEmpty(blockposition.up())) { + int i; + + for (i = 1; world.getType(blockposition.down(i)).getBlock() == this; ++i) { + ; + } + + if (i < world.paperSpigotConfig.reedMaxHeight) { // PaperSpigot - Configurable max growth height for reed blocks) { + int j = ((Integer) iblockdata.get(BlockReed.AGE)).intValue(); + + if (j >= (byte) range(3, (world.growthOdds / world.spigotConfig.caneModifier * 15) + 0.5F, 15)) { // Spigot + // CraftBukkit start + // world.setTypeUpdate(blockposition.up(), this.getBlockData()); // CraftBukkit + BlockPosition upPos = blockposition.up(); + org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, upPos.getX(), upPos.getY(), upPos.getZ(), this, 0); + world.setTypeAndData(blockposition, iblockdata.set(BlockReed.AGE, Integer.valueOf(0)), 4); + // CraftBukkit end + } else { + world.setTypeAndData(blockposition, iblockdata.set(BlockReed.AGE, Integer.valueOf(j + 1)), 4); + } + } + } + + } + } + + public boolean canPlace(World world, BlockPosition blockposition) { + Block block = world.getType(blockposition.down()).getBlock(); + + if (block == this) { + return true; + } else if (block != Blocks.GRASS && block != Blocks.DIRT && block != Blocks.SAND) { + return false; + } else { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + EnumDirection enumdirection; + + do { + if (!iterator.hasNext()) { + return false; + } + + enumdirection = (EnumDirection) iterator.next(); + } while (world.getType(blockposition.shift(enumdirection).down()).getBlock().getMaterial() != Material.WATER); + + return true; + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + this.e(world, blockposition, iblockdata); + } + + protected final boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (this.e(world, blockposition)) { + return true; + } else { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + return false; + } + } + + public boolean e(World world, BlockPosition blockposition) { + return this.canPlace(world, blockposition); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Items.REEDS; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockReed.AGE, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockReed.AGE)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockReed.AGE}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSapling.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSapling.java new file mode 100644 index 0000000..45fbf5c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSapling.java @@ -0,0 +1,275 @@ +package net.minecraft.server; + +import java.util.Random; + +// CraftBukkit start +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.TreeType; +import org.bukkit.block.BlockState; +import org.bukkit.event.world.StructureGrowEvent; +// CraftBukkit end + +public class BlockSapling extends BlockPlant implements IBlockFragilePlantElement { + + public static final BlockStateEnum TYPE = BlockStateEnum.of("type", BlockWood.EnumLogVariant.class); + public static final BlockStateInteger STAGE = BlockStateInteger.of("stage", 0, 1); + public static TreeType treeType; // CraftBukkit + + protected BlockSapling() { + this.j(this.blockStateList.getBlockData().set(BlockSapling.TYPE, BlockWood.EnumLogVariant.OAK).set(BlockSapling.STAGE, Integer.valueOf(0))); + float f = 0.4F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f); + this.a(CreativeModeTab.c); + } + + public String getName() { + return LocaleI18n.get(this.a() + "." + BlockWood.EnumLogVariant.OAK.d() + ".name"); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + super.b(world, blockposition, iblockdata, random); + if (world.getLightLevel(blockposition.up()) >= 9 && (random.nextInt(Math.max(2, (int) ((world.growthOdds / world.spigotConfig.saplingModifier * 7) + 0.5F))) == 0)) { // Spigot) { + // CraftBukkit start + world.captureTreeGeneration = true; + // CraftBukkit end + this.grow(world, blockposition, iblockdata, random); + // CraftBukkit start + world.captureTreeGeneration = false; + if (world.capturedBlockStates.size() > 0) { + TreeType treeType = BlockSapling.treeType; + BlockSapling.treeType = null; + Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + List blocks = (List) world.capturedBlockStates.clone(); + world.capturedBlockStates.clear(); + StructureGrowEvent event = null; + if (treeType != null) { + event = new StructureGrowEvent(location, treeType, false, null, blocks); + org.bukkit.Bukkit.getPluginManager().callEvent(event); + } + if (event == null || !event.isCancelled()) { + for (BlockState blockstate : blocks) { + blockstate.update(true); + } + } + } + // CraftBukkit end + } + + } + } + + public void grow(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (((Integer) iblockdata.get(BlockSapling.STAGE)).intValue() == 0) { + world.setTypeAndData(blockposition, iblockdata.a(BlockSapling.STAGE), 4); + } else { + this.e(world, blockposition, iblockdata, random); + } + + } + + public void e(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + // CraftBukkit start - Turn ternary operator into if statement to set treeType + // Object object = random.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true); + Object object; + if (random.nextInt(10) == 0) { + treeType = TreeType.BIG_TREE; + object = new WorldGenBigTree(true); + } else { + treeType = TreeType.TREE; + object = new WorldGenTrees(true); + } + // CraftBukkit end + int i = 0; + int j = 0; + boolean flag = false; + IBlockData iblockdata1; + + switch (BlockSapling.SyntheticClass_1.a[((BlockWood.EnumLogVariant) iblockdata.get(BlockSapling.TYPE)).ordinal()]) { + case 1: + label66: + for (i = 0; i >= -1; --i) { + for (j = 0; j >= -1; --j) { + if (this.a(world, blockposition, i, j, BlockWood.EnumLogVariant.SPRUCE)) { + treeType = TreeType.MEGA_REDWOOD; // CraftBukkit + object = new WorldGenMegaTree(false, random.nextBoolean()); + flag = true; + break label66; + } + } + } + + if (!flag) { + j = 0; + i = 0; + treeType = TreeType.REDWOOD; // CraftBukkit + object = new WorldGenTaiga2(true); + } + break; + + case 2: + treeType = TreeType.BIRCH; // CraftBukkit + object = new WorldGenForest(true, false); + break; + + case 3: + iblockdata1 = Blocks.LOG.getBlockData().set(BlockLog1.VARIANT, BlockWood.EnumLogVariant.JUNGLE); + IBlockData iblockdata2 = Blocks.LEAVES.getBlockData().set(BlockLeaves1.VARIANT, BlockWood.EnumLogVariant.JUNGLE).set(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + + label78: + for (i = 0; i >= -1; --i) { + for (j = 0; j >= -1; --j) { + if (this.a(world, blockposition, i, j, BlockWood.EnumLogVariant.JUNGLE)) { + treeType = TreeType.JUNGLE; // CraftBukkit + object = new WorldGenJungleTree(true, 10, 20, iblockdata1, iblockdata2); + flag = true; + break label78; + } + } + } + + if (!flag) { + j = 0; + i = 0; + treeType = TreeType.SMALL_JUNGLE; // CraftBukkit + object = new WorldGenTrees(true, 4 + random.nextInt(7), iblockdata1, iblockdata2, false); + } + break; + + case 4: + treeType = TreeType.ACACIA; // CraftBukkit + object = new WorldGenAcaciaTree(true); + break; + + case 5: + label90: + for (i = 0; i >= -1; --i) { + for (j = 0; j >= -1; --j) { + if (this.a(world, blockposition, i, j, BlockWood.EnumLogVariant.DARK_OAK)) { + treeType = TreeType.DARK_OAK; // CraftBukkit + object = new WorldGenForestTree(true); + flag = true; + break label90; + } + } + } + + if (!flag) { + return; + } + + case 6: + } + + iblockdata1 = Blocks.AIR.getBlockData(); + if (flag) { + world.setTypeAndData(blockposition.a(i, 0, j), iblockdata1, 4); + world.setTypeAndData(blockposition.a(i + 1, 0, j), iblockdata1, 4); + world.setTypeAndData(blockposition.a(i, 0, j + 1), iblockdata1, 4); + world.setTypeAndData(blockposition.a(i + 1, 0, j + 1), iblockdata1, 4); + } else { + world.setTypeAndData(blockposition, iblockdata1, 4); + } + + if (!((WorldGenerator) object).generate(world, random, blockposition.a(i, 0, j))) { + if (flag) { + world.setTypeAndData(blockposition.a(i, 0, j), iblockdata, 4); + world.setTypeAndData(blockposition.a(i + 1, 0, j), iblockdata, 4); + world.setTypeAndData(blockposition.a(i, 0, j + 1), iblockdata, 4); + world.setTypeAndData(blockposition.a(i + 1, 0, j + 1), iblockdata, 4); + } else { + world.setTypeAndData(blockposition, iblockdata, 4); + } + } + + } + + private boolean a(World world, BlockPosition blockposition, int i, int j, BlockWood.EnumLogVariant blockwood_enumlogvariant) { + return this.a(world, blockposition.a(i, 0, j), blockwood_enumlogvariant) && this.a(world, blockposition.a(i + 1, 0, j), blockwood_enumlogvariant) && this.a(world, blockposition.a(i, 0, j + 1), blockwood_enumlogvariant) && this.a(world, blockposition.a(i + 1, 0, j + 1), blockwood_enumlogvariant); + } + + public boolean a(World world, BlockPosition blockposition, BlockWood.EnumLogVariant blockwood_enumlogvariant) { + IBlockData iblockdata = world.getType(blockposition); + + return iblockdata.getBlock() == this && iblockdata.get(BlockSapling.TYPE) == blockwood_enumlogvariant; + } + + public int getDropData(IBlockData iblockdata) { + return ((BlockWood.EnumLogVariant) iblockdata.get(BlockSapling.TYPE)).a(); + } + + public boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return true; + } + + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return (double) world.random.nextFloat() < 0.45D; + } + + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + this.grow(world, blockposition, iblockdata, random); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockSapling.TYPE, BlockWood.EnumLogVariant.a(i & 7)).set(BlockSapling.STAGE, Integer.valueOf((i & 8) >> 3)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((BlockWood.EnumLogVariant) iblockdata.get(BlockSapling.TYPE)).a(); + + i |= ((Integer) iblockdata.get(BlockSapling.STAGE)).intValue() << 3; + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockSapling.TYPE, BlockSapling.STAGE}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[BlockWood.EnumLogVariant.values().length]; + + static { + try { + BlockSapling.SyntheticClass_1.a[BlockWood.EnumLogVariant.SPRUCE.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockSapling.SyntheticClass_1.a[BlockWood.EnumLogVariant.BIRCH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockSapling.SyntheticClass_1.a[BlockWood.EnumLogVariant.JUNGLE.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockSapling.SyntheticClass_1.a[BlockWood.EnumLogVariant.ACACIA.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockSapling.SyntheticClass_1.a[BlockWood.EnumLogVariant.DARK_OAK.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + try { + BlockSapling.SyntheticClass_1.a[BlockWood.EnumLogVariant.OAK.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror5) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSkull.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSkull.java new file mode 100644 index 0000000..95a1049 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSkull.java @@ -0,0 +1,299 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.Iterator; +import java.util.Random; + +// CraftBukkit start +import org.bukkit.craftbukkit.util.BlockStateListPopulator; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +// CraftBukkit end + +public class BlockSkull extends BlockContainer { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing"); + public static final BlockStateBoolean NODROP = BlockStateBoolean.of("nodrop"); + private static final Predicate N = new Predicate() { + public boolean a(ShapeDetectorBlock shapedetectorblock) { + return shapedetectorblock.a() != null && shapedetectorblock.a().getBlock() == Blocks.SKULL && shapedetectorblock.b() instanceof TileEntitySkull && ((TileEntitySkull) shapedetectorblock.b()).getSkullType() == 1; + } + + public boolean apply(Object object) { + return this.a((ShapeDetectorBlock) object); + } + }; + private ShapeDetector O; + private ShapeDetector P; + + protected BlockSkull() { + super(Material.ORIENTABLE); + this.j(this.blockStateList.getBlockData().set(BlockSkull.FACING, EnumDirection.NORTH).set(BlockSkull.NODROP, Boolean.valueOf(false))); + this.a(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); + } + + public String getName() { + return LocaleI18n.get("tile.skull.skeleton.name"); + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + switch (BlockSkull.SyntheticClass_1.a[((EnumDirection) iblockaccess.getType(blockposition).get(BlockSkull.FACING)).ordinal()]) { + case 1: + default: + this.a(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); + break; + + case 2: + this.a(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F); + break; + + case 3: + this.a(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F); + break; + + case 4: + this.a(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F); + break; + + case 5: + this.a(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F); + } + + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.updateShape(world, blockposition); + return super.a(world, blockposition, iblockdata); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + return this.getBlockData().set(BlockSkull.FACING, entityliving.getDirection()).set(BlockSkull.NODROP, Boolean.valueOf(false)); + } + + public TileEntity a(World world, int i) { + return new TileEntitySkull(); + } + + public int getDropData(World world, BlockPosition blockposition) { + TileEntity tileentity = world.getTileEntity(blockposition); + + return tileentity instanceof TileEntitySkull ? ((TileEntitySkull) tileentity).getSkullType() : super.getDropData(world, blockposition); + } + + // CraftBukkit start - Special case dropping so we can get info from the tile entity + @Override + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + if (world.random.nextFloat() < f) { + ItemStack itemstack = new ItemStack(Items.SKULL, 1, this.getDropData(world, blockposition)); + TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(blockposition); + + if (tileentityskull.getSkullType() == 3 && tileentityskull.getGameProfile() != null) { + itemstack.setTag(new NBTTagCompound()); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile()); + itemstack.getTag().set("SkullOwner", nbttagcompound); + } + + a(world, blockposition, itemstack); + } + } + // CraftBukkit end + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { + if (entityhuman.abilities.canInstantlyBuild) { + iblockdata = iblockdata.set(BlockSkull.NODROP, Boolean.valueOf(true)); + world.setTypeAndData(blockposition, iblockdata, 4); + } + + super.a(world, blockposition, iblockdata, entityhuman); + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!world.isClientSide) { + // CraftBukkit start - Drop item in code above, not here + // if (!((Boolean) iblockdata.get(BlockSkull.NODROP)).booleanValue()) { + if (false) { + // CraftBukkit end + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntitySkull) { + TileEntitySkull tileentityskull = (TileEntitySkull) tileentity; + ItemStack itemstack = new ItemStack(Items.SKULL, 1, this.getDropData(world, blockposition)); + + if (tileentityskull.getSkullType() == 3 && tileentityskull.getGameProfile() != null) { + itemstack.setTag(new NBTTagCompound()); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile()); + itemstack.getTag().set("SkullOwner", nbttagcompound); + } + + a(world, blockposition, itemstack); + } + } + + super.remove(world, blockposition, iblockdata); + } + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Items.SKULL; + } + + public boolean b(World world, BlockPosition blockposition, ItemStack itemstack) { + return itemstack.getData() == 1 && blockposition.getY() >= 2 && world.getDifficulty() != EnumDifficulty.PEACEFUL && !world.isClientSide ? this.l().a(world, blockposition) != null : false; + } + + public void a(World world, BlockPosition blockposition, TileEntitySkull tileentityskull) { + if (world.captureBlockStates) return; // CraftBukkit + if (tileentityskull.getSkullType() == 1 && blockposition.getY() >= 2 && world.getDifficulty() != EnumDifficulty.PEACEFUL && !world.isClientSide) { + ShapeDetector shapedetector = this.n(); + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = shapedetector.a(world, blockposition); + + if (shapedetector_shapedetectorcollection != null) { + // CraftBukkit start - Use BlockStateListPopulator + BlockStateListPopulator blockList = new BlockStateListPopulator(world.getWorld()); + int i; + + for (i = 0; i < 3; ++i) { + ShapeDetectorBlock shapedetectorblock = shapedetector_shapedetectorcollection.a(i, 0, 0); + + // CraftBukkit start + // world.setTypeAndData(shapedetectorblock.getPosition(), shapedetectorblock.a().set(BlockSkull.NODROP, Boolean.valueOf(true)), 2); + BlockPosition pos = shapedetectorblock.getPosition(); + IBlockData data = shapedetectorblock.a().set(BlockSkull.NODROP, Boolean.valueOf(true)); + blockList.setTypeAndData(pos.getX(), pos.getY(), pos.getZ(), data.getBlock(), data.getBlock().toLegacyData(data), 2); + // CraftBukkit end + } + + for (i = 0; i < shapedetector.c(); ++i) { + for (int j = 0; j < shapedetector.b(); ++j) { + ShapeDetectorBlock shapedetectorblock1 = shapedetector_shapedetectorcollection.a(i, j, 0); + + // CraftBukkit start + // world.setTypeAndData(shapedetectorblock1.getPosition(), Blocks.AIR.getBlockData(), 2); + BlockPosition pos = shapedetectorblock1.getPosition(); + blockList.setTypeAndData(pos.getX(), pos.getY(), pos.getZ(), Blocks.AIR, 0, 2); + // CraftBukkit end + } + } + + BlockPosition blockposition1 = shapedetector_shapedetectorcollection.a(1, 0, 0).getPosition(); + EntityWither entitywither = new EntityWither(world); + BlockPosition blockposition2 = shapedetector_shapedetectorcollection.a(1, 2, 0).getPosition(); + + entitywither.setPositionRotation((double) blockposition2.getX() + 0.5D, (double) blockposition2.getY() + 0.55D, (double) blockposition2.getZ() + 0.5D, shapedetector_shapedetectorcollection.b().k() == EnumDirection.EnumAxis.X ? 0.0F : 90.0F, 0.0F); + entitywither.aI = shapedetector_shapedetectorcollection.b().k() == EnumDirection.EnumAxis.X ? 0.0F : 90.0F; + entitywither.n(); + Iterator iterator = world.a(EntityHuman.class, entitywither.getBoundingBox().grow(50.0D, 50.0D, 50.0D)).iterator(); + + // CraftBukkit start + if (world.addEntity(entitywither, SpawnReason.BUILD_WITHER)) { + blockList.updateList(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + entityhuman.b((Statistic) AchievementList.I); + } + + 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]); + } + + for (k = 0; k < shapedetector.c(); ++k) { + for (int l = 0; l < shapedetector.b(); ++l) { + ShapeDetectorBlock shapedetectorblock2 = shapedetector_shapedetectorcollection.a(k, l, 0); + + world.update(shapedetectorblock2.getPosition(), Blocks.AIR); + } + } + } // CraftBukkit end + + } + } + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockSkull.FACING, EnumDirection.fromType1(i & 7)).set(BlockSkull.NODROP, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((EnumDirection) iblockdata.get(BlockSkull.FACING)).a(); + + if (((Boolean) iblockdata.get(BlockSkull.NODROP)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockSkull.FACING, BlockSkull.NODROP}); + } + + protected ShapeDetector l() { + if (this.O == null) { + this.O = ShapeDetectorBuilder.a().a(new String[] { " ", "###", "~#~"}).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SOUL_SAND))).a('~', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.AIR))).b(); + } + + return this.O; + } + + protected ShapeDetector n() { + if (this.P == null) { + this.P = ShapeDetectorBuilder.a().a(new String[] { "^^^", "###", "~#~"}).a('#', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.SOUL_SAND))).a('^', BlockSkull.N).a('~', ShapeDetectorBlock.a(BlockStatePredicate.a(Blocks.AIR))).b(); + } + + return this.P; + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + BlockSkull.SyntheticClass_1.a[EnumDirection.UP.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockSkull.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockSkull.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockSkull.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockSkull.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSnow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSnow.java new file mode 100644 index 0000000..03b1a8b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSnow.java @@ -0,0 +1,114 @@ +package net.minecraft.server; + +import java.util.Random; + +public class BlockSnow extends Block { + + public static final BlockStateInteger LAYERS = BlockStateInteger.of("layers", 1, 8); + + protected BlockSnow() { + super(Material.PACKED_ICE); + this.j(this.blockStateList.getBlockData().set(BlockSnow.LAYERS, Integer.valueOf(1))); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F); + this.a(true); + this.a(CreativeModeTab.c); + this.j(); + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition) { + return ((Integer) iblockaccess.getType(blockposition).get(BlockSnow.LAYERS)).intValue() < 5; + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + int i = ((Integer) iblockdata.get(BlockSnow.LAYERS)).intValue() - 1; + float f = 0.125F; + + return new AxisAlignedBB((double) blockposition.getX() + this.minX, (double) blockposition.getY() + this.minY, (double) blockposition.getZ() + this.minZ, (double) blockposition.getX() + this.maxX, (double) ((float) blockposition.getY() + (float) i * f), (double) blockposition.getZ() + this.maxZ); + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public void j() { + this.b(0); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + + this.b(((Integer) iblockdata.get(BlockSnow.LAYERS)).intValue()); + } + + protected void b(int i) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, (float) i / 8.0F, 1.0F); + } + + public boolean canPlace(World world, BlockPosition blockposition) { + IBlockData iblockdata = world.getType(blockposition.down()); + Block block = iblockdata.getBlock(); + + return block != Blocks.ICE && block != Blocks.PACKED_ICE ? (block.getMaterial() == Material.LEAVES ? true : (block == this && ((Integer) iblockdata.get(BlockSnow.LAYERS)).intValue() >= 7 ? true : block.c() && block.material.isSolid())) : false; + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + this.e(world, blockposition, iblockdata); + } + + private boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!this.canPlace(world, blockposition)) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + return false; + } else { + return true; + } + } + + public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, TileEntity tileentity) { + a(world, blockposition, new ItemStack(Items.SNOWBALL, ((Integer) iblockdata.get(BlockSnow.LAYERS)).intValue() + 1, 0)); + world.setAir(blockposition); + entityhuman.b(StatisticList.MINE_BLOCK_COUNT[Block.getId(this)]); + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Items.SNOWBALL; + } + + public int a(Random random) { + return 0; + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (world.b(EnumSkyBlock.BLOCK, blockposition) > 11) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), Blocks.AIR).isCancelled()) { + return; + } + // CraftBukkit end + this.b(world, blockposition, world.getType(blockposition), 0); + world.setAir(blockposition); + } + + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockSnow.LAYERS, Integer.valueOf((i & 7) + 1)); + } + + public boolean a(World world, BlockPosition blockposition) { + return ((Integer) world.getType(blockposition).get(BlockSnow.LAYERS)).intValue() == 1; + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockSnow.LAYERS)).intValue() - 1; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockSnow.LAYERS}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSoil.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSoil.java new file mode 100644 index 0000000..362a346 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockSoil.java @@ -0,0 +1,134 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Random; + +// CraftBukkit start +import org.bukkit.event.entity.EntityInteractEvent; +import org.bukkit.craftbukkit.event.CraftEventFactory; +// CraftBukkit end + +public class BlockSoil extends Block { + + public static final BlockStateInteger MOISTURE = BlockStateInteger.of("moisture", 0, 7); + + protected BlockSoil() { + super(Material.EARTH); + this.j(this.blockStateList.getBlockData().set(BlockSoil.MOISTURE, Integer.valueOf(0))); + this.a(true); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.9375F, 1.0F); + this.e(255); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return new AxisAlignedBB((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 1), (double) (blockposition.getZ() + 1)); + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + int i = ((Integer) iblockdata.get(BlockSoil.MOISTURE)).intValue(); + + if (!this.f(world, blockposition) && !world.isRainingAt(blockposition.up())) { + if (i > 0) { + world.setTypeAndData(blockposition, iblockdata.set(BlockSoil.MOISTURE, Integer.valueOf(i - 1)), 2); + } else if (!this.e(world, blockposition)) { + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + if (CraftEventFactory.callBlockFadeEvent(block, Blocks.DIRT).isCancelled()) { + return; + } + // CraftBukkit end + world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); + } + } else if (i < 7) { + world.setTypeAndData(blockposition, iblockdata.set(BlockSoil.MOISTURE, Integer.valueOf(7)), 2); + } + + } + + public void fallOn(World world, BlockPosition blockposition, Entity entity, float f) { + super.fallOn(world, blockposition, entity, f); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. + if (entity instanceof EntityLiving) { + if (!world.isClientSide && world.random.nextFloat() < f - 0.5F) { + if (!(entity instanceof EntityHuman) && !world.getGameRules().getBoolean("mobGriefing")) { + return; + } + + // CraftBukkit start - Interact soil + org.bukkit.event.Cancellable cancellable; + if (entity instanceof EntityHuman) { + cancellable = CraftEventFactory.callPlayerInteractEvent((EntityHuman) entity, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); + } else { + cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + world.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); + } + + if (cancellable.isCancelled()) { + return; + } + + if (CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.DIRT, 0).isCancelled()) { + return; + } + // CraftBukkit end + + world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); + } + + // super.fallOn(world, blockposition, entity, f); // CraftBukkit - moved up + } + } + + private boolean e(World world, BlockPosition blockposition) { + Block block = world.getType(blockposition.up()).getBlock(); + + return block instanceof BlockCrops || block instanceof BlockStem; + } + + private boolean f(World world, BlockPosition blockposition) { + Iterator iterator = BlockPosition.b(blockposition.a(-4, 0, -4), blockposition.a(4, 1, 4)).iterator(); + + BlockPosition.MutableBlockPosition blockposition_mutableblockposition; + + do { + if (!iterator.hasNext()) { + return false; + } + + blockposition_mutableblockposition = (BlockPosition.MutableBlockPosition) iterator.next(); + } while (world.getType(blockposition_mutableblockposition).getBlock().getMaterial() != Material.WATER); + + return true; + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + super.doPhysics(world, blockposition, iblockdata, block); + if (world.getType(blockposition.up()).getBlock().getMaterial().isBuildable()) { + world.setTypeUpdate(blockposition, Blocks.DIRT.getBlockData()); + } + + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Blocks.DIRT.getDropType(Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, BlockDirt.EnumDirtVariant.DIRT), random, i); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockSoil.MOISTURE, Integer.valueOf(i & 7)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockSoil.MOISTURE)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockSoil.MOISTURE}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockState.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockState.java new file mode 100644 index 0000000..17a1617 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockState.java @@ -0,0 +1,63 @@ +package net.minecraft.server; + +import com.google.common.base.Objects; + +// TacoSpigot start +import com.google.common.base.Preconditions; + +import net.techcable.tacospigot.BlockStateRegistry; +// TacoSpigot end + +public abstract class BlockState> implements IBlockState { + + private final Class a; + private final String b; + // TacoSpigot start + private int id = -1; + + @Override + public int getId() { + assert id >= 0 : "Id not initialized"; + return id; + } + + public void tryInitId() { + if (id < 0) { + this.id = BlockStateRegistry.getId(this); + } + } + // TacoSpigot end + + protected BlockState(String s, Class oclass) { + this.a = oclass; + this.b = s; + } + + public String a() { + return this.b; + } + + public Class b() { + return this.a; + } + + public String toString() { + return Objects.toStringHelper(this).add("name", this.b).add("clazz", this.a).add("values", this.c()).toString(); + } + + public boolean equals(Object object) { + if (this == object) { + return true; + } else if (object != null && this.getClass() == object.getClass()) { + BlockState blockstate = (BlockState) object; + + return this.a.equals(blockstate.a) && this.b.equals(blockstate.b); + } else { + return false; + } + } + + public int hashCode() { + return 31 * this.a.hashCode() + this.b.hashCode(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateBoolean.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateBoolean.java new file mode 100644 index 0000000..d6d9a22 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateBoolean.java @@ -0,0 +1,52 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableSet; +import java.util.Collection; + +public class BlockStateBoolean extends BlockState { + + private final ImmutableSet a = ImmutableSet.of(Boolean.valueOf(true), Boolean.valueOf(false)); + + protected BlockStateBoolean(String s) { + super(s, Boolean.class); + } + + // TacoSpigot start + @Override + public int getValueId(Boolean value) { + return value ? 1 : 0; + } + + @Override + public Boolean getByValueId(int id) { + switch (id) { + case 0: + return false; + case 1: + return true; + default: + throw new IllegalArgumentException("Invalid id: " + id); + } + } + // TacoSpigot end + + public Collection c() { + return this.a; + } + + public static BlockStateBoolean of(String s) { + return new BlockStateBoolean(s); + } + + public String a(Boolean obool) { + return obool.toString(); + } + + // TacoSpigot start - fix stupid generic thingies + /* + public String a(Comparable comparable) { + return this.a((Boolean) comparable); + } + */ + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateEnum.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateEnum.java new file mode 100644 index 0000000..ca38c59 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateEnum.java @@ -0,0 +1,84 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +public class BlockStateEnum & INamable> extends BlockState { + + private final ImmutableSet a; + private final Map b = Maps.newHashMap(); + + protected BlockStateEnum(String s, Class oclass, Collection collection) { + super(s, oclass); + this.a = ImmutableSet.copyOf(collection); + Iterator iterator = collection.iterator(); // TacoSpigot - generic iterator + + while (iterator.hasNext()) { + T oenum = iterator.next(); // TacoSpigot - generics + String s1 = ((INamable) oenum).getName(); + + if (this.b.containsKey(s1)) { + throw new IllegalArgumentException("Multiple values have the same name \'" + s1 + "\'"); + } + + this.b.put(s1, oenum); + } + + } + + public Collection c() { + return this.a; + } + public String a(T t0) { + return ((INamable) t0).getName(); + } + + // TacoSpigot start + @Override + public int +getValueId(T value) { + return value.ordinal(); + } + + @Override + public T getByValueId(int id) { + T[] values = this.b().getEnumConstants(); + if (id >= 0 && id < values.length) { + return values[id]; + } else { + throw new IllegalArgumentException("Invalid id: " + id); + } + } + // TacoSpigot end + + public static & INamable> BlockStateEnum of(String s, Class oclass) { + return a(s, oclass, Predicates.alwaysTrue()); + } + + public static & INamable> BlockStateEnum a(String s, Class oclass, Predicate predicate) { + return a(s, oclass, Collections2.filter(Lists.newArrayList(oclass.getEnumConstants()), predicate)); + } + + public static & INamable> BlockStateEnum of(String s, Class oclass, T... at) { + return a(s, oclass, (Collection) Lists.newArrayList(at)); + } + + public static & INamable> BlockStateEnum a(String s, Class oclass, Collection collection) { + return new BlockStateEnum(s, oclass, collection); + } + + // TacoSpigot start - fix stupid generic thingies + /* + public String a(Comparable comparable) { + return this.a((Enum) comparable); + } + */ + // TacoSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateInteger.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateInteger.java new file mode 100644 index 0000000..13b7d37 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateInteger.java @@ -0,0 +1,102 @@ +package net.minecraft.server; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.HashSet; + +public class BlockStateInteger extends BlockState { + + private final ImmutableSet a; + // TacoSpigot start + private final int min, max; + private final int range; + + @Override + public int getValueId(Integer value) { + if (value < min) { + throw new IllegalArgumentException("Too small: " + value); + } else if (value > max) { + throw new IllegalArgumentException("Too large: " + value); + } else { + return value - min; + } + } + + @Override + public Integer getByValueId(int id) { + if (id < 0) { + throw new IllegalArgumentException("Negative id: " + id); + } else if (id > range) { + throw new IllegalArgumentException("Id is out of range: " + id); + } else { + return id; + } + } + // TacoSpigot end + + protected BlockStateInteger(String s, int i, int j) { + super(s, Integer.class); + // TacoSpigot start + this.min = i; + this.max = j; + this.range = (max - min); // min and max are _both_ inclusive (there's a reason you're not supposed to do this :p) + // TacoSpigot end + if (i < 0) { + throw new IllegalArgumentException("Min value of " + s + " must be 0 or greater"); + } else if (j <= i) { + throw new IllegalArgumentException("Max value of " + s + " must be greater than min (" + i + ")"); + } else { + HashSet hashset = Sets.newHashSet(); + + for (int k = i; k <= j; ++k) { + hashset.add(Integer.valueOf(k)); + } + + this.a = ImmutableSet.copyOf(hashset); + } + } + + public Collection c() { + return this.a; + } + + public boolean equals(Object object) { + if (this == object) { + return true; + } else if (object != null && this.getClass() == object.getClass()) { + if (!super.equals(object)) { + return false; + } else { + BlockStateInteger blockstateinteger = (BlockStateInteger) object; + + return this.a.equals(blockstateinteger.a); + } + } else { + return false; + } + } + + public int hashCode() { + int i = super.hashCode(); + + i = 31 * i + this.a.hashCode(); + return i; + } + + public static BlockStateInteger of(String s, int i, int j) { + return new BlockStateInteger(s, i, j); + } + + public String a(Integer integer) { + return integer.toString(); + } + + // TacoSpigot start - fix stupid generic thingies + /* + public String a(Comparable comparable) { + return this.a((Integer) comparable); + } + */ + // TacoSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateList.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateList.java new file mode 100644 index 0000000..fda9640 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStateList.java @@ -0,0 +1,227 @@ +package net.minecraft.server; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.base.Objects; +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +// TacoSpigot start +import com.google.common.collect.Table; + +import net.techcable.tacospigot.BlockStateRegistry; +import net.techcable.tacospigot.ImmutableArrayMap; +import net.techcable.tacospigot.ImmutableArrayTable; +import net.techcable.tacospigot.TacoSpigotConfig; +// TacoSpigot end + +public class BlockStateList { + + private static final Joiner a = Joiner.on(", "); + private static final Function b = new Function() { + public String a(IBlockState iblockstate) { + return iblockstate == null ? "" : iblockstate.a(); + } + + public Object apply(Object object) { + return this.a((IBlockState) object); + } + }; + private final Block c; + private final ImmutableList d; + private final ImmutableList e; + + public BlockStateList(Block block, IBlockState... aiblockstate) { + this.c = block; + Arrays.sort(aiblockstate, new Comparator() { + public int a(IBlockState iblockstate, IBlockState iblockstate1) { + return iblockstate.a().compareTo(iblockstate1.a()); + } + + public int compare(Object object, Object object1) { + return this.a((IBlockState) object, (IBlockState) object1); + } + }); + for (IBlockState state : aiblockstate) state.tryInitId(); // TacoSpigot + this.d = ImmutableList.copyOf(aiblockstate); + LinkedHashMap linkedhashmap = Maps.newLinkedHashMap(); + ArrayList arraylist = Lists.newArrayList(); + Iterable iterable = IteratorUtils.a(this.e()); + Iterator iterator = iterable.iterator(); + + while (iterator.hasNext()) { + List list = (List) iterator.next(); + Map map = MapGeneratorUtils.b(this.d, list); + BlockStateList.BlockData blockstatelist_blockdata = new BlockStateList.BlockData(block, ImmutableMap.copyOf(map), null); + + linkedhashmap.put(map, blockstatelist_blockdata); + arraylist.add(blockstatelist_blockdata); + } + + iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + BlockStateList.BlockData blockstatelist_blockdata1 = (BlockStateList.BlockData) iterator.next(); + + blockstatelist_blockdata1.a((Map) linkedhashmap); + } + + this.e = ImmutableList.copyOf(arraylist); + } + + public ImmutableList a() { + return this.e; + } + + private List> e() { + ArrayList arraylist = Lists.newArrayList(); + + for (int i = 0; i < this.d.size(); ++i) { + arraylist.add(((IBlockState) this.d.get(i)).c()); + } + + return arraylist; + } + + public IBlockData getBlockData() { + return (IBlockData) this.e.get(0); + } + + public Block getBlock() { + return this.c; + } + + public Collection d() { + return this.d; + } + + public String toString() { + return Objects.toStringHelper(this).add("block", Block.REGISTRY.c(this.c)).add("properties", Iterables.transform(this.d, BlockStateList.b)).toString(); + } + + static class BlockData extends BlockDataAbstract { + + private final Block a; + // TacoSpigot start + private final ImmutableMap bAsImmutableMap; + private final Map b; + private Table c; + // TacoSpigot end + + private BlockData(Block block, ImmutableMap immutablemap) { + this.a = block; + // TacoSpigot start + this.bAsImmutableMap = immutablemap; + if (TacoSpigotConfig.useArraysForBlockStates) { + b = new ImmutableArrayMap<>(IBlockState.INDEXER, immutablemap); + } else { + b = immutablemap; + } + // TacoSpigot end + } + + public Collection a() { + return Collections.unmodifiableCollection(this.b.keySet()); + } + + public > T get(IBlockState iblockstate) { + // TacoSpigot start - runtime check -> assertion + assert this.b.containsKey(iblockstate) : "Cannot get property " + iblockstate + " as it does not exist in " + this.a.P(); + Object value = this.b.get(iblockstate); + assert value == bAsImmutableMap.get(iblockstate) : "Array map gave data " + String.valueOf(value) + " and regular map gave data " + String.valueOf(bAsImmutableMap.get(iblockstate)); + assert value != null : "Null value for state " + iblockstate + " and data " + this; + assert iblockstate.b().isInstance(value) : "Value " + value + " for state " + iblockstate + " and data " + this + " not instanceof " + iblockstate.b().getTypeName(); + return (T) value; + // TacoSpigot end + } + + public , V extends T> IBlockData set(IBlockState iblockstate, V v0) { + // TacoSpigot start - runtime check -> assertion + assert iblockstate != null : "Null block state"; + assert v0 != null : "Null value for block state " + iblockstate; + assert this.b.containsKey(iblockstate) : "Cannot set property " + iblockstate + " as it does not exist in " + this.a.P(); + assert iblockstate.c().contains(v0) : "Cannot set property " + iblockstate + " to " + v0 + " on block " + Block.REGISTRY.c(this.a) + ", it is not an allowed value"; + IBlockData data = (IBlockData) (this.b.get(iblockstate) == v0 ? this : (IBlockData) this.c.get(iblockstate, v0)); + assert data != null : "No block data with property " + iblockstate + " and value " + v0 + " for block data " + this; + return data; + // TacoSpigot end + } + + public ImmutableMap b() { + return this.bAsImmutableMap; // TacoSpigot + } + + public Block getBlock() { + return this.a; + } + + public boolean equals(Object object) { + return this == object; + } + + public int hashCode() { + return this.b.hashCode(); + } + + public void a(Map, BlockStateList.BlockData> map) { + if (this.c != null) { + throw new IllegalStateException(); + } else { + HashBasedTable hashbasedtable = HashBasedTable.create(); + Iterator iterator = this.b.keySet().iterator(); + + while (iterator.hasNext()) { + IBlockState iblockstate = (IBlockState) iterator.next(); + Iterator iterator1 = iblockstate.c().iterator(); + + while (iterator1.hasNext()) { + Comparable comparable = (Comparable) iterator1.next(); + + if (comparable != this.get(iblockstate)) { // TacoSpigot - use this.get(iblockstate) instead of this.b.get(iblockstate) + assert map.get(this.b(iblockstate, comparable)) != null : "Map doesn't contain block data with state " + iblockstate + " and comparable " + comparable + b(iblockstate, comparable); // TacoSpigot - assert present + hashbasedtable.put(iblockstate, comparable, map.get(this.b(iblockstate, comparable))); + } + } + } + + // TacoSpigot start + if (TacoSpigotConfig.useArraysForBlockStates) { + this.c = new ImmutableArrayTable ( + IBlockState.INDEXER, + (IBlockState state, Comparable value) -> state.getValueId(value), + hashbasedtable + ); + } else { + this.c = ImmutableTable.copyOf(hashbasedtable); + } + // TacoSpigot end + } + } + + private Map b(IBlockState iblockstate, Comparable comparable) { + HashMap hashmap = Maps.newHashMap(this.b); + + hashmap.put(iblockstate, comparable); + return hashmap; + } + + BlockData(Block block, ImmutableMap immutablemap, Object object) { + this(block, immutablemap); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStationary.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStationary.java new file mode 100644 index 0000000..4860aa4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStationary.java @@ -0,0 +1,100 @@ +package net.minecraft.server; + +import java.util.Random; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class BlockStationary extends BlockFluids { + + protected BlockStationary(Material material) { + super(material); + this.a(false); + if (material == Material.LAVA) { + this.a(true); + } + + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!this.e(world, blockposition, iblockdata)) { + this.f(world, blockposition, iblockdata); + } + + } + + private void f(World world, BlockPosition blockposition, IBlockData iblockdata) { + BlockFlowing blockflowing = a(this.material); + + world.setTypeAndData(blockposition, blockflowing.getBlockData().set(BlockStationary.LEVEL, iblockdata.get(BlockStationary.LEVEL)), 2); + world.a(blockposition, (Block) blockflowing, this.a(world)); + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (this.material == Material.LAVA) { + if (world.getGameRules().getBoolean("doFireTick")) { + int i = random.nextInt(3); + + if (i > 0) { + BlockPosition blockposition1 = blockposition; + + for (int j = 0; j < i; ++j) { + blockposition1 = blockposition1.a(random.nextInt(3) - 1, 1, random.nextInt(3) - 1); + Block block = world.getType(blockposition1).getBlock(); + + if (block.material == Material.AIR) { + if (this.f(world, blockposition1)) { + // CraftBukkit start - Prevent lava putting something on fire + if (world.getType(blockposition1) != Blocks.FIRE) { + if (CraftEventFactory.callBlockIgniteEvent(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), blockposition.getX(), blockposition.getY(), blockposition.getZ()).isCancelled()) { + continue; + } + } + // CraftBukkit end + world.setTypeUpdate(blockposition1, Blocks.FIRE.getBlockData()); + return; + } + } else if (block.material.isSolid()) { + return; + } + } + } else { + for (int k = 0; k < 3; ++k) { + BlockPosition blockposition2 = blockposition.a(random.nextInt(3) - 1, 0, random.nextInt(3) - 1); + + if (world.isEmpty(blockposition2.up()) && this.m(world, blockposition2)) { + // CraftBukkit start - Prevent lava putting something on fire + BlockPosition up = blockposition2.up(); + if (world.getType(up) != Blocks.FIRE) { + if (CraftEventFactory.callBlockIgniteEvent(world, up.getX(), up.getY(), up.getZ(), blockposition.getX(), blockposition.getY(), blockposition.getZ()).isCancelled()) { + continue; + } + } + // CraftBukkit end + world.setTypeUpdate(blockposition2.up(), Blocks.FIRE.getBlockData()); + } + } + } + + } + } + } + + protected boolean f(World world, BlockPosition blockposition) { + EnumDirection[] aenumdirection = EnumDirection.values(); + int i = aenumdirection.length; + + for (int j = 0; j < i; ++j) { + EnumDirection enumdirection = aenumdirection[j]; + + if (this.m(world, blockposition.shift(enumdirection))) { + return true; + } + } + + return false; + } + + private boolean m(World world, BlockPosition blockposition) { + return world.getType(blockposition).getBlock().getMaterial().isBurnable(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStem.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStem.java new file mode 100644 index 0000000..2618c40 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockStem.java @@ -0,0 +1,158 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.Iterator; +import java.util.Random; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class BlockStem extends BlockPlant implements IBlockFragilePlantElement { + + public static final BlockStateInteger AGE = BlockStateInteger.of("age", 0, 7); + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", new Predicate() { + public boolean a(EnumDirection enumdirection) { + return enumdirection != EnumDirection.DOWN; + } + + public boolean apply(Object object) { + return this.a((EnumDirection) object); + } + }); + private final Block blockFruit; + + protected BlockStem(Block block) { + this.j(this.blockStateList.getBlockData().set(BlockStem.AGE, Integer.valueOf(0)).set(BlockStem.FACING, EnumDirection.UP)); + this.blockFruit = block; + this.a(true); + float f = 0.125F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f); + this.a((CreativeModeTab) null); + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + iblockdata = iblockdata.set(BlockStem.FACING, EnumDirection.UP); + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + + if (iblockaccess.getType(blockposition.shift(enumdirection)).getBlock() == this.blockFruit) { + iblockdata = iblockdata.set(BlockStem.FACING, enumdirection); + break; + } + } + + return iblockdata; + } + + protected boolean c(Block block) { + return block == Blocks.FARMLAND; + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + super.b(world, blockposition, iblockdata, random); + if (world.getLightLevel(blockposition.up()) >= 9) { + float f = BlockCrops.a((Block) this, world, blockposition); + + if (random.nextInt((int) (world.growthOdds / (this == Blocks.PUMPKIN_STEM? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier) * (25.0F / f)) + 1) == 0) { // Spigot + int i = ((Integer) iblockdata.get(BlockStem.AGE)).intValue(); + + if (i < 7) { + iblockdata = iblockdata.set(BlockStem.AGE, Integer.valueOf(i + 1)); + // world.setTypeAndData(blockposition, iblockdata, 2); // CraftBukkit + CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(iblockdata)); // CraftBukkit + } else { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + + if (world.getType(blockposition.shift(enumdirection)).getBlock() == this.blockFruit) { + return; + } + } + + blockposition = blockposition.shift(EnumDirection.EnumDirectionLimit.HORIZONTAL.a(random)); + Block block = world.getType(blockposition.down()).getBlock(); + + if (world.getType(blockposition).getBlock().material == Material.AIR && (block == Blocks.FARMLAND || block == Blocks.DIRT || block == Blocks.GRASS)) { + // world.setTypeUpdate(blockposition, this.blockFruit.getBlockData()); // CraftBukkit + CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.blockFruit, 0); // CraftBukkit + } + } + } + + } + } + + public void g(World world, BlockPosition blockposition, IBlockData iblockdata) { + int i = ((Integer) iblockdata.get(BlockStem.AGE)).intValue() + MathHelper.nextInt(world.random, 2, 5); + + // world.setTypeAndData(blockposition, iblockdata.set(BlockStem.AGE, Integer.valueOf(Math.min(7, i))), 2); + CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, Math.min(7, i)); // CraftBukkit + } + + public void j() { + float f = 0.125F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + this.maxY = (double) ((float) (((Integer) iblockaccess.getType(blockposition).get(BlockStem.AGE)).intValue() * 2 + 2) / 16.0F); + float f = 0.125F; + + this.a(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, (float) this.maxY, 0.5F + f); + } + + public void dropNaturally(World world, BlockPosition blockposition, IBlockData iblockdata, float f, int i) { + super.dropNaturally(world, blockposition, iblockdata, f, i); + if (!world.isClientSide) { + Item item = this.l(); + + if (item != null) { + int j = ((Integer) iblockdata.get(BlockStem.AGE)).intValue(); + + for (int k = 0; k < 3; ++k) { + if (world.random.nextInt(15) <= j) { + a(world, blockposition, new ItemStack(item)); + } + } + + } + } + } + + protected Item l() { + return this.blockFruit == Blocks.PUMPKIN ? Items.PUMPKIN_SEEDS : (this.blockFruit == Blocks.MELON_BLOCK ? Items.MELON_SEEDS : null); + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return null; + } + + public boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag) { + return ((Integer) iblockdata.get(BlockStem.AGE)).intValue() != 7; + } + + public boolean a(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + return true; + } + + public void b(World world, Random random, BlockPosition blockposition, IBlockData iblockdata) { + this.g(world, blockposition, iblockdata); + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockStem.AGE, Integer.valueOf(i)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Integer) iblockdata.get(BlockStem.AGE)).intValue(); + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockStem.AGE, BlockStem.FACING}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTNT.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTNT.java new file mode 100644 index 0000000..3d1e583 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTNT.java @@ -0,0 +1,117 @@ +package net.minecraft.server; + +public class BlockTNT extends Block { + + public static final BlockStateBoolean EXPLODE = BlockStateBoolean.of("explode"); + + public BlockTNT() { + super(Material.TNT); + this.j(this.blockStateList.getBlockData().set(BlockTNT.EXPLODE, Boolean.valueOf(false))); + this.a(CreativeModeTab.d); + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + super.onPlace(world, blockposition, iblockdata); + if (world.isBlockIndirectlyPowered(blockposition)) { + this.postBreak(world, blockposition, iblockdata.set(BlockTNT.EXPLODE, Boolean.valueOf(true))); + world.setAir(blockposition); + } + + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (world.isBlockIndirectlyPowered(blockposition)) { + this.postBreak(world, blockposition, iblockdata.set(BlockTNT.EXPLODE, Boolean.valueOf(true))); + world.setAir(blockposition); + } + + } + + public void wasExploded(World world, BlockPosition blockposition, Explosion explosion) { + if (!world.isClientSide) { + org.bukkit.Location loc = explosion.source instanceof EntityTNTPrimed ? ((EntityTNTPrimed) explosion.source).sourceLoc : new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); // PaperSpigot + // PaperSpigot start - Fix cannons + double y = blockposition.getY(); + if (!world.paperSpigotConfig.fixCannons) y += 0.5; + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(loc, world, (double) ((float) blockposition.getX() + 0.5F), y, (double) ((float) blockposition.getZ() + 0.5F), explosion.getSource()); // PaperSpigot - add loc + // PaperSpigot end + + entitytntprimed.fuseTicks = world.random.nextInt(entitytntprimed.fuseTicks / 4) + entitytntprimed.fuseTicks / 8; + world.addEntity(entitytntprimed); + } + } + + public void postBreak(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.a(world, blockposition, iblockdata, (EntityLiving) null); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving) { + if (!world.isClientSide) { + if (((Boolean) iblockdata.get(BlockTNT.EXPLODE)).booleanValue()) { + org.bukkit.Location loc = new org.bukkit.Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); // PaperSpigot + // PaperSpigot start - Fix cannons + double y = blockposition.getY(); + if (!world.paperSpigotConfig.fixCannons) y += 0.5; + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(loc, world, (double) ((float) blockposition.getX() + 0.5F), y, (double) ((float) blockposition.getZ() + 0.5F), entityliving); // PaperSpigot - add loc + // PaperSpigot end + + world.addEntity(entitytntprimed); + world.makeSound(entitytntprimed, "game.tnt.primed", 1.0F, 1.0F); + } + + } + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (entityhuman.bZ() != null) { + Item item = entityhuman.bZ().getItem(); + + if (item == Items.FLINT_AND_STEEL || item == Items.FIRE_CHARGE) { + this.a(world, blockposition, iblockdata.set(BlockTNT.EXPLODE, Boolean.valueOf(true)), (EntityLiving) entityhuman); + world.setAir(blockposition); + if (item == Items.FLINT_AND_STEEL) { + entityhuman.bZ().damage(1, entityhuman); + } else if (!entityhuman.abilities.canInstantlyBuild) { + --entityhuman.bZ().count; + } + + return true; + } + } + + return super.interact(world, blockposition, iblockdata, entityhuman, enumdirection, f, f1, f2); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (!world.isClientSide && entity instanceof EntityArrow) { + EntityArrow entityarrow = (EntityArrow) entity; + + if (entityarrow.isBurning()) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityarrow, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.AIR, 0).isCancelled()) { + return; + } + // CraftBukkit end + this.a(world, blockposition, world.getType(blockposition).set(BlockTNT.EXPLODE, Boolean.valueOf(true)), entityarrow.shooter instanceof EntityLiving ? (EntityLiving) entityarrow.shooter : null); + world.setAir(blockposition); + } + } + + } + + public boolean a(Explosion explosion) { + return false; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockTNT.EXPLODE, Boolean.valueOf((i & 1) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + return ((Boolean) iblockdata.get(BlockTNT.EXPLODE)).booleanValue() ? 1 : 0; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockTNT.EXPLODE}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTrapdoor.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTrapdoor.java new file mode 100644 index 0000000..1a2cdd1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTrapdoor.java @@ -0,0 +1,262 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; + +import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + +public class BlockTrapdoor extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirection.EnumDirectionLimit.HORIZONTAL); + public static final BlockStateBoolean OPEN = BlockStateBoolean.of("open"); + public static final BlockStateEnum HALF = BlockStateEnum.of("half", BlockTrapdoor.EnumTrapdoorHalf.class); + + protected BlockTrapdoor(Material material) { + super(material); + this.j(this.blockStateList.getBlockData().set(BlockTrapdoor.FACING, EnumDirection.NORTH).set(BlockTrapdoor.OPEN, Boolean.valueOf(false)).set(BlockTrapdoor.HALF, BlockTrapdoor.EnumTrapdoorHalf.BOTTOM)); + float f = 0.5F; + float f1 = 1.0F; + + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + this.a(CreativeModeTab.d); + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public boolean b(IBlockAccess iblockaccess, BlockPosition blockposition) { + return !((Boolean) iblockaccess.getType(blockposition).get(BlockTrapdoor.OPEN)).booleanValue(); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.updateShape(world, blockposition); + return super.a(world, blockposition, iblockdata); + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + this.d(iblockaccess.getType(blockposition)); + } + + public void j() { + float f = 0.1875F; + + this.a(0.0F, 0.40625F, 0.0F, 1.0F, 0.59375F, 1.0F); + } + + public void d(IBlockData iblockdata) { + if (iblockdata.getBlock() == this) { + boolean flag = iblockdata.get(BlockTrapdoor.HALF) == BlockTrapdoor.EnumTrapdoorHalf.TOP; + Boolean obool = (Boolean) iblockdata.get(BlockTrapdoor.OPEN); + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockTrapdoor.FACING); + float f = 0.1875F; + + if (flag) { + this.a(0.0F, 0.8125F, 0.0F, 1.0F, 1.0F, 1.0F); + } else { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.1875F, 1.0F); + } + + if (obool.booleanValue()) { + if (enumdirection == EnumDirection.NORTH) { + this.a(0.0F, 0.0F, 0.8125F, 1.0F, 1.0F, 1.0F); + } + + if (enumdirection == EnumDirection.SOUTH) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.1875F); + } + + if (enumdirection == EnumDirection.WEST) { + this.a(0.8125F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + if (enumdirection == EnumDirection.EAST) { + this.a(0.0F, 0.0F, 0.0F, 0.1875F, 1.0F, 1.0F); + } + } + + } + } + + public boolean interact(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman, EnumDirection enumdirection, float f, float f1, float f2) { + if (this.material == Material.ORE) { + return true; + } else { + iblockdata = iblockdata.a(BlockTrapdoor.OPEN); + world.setTypeAndData(blockposition, iblockdata, 2); + world.a(entityhuman, ((Boolean) iblockdata.get(BlockTrapdoor.OPEN)).booleanValue() ? 1003 : 1006, blockposition, 0); + return true; + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!world.isClientSide) { + BlockPosition blockposition1 = blockposition.shift(((EnumDirection) iblockdata.get(BlockTrapdoor.FACING)).opposite()); + + if (!c(world.getType(blockposition1).getBlock())) { + world.setAir(blockposition); + this.b(world, blockposition, iblockdata, 0); + } else { + boolean flag = world.isBlockIndirectlyPowered(blockposition); + + if (flag || block.isPowerSource()) { + // CraftBukkit start + org.bukkit.World bworld = world.getWorld(); + org.bukkit.block.Block bblock = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + int power = bblock.getBlockPower(); + int oldPower = (Boolean) iblockdata.get(OPEN) ? 15 : 0; + + if (oldPower == 0 ^ power == 0 || block.isPowerSource()) { + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bblock, oldPower, power); + world.getServer().getPluginManager().callEvent(eventRedstone); + flag = eventRedstone.getNewCurrent() > 0; + } + // CraftBukkit end + boolean flag1 = ((Boolean) iblockdata.get(BlockTrapdoor.OPEN)).booleanValue(); + + if (flag1 != flag) { + world.setTypeAndData(blockposition, iblockdata.set(BlockTrapdoor.OPEN, Boolean.valueOf(flag)), 2); + world.a((EntityHuman) null, flag ? 1003 : 1006, blockposition, 0); + } + } + + } + } + } + + public MovingObjectPosition a(World world, BlockPosition blockposition, Vec3D vec3d, Vec3D vec3d1) { + this.updateShape(world, blockposition); + return super.a(world, blockposition, vec3d, vec3d1); + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + IBlockData iblockdata = this.getBlockData(); + + if (enumdirection.k().c()) { + iblockdata = iblockdata.set(BlockTrapdoor.FACING, enumdirection).set(BlockTrapdoor.OPEN, Boolean.valueOf(false)); + iblockdata = iblockdata.set(BlockTrapdoor.HALF, f1 > 0.5F ? BlockTrapdoor.EnumTrapdoorHalf.TOP : BlockTrapdoor.EnumTrapdoorHalf.BOTTOM); + } + + return iblockdata; + } + + public boolean canPlace(World world, BlockPosition blockposition, EnumDirection enumdirection) { + return !enumdirection.k().b() && c(world.getType(blockposition.shift(enumdirection.opposite())).getBlock()); + } + + protected static EnumDirection b(int i) { + switch (i & 3) { + case 0: + return EnumDirection.NORTH; + + case 1: + return EnumDirection.SOUTH; + + case 2: + return EnumDirection.WEST; + + case 3: + default: + return EnumDirection.EAST; + } + } + + protected static int a(EnumDirection enumdirection) { + switch (BlockTrapdoor.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + return 0; + + case 2: + return 1; + + case 3: + return 2; + + case 4: + default: + return 3; + } + } + + private static boolean c(Block block) { + return block.material.k() && block.d() || block == Blocks.GLOWSTONE || block instanceof BlockStepAbstract || block instanceof BlockStairs; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockTrapdoor.FACING, b(i)).set(BlockTrapdoor.OPEN, Boolean.valueOf((i & 4) != 0)).set(BlockTrapdoor.HALF, (i & 8) == 0 ? BlockTrapdoor.EnumTrapdoorHalf.BOTTOM : BlockTrapdoor.EnumTrapdoorHalf.TOP); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | a((EnumDirection) iblockdata.get(BlockTrapdoor.FACING)); + + if (((Boolean) iblockdata.get(BlockTrapdoor.OPEN)).booleanValue()) { + i |= 4; + } + + if (iblockdata.get(BlockTrapdoor.HALF) == BlockTrapdoor.EnumTrapdoorHalf.TOP) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockTrapdoor.FACING, BlockTrapdoor.OPEN, BlockTrapdoor.HALF}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + BlockTrapdoor.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockTrapdoor.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockTrapdoor.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockTrapdoor.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + } + } + + public static enum EnumTrapdoorHalf implements INamable { + + TOP("top"), BOTTOM("bottom"); + + private final String c; + + private EnumTrapdoorHalf(String s) { + this.c = s; + } + + public String toString() { + return this.c; + } + + public String getName() { + return this.c; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTripwire.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTripwire.java new file mode 100644 index 0000000..bc61e17 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTripwire.java @@ -0,0 +1,254 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit + +public class BlockTripwire extends Block { + + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); + public static final BlockStateBoolean SUSPENDED = BlockStateBoolean.of("suspended"); + public static final BlockStateBoolean ATTACHED = BlockStateBoolean.of("attached"); + public static final BlockStateBoolean DISARMED = BlockStateBoolean.of("disarmed"); + public static final BlockStateBoolean NORTH = BlockStateBoolean.of("north"); + public static final BlockStateBoolean EAST = BlockStateBoolean.of("east"); + public static final BlockStateBoolean SOUTH = BlockStateBoolean.of("south"); + public static final BlockStateBoolean WEST = BlockStateBoolean.of("west"); + + public BlockTripwire() { + super(Material.ORIENTABLE); + this.j(this.blockStateList.getBlockData().set(BlockTripwire.POWERED, Boolean.valueOf(false)).set(BlockTripwire.SUSPENDED, Boolean.valueOf(false)).set(BlockTripwire.ATTACHED, Boolean.valueOf(false)).set(BlockTripwire.DISARMED, Boolean.valueOf(false)).set(BlockTripwire.NORTH, Boolean.valueOf(false)).set(BlockTripwire.EAST, Boolean.valueOf(false)).set(BlockTripwire.SOUTH, Boolean.valueOf(false)).set(BlockTripwire.WEST, Boolean.valueOf(false))); + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.15625F, 1.0F); + this.a(true); + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata.set(BlockTripwire.NORTH, Boolean.valueOf(c(iblockaccess, blockposition, iblockdata, EnumDirection.NORTH))).set(BlockTripwire.EAST, Boolean.valueOf(c(iblockaccess, blockposition, iblockdata, EnumDirection.EAST))).set(BlockTripwire.SOUTH, Boolean.valueOf(c(iblockaccess, blockposition, iblockdata, EnumDirection.SOUTH))).set(BlockTripwire.WEST, Boolean.valueOf(c(iblockaccess, blockposition, iblockdata, EnumDirection.WEST))); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return Items.STRING; + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + boolean flag = ((Boolean) iblockdata.get(BlockTripwire.SUSPENDED)).booleanValue(); + boolean flag1 = !World.a((IBlockAccess) world, blockposition.down()); + + if (flag != flag1) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + boolean flag = ((Boolean) iblockdata.get(BlockTripwire.ATTACHED)).booleanValue(); + boolean flag1 = ((Boolean) iblockdata.get(BlockTripwire.SUSPENDED)).booleanValue(); + + if (!flag1) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.09375F, 1.0F); + } else if (!flag) { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 0.5F, 1.0F); + } else { + this.a(0.0F, 0.0625F, 0.0F, 1.0F, 0.15625F, 1.0F); + } + + } + + public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) { + iblockdata = iblockdata.set(BlockTripwire.SUSPENDED, Boolean.valueOf(!World.a((IBlockAccess) world, blockposition.down()))); + world.setTypeAndData(blockposition, iblockdata, 3); + this.e(world, blockposition, iblockdata); + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + this.e(world, blockposition, iblockdata.set(BlockTripwire.POWERED, Boolean.valueOf(true))); + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, EntityHuman entityhuman) { + if (!world.isClientSide) { + if (entityhuman.bZ() != null && entityhuman.bZ().getItem() == Items.SHEARS) { + world.setTypeAndData(blockposition, iblockdata.set(BlockTripwire.DISARMED, Boolean.valueOf(true)), 4); + } + + } + } + + private void e(World world, BlockPosition blockposition, IBlockData iblockdata) { + EnumDirection[] aenumdirection = new EnumDirection[] { EnumDirection.SOUTH, EnumDirection.WEST}; + int i = aenumdirection.length; + int j = 0; + + while (j < i) { + EnumDirection enumdirection = aenumdirection[j]; + int k = 1; + + while (true) { + if (k < 42) { + BlockPosition blockposition1 = blockposition.shift(enumdirection, k); + IBlockData iblockdata1 = world.getType(blockposition1); + + if (iblockdata1.getBlock() == Blocks.TRIPWIRE_HOOK) { + if (iblockdata1.get(BlockTripwireHook.FACING) == enumdirection.opposite()) { + Blocks.TRIPWIRE_HOOK.a(world, blockposition1, iblockdata1, false, true, k, iblockdata); + } + } else if (iblockdata1.getBlock() == Blocks.TRIPWIRE) { + ++k; + continue; + } + } + + ++j; + break; + } + } + + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Entity entity) { + if (!world.isClientSide) { + if (!((Boolean) iblockdata.get(BlockTripwire.POWERED)).booleanValue()) { + this.e(world, blockposition); + } + } + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {} + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (((Boolean) world.getType(blockposition).get(BlockTripwire.POWERED)).booleanValue()) { + this.e(world, blockposition); + } + } + } + + private void e(World world, BlockPosition blockposition) { + IBlockData iblockdata = world.getType(blockposition); + boolean flag = ((Boolean) iblockdata.get(BlockTripwire.POWERED)).booleanValue(); + boolean flag1 = false; + List list = world.getEntities((Entity) null, new AxisAlignedBB((double) blockposition.getX() + this.minX, (double) blockposition.getY() + this.minY, (double) blockposition.getZ() + this.minZ, (double) blockposition.getX() + this.maxX, (double) blockposition.getY() + this.maxY, (double) blockposition.getZ() + this.maxZ)); + + if (!list.isEmpty()) { + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (!entity.aI()) { + flag1 = true; + break; + } + } + } + + // CraftBukkit start - Call interact even when triggering connected tripwire + if (flag != flag1 && flag1 && (Boolean)iblockdata.get(ATTACHED)) { + org.bukkit.World bworld = world.getWorld(); + org.bukkit.plugin.PluginManager manager = world.getServer().getPluginManager(); + org.bukkit.block.Block block = bworld.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + boolean allowed = false; + + // If all of the events are cancelled block the tripwire trigger, else allow + for (Object object : list) { + if (object != null) { + org.bukkit.event.Cancellable cancellable; + + if (object instanceof EntityHuman) { + cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityHuman) object, org.bukkit.event.block.Action.PHYSICAL, blockposition, null, null); + } else if (object instanceof Entity) { + cancellable = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block); + manager.callEvent((EntityInteractEvent) cancellable); + } else { + continue; + } + + if (!cancellable.isCancelled()) { + allowed = true; + break; + } + } + } + + if (!allowed) { + return; + } + } + // CraftBukkit end + + if (flag1 != flag) { + iblockdata = iblockdata.set(BlockTripwire.POWERED, Boolean.valueOf(flag1)); + world.setTypeAndData(blockposition, iblockdata, 3); + this.e(world, blockposition, iblockdata); + } + + if (flag1) { + world.a(blockposition, (Block) this, this.a(world)); + } + + } + + public static boolean c(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + BlockPosition blockposition1 = blockposition.shift(enumdirection); + IBlockData iblockdata1 = iblockaccess.getType(blockposition1); + Block block = iblockdata1.getBlock(); + + if (block == Blocks.TRIPWIRE_HOOK) { + EnumDirection enumdirection1 = enumdirection.opposite(); + + return iblockdata1.get(BlockTripwireHook.FACING) == enumdirection1; + } else if (block == Blocks.TRIPWIRE) { + boolean flag = ((Boolean) iblockdata.get(BlockTripwire.SUSPENDED)).booleanValue(); + boolean flag1 = ((Boolean) iblockdata1.get(BlockTripwire.SUSPENDED)).booleanValue(); + + return flag == flag1; + } else { + return false; + } + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockTripwire.POWERED, Boolean.valueOf((i & 1) > 0)).set(BlockTripwire.SUSPENDED, Boolean.valueOf((i & 2) > 0)).set(BlockTripwire.ATTACHED, Boolean.valueOf((i & 4) > 0)).set(BlockTripwire.DISARMED, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + int i = 0; + + if (((Boolean) iblockdata.get(BlockTripwire.POWERED)).booleanValue()) { + i |= 1; + } + + if (((Boolean) iblockdata.get(BlockTripwire.SUSPENDED)).booleanValue()) { + i |= 2; + } + + if (((Boolean) iblockdata.get(BlockTripwire.ATTACHED)).booleanValue()) { + i |= 4; + } + + if (((Boolean) iblockdata.get(BlockTripwire.DISARMED)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockTripwire.POWERED, BlockTripwire.SUSPENDED, BlockTripwire.ATTACHED, BlockTripwire.DISARMED, BlockTripwire.NORTH, BlockTripwire.EAST, BlockTripwire.WEST, BlockTripwire.SOUTH}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTripwireHook.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTripwireHook.java new file mode 100644 index 0000000..0ad4a20 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockTripwireHook.java @@ -0,0 +1,316 @@ +package net.minecraft.server; + +import com.google.common.base.Objects; +import com.google.common.base.Predicate; +import java.util.Iterator; +import java.util.Random; + +import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit + +public class BlockTripwireHook extends Block { + + public static final BlockStateDirection FACING = BlockStateDirection.of("facing", (Predicate) EnumDirection.EnumDirectionLimit.HORIZONTAL); + public static final BlockStateBoolean POWERED = BlockStateBoolean.of("powered"); + public static final BlockStateBoolean ATTACHED = BlockStateBoolean.of("attached"); + public static final BlockStateBoolean SUSPENDED = BlockStateBoolean.of("suspended"); + + public BlockTripwireHook() { + super(Material.ORIENTABLE); + this.j(this.blockStateList.getBlockData().set(BlockTripwireHook.FACING, EnumDirection.NORTH).set(BlockTripwireHook.POWERED, Boolean.valueOf(false)).set(BlockTripwireHook.ATTACHED, Boolean.valueOf(false)).set(BlockTripwireHook.SUSPENDED, Boolean.valueOf(false))); + this.a(CreativeModeTab.d); + this.a(true); + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata.set(BlockTripwireHook.SUSPENDED, Boolean.valueOf(!World.a(iblockaccess, blockposition.down()))); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public boolean canPlace(World world, BlockPosition blockposition, EnumDirection enumdirection) { + return enumdirection.k().c() && world.getType(blockposition.shift(enumdirection.opposite())).getBlock().isOccluding(); + } + + public boolean canPlace(World world, BlockPosition blockposition) { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + EnumDirection enumdirection; + + do { + if (!iterator.hasNext()) { + return false; + } + + enumdirection = (EnumDirection) iterator.next(); + } while (!world.getType(blockposition.shift(enumdirection)).getBlock().isOccluding()); + + return true; + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + IBlockData iblockdata = this.getBlockData().set(BlockTripwireHook.POWERED, Boolean.valueOf(false)).set(BlockTripwireHook.ATTACHED, Boolean.valueOf(false)).set(BlockTripwireHook.SUSPENDED, Boolean.valueOf(false)); + + if (enumdirection.k().c()) { + iblockdata = iblockdata.set(BlockTripwireHook.FACING, enumdirection); + } + + return iblockdata; + } + + public void postPlace(World world, BlockPosition blockposition, IBlockData iblockdata, EntityLiving entityliving, ItemStack itemstack) { + this.a(world, blockposition, iblockdata, false, false, -1, (IBlockData) null); + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (block != this) { + if (this.e(world, blockposition, iblockdata)) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockTripwireHook.FACING); + + if (!world.getType(blockposition.shift(enumdirection.opposite())).getBlock().isOccluding()) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + } + + } + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, boolean flag, boolean flag1, int i, IBlockData iblockdata1) { + EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockTripwireHook.FACING); + boolean flag2 = ((Boolean) iblockdata.get(BlockTripwireHook.ATTACHED)).booleanValue(); + boolean flag3 = ((Boolean) iblockdata.get(BlockTripwireHook.POWERED)).booleanValue(); + boolean flag4 = !World.a((IBlockAccess) world, blockposition.down()); + boolean flag5 = !flag; + boolean flag6 = false; + int j = 0; + IBlockData[] aiblockdata = new IBlockData[42]; + + BlockPosition blockposition1; + + for (int k = 1; k < 42; ++k) { + blockposition1 = blockposition.shift(enumdirection, k); + IBlockData iblockdata2 = world.getType(blockposition1); + + if (iblockdata2.getBlock() == Blocks.TRIPWIRE_HOOK) { + if (iblockdata2.get(BlockTripwireHook.FACING) == enumdirection.opposite()) { + j = k; + } + break; + } + + if (iblockdata2.getBlock() != Blocks.TRIPWIRE && k != i) { + aiblockdata[k] = null; + flag5 = false; + } else { + if (k == i) { + iblockdata2 = (IBlockData) Objects.firstNonNull(iblockdata1, iblockdata2); + } + + boolean flag7 = !((Boolean) iblockdata2.get(BlockTripwire.DISARMED)).booleanValue(); + boolean flag8 = ((Boolean) iblockdata2.get(BlockTripwire.POWERED)).booleanValue(); + boolean flag9 = ((Boolean) iblockdata2.get(BlockTripwire.SUSPENDED)).booleanValue(); + + flag5 &= flag9 == flag4; + flag6 |= flag7 && flag8; + aiblockdata[k] = iblockdata2; + if (k == i) { + world.a(blockposition, (Block) this, this.a(world)); + flag5 &= flag7; + } + } + } + + flag5 &= j > 1; + flag6 &= flag5; + IBlockData iblockdata3 = this.getBlockData().set(BlockTripwireHook.ATTACHED, Boolean.valueOf(flag5)).set(BlockTripwireHook.POWERED, Boolean.valueOf(flag6)); + + if (j > 0) { + blockposition1 = blockposition.shift(enumdirection, j); + EnumDirection enumdirection1 = enumdirection.opposite(); + + world.setTypeAndData(blockposition1, iblockdata3.set(BlockTripwireHook.FACING, enumdirection1), 3); + this.a(world, blockposition1, enumdirection1); + this.a(world, blockposition1, flag5, flag6, flag2, flag3); + } + + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); + world.getServer().getPluginManager().callEvent(eventRedstone); + + if (eventRedstone.getNewCurrent() > 0) { + return; + } + // CraftBukkit end + + this.a(world, blockposition, flag5, flag6, flag2, flag3); + if (!flag) { + world.setTypeAndData(blockposition, iblockdata3.set(BlockTripwireHook.FACING, enumdirection), 3); + if (flag1) { + this.a(world, blockposition, enumdirection); + } + } + + if (flag2 != flag5) { + for (int l = 1; l < j; ++l) { + BlockPosition blockposition2 = blockposition.shift(enumdirection, l); + IBlockData iblockdata4 = aiblockdata[l]; + + if (iblockdata4 != null && world.getType(blockposition2).getBlock() != Blocks.AIR) { + world.setTypeAndData(blockposition2, iblockdata4.set(BlockTripwireHook.ATTACHED, Boolean.valueOf(flag5)), 3); + } + } + } + + } + + public void a(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {} + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + this.a(world, blockposition, iblockdata, false, true, -1, (IBlockData) null); + } + + private void a(World world, BlockPosition blockposition, boolean flag, boolean flag1, boolean flag2, boolean flag3) { + if (flag1 && !flag3) { + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.1D, (double) blockposition.getZ() + 0.5D, "random.click", 0.4F, 0.6F); + } else if (!flag1 && flag3) { + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.1D, (double) blockposition.getZ() + 0.5D, "random.click", 0.4F, 0.5F); + } else if (flag && !flag2) { + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.1D, (double) blockposition.getZ() + 0.5D, "random.click", 0.4F, 0.7F); + } else if (!flag && flag2) { + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.1D, (double) blockposition.getZ() + 0.5D, "random.bowhit", 0.4F, 1.2F / (world.random.nextFloat() * 0.2F + 0.9F)); + } + + } + + private void a(World world, BlockPosition blockposition, EnumDirection enumdirection) { + world.applyPhysics(blockposition, this); + world.applyPhysics(blockposition.shift(enumdirection.opposite()), this); + } + + private boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + if (!this.canPlace(world, blockposition)) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + return false; + } else { + return true; + } + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + float f = 0.1875F; + + switch (BlockTripwireHook.SyntheticClass_1.a[((EnumDirection) iblockaccess.getType(blockposition).get(BlockTripwireHook.FACING)).ordinal()]) { + case 1: + this.a(0.0F, 0.2F, 0.5F - f, f * 2.0F, 0.8F, 0.5F + f); + break; + + case 2: + this.a(1.0F - f * 2.0F, 0.2F, 0.5F - f, 1.0F, 0.8F, 0.5F + f); + break; + + case 3: + this.a(0.5F - f, 0.2F, 0.0F, 0.5F + f, 0.8F, f * 2.0F); + break; + + case 4: + this.a(0.5F - f, 0.2F, 1.0F - f * 2.0F, 0.5F + f, 0.8F, 1.0F); + } + + } + + public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) { + boolean flag = ((Boolean) iblockdata.get(BlockTripwireHook.ATTACHED)).booleanValue(); + boolean flag1 = ((Boolean) iblockdata.get(BlockTripwireHook.POWERED)).booleanValue(); + + if (flag || flag1) { + this.a(world, blockposition, iblockdata, true, false, -1, (IBlockData) null); + } + + if (flag1) { + world.applyPhysics(blockposition, this); + world.applyPhysics(blockposition.shift(((EnumDirection) iblockdata.get(BlockTripwireHook.FACING)).opposite()), this); + } + + super.remove(world, blockposition, iblockdata); + } + + public int a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return ((Boolean) iblockdata.get(BlockTripwireHook.POWERED)).booleanValue() ? 15 : 0; + } + + public int b(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, EnumDirection enumdirection) { + return !((Boolean) iblockdata.get(BlockTripwireHook.POWERED)).booleanValue() ? 0 : (iblockdata.get(BlockTripwireHook.FACING) == enumdirection ? 15 : 0); + } + + public boolean isPowerSource() { + return true; + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockTripwireHook.FACING, EnumDirection.fromType2(i & 3)).set(BlockTripwireHook.POWERED, Boolean.valueOf((i & 8) > 0)).set(BlockTripwireHook.ATTACHED, Boolean.valueOf((i & 4) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + byte b0 = 0; + int i = b0 | ((EnumDirection) iblockdata.get(BlockTripwireHook.FACING)).b(); + + if (((Boolean) iblockdata.get(BlockTripwireHook.POWERED)).booleanValue()) { + i |= 8; + } + + if (((Boolean) iblockdata.get(BlockTripwireHook.ATTACHED)).booleanValue()) { + i |= 4; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockTripwireHook.FACING, BlockTripwireHook.POWERED, BlockTripwireHook.ATTACHED, BlockTripwireHook.SUSPENDED}); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + BlockTripwireHook.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockTripwireHook.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockTripwireHook.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockTripwireHook.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockVine.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockVine.java new file mode 100644 index 0000000..25d19c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/BlockVine.java @@ -0,0 +1,441 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Random; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class BlockVine extends Block { + + public static final BlockStateBoolean UP = BlockStateBoolean.of("up"); + public static final BlockStateBoolean NORTH = BlockStateBoolean.of("north"); + public static final BlockStateBoolean EAST = BlockStateBoolean.of("east"); + public static final BlockStateBoolean SOUTH = BlockStateBoolean.of("south"); + public static final BlockStateBoolean WEST = BlockStateBoolean.of("west"); + public static final BlockStateBoolean[] Q = new BlockStateBoolean[] { BlockVine.UP, BlockVine.NORTH, BlockVine.SOUTH, BlockVine.WEST, BlockVine.EAST}; + + public BlockVine() { + super(Material.REPLACEABLE_PLANT); + this.j(this.blockStateList.getBlockData().set(BlockVine.UP, Boolean.valueOf(false)).set(BlockVine.NORTH, Boolean.valueOf(false)).set(BlockVine.EAST, Boolean.valueOf(false)).set(BlockVine.SOUTH, Boolean.valueOf(false)).set(BlockVine.WEST, Boolean.valueOf(false))); + this.a(true); + this.a(CreativeModeTab.c); + } + + public IBlockData updateState(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) { + return iblockdata.set(BlockVine.UP, Boolean.valueOf(iblockaccess.getType(blockposition.up()).getBlock().u())); + } + + public void j() { + this.a(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F); + } + + public boolean c() { + return false; + } + + public boolean d() { + return false; + } + + public boolean a(World world, BlockPosition blockposition) { + return true; + } + + public void updateShape(IBlockAccess iblockaccess, BlockPosition blockposition) { + float f = 0.0625F; + float f1 = 1.0F; + float f2 = 1.0F; + float f3 = 1.0F; + float f4 = 0.0F; + float f5 = 0.0F; + float f6 = 0.0F; + boolean flag = false; + + if (((Boolean) iblockaccess.getType(blockposition).get(BlockVine.WEST)).booleanValue()) { + f4 = Math.max(f4, 0.0625F); + f1 = 0.0F; + f2 = 0.0F; + f5 = 1.0F; + f3 = 0.0F; + f6 = 1.0F; + flag = true; + } + + if (((Boolean) iblockaccess.getType(blockposition).get(BlockVine.EAST)).booleanValue()) { + f1 = Math.min(f1, 0.9375F); + f4 = 1.0F; + f2 = 0.0F; + f5 = 1.0F; + f3 = 0.0F; + f6 = 1.0F; + flag = true; + } + + if (((Boolean) iblockaccess.getType(blockposition).get(BlockVine.NORTH)).booleanValue()) { + f6 = Math.max(f6, 0.0625F); + f3 = 0.0F; + f1 = 0.0F; + f4 = 1.0F; + f2 = 0.0F; + f5 = 1.0F; + flag = true; + } + + if (((Boolean) iblockaccess.getType(blockposition).get(BlockVine.SOUTH)).booleanValue()) { + f3 = Math.min(f3, 0.9375F); + f6 = 1.0F; + f1 = 0.0F; + f4 = 1.0F; + f2 = 0.0F; + f5 = 1.0F; + flag = true; + } + + if (!flag && this.c(iblockaccess.getType(blockposition.up()).getBlock())) { + f2 = Math.min(f2, 0.9375F); + f5 = 1.0F; + f1 = 0.0F; + f4 = 1.0F; + f3 = 0.0F; + f6 = 1.0F; + } + + this.a(f1, f2, f3, f4, f5, f6); + } + + public AxisAlignedBB a(World world, BlockPosition blockposition, IBlockData iblockdata) { + return null; + } + + public boolean canPlace(World world, BlockPosition blockposition, EnumDirection enumdirection) { + switch (BlockVine.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + return this.c(world.getType(blockposition.up()).getBlock()); + + case 2: + case 3: + case 4: + case 5: + return this.c(world.getType(blockposition.shift(enumdirection.opposite())).getBlock()); + + default: + return false; + } + } + + private boolean c(Block block) { + return block.d() && block.material.isSolid(); + } + + private boolean e(World world, BlockPosition blockposition, IBlockData iblockdata) { + IBlockData iblockdata1 = iblockdata; + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + BlockStateBoolean blockstateboolean = getDirection(enumdirection); + + if (((Boolean) iblockdata.get(blockstateboolean)).booleanValue() && !this.c(world.getType(blockposition.shift(enumdirection)).getBlock())) { + IBlockData iblockdata2 = world.getType(blockposition.up()); + + if (iblockdata2.getBlock() != this || !((Boolean) iblockdata2.get(blockstateboolean)).booleanValue()) { + iblockdata = iblockdata.set(blockstateboolean, Boolean.valueOf(false)); + } + } + } + + if (d(iblockdata) == 0) { + return false; + } else { + if (iblockdata1 != iblockdata) { + world.setTypeAndData(blockposition, iblockdata, 2); + } + + return true; + } + } + + public void doPhysics(World world, BlockPosition blockposition, IBlockData iblockdata, Block block) { + if (!world.isClientSide && !this.e(world, blockposition, iblockdata)) { + this.b(world, blockposition, iblockdata, 0); + world.setAir(blockposition); + } + + } + + public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) { + if (!world.isClientSide) { + if (world.random.nextInt(4) == 0) { + byte b0 = 4; + int i = 5; + boolean flag = false; + + label188: + for (int j = -b0; j <= b0; ++j) { + for (int k = -b0; k <= b0; ++k) { + for (int l = -1; l <= 1; ++l) { + if (world.getType(blockposition.a(j, l, k)).getBlock() == this) { + --i; + if (i <= 0) { + flag = true; + break label188; + } + } + } + } + } + + EnumDirection enumdirection = EnumDirection.a(random); + BlockPosition blockposition1 = blockposition.up(); + EnumDirection enumdirection1; + + if (enumdirection == EnumDirection.UP && blockposition.getY() < 255 && world.isEmpty(blockposition1)) { + if (!flag) { + IBlockData iblockdata1 = iblockdata; + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + enumdirection1 = (EnumDirection) iterator.next(); + if (random.nextBoolean() || !this.c(world.getType(blockposition1.shift(enumdirection1)).getBlock())) { + iblockdata1 = iblockdata1.set(getDirection(enumdirection1), Boolean.valueOf(false)); + } + } + + if (((Boolean) iblockdata1.get(BlockVine.NORTH)).booleanValue() || ((Boolean) iblockdata1.get(BlockVine.EAST)).booleanValue() || ((Boolean) iblockdata1.get(BlockVine.SOUTH)).booleanValue() || ((Boolean) iblockdata1.get(BlockVine.WEST)).booleanValue()) { + // CraftBukkit start - Call BlockSpreadEvent + // world.setTypeAndData(blockposition1, iblockdata1, 2); + BlockPosition target = blockposition1; + org.bukkit.block.Block source = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block block = world.getWorld().getBlockAt(target.getX(), target.getY(), target.getZ()); + CraftEventFactory.handleBlockSpreadEvent(block, source, this, toLegacyData(iblockdata1)); + // CraftBukkit end + } + + } + } else { + BlockPosition blockposition2; + + if (enumdirection.k().c() && !((Boolean) iblockdata.get(getDirection(enumdirection))).booleanValue()) { + if (!flag) { + blockposition2 = blockposition.shift(enumdirection); + Block block = world.getType(blockposition2).getBlock(); + + if (block.material == Material.AIR) { + enumdirection1 = enumdirection.e(); + EnumDirection enumdirection2 = enumdirection.f(); + boolean flag1 = ((Boolean) iblockdata.get(getDirection(enumdirection1))).booleanValue(); + boolean flag2 = ((Boolean) iblockdata.get(getDirection(enumdirection2))).booleanValue(); + BlockPosition blockposition3 = blockposition2.shift(enumdirection1); + BlockPosition blockposition4 = blockposition2.shift(enumdirection2); + + // CraftBukkit start - Call BlockSpreadEvent + org.bukkit.block.Block source = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()); + + if (flag1 && this.c(world.getType(blockposition3).getBlock())) { + // world.setTypeAndData(blockposition2, this.getBlockData().set(a(enumdirection1), Boolean.valueOf(true)), 2); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData().set(getDirection(enumdirection1), Boolean.valueOf(true)))); + } else if (flag2 && this.c(world.getType(blockposition4).getBlock())) { + // world.setTypeAndData(blockposition2, this.getBlockData().set(a(enumdirection2), Boolean.valueOf(true)), 2); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData().set(getDirection(enumdirection2), Boolean.valueOf(true)))); + } else if (flag1 && world.isEmpty(blockposition3) && this.c(world.getType(blockposition.shift(enumdirection1)).getBlock())) { + // world.setTypeAndData(blockposition3, this.getBlockData().set(a(enumdirection.opposite()), Boolean.valueOf(true)), 2); + bukkitBlock = world.getWorld().getBlockAt(blockposition3.getX(), blockposition3.getY(), blockposition3.getZ()); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData().set(getDirection(enumdirection.opposite()), Boolean.valueOf(true)))); + } else if (flag2 && world.isEmpty(blockposition4) && this.c(world.getType(blockposition.shift(enumdirection2)).getBlock())) { + // world.setTypeAndData(blockposition4, this.getBlockData().set(a(enumdirection.opposite()), Boolean.valueOf(true)), 2); + bukkitBlock = world.getWorld().getBlockAt(blockposition4.getX(), blockposition4.getY(), blockposition4.getZ()); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData().set(getDirection(enumdirection.opposite()), Boolean.valueOf(true)))); + } else if (this.c(world.getType(blockposition2.up()).getBlock())) { + // world.setTypeAndData(blockposition2, this.getBlockData(), 2); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(this.getBlockData())); + } + // CraftBukkit end + } else if (block.material.k() && block.d()) { + world.setTypeAndData(blockposition, iblockdata.set(getDirection(enumdirection), Boolean.valueOf(true)), 2); + } + + } + } else { + if (blockposition.getY() > 1) { + blockposition2 = blockposition.down(); + IBlockData iblockdata2 = world.getType(blockposition2); + Block block1 = iblockdata2.getBlock(); + IBlockData iblockdata3; + Iterator iterator1; + EnumDirection enumdirection3; + + if (block1.material == Material.AIR) { + iblockdata3 = iblockdata; + iterator1 = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator1.hasNext()) { + enumdirection3 = (EnumDirection) iterator1.next(); + if (random.nextBoolean()) { + iblockdata3 = iblockdata3.set(getDirection(enumdirection3), Boolean.valueOf(false)); + } + } + + if (((Boolean) iblockdata3.get(BlockVine.NORTH)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.EAST)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.SOUTH)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.WEST)).booleanValue()) { + // CraftBukkit start - Call BlockSpreadEvent + // world.setTypeAndData(blockposition2, iblockdata3, 2); + org.bukkit.block.Block source = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(blockposition2.getX(), blockposition2.getY(), blockposition2.getZ()); + CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, toLegacyData(iblockdata3)); + // CraftBukkit end + } + } else if (block1 == this) { + iblockdata3 = iblockdata2; + iterator1 = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator1.hasNext()) { + enumdirection3 = (EnumDirection) iterator1.next(); + BlockStateBoolean blockstateboolean = getDirection(enumdirection3); + + if (random.nextBoolean() && ((Boolean) iblockdata.get(blockstateboolean)).booleanValue()) { + iblockdata3 = iblockdata3.set(blockstateboolean, Boolean.valueOf(true)); + } + } + + if (((Boolean) iblockdata3.get(BlockVine.NORTH)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.EAST)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.SOUTH)).booleanValue() || ((Boolean) iblockdata3.get(BlockVine.WEST)).booleanValue()) { + world.setTypeAndData(blockposition2, iblockdata3, 2); + } + } + } + + } + } + } + } + } + + public IBlockData getPlacedState(World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2, int i, EntityLiving entityliving) { + IBlockData iblockdata = this.getBlockData().set(BlockVine.UP, Boolean.valueOf(false)).set(BlockVine.NORTH, Boolean.valueOf(false)).set(BlockVine.EAST, Boolean.valueOf(false)).set(BlockVine.SOUTH, Boolean.valueOf(false)).set(BlockVine.WEST, Boolean.valueOf(false)); + + return enumdirection.k().c() ? iblockdata.set(getDirection(enumdirection.opposite()), Boolean.valueOf(true)) : iblockdata; + } + + public Item getDropType(IBlockData iblockdata, Random random, int i) { + return null; + } + + public int a(Random random) { + return 0; + } + + public void a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, TileEntity tileentity) { + if (!world.isClientSide && entityhuman.bZ() != null && entityhuman.bZ().getItem() == Items.SHEARS) { + entityhuman.b(StatisticList.MINE_BLOCK_COUNT[Block.getId(this)]); + a(world, blockposition, new ItemStack(Blocks.VINE, 1, 0)); + } else { + super.a(world, entityhuman, blockposition, iblockdata, tileentity); + } + + } + + public IBlockData fromLegacyData(int i) { + return this.getBlockData().set(BlockVine.SOUTH, Boolean.valueOf((i & 1) > 0)).set(BlockVine.WEST, Boolean.valueOf((i & 2) > 0)).set(BlockVine.NORTH, Boolean.valueOf((i & 4) > 0)).set(BlockVine.EAST, Boolean.valueOf((i & 8) > 0)); + } + + public int toLegacyData(IBlockData iblockdata) { + int i = 0; + + if (((Boolean) iblockdata.get(BlockVine.SOUTH)).booleanValue()) { + i |= 1; + } + + if (((Boolean) iblockdata.get(BlockVine.WEST)).booleanValue()) { + i |= 2; + } + + if (((Boolean) iblockdata.get(BlockVine.NORTH)).booleanValue()) { + i |= 4; + } + + if (((Boolean) iblockdata.get(BlockVine.EAST)).booleanValue()) { + i |= 8; + } + + return i; + } + + protected BlockStateList getStateList() { + return new BlockStateList(this, new IBlockState[] { BlockVine.UP, BlockVine.NORTH, BlockVine.EAST, BlockVine.SOUTH, BlockVine.WEST}); + } + + public static BlockStateBoolean getDirection(EnumDirection enumdirection) { + switch (BlockVine.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + return BlockVine.UP; + + case 2: + return BlockVine.NORTH; + + case 3: + return BlockVine.SOUTH; + + case 4: + return BlockVine.EAST; + + case 5: + return BlockVine.WEST; + + default: + throw new IllegalArgumentException(enumdirection + " is an invalid choice"); + } + } + + public static int d(IBlockData iblockdata) { + int i = 0; + BlockStateBoolean[] ablockstateboolean = BlockVine.Q; + int j = ablockstateboolean.length; + + for (int k = 0; k < j; ++k) { + BlockStateBoolean blockstateboolean = ablockstateboolean[k]; + + if (((Boolean) iblockdata.get(blockstateboolean)).booleanValue()) { + ++i; + } + } + + return i; + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + BlockVine.SyntheticClass_1.a[EnumDirection.UP.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + BlockVine.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + BlockVine.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + BlockVine.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + try { + BlockVine.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror4) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChatBaseComponent.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChatBaseComponent.java new file mode 100644 index 0000000..dc496c2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChatBaseComponent.java @@ -0,0 +1,120 @@ +package net.minecraft.server; + +import com.google.common.base.Function; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; + +public abstract class ChatBaseComponent implements IChatBaseComponent { + + protected List a = Lists.newArrayList(); + private ChatModifier b; + + public ChatBaseComponent() {} + + public IChatBaseComponent addSibling(IChatBaseComponent ichatbasecomponent) { + ichatbasecomponent.getChatModifier().setChatModifier(this.getChatModifier()); + this.a.add(ichatbasecomponent); + return this; + } + + public List a() { + return this.a; + } + + public IChatBaseComponent a(String s) { + return this.addSibling(new ChatComponentText(s)); + } + + public IChatBaseComponent setChatModifier(ChatModifier chatmodifier) { + this.b = chatmodifier; + Iterator iterator = this.a.iterator(); + + while (iterator.hasNext()) { + IChatBaseComponent ichatbasecomponent = (IChatBaseComponent) iterator.next(); + + ichatbasecomponent.getChatModifier().setChatModifier(this.getChatModifier()); + } + + return this; + } + + public ChatModifier getChatModifier() { + if (this.b == null) { + this.b = new ChatModifier(); + Iterator iterator = this.a.iterator(); + + while (iterator.hasNext()) { + IChatBaseComponent ichatbasecomponent = (IChatBaseComponent) iterator.next(); + + ichatbasecomponent.getChatModifier().setChatModifier(this.b); + } + } + + return this.b; + } + + public Iterator iterator() { + return Iterators.concat(Iterators.forArray(new ChatBaseComponent[] { this}), a((Iterable) this.a)); + } + + public final String c() { + StringBuilder stringbuilder = new StringBuilder(); + Iterator iterator = this.iterator(); + + while (iterator.hasNext()) { + IChatBaseComponent ichatbasecomponent = (IChatBaseComponent) iterator.next(); + + stringbuilder.append(ichatbasecomponent.getText()); + } + + return stringbuilder.toString(); + } + + public static Iterator a(Iterable iterable) { + Iterator iterator = Iterators.concat(Iterators.transform(iterable.iterator(), new Function() { + public Iterator a(IChatBaseComponent ichatbasecomponent) { + return ichatbasecomponent.iterator(); + } + + public Object apply(Object object) { + return this.a((IChatBaseComponent) object); + } + })); + + iterator = Iterators.transform(iterator, new Function() { + public IChatBaseComponent a(IChatBaseComponent ichatbasecomponent) { + IChatBaseComponent ichatbasecomponent1 = ichatbasecomponent.f(); + + ichatbasecomponent1.setChatModifier(ichatbasecomponent1.getChatModifier().n()); + return ichatbasecomponent1; + } + + public Object apply(Object object) { + return this.a((IChatBaseComponent) object); + } + }); + return iterator; + } + + public boolean equals(Object object) { + if (this == object) { + return true; + } else if (!(object instanceof ChatBaseComponent)) { + return false; + } else { + ChatBaseComponent chatbasecomponent = (ChatBaseComponent) object; + + return this.a.equals(chatbasecomponent.a) && this.getChatModifier().equals(chatbasecomponent.getChatModifier()); + } + } + + public int hashCode() { + return 31 * this.getChatModifier().hashCode() + this.a.hashCode(); // CraftBukkit - fix null pointer + } + + public String toString() { + return "BaseComponent{style=" + this.b + ", siblings=" + this.a + '}'; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChatModifier.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChatModifier.java new file mode 100644 index 0000000..21f7e6b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChatModifier.java @@ -0,0 +1,442 @@ +package net.minecraft.server; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.lang.reflect.Type; + +public class ChatModifier { + + private ChatModifier a; + private EnumChatFormat b; + private Boolean c; + private Boolean d; + private Boolean e; + private Boolean f; + private Boolean g; + private ChatClickable h; + private ChatHoverable i; + private String j; + private static final ChatModifier k = new ChatModifier() { + public EnumChatFormat getColor() { + return null; + } + + public boolean isBold() { + return false; + } + + public boolean isItalic() { + return false; + } + + public boolean isStrikethrough() { + return false; + } + + public boolean isUnderlined() { + return false; + } + + public boolean isRandom() { + return false; + } + + public ChatClickable h() { + return null; + } + + public ChatHoverable i() { + return null; + } + + public String j() { + return null; + } + + public ChatModifier setColor(EnumChatFormat enumchatformat) { + throw new UnsupportedOperationException(); + } + + public ChatModifier setBold(Boolean obool) { + throw new UnsupportedOperationException(); + } + + public ChatModifier setItalic(Boolean obool) { + throw new UnsupportedOperationException(); + } + + public ChatModifier setStrikethrough(Boolean obool) { + throw new UnsupportedOperationException(); + } + + public ChatModifier setUnderline(Boolean obool) { + throw new UnsupportedOperationException(); + } + + public ChatModifier setRandom(Boolean obool) { + throw new UnsupportedOperationException(); + } + + public ChatModifier setChatClickable(ChatClickable chatclickable) { + throw new UnsupportedOperationException(); + } + + public ChatModifier setChatHoverable(ChatHoverable chathoverable) { + throw new UnsupportedOperationException(); + } + + public ChatModifier setChatModifier(ChatModifier chatmodifier) { + throw new UnsupportedOperationException(); + } + + public String toString() { + return "Style.ROOT"; + } + + public ChatModifier clone() { + return this; + } + + public ChatModifier n() { + return this; + } + }; + + public ChatModifier() {} + + public EnumChatFormat getColor() { + return this.b == null ? this.o().getColor() : this.b; + } + + public boolean isBold() { + return this.c == null ? this.o().isBold() : this.c.booleanValue(); + } + + public boolean isItalic() { + return this.d == null ? this.o().isItalic() : this.d.booleanValue(); + } + + public boolean isStrikethrough() { + return this.f == null ? this.o().isStrikethrough() : this.f.booleanValue(); + } + + public boolean isUnderlined() { + return this.e == null ? this.o().isUnderlined() : this.e.booleanValue(); + } + + public boolean isRandom() { + return this.g == null ? this.o().isRandom() : this.g.booleanValue(); + } + + public boolean g() { + return this.c == null && this.d == null && this.f == null && this.e == null && this.g == null && this.b == null && this.h == null && this.i == null; + } + + public ChatClickable h() { + return this.h == null ? this.o().h() : this.h; + } + + public ChatHoverable i() { + return this.i == null ? this.o().i() : this.i; + } + + public String j() { + return this.j == null ? this.o().j() : this.j; + } + + public ChatModifier setColor(EnumChatFormat enumchatformat) { + this.b = enumchatformat; + return this; + } + + public ChatModifier setBold(Boolean obool) { + this.c = obool; + return this; + } + + public ChatModifier setItalic(Boolean obool) { + this.d = obool; + return this; + } + + public ChatModifier setStrikethrough(Boolean obool) { + this.f = obool; + return this; + } + + public ChatModifier setUnderline(Boolean obool) { + this.e = obool; + return this; + } + + public ChatModifier setRandom(Boolean obool) { + this.g = obool; + return this; + } + + public ChatModifier setChatClickable(ChatClickable chatclickable) { + this.h = chatclickable; + return this; + } + + public ChatModifier setChatHoverable(ChatHoverable chathoverable) { + this.i = chathoverable; + return this; + } + + public ChatModifier setInsertion(String s) { + this.j = s; + return this; + } + + public ChatModifier setChatModifier(ChatModifier chatmodifier) { + this.a = chatmodifier; + return this; + } + + private ChatModifier o() { + return this.a == null ? ChatModifier.k : this.a; + } + + public String toString() { + return "Style{hasParent=" + (this.a != null) + ", color=" + this.b + ", bold=" + this.c + ", italic=" + this.d + ", underlined=" + this.e + ", obfuscated=" + this.g + ", clickEvent=" + this.h() + ", hoverEvent=" + this.i() + ", insertion=" + this.j() + '}'; + } + + public boolean equals(Object object) { + if (this == object) { + return true; + } else if (!(object instanceof ChatModifier)) { + return false; + } else { + ChatModifier chatmodifier = (ChatModifier) object; + boolean flag; + + if (this.isBold() == chatmodifier.isBold() && this.getColor() == chatmodifier.getColor() && this.isItalic() == chatmodifier.isItalic() && this.isRandom() == chatmodifier.isRandom() && this.isStrikethrough() == chatmodifier.isStrikethrough() && this.isUnderlined() == chatmodifier.isUnderlined()) { + label65: { + if (this.h() != null) { + if (!this.h().equals(chatmodifier.h())) { + break label65; + } + } else if (chatmodifier.h() != null) { + break label65; + } + + if (this.i() != null) { + if (!this.i().equals(chatmodifier.i())) { + break label65; + } + } else if (chatmodifier.i() != null) { + break label65; + } + + if (this.j() != null) { + if (!this.j().equals(chatmodifier.j())) { + break label65; + } + } else if (chatmodifier.j() != null) { + break label65; + } + + flag = true; + return flag; + } + } + + flag = false; + return flag; + } + } + + public int hashCode() { + // CraftBukkit start - fix npe + int i = b == null ? 0 : this.b.hashCode(); + + i = 31 * i + (c == null ? 0 : this.c.hashCode()); + i = 31 * i + (d == null ? 0 : this.d.hashCode()); + i = 31 * i + (e == null ? 0 : this.e.hashCode()); + i = 31 * i + (f == null ? 0 : this.f.hashCode()); + i = 31 * i + (g == null ? 0 : this.g.hashCode()); + i = 31 * i + (h == null ? 0 : this.h.hashCode()); + i = 31 * i + (this.i == null ? 0 : this.i.hashCode()); + i = 31 * i + (j == null ? 0 : this.j.hashCode()); + // CraftBukkit end + return i; + } + + public ChatModifier clone() { + ChatModifier chatmodifier = new ChatModifier(); + + chatmodifier.c = this.c; + chatmodifier.d = this.d; + chatmodifier.f = this.f; + chatmodifier.e = this.e; + chatmodifier.g = this.g; + chatmodifier.b = this.b; + chatmodifier.h = this.h; + chatmodifier.i = this.i; + chatmodifier.a = this.a; + chatmodifier.j = this.j; + return chatmodifier; + } + + public ChatModifier n() { + ChatModifier chatmodifier = new ChatModifier(); + + chatmodifier.setBold(Boolean.valueOf(this.isBold())); + chatmodifier.setItalic(Boolean.valueOf(this.isItalic())); + chatmodifier.setStrikethrough(Boolean.valueOf(this.isStrikethrough())); + chatmodifier.setUnderline(Boolean.valueOf(this.isUnderlined())); + chatmodifier.setRandom(Boolean.valueOf(this.isRandom())); + chatmodifier.setColor(this.getColor()); + chatmodifier.setChatClickable(this.h()); + chatmodifier.setChatHoverable(this.i()); + chatmodifier.setInsertion(this.j()); + return chatmodifier; + } + + public static class ChatModifierSerializer implements JsonDeserializer, JsonSerializer { + + public ChatModifierSerializer() {} + + public ChatModifier a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { + if (jsonelement.isJsonObject()) { + ChatModifier chatmodifier = new ChatModifier(); + JsonObject jsonobject = jsonelement.getAsJsonObject(); + + if (jsonobject == null) { + return null; + } else { + if (jsonobject.has("bold")) { + chatmodifier.c = Boolean.valueOf(jsonobject.get("bold").getAsBoolean()); + } + + if (jsonobject.has("italic")) { + chatmodifier.d = Boolean.valueOf(jsonobject.get("italic").getAsBoolean()); + } + + if (jsonobject.has("underlined")) { + chatmodifier.e = Boolean.valueOf(jsonobject.get("underlined").getAsBoolean()); + } + + if (jsonobject.has("strikethrough")) { + chatmodifier.f = Boolean.valueOf(jsonobject.get("strikethrough").getAsBoolean()); + } + + if (jsonobject.has("obfuscated")) { + chatmodifier.g = Boolean.valueOf(jsonobject.get("obfuscated").getAsBoolean()); + } + + if (jsonobject.has("color")) { + chatmodifier.b = (EnumChatFormat) jsondeserializationcontext.deserialize(jsonobject.get("color"), EnumChatFormat.class); + } + + if (jsonobject.has("insertion")) { + chatmodifier.j = jsonobject.get("insertion").getAsString(); + } + + JsonObject jsonobject1; + JsonPrimitive jsonprimitive; + + if (jsonobject.has("clickEvent")) { + jsonobject1 = jsonobject.getAsJsonObject("clickEvent"); + if (jsonobject1 != null) { + jsonprimitive = jsonobject1.getAsJsonPrimitive("action"); + ChatClickable.EnumClickAction chatclickable_enumclickaction = jsonprimitive == null ? null : ChatClickable.EnumClickAction.a(jsonprimitive.getAsString()); + JsonPrimitive jsonprimitive1 = jsonobject1.getAsJsonPrimitive("value"); + String s = jsonprimitive1 == null ? null : jsonprimitive1.getAsString(); + + if (chatclickable_enumclickaction != null && s != null && chatclickable_enumclickaction.a()) { + chatmodifier.h = new ChatClickable(chatclickable_enumclickaction, s); + } + } + } + + if (jsonobject.has("hoverEvent")) { + jsonobject1 = jsonobject.getAsJsonObject("hoverEvent"); + if (jsonobject1 != null) { + jsonprimitive = jsonobject1.getAsJsonPrimitive("action"); + ChatHoverable.EnumHoverAction chathoverable_enumhoveraction = jsonprimitive == null ? null : ChatHoverable.EnumHoverAction.a(jsonprimitive.getAsString()); + IChatBaseComponent ichatbasecomponent = (IChatBaseComponent) jsondeserializationcontext.deserialize(jsonobject1.get("value"), IChatBaseComponent.class); + + if (chathoverable_enumhoveraction != null && ichatbasecomponent != null && chathoverable_enumhoveraction.a()) { + chatmodifier.i = new ChatHoverable(chathoverable_enumhoveraction, ichatbasecomponent); + } + } + } + + return chatmodifier; + } + } else { + return null; + } + } + + public JsonElement a(ChatModifier chatmodifier, Type type, JsonSerializationContext jsonserializationcontext) { + if (chatmodifier.g()) { + return null; + } else { + JsonObject jsonobject = new JsonObject(); + + if (chatmodifier.c != null) { + jsonobject.addProperty("bold", chatmodifier.c); + } + + if (chatmodifier.d != null) { + jsonobject.addProperty("italic", chatmodifier.d); + } + + if (chatmodifier.e != null) { + jsonobject.addProperty("underlined", chatmodifier.e); + } + + if (chatmodifier.f != null) { + jsonobject.addProperty("strikethrough", chatmodifier.f); + } + + if (chatmodifier.g != null) { + jsonobject.addProperty("obfuscated", chatmodifier.g); + } + + if (chatmodifier.b != null) { + jsonobject.add("color", jsonserializationcontext.serialize(chatmodifier.b)); + } + + if (chatmodifier.j != null) { + jsonobject.add("insertion", jsonserializationcontext.serialize(chatmodifier.j)); + } + + JsonObject jsonobject1; + + if (chatmodifier.h != null) { + jsonobject1 = new JsonObject(); + jsonobject1.addProperty("action", chatmodifier.h.a().b()); + jsonobject1.addProperty("value", chatmodifier.h.b()); + jsonobject.add("clickEvent", jsonobject1); + } + + if (chatmodifier.i != null) { + jsonobject1 = new JsonObject(); + jsonobject1.addProperty("action", chatmodifier.i.a().b()); + jsonobject1.add("value", jsonserializationcontext.serialize(chatmodifier.i.b())); + jsonobject.add("hoverEvent", jsonobject1); + } + + return jsonobject; + } + } + + public JsonElement serialize(ChatModifier object, Type type, JsonSerializationContext jsonserializationcontext) { // CraftBukkit - fix decompile error + return this.a((ChatModifier) object, type, jsonserializationcontext); + } + + public ChatModifier deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { // CraftBukkit - fix decompile error + return this.a(jsonelement, type, jsondeserializationcontext); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Chunk.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Chunk.java new file mode 100644 index 0000000..d579a42 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Chunk.java @@ -0,0 +1,1515 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Queues; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import me.levansj01.mythicspigot.limiter.TickLimiter; +import net.jafama.FastMath; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Bukkit; + +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; + +public class Chunk { + + private static final Logger c = LogManager.getLogger(); + private final ChunkSection[] sections; + private final byte[] e; + private final int[] f; + private final boolean[] g; + private boolean h; + public final World world; + public final int[] heightMap; + public final long chunkKey; + public final int locX; + public final int locZ; + private boolean k; + public final Map tileEntities; + public final List[] entitySlices; // Spigot + // PaperSpigot start - track the number of minecarts and items + // Keep this synced with entitySlices.add() and entitySlices.remove() + private final int[] itemCounts = new int[16]; + private final int[] inventoryEntityCounts = new int[16]; + // PaperSpigot end + private boolean done; + private boolean lit; + private boolean p; + private boolean q; + private boolean r; + private long lastSaved; + private int t; + private long u; + private int v; + private final ConcurrentLinkedQueue w; + protected gnu.trove.map.hash.TObjectIntHashMap entityCount = new gnu.trove.map.hash.TObjectIntHashMap(); // Spigot + // PaperSpigot start - Asynchronous light updates + public AtomicInteger pendingLightUpdates = new AtomicInteger(); + public long lightUpdateTime; + // PaperSpigot end + + // PaperSpigot start - ChunkMap caching + private PacketPlayOutMapChunk.ChunkMap chunkMap; + private int emptySectionBits; + + public final TickLimiter physics = new TickLimiter(() -> MythicConfiguration.Options.World.Physics.Limits.ticks, () -> MythicConfiguration.Options.World.Physics.Limits.amount); + + public PacketPlayOutMapChunk.ChunkMap getChunkMap(boolean groundUpContinuous, int primaryBitMask) { + if (!world.paperSpigotConfig.cacheChunkMaps || !groundUpContinuous || (primaryBitMask != 0 && primaryBitMask != '\uffff')) { + return PacketPlayOutMapChunk.a(this, groundUpContinuous, !world.worldProvider.o(), primaryBitMask); + } + + if (primaryBitMask == 0) { + PacketPlayOutMapChunk.ChunkMap chunkMap = new PacketPlayOutMapChunk.ChunkMap(); + chunkMap.a = new byte[0]; + return chunkMap; + } + + boolean isDirty = false; + for (int i = 0; i < sections.length; ++i) { + ChunkSection section = sections[i]; + if (section == null) { + if ((emptySectionBits & (1 << i)) == 0) { + isDirty = true; + emptySectionBits |= (1 << i); + } + } else { + if ((emptySectionBits & (1 << i)) == 1) { + isDirty = true; + emptySectionBits &= ~(1 << i); + section.isDirty = false; + } else if (section.isDirty) { + isDirty = true; + section.isDirty = false; + } + } + } + + if (isDirty || chunkMap == null) { + chunkMap = PacketPlayOutMapChunk.a(this, true, !world.worldProvider.o(), '\uffff'); + } + + return chunkMap; + } + // PaperSpigot end + + // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking + private int neighbors = 0x1 << 12; + + public boolean areNeighborsLoaded(final int radius) { + switch (radius) { + case 2: + return this.neighbors == Integer.MAX_VALUE >> 6; + case 1: + final int mask = + // x z offset x z offset x z offset + (0x1 << (1 * 5 + 1 + 12)) | (0x1 << (0 * 5 + 1 + 12)) | (0x1 << (-1 * 5 + 1 + 12)) | + (0x1 << (1 * 5 + 0 + 12)) | (0x1 << (0 * 5 + 0 + 12)) | (0x1 << (-1 * 5 + 0 + 12)) | + (0x1 << (1 * 5 + -1 + 12)) | (0x1 << (0 * 5 + -1 + 12)) | (0x1 << (-1 * 5 + -1 + 12)); + return (this.neighbors & mask) == mask; + default: + throw new UnsupportedOperationException(String.valueOf(radius)); + } + } + + public void setNeighborLoaded(final int x, final int z) { + this.neighbors |= 0x1 << (x * 5 + 12 + z); + } + + public void setNeighborUnloaded(final int x, final int z) { + this.neighbors &= ~(0x1 << (x * 5 + 12 + z)); + } + // CraftBukkit end + + public Chunk(World world, int i, int j) { + this.sections = new ChunkSection[16]; + this.e = new byte[256]; + this.f = new int[256]; + this.g = new boolean[256]; + this.tileEntities = Maps.newHashMap(); + this.v = 4096; + this.w = Queues.newConcurrentLinkedQueue(); + this.entitySlices = (List[]) (new List[16]); // Spigot + this.world = world; + this.locX = i; + this.locZ = j; + this.chunkKey = org.bukkit.craftbukkit.util.LongHash.toLong(this.locX, this.locZ); + this.heightMap = new int[256]; + + for (int k = 0; k < this.entitySlices.length; ++k) { + this.entitySlices[k] = new org.bukkit.craftbukkit.util.UnsafeList(); // Spigot + } + + Arrays.fill(this.f, -999); + Arrays.fill(this.e, (byte) -1); + + // CraftBukkit start + if (!(this instanceof EmptyChunk)) { + this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); + } + } + + public org.bukkit.Chunk bukkitChunk; + public boolean mustSave; + // CraftBukkit end + + public Chunk(World world, ChunkSnapshot chunksnapshot, int i, int j) { + this(world, i, j); + short short0 = 256; + boolean flag = !world.worldProvider.o(); + + for (int k = 0; k < 16; ++k) { + for (int l = 0; l < 16; ++l) { + for (int i1 = 0; i1 < short0; ++i1) { + int j1 = k * short0 * 16 | l * short0 | i1; + IBlockData iblockdata = chunksnapshot.a(j1); + + if (iblockdata.getBlock().getMaterial() != Material.AIR) { + int k1 = i1 >> 4; + + if (this.sections[k1] == null) { + this.sections[k1] = new ChunkSection(k1 << 4, flag); + } + + this.sections[k1].setType(k, i1 & 15, l, iblockdata); + } + } + } + } + + } + + public boolean a(int i, int j) { + return i == this.locX && j == this.locZ; + } + + public int f(BlockPosition blockposition) { + return this.b(blockposition.getX() & 15, blockposition.getZ() & 15); + } + + public int b(int i, int j) { + return this.heightMap[j << 4 | i]; + } + + public int g() { + for (int i = this.sections.length - 1; i >= 0; --i) { + if (this.sections[i] != null) { + return this.sections[i].getYPosition(); + } + } + + return 0; + } + + public ChunkSection[] getSections() { + return this.sections; + } + + public void initLighting() { + int i = this.g(); + + this.t = Integer.MAX_VALUE; + + for (int j = 0; j < 16; ++j) { + int k = 0; + + while (k < 16) { + this.f[j + (k << 4)] = -999; + int l = i + 16; + + while (true) { + if (l > 0) { + if (this.e(j, l - 1, k) == 0) { + --l; + continue; + } + + this.heightMap[k << 4 | j] = l; + if (l < this.t) { + this.t = l; + } + } + + if (!this.world.worldProvider.o()) { + l = 15; + int i1 = i + 16 - 1; + + do { + int j1 = this.e(j, i1, k); + + if (j1 == 0 && l != 15) { + j1 = 1; + } + + l -= j1; + if (l > 0) { + ChunkSection chunksection = this.sections[i1 >> 4]; + + if (chunksection != null) { + chunksection.a(j, i1 & 15, k, l); + this.world.n(new BlockPosition((this.locX << 4) + j, i1, (this.locZ << 4) + k)); + } + } + + --i1; + } while (i1 > 0 && l > 0); + } + + ++k; + break; + } + } + } + + this.q = true; + } + + private void d(int i, int j) { + this.g[i + j * 16] = true; + this.k = true; + } + + private void h(boolean flag) { + this.world.methodProfiler.a("recheckGaps"); + if (this.world.areChunksLoaded(this.locX * 16 + 8, 0, this.locZ * 16 + 8, 16)) { + for (int i = 0; i < 16; ++i) { + for (int j = 0; j < 16; ++j) { + if (this.g[i + j * 16]) { + this.g[i + j * 16] = false; + int k = this.b(i, j); + int l = this.locX * 16 + i; + int i1 = this.locZ * 16 + j; + int j1 = Integer.MAX_VALUE; + + Iterator iterator; + EnumDirection enumdirection; + + for (iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); iterator.hasNext(); j1 = FastMath.min(j1, this.world.b(l + enumdirection.getAdjacentX(), i1 + enumdirection.getAdjacentZ()))) { + enumdirection = (EnumDirection) iterator.next(); + } + + this.c(l, i1, j1); + iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + enumdirection = (EnumDirection) iterator.next(); + this.c(l + enumdirection.getAdjacentX(), i1 + enumdirection.getAdjacentZ(), k); + } + + if (flag) { + this.world.methodProfiler.b(); + return; + } + } + } + } + + this.k = false; + } + + this.world.methodProfiler.b(); + } + + private void c(int i, int j, int k) { + int l = this.world.getHighestBlockYAt(i, j); + + if (l > k) { + this.a(i, j, k, l + 1); + } else if (l < k) { + this.a(i, j, l, k + 1); + } + + } + + private void a(int i, int j, int k, int l) { + if (l > k && this.world.areChunksLoaded(i, 0, j, 16)) { + for (int i1 = k; i1 < l; ++i1) { + this.world.updateLight(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); // PaperSpigot - Asynchronous lighting updates + } + + this.q = true; + } + + } + + private void d(int i, int j, int k) { + int l = this.heightMap[k << 4 | i] & 255; + int i1 = l; + + if (j > l) { + i1 = j; + } + + while (i1 > 0 && this.e(i, i1 - 1, k) == 0) { + --i1; + } + + if (i1 != l) { + this.world.a(i + this.locX * 16, k + this.locZ * 16, i1, l); + this.heightMap[k << 4 | i] = i1; + int j1 = this.locX * 16 + i; + int k1 = this.locZ * 16 + k; + int l1; + int i2; + + if (!this.world.worldProvider.o()) { + ChunkSection chunksection; + + if (i1 < l) { + for (l1 = i1; l1 < l; ++l1) { + chunksection = this.sections[l1 >> 4]; + if (chunksection != null) { + chunksection.a(i, l1 & 15, k, 15); + this.world.n(new BlockPosition((this.locX << 4) + i, l1, (this.locZ << 4) + k)); + } + } + } else { + for (l1 = l; l1 < i1; ++l1) { + chunksection = this.sections[l1 >> 4]; + if (chunksection != null) { + chunksection.a(i, l1 & 15, k, 0); + this.world.n(new BlockPosition((this.locX << 4) + i, l1, (this.locZ << 4) + k)); + } + } + } + + l1 = 15; + + while (i1 > 0 && l1 > 0) { + --i1; + i2 = this.e(i, i1, k); + if (i2 == 0) { + i2 = 1; + } + + l1 -= i2; + if (l1 < 0) { + l1 = 0; + } + + ChunkSection chunksection1 = this.sections[i1 >> 4]; + + if (chunksection1 != null) { + chunksection1.a(i, i1 & 15, k, l1); + } + } + } + + l1 = this.heightMap[k << 4 | i]; + i2 = l; + int j2 = l1; + + if (l1 < l) { + i2 = l1; + j2 = l; + } + + if (l1 < this.t) { + this.t = l1; + } + + if (!this.world.worldProvider.o()) { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + + this.a(j1 + enumdirection.getAdjacentX(), k1 + enumdirection.getAdjacentZ(), i2, j2); + } + + this.a(j1, k1, i2, j2); + } + + this.q = true; + } + } + + public int b(BlockPosition blockposition) { + return this.getType(blockposition).p(); + } + + private int e(int i, int j, int k) { + return this.getType(i, j, k).p(); + } + + private Block getType(int i, int j, int k) { + Block block = Blocks.AIR; + + if (j >= 0 && j >> 4 < this.sections.length) { + ChunkSection chunksection = this.sections[j >> 4]; + + if (chunksection != null) { + try { + block = chunksection.b(i, j & 15, k); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Getting block"); + + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + } + + return block; + } + + public Block getTypeAbs(final int i, final int j, final int k) { + try { + return this.getType(i & 15, j, k & 15); + } catch (ReportedException reportedexception) { + CrashReportSystemDetails crashreportsystemdetails = reportedexception.a().a("Block being got"); + + crashreportsystemdetails.a("Location", new Callable() { + public String a() throws Exception { + return CrashReportSystemDetails.a(new BlockPosition(Chunk.this.locX * 16 + i, j, Chunk.this.locZ * 16 + k)); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", reportedexception); + return Blocks.AIR; + } + throw reportedexception; + } + } + + public Block getType(final BlockPosition blockposition) { + return getTypeNew(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } + + // Mythic - Reduce churn rate + public Block getTypeNew(int x, int y, int z) { + try { + return this.getType(x & 15, y, z & 15); + } catch (ReportedException reportedexception) { + CrashReportSystemDetails crashreportsystemdetails = reportedexception.a().a("Block being got"); + + crashreportsystemdetails.a("Location", new Callable() { + public String a() throws Exception { + return CrashReportSystemDetails.a(new BlockPosition(x, y, z)); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", reportedexception); + return Blocks.AIR; + } + throw reportedexception; + } + } + + public IBlockData getBlockData(final BlockPosition blockposition) { + return getBlockData(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } + + // Mythic - Reduce churn rate + // PaperSpigot start - Optimize getBlockData + public IBlockData getBlockData(int x, int y, int z) { + if (y >= 0 && y >> 4 < this.sections.length) { + ChunkSection chunksection = this.sections[y >> 4]; + if (chunksection != null) { + return chunksection.getType(x & 15, y & 15, z & 15); + } + } + return Blocks.AIR.getBlockData(); + } + public IBlockData getBlockDataSlow(final BlockPosition blockposition) { + // PaperSpigot end + if (this.world.G() == WorldType.DEBUG_ALL_BLOCK_STATES) { + IBlockData iblockdata = null; + + if (blockposition.getY() == 60) { + iblockdata = Blocks.BARRIER.getBlockData(); + } + + if (blockposition.getY() == 70) { + iblockdata = ChunkProviderDebug.b(blockposition.getX(), blockposition.getZ()); + } + + return iblockdata == null ? Blocks.AIR.getBlockData() : iblockdata; + } else { + try { + if (blockposition.getY() >= 0 && blockposition.getY() >> 4 < this.sections.length) { + ChunkSection chunksection = this.sections[blockposition.getY() >> 4]; + + if (chunksection != null) { + int i = blockposition.getX() & 15; + int j = blockposition.getY() & 15; + int k = blockposition.getZ() & 15; + + return chunksection.getType(i, j, k); + } + } + + return Blocks.AIR.getBlockData(); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Getting block state"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being got"); + + crashreportsystemdetails.a("Location", new Callable() { + public String a() throws Exception { + return CrashReportSystemDetails.a(blockposition); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + return Blocks.AIR.getBlockData(); + } + throw new ReportedException(crashreport); + } + } + } + + private int g(int i, int j, int k) { + if (j >> 4 >= this.sections.length) { + return 0; + } else { + ChunkSection chunksection = this.sections[j >> 4]; + + return chunksection != null ? chunksection.c(i, j & 15, k) : 0; + } + } + + public int c(BlockPosition blockposition) { + return this.g(blockposition.getX() & 15, blockposition.getY(), blockposition.getZ() & 15); + } + + public IBlockData a(BlockPosition blockposition, IBlockData iblockdata) { + int i = blockposition.getX() & 15; + int j = blockposition.getY(); + int k = blockposition.getZ() & 15; + int l = k << 4 | i; + + if (j >= this.f[l] - 1) { + this.f[l] = -999; + } + + int i1 = this.heightMap[l]; + IBlockData iblockdata1 = this.getBlockData(blockposition); + + if (iblockdata1 == iblockdata) { + return null; + } else { + Block block = iblockdata.getBlock(); + Block block1 = iblockdata1.getBlock(); + ChunkSection chunksection = this.sections[j >> 4]; + boolean flag = false; + + if (chunksection == null) { + if (block == Blocks.AIR) { + return null; + } + + chunksection = this.sections[j >> 4] = new ChunkSection(j >> 4 << 4, !this.world.worldProvider.o()); + flag = j >= i1; + } + + chunksection.setType(i, j & 15, k, iblockdata); + if (block1 != block) { + if (!this.world.isClientSide) { + block1.remove(this.world, blockposition, iblockdata1); + } else if (block1 instanceof IContainer) { + this.world.t(blockposition); + } + } + + if (chunksection.b(i, j & 15, k) != block) { + return null; + } else { + if (flag) { + this.initLighting(); + } else { + int j1 = block.p(); + int k1 = block1.p(); + + if (j1 > 0) { + if (j >= i1) { + this.d(i, j + 1, k); + } + } else if (j == i1 - 1) { + this.d(i, j, k); + } + + if (j1 != k1 && (j1 < k1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) { + this.d(i, k); + } + } + + TileEntity tileentity; + + if (block1 instanceof IContainer) { + tileentity = this.a(blockposition, Chunk.EnumTileEntityState.CHECK); + if (tileentity != null) { + tileentity.E(); + } + } + + // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. + if (!this.world.isClientSide && block1 != block && (!this.world.captureBlockStates || block instanceof BlockContainer)) { + block.onPlace(this.world, blockposition, iblockdata); + } + + if (block instanceof IContainer) { + tileentity = this.a(blockposition, Chunk.EnumTileEntityState.CHECK); + if (tileentity == null) { + tileentity = ((IContainer) block).a(this.world, block.toLegacyData(iblockdata)); + this.world.setTileEntity(blockposition, tileentity); + } + + if (tileentity != null) { + tileentity.E(); + } + } + + this.q = true; + return iblockdata1; + } + } + } + + public int getBrightness(EnumSkyBlock enumskyblock, BlockPosition blockposition) { + int i = blockposition.getX() & 15; + int j = blockposition.getY(); + int k = blockposition.getZ() & 15; + ChunkSection chunksection = this.sections[j >> 4]; + + 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 void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { + int j = blockposition.getX() & 15; + int k = blockposition.getY(); + int l = blockposition.getZ() & 15; + ChunkSection chunksection = this.sections[k >> 4]; + + if (chunksection == null) { + chunksection = this.sections[k >> 4] = new ChunkSection(k >> 4 << 4, !this.world.worldProvider.o()); + this.initLighting(); + } + + this.q = true; + if (enumskyblock == EnumSkyBlock.SKY) { + if (!this.world.worldProvider.o()) { + chunksection.a(j, k & 15, l, i); + } + } else if (enumskyblock == EnumSkyBlock.BLOCK) { + chunksection.b(j, k & 15, l, i); + } + + } + + public int a(BlockPosition blockposition, int i) { + return aNew(blockposition.getX(), blockposition.getY(), blockposition.getZ(), i); + } + + // Mythic - Reduce churn rate + public int aNew(int x, int y, int z, int i) { + int j = x & 15; + int k = y; + int l = z & 15; + ChunkSection chunksection = this.sections[k >> 4]; + + if (chunksection == null) { + return !this.world.worldProvider.o() && i < EnumSkyBlock.SKY.c ? EnumSkyBlock.SKY.c - i : 0; + } else { + int i1 = this.world.worldProvider.o() ? 0 : chunksection.d(j, k & 15, l); + + i1 -= i; + int j1 = chunksection.e(j, k & 15, l); + + if (j1 > i1) { + i1 = j1; + } + + return i1; + } + } + + public void a(Entity entity) { + this.r = true; + int i = MathHelper.floor(entity.locX / 16.0D); + int j = MathHelper.floor(entity.locZ / 16.0D); + + if (i != this.locX || j != this.locZ) { + // CraftBukkit start + Bukkit.getLogger().warning("Wrong location for " + entity + " in world '" + world.getWorld().getName() + "'!"); + // Chunk.c.warn("Wrong location! (" + i + ", " + j + ") should be (" + this.locX + ", " + this.locZ + "), " + entity, new Object[] { entity}); + Bukkit.getLogger().warning("Entity is at " + entity.locX + "," + entity.locZ + " (chunk " + i + "," + j + ") but was stored in chunk " + this.locX + "," + this.locZ); + // CraftBukkit end + entity.die(); + } + + int k = MathHelper.floor(entity.locY / 16.0D); + + if (k < 0) { + k = 0; + } + + if (k >= this.entitySlices.length) { + k = this.entitySlices.length - 1; + } + + entity.ad = true; + entity.ae = this.locX; + entity.af = k; + entity.ag = this.locZ; + this.entitySlices[k].add(entity); + // PaperSpigot start - update counts + if (entity instanceof EntityItem) { + itemCounts[k]++; + } else if (entity instanceof IInventory) { + inventoryEntityCounts[k]++; + } + // PaperSpigot end + // Spigot start - increment creature type count + // Keep this synced up with World.a(Class) + if (entity instanceof EntityInsentient) { + EntityInsentient entityinsentient = (EntityInsentient) entity; + if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { + return; + } + } + for ( EnumCreatureType creatureType : EnumCreatureType.values() ) + { + if ( creatureType.a().isAssignableFrom( entity.getClass() ) ) + { + this.entityCount.adjustOrPutValue( creatureType.a(), 1, 1 ); + } + } + // Spigot end + } + + public void b(Entity entity) { + this.a(entity, entity.af); + } + + public void a(Entity entity, int i) { + if (i < 0) { + i = 0; + } + + if (i >= this.entitySlices.length) { + i = this.entitySlices.length - 1; + } + + if (!this.entitySlices[i].remove(entity)) return; // TacoSpigot + // PaperSpigot start - update counts + if (entity instanceof EntityItem) { + itemCounts[i]--; + } else if (entity instanceof IInventory) { + inventoryEntityCounts[i]--; + } + // PaperSpigot end + // Spigot start - decrement creature type count + // Keep this synced up with World.a(Class) + if (entity instanceof EntityInsentient) { + EntityInsentient entityinsentient = (EntityInsentient) entity; + if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { + return; + } + } + for ( EnumCreatureType creatureType : EnumCreatureType.values() ) + { + if ( creatureType.a().isAssignableFrom( entity.getClass() ) ) + { + this.entityCount.adjustValue( creatureType.a(), -1 ); + } + } + // Spigot end + } + + public boolean d(BlockPosition blockposition) { + int i = blockposition.getX() & 15; + int j = blockposition.getY(); + int k = blockposition.getZ() & 15; + + return j >= this.heightMap[k << 4 | i]; + } + + private TileEntity i(BlockPosition blockposition) { + Block block = this.getType(blockposition); + + return !block.isTileEntity() ? null : ((IContainer) block).a(this.world, this.c(blockposition)); + } + + public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) { + // CraftBukkit start + TileEntity tileentity = null; + if (world.captureBlockStates) { + tileentity = world.capturedTileEntities.get(blockposition); + } + if (tileentity == null) { + tileentity = this.tileEntities.get(blockposition); + } + // CraftBukkit end + + if (tileentity == null) { + if (chunk_enumtileentitystate == Chunk.EnumTileEntityState.IMMEDIATE) { + tileentity = this.i(blockposition); + this.world.setTileEntity(blockposition, tileentity); + } else if (chunk_enumtileentitystate == Chunk.EnumTileEntityState.QUEUED) { + this.w.add(blockposition); + } + } else if (tileentity.x()) { + this.tileEntities.remove(blockposition); + return null; + } + + return tileentity; + } + + public void a(TileEntity tileentity) { + this.a(tileentity.getPosition(), tileentity); + if (this.h) { + this.world.a(tileentity); + } + + } + + public void a(BlockPosition blockposition, TileEntity tileentity) { + tileentity.a(this.world); + tileentity.a(blockposition); + if (this.getType(blockposition) instanceof IContainer) { + if (this.tileEntities.containsKey(blockposition)) { + this.tileEntities.get(blockposition).y(); + } + + tileentity.D(); + this.tileEntities.put(blockposition, tileentity); + // CraftBukkit start + // PaperSpigot start - Remove invalid mob spawner tile entities + } else if (this.world.paperSpigotConfig.removeInvalidMobSpawnerTEs && tileentity instanceof TileEntityMobSpawner && + org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(getType(blockposition)) != org.bukkit.Material.MOB_SPAWNER) { + this.tileEntities.remove(blockposition); + // PaperSpigot end + } else { + System.out.println("Attempted to place a tile entity (" + tileentity + ") at " + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ() + + " (" + org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(getType(blockposition)) + ") where there was no entity tile!"); + System.out.println("Chunk coordinates: " + (this.locX * 16) + "," + (this.locZ * 16)); + new Exception().printStackTrace(); + // CraftBukkit end + } + } + + public void e(BlockPosition blockposition) { + if (this.h) { + TileEntity tileentity = this.tileEntities.remove(blockposition); + + if (tileentity != null) { + tileentity.y(); + } + } + + } + + public void addEntities() { + this.h = true; + this.world.a(this.tileEntities.values()); + + for (int i = 0; i < this.entitySlices.length; ++i) { + Iterator iterator = this.entitySlices[i].iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + entity.ah(); + } + + this.world.b(this.entitySlices[i]); + } + + } + + public void removeEntities() { + this.h = false; + Iterator iterator = this.tileEntities.values().iterator(); + + while (iterator.hasNext()) { + TileEntity tileentity = (TileEntity) iterator.next(); + // Spigot Start + if ( tileentity instanceof IInventory ) + { + for ( org.bukkit.entity.HumanEntity h : Lists.newArrayList(( (IInventory) tileentity ).getViewers()) ) + { + if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity ) + { + ( (org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeInventory(); + } + } + } + // Spigot End + + this.world.b(tileentity); + } + + for (int i = 0; i < this.entitySlices.length; ++i) { + // CraftBukkit start + List newList = Lists.newArrayList(this.entitySlices[i]); + java.util.Iterator iter = newList.iterator(); + while (iter.hasNext()) { + Entity entity = iter.next(); + // Spigot Start + if ( entity instanceof IInventory ) + { + for ( org.bukkit.entity.HumanEntity h : Lists.newArrayList(( (IInventory) entity ).getViewers()) ) + { + if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity ) + { + ( (org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeInventory(); + } + } + } + // Spigot End + + // Do not pass along players, as doing so can get them stuck outside of time. + // (which for example disables inventory icon updates and prevents block breaking) + if (entity instanceof EntityPlayer) { + iter.remove(); + } + } + + this.world.c(newList); + // CraftBukkit end + } + + } + + public void e() { + this.q = true; + } + + public void a(Entity entity, AxisAlignedBB axisalignedbb, List list, Predicate predicate) { + int i = MathHelper.floor((axisalignedbb.b - 2.0D) / 16.0D); + int j = MathHelper.floor((axisalignedbb.e + 2.0D) / 16.0D); + + i = MathHelper.clamp(i, 0, this.entitySlices.length - 1); + j = MathHelper.clamp(j, 0, this.entitySlices.length - 1); + + for (int k = i; k <= j; ++k) { + if (!this.entitySlices[k].isEmpty()) { + Iterator iterator = this.entitySlices[k].iterator(); + // PaperSpigot start - Don't search for inventories if we have none, and that is all we want + /* + * We check if they want inventories by seeing if it is the static `IEntitySelector.c` + * + * Make sure the inventory selector stays in sync. + * It should be the one that checks `var1 instanceof IInventory && var1.isAlive()` + */ + if (predicate == IEntitySelector.c && inventoryEntityCounts[k] <= 0) continue; + // PaperSpigot end + while (iterator.hasNext()) { + Entity entity1 = (Entity) iterator.next(); + + if (entity1.getBoundingBox().b(axisalignedbb) && entity1 != entity) { + if (predicate == null || predicate.apply(entity1)) { + list.add(entity1); + } + + Entity[] aentity = entity1.aB(); + + if (aentity != null) { + for (int l = 0; l < aentity.length; ++l) { + entity1 = aentity[l]; + if (entity1 != entity && entity1.getBoundingBox().b(axisalignedbb) && (predicate == null || predicate.apply(entity1))) { + list.add(entity1); + } + } + } + } + } + } + } + + } + + public void a(Class oclass, AxisAlignedBB axisalignedbb, List list, Predicate predicate) { + int i = MathHelper.floor((axisalignedbb.b - 2.0D) / 16.0D); + int j = MathHelper.floor((axisalignedbb.e + 2.0D) / 16.0D); + + i = MathHelper.clamp(i, 0, this.entitySlices.length - 1); + j = MathHelper.clamp(j, 0, this.entitySlices.length - 1); + + // PaperSpigot start + int[] counts; + if (ItemStack.class.isAssignableFrom(oclass)) { + counts = itemCounts; + } else if (IInventory.class.isAssignableFrom(oclass)) { + counts = inventoryEntityCounts; + } else { + counts = null; + } + // PaperSpigot end + for (int k = i; k <= j; ++k) { + if (counts != null && counts[k] <= 0) continue; // PaperSpigot - Don't check a chunk if it doesn't have the type we are looking for + Iterator iterator = this.entitySlices[k].iterator(); // Spigot + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (oclass.isInstance(entity) && entity.getBoundingBox().b(axisalignedbb) && (predicate == null || predicate.apply((T) entity))) { // CraftBukkit - fix decompile error // Spigot + list.add((T) entity); // Fix decompile error + } + } + } + + } + + public boolean a(boolean flag) { + if (flag) { + if (this.r && this.world.getTime() != this.lastSaved || this.q) { + return true; + } + } else if (this.r && this.world.getTime() >= this.lastSaved + MinecraftServer.getServer().autosavePeriod * 4) { // Spigot - Only save if we've passed 2 auto save intervals without modification + return true; + } + + return this.q; + } + + public Random a(long i) { + return new Random(this.world.getSeed() + (long) (this.locX * this.locX * 4987142) + (long) (this.locX * 5947611) + (long) (this.locZ * this.locZ) * 4392871L + (long) (this.locZ * 389711) ^ i); + } + + public boolean isEmpty() { + return false; + } + + public void loadNearby(IChunkProvider ichunkprovider, IChunkProvider ichunkprovider1, int i, int j) { + world.timings.syncChunkLoadPostTimer.startTiming(); // Spigot + boolean flag = ichunkprovider.isChunkLoaded(i, j - 1); + boolean flag1 = ichunkprovider.isChunkLoaded(i + 1, j); + boolean flag2 = ichunkprovider.isChunkLoaded(i, j + 1); + boolean flag3 = ichunkprovider.isChunkLoaded(i - 1, j); + boolean flag4 = ichunkprovider.isChunkLoaded(i - 1, j - 1); + boolean flag5 = ichunkprovider.isChunkLoaded(i + 1, j + 1); + boolean flag6 = ichunkprovider.isChunkLoaded(i - 1, j + 1); + boolean flag7 = ichunkprovider.isChunkLoaded(i + 1, j - 1); + + if (flag1 && flag2 && flag5) { + if (!this.done) { + ichunkprovider.getChunkAt(ichunkprovider1, i, j); + } else { + ichunkprovider.a(ichunkprovider1, this, i, j); + } + } + + Chunk chunk; + + if (flag3 && flag2 && flag6) { + chunk = ichunkprovider.getOrCreateChunk(i - 1, j); + if (!chunk.done) { + ichunkprovider.getChunkAt(ichunkprovider1, i - 1, j); + } else { + ichunkprovider.a(ichunkprovider1, chunk, i - 1, j); + } + } + + if (flag && flag1 && flag7) { + chunk = ichunkprovider.getOrCreateChunk(i, j - 1); + if (!chunk.done) { + ichunkprovider.getChunkAt(ichunkprovider1, i, j - 1); + } else { + ichunkprovider.a(ichunkprovider1, chunk, i, j - 1); + } + } + + if (flag4 && flag && flag3) { + chunk = ichunkprovider.getOrCreateChunk(i - 1, j - 1); + if (!chunk.done) { + ichunkprovider.getChunkAt(ichunkprovider1, i - 1, j - 1); + } else { + ichunkprovider.a(ichunkprovider1, chunk, i - 1, j - 1); + } + } + + world.timings.syncChunkLoadPostTimer.stopTiming(); // Spigot + } + + public BlockPosition h(BlockPosition blockposition) { + int i = blockposition.getX() & 15; + int j = blockposition.getZ() & 15; + int k = i | j << 4; + BlockPosition blockposition1 = new BlockPosition(blockposition.getX(), this.f[k], blockposition.getZ()); + + if (blockposition1.getY() == -999) { + int l = this.g() + 15; + + blockposition1 = new BlockPosition(blockposition.getX(), l, blockposition.getZ()); + int i1 = -1; + + while (blockposition1.getY() > 0 && i1 == -1) { + Block block = this.getType(blockposition1); + Material material = block.getMaterial(); + + if (!material.isSolid() && !material.isLiquid()) { + blockposition1 = blockposition1.down(); + } else { + i1 = blockposition1.getY() + 1; + } + } + + this.f[k] = i1; + } + + return new BlockPosition(blockposition.getX(), this.f[k], blockposition.getZ()); + } + + public void b(boolean flag) { + if (this.k && !this.world.worldProvider.o() && !flag) { + this.recheckGaps(this.world.isClientSide); // PaperSpigot - Asynchronous lighting updates + } + + this.p = true; + if (!this.lit && this.done && this.world.spigotConfig.randomLightUpdates) { // Spigot - also use random light updates setting to determine if we should relight + this.n(); + } + + while (!this.w.isEmpty()) { + BlockPosition blockposition = this.w.poll(); + + if (this.a(blockposition, Chunk.EnumTileEntityState.CHECK) == null && this.getType(blockposition).isTileEntity()) { + TileEntity tileentity = this.i(blockposition); + + this.world.setTileEntity(blockposition, tileentity); + this.world.b(blockposition, blockposition); + } + } + + } + + /** + * PaperSpigot - Recheck gaps asynchronously. + */ + public void recheckGaps(final boolean isClientSide) { + if (!world.paperSpigotConfig.useAsyncLighting) { + this.h(isClientSide); + return; + } + + world.lightingExecutor.submit(new Runnable() { + @Override + public void run() { + Chunk.this.h(isClientSide); + } + }); + } + + public boolean isReady() { + // Spigot Start + /* + * As of 1.7, Mojang added a check to make sure that only chunks which have been lit are sent to the client. + * Unfortunately this interferes with our modified chunk ticking algorithm, which will only tick chunks distant from the player on a very infrequent basis. + * We cannot unfortunately do this lighting stage during chunk gen as it appears to put a lot more noticeable load on the server, than when it is done at play time. + * For now at least we will simply send all chunks, in accordance with pre 1.7 behaviour. + */ + return true; + // Spigot End + } + + public ChunkCoordIntPair j() { + return new ChunkCoordIntPair(this.locX, this.locZ); + } + + public boolean c(int i, int j) { + if (i < 0) { + i = 0; + } + + if (j >= 256) { + j = 255; + } + + for (int k = i; k <= j; k += 16) { + ChunkSection chunksection = this.sections[k >> 4]; + + if (chunksection != null && !chunksection.a()) { + return false; + } + } + + return true; + } + + public void a(ChunkSection[] achunksection) { + if (this.sections.length != achunksection.length) { + Chunk.c.warn("Could not set level chunk sections, array length is " + achunksection.length + " instead of " + this.sections.length); + } else { + for (int i = 0; i < this.sections.length; ++i) { + this.sections[i] = achunksection[i]; + } + + } + } + + public BiomeBase getBiome(BlockPosition blockposition, WorldChunkManager worldchunkmanager) { + int i = blockposition.getX() & 15; + int j = blockposition.getZ() & 15; + int k = this.e[j << 4 | i] & 255; + BiomeBase biomebase; + + if (k == 255) { + biomebase = worldchunkmanager.getBiome(blockposition, BiomeBase.PLAINS); + k = biomebase.id; + this.e[j << 4 | i] = (byte) (k & 255); + } + + biomebase = BiomeBase.getBiome(k); + return biomebase == null ? BiomeBase.PLAINS : biomebase; + } + + public byte[] getBiomeIndex() { + return this.e; + } + + public void a(byte[] abyte) { + if (this.e.length != abyte.length) { + Chunk.c.warn("Could not set level chunk biomes, array length is " + abyte.length + " instead of " + this.e.length); + } else { + for (int i = 0; i < this.e.length; ++i) { + this.e[i] = abyte[i]; + } + + } + } + + public void l() { + this.v = 0; + } + + public void m() { + BlockPosition blockposition = new BlockPosition(this.locX << 4, 0, this.locZ << 4); + + for (int i = 0; i < 8; ++i) { + if (this.v >= 4096) { + return; + } + + int j = this.v % 16; + int k = this.v / 16 % 16; + int l = this.v / 256; + + ++this.v; + + for (int i1 = 0; i1 < 16; ++i1) { + BlockPosition blockposition1 = blockposition.a(k, (j << 4) + i1, l); + boolean flag = i1 == 0 || i1 == 15 || k == 0 || k == 15 || l == 0 || l == 15; + + if (this.sections[j] == null && flag || this.sections[j] != null && this.sections[j].b(k, i1, l).getMaterial() == Material.AIR) { + EnumDirection[] aenumdirection = EnumDirection.values(); + int j1 = aenumdirection.length; + + for (int k1 = 0; k1 < j1; ++k1) { + EnumDirection enumdirection = aenumdirection[k1]; + BlockPosition blockposition2 = blockposition1.shift(enumdirection); + + if (this.world.getType(blockposition2).getBlock().r() > 0) { + this.world.x(blockposition2); + } + } + + this.world.x(blockposition1); + } + } + } + + } + + public void n() { + this.done = true; + this.lit = true; + BlockPosition blockposition = new BlockPosition(this.locX << 4, 0, this.locZ << 4); + + if (!this.world.worldProvider.o()) { + if (this.world.areChunksLoadedBetween(blockposition.a(-1, 0, -1), blockposition.a(16, this.world.F(), 16))) { + label42: + for (int i = 0; i < 16; ++i) { + for (int j = 0; j < 16; ++j) { + if (!this.e(i, j)) { + this.lit = false; + break label42; + } + } + } + + if (this.lit) { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + int k = enumdirection.c() == EnumDirection.EnumAxisDirection.POSITIVE ? 16 : 1; + + this.world.getChunkAtWorldCoords(blockposition.shift(enumdirection, k)).a(enumdirection.opposite()); + } + + this.y(); + } + } else { + this.lit = false; + } + } + + } + + private void y() { + for (int i = 0; i < this.g.length; ++i) { + this.g[i] = true; + } + + this.h(false); + } + + private void a(EnumDirection enumdirection) { + if (this.done) { + int i; + + if (enumdirection == EnumDirection.EAST) { + for (i = 0; i < 16; ++i) { + this.e(15, i); + } + } else if (enumdirection == EnumDirection.WEST) { + for (i = 0; i < 16; ++i) { + this.e(0, i); + } + } else if (enumdirection == EnumDirection.SOUTH) { + for (i = 0; i < 16; ++i) { + this.e(i, 15); + } + } else if (enumdirection == EnumDirection.NORTH) { + for (i = 0; i < 16; ++i) { + this.e(i, 0); + } + } + + } + } + + private boolean e(int i, int j) { + int k = this.g(); + boolean flag = false; + boolean flag1 = false; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition((this.locX << 4) + i, 0, (this.locZ << 4) + j); + + int l; + + for (l = k + 16 - 1; l > this.world.F() || l > 0 && !flag1; --l) { + blockposition_mutableblockposition.c(blockposition_mutableblockposition.getX(), l, blockposition_mutableblockposition.getZ()); + int i1 = this.b(blockposition_mutableblockposition); + + if (i1 == 255 && blockposition_mutableblockposition.getY() < this.world.F()) { + flag1 = true; + } + + if (!flag && i1 > 0) { + flag = true; + } else if (flag && i1 == 0 && !this.world.x(blockposition_mutableblockposition)) { + return false; + } + } + + for (l = blockposition_mutableblockposition.getY(); l > 0; --l) { + blockposition_mutableblockposition.c(blockposition_mutableblockposition.getX(), l, blockposition_mutableblockposition.getZ()); + if (this.getType(blockposition_mutableblockposition).r() > 0) { + this.world.x(blockposition_mutableblockposition); + } + } + + return true; + } + + public boolean o() { + return this.h; + } + + public World getWorld() { + return this.world; + } + + public int[] q() { + return this.heightMap; + } + + public void a(int[] aint) { + if (this.heightMap.length != aint.length) { + Chunk.c.warn("Could not set level chunk heightmap, array length is " + aint.length + " instead of " + this.heightMap.length); + } else { + for (int i = 0; i < this.heightMap.length; ++i) { + this.heightMap[i] = aint[i]; + } + + } + } + + public Map getTileEntities() { + return this.tileEntities; + } + + public List[] getEntitySlices() { + return this.entitySlices; + } + + public boolean isDone() { + return this.done; + } + + public void d(boolean flag) { + this.done = flag; + } + + public boolean u() { + return this.lit; + } + + public void e(boolean flag) { + this.lit = flag; + } + + public void f(boolean flag) { + this.q = flag; + } + + public void g(boolean flag) { + this.r = flag; + } + + public void setLastSaved(long i) { + this.lastSaved = i; + } + + public int v() { + return this.t; + } + + public long w() { + return this.u; + } + + public void c(long i) { + this.u = i; + } + + public enum EnumTileEntityState { + + IMMEDIATE, QUEUED, CHECK; + + EnumTileEntityState() {} + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderFlat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderFlat.java new file mode 100644 index 0000000..b939f47 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderFlat.java @@ -0,0 +1,244 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class ChunkProviderFlat implements IChunkProvider { + + private World a; + private Random b; + private final IBlockData[] c = new IBlockData[256]; + private final WorldGenFlatInfo d; + private final List e = Lists.newArrayList(); + private final boolean f; + private final boolean g; + private WorldGenLakes h; + private WorldGenLakes i; + + public ChunkProviderFlat(World world, long i, boolean flag, String s) { + this.a = world; + this.b = new Random(i); + this.d = WorldGenFlatInfo.a(s); + if (flag) { + Map map = this.d.b(); + + if (map.containsKey("village") && world.paperSpigotConfig.generateVillage) { // PaperSpigot + Map map1 = (Map) map.get("village"); + + if (!map1.containsKey("size")) { + map1.put("size", "1"); + } + + this.e.add(new WorldGenVillage(map1)); + } + + if (map.containsKey("biome_1") && world.paperSpigotConfig.generateTemple) { // PaperSpigot + this.e.add(new WorldGenLargeFeature((Map) map.get("biome_1"))); + } + + if (map.containsKey("mineshaft") && world.paperSpigotConfig.generateMineshaft) { // PaperSpigot + this.e.add(new WorldGenMineshaft((Map) map.get("mineshaft"))); + } + + if (map.containsKey("stronghold") && world.paperSpigotConfig.generateStronghold) { // PaperSpigot + this.e.add(new WorldGenStronghold((Map) map.get("stronghold"))); + } + + if (map.containsKey("oceanmonument") && world.paperSpigotConfig.generateMonument) { // PaperSpigot + this.e.add(new WorldGenMonument((Map) map.get("oceanmonument"))); + } + } + + if (this.d.b().containsKey("lake")) { + this.h = new WorldGenLakes(Blocks.WATER); + } + + if (this.d.b().containsKey("lava_lake")) { + this.i = new WorldGenLakes(Blocks.LAVA); + } + + this.g = world.paperSpigotConfig.generateDungeon && this.d.b().containsKey("dungeon"); // PaperSpigot + int j = 0; + int k = 0; + boolean flag1 = true; + Iterator iterator = this.d.c().iterator(); + + while (iterator.hasNext()) { + WorldGenFlatLayerInfo worldgenflatlayerinfo = (WorldGenFlatLayerInfo) iterator.next(); + + for (int l = worldgenflatlayerinfo.d(); l < worldgenflatlayerinfo.d() + worldgenflatlayerinfo.b(); ++l) { + IBlockData iblockdata = worldgenflatlayerinfo.c(); + + if (iblockdata.getBlock() != Blocks.AIR) { + flag1 = false; + this.c[l] = iblockdata; + } + } + + if (worldgenflatlayerinfo.c().getBlock() == Blocks.AIR) { + k += worldgenflatlayerinfo.b(); + } else { + j += worldgenflatlayerinfo.b() + k; + k = 0; + } + } + + world.b(j); + this.f = flag1 ? false : this.d.b().containsKey("decoration"); + } + + public Chunk getOrCreateChunk(int i, int j) { + ChunkSnapshot chunksnapshot = new ChunkSnapshot(); + + int k; + + for (int l = 0; l < this.c.length; ++l) { + IBlockData iblockdata = this.c[l]; + + if (iblockdata != null) { + for (int i1 = 0; i1 < 16; ++i1) { + for (k = 0; k < 16; ++k) { + chunksnapshot.a(i1, l, k, iblockdata); + } + } + } + } + + Iterator iterator = this.e.iterator(); + + while (iterator.hasNext()) { + WorldGenBase worldgenbase = (WorldGenBase) iterator.next(); + + worldgenbase.a(this, this.a, i, j, chunksnapshot); + } + + Chunk chunk = new Chunk(this.a, chunksnapshot, i, j); + BiomeBase[] abiomebase = this.a.getWorldChunkManager().getBiomeBlock((BiomeBase[]) null, i * 16, j * 16, 16, 16); + byte[] abyte = chunk.getBiomeIndex(); + + for (k = 0; k < abyte.length; ++k) { + abyte[k] = (byte) abiomebase[k].id; + } + + chunk.initLighting(); + return chunk; + } + + public boolean isChunkLoaded(int i, int j) { + return true; + } + + public void getChunkAt(IChunkProvider ichunkprovider, int i, int j) { + int k = i * 16; + int l = j * 16; + BlockPosition blockposition = new BlockPosition(k, 0, l); + BiomeBase biomebase = this.a.getBiome(new BlockPosition(k + 16, 0, l + 16)); + boolean flag = false; + + this.b.setSeed(this.a.getSeed()); + long i1 = this.b.nextLong() / 2L * 2L + 1L; + long j1 = this.b.nextLong() / 2L * 2L + 1L; + + this.b.setSeed((long) i * i1 + (long) j * j1 ^ this.a.getSeed()); + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + Iterator iterator = this.e.iterator(); + + while (iterator.hasNext()) { + StructureGenerator structuregenerator = (StructureGenerator) iterator.next(); + boolean flag1 = structuregenerator.a(this.a, this.b, chunkcoordintpair); + + if (structuregenerator instanceof WorldGenVillage) { + flag |= flag1; + } + } + + if (this.h != null && !flag && this.b.nextInt(4) == 0) { + this.h.generate(this.a, this.b, blockposition.a(this.b.nextInt(16) + 8, this.b.nextInt(256), this.b.nextInt(16) + 8)); + } + + if (this.i != null && !flag && this.b.nextInt(8) == 0) { + BlockPosition blockposition1 = blockposition.a(this.b.nextInt(16) + 8, this.b.nextInt(this.b.nextInt(248) + 8), this.b.nextInt(16) + 8); + + if (blockposition1.getY() < this.a.F() || this.b.nextInt(10) == 0) { + this.i.generate(this.a, this.b, blockposition1); + } + } + + if (this.g) { + for (int k1 = 0; k1 < 8; ++k1) { + (new WorldGenDungeons()).generate(this.a, this.b, blockposition.a(this.b.nextInt(16) + 8, this.b.nextInt(256), this.b.nextInt(16) + 8)); + } + } + + if (this.f) { + biomebase.a(this.a, this.b, blockposition); + } + + } + + public boolean a(IChunkProvider ichunkprovider, Chunk chunk, int i, int j) { + return false; + } + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) { + return true; + } + + public void c() {} + + public boolean unloadChunks() { + return false; + } + + public boolean canSave() { + return true; + } + + public String getName() { + return "FlatLevelSource"; + } + + public List getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { + BiomeBase biomebase = this.a.getBiome(blockposition); + + return biomebase.getMobs(enumcreaturetype); + } + + public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition) { + if ("Stronghold".equals(s)) { + Iterator iterator = this.e.iterator(); + + while (iterator.hasNext()) { + StructureGenerator structuregenerator = (StructureGenerator) iterator.next(); + + if (structuregenerator instanceof WorldGenStronghold) { + return structuregenerator.getNearestGeneratedFeature(world, blockposition); + } + } + } + + return null; + } + + public int getLoadedChunks() { + return 0; + } + + public void recreateStructures(Chunk chunk, int i, int j) { + Iterator iterator = this.e.iterator(); + + while (iterator.hasNext()) { + StructureGenerator structuregenerator = (StructureGenerator) iterator.next(); + + structuregenerator.a(this, this.a, i, j, (ChunkSnapshot) null); + } + + } + + public Chunk getChunkAt(BlockPosition blockposition) { + return this.getOrCreateChunk(blockposition.getX() >> 4, blockposition.getZ() >> 4); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderGenerate.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderGenerate.java new file mode 100644 index 0000000..ad464d3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderGenerate.java @@ -0,0 +1,472 @@ +package net.minecraft.server; + +import java.util.List; +import java.util.Random; + +public class ChunkProviderGenerate implements IChunkProvider { + + private Random h; + private NoiseGeneratorOctaves i; + private NoiseGeneratorOctaves j; + private NoiseGeneratorOctaves k; + private NoiseGenerator3 l; + public NoiseGeneratorOctaves a; + public NoiseGeneratorOctaves b; + public NoiseGeneratorOctaves c; + private World m; + private final boolean n; + private WorldType o; + private final double[] p; + private final float[] q; + private CustomWorldSettingsFinal r; + private Block s; + private double[] t; + private WorldGenBase u; + private WorldGenStronghold v; + private WorldGenVillage w; + private WorldGenMineshaft x; + private WorldGenLargeFeature y; + private WorldGenBase z; + private WorldGenMonument A; + private BiomeBase[] B; + double[] d; + double[] e; + double[] f; + double[] g; + + public ChunkProviderGenerate(World world, long i, boolean flag, String s) { + this.s = Blocks.WATER; + this.t = new double[256]; + this.u = new WorldGenCaves(); + this.v = new WorldGenStronghold(); + this.w = new WorldGenVillage(); + this.x = new WorldGenMineshaft(); + this.y = new WorldGenLargeFeature(); + this.z = new WorldGenCanyon(); + this.A = new WorldGenMonument(); + this.m = world; + this.n = flag; + this.o = world.getWorldData().getType(); + this.h = new Random(i); + this.i = new NoiseGeneratorOctaves(this.h, 16); + this.j = new NoiseGeneratorOctaves(this.h, 16); + this.k = new NoiseGeneratorOctaves(this.h, 8); + this.l = new NoiseGenerator3(this.h, 4); + this.a = new NoiseGeneratorOctaves(this.h, 10); + this.b = new NoiseGeneratorOctaves(this.h, 16); + this.c = new NoiseGeneratorOctaves(this.h, 8); + this.p = new double[825]; + this.q = new float[25]; + + for (int j = -2; j <= 2; ++j) { + for (int k = -2; k <= 2; ++k) { + float f = 10.0F / MathHelper.c((float) (j * j + k * k) + 0.2F); + + this.q[j + 2 + (k + 2) * 5] = f; + } + } + + if (s != null) { + this.r = CustomWorldSettingsFinal.CustomWorldSettings.a(s).b(); + this.s = this.r.E ? Blocks.LAVA : Blocks.WATER; + world.b(this.r.q); + } + + } + + public void a(int i, int j, ChunkSnapshot chunksnapshot) { + this.B = this.m.getWorldChunkManager().getBiomes(this.B, i * 4 - 2, j * 4 - 2, 10, 10); + this.a(i * 4, 0, j * 4); + + for (int k = 0; k < 4; ++k) { + int l = k * 5; + int i1 = (k + 1) * 5; + + for (int j1 = 0; j1 < 4; ++j1) { + int k1 = (l + j1) * 33; + int l1 = (l + j1 + 1) * 33; + int i2 = (i1 + j1) * 33; + int j2 = (i1 + j1 + 1) * 33; + + for (int k2 = 0; k2 < 32; ++k2) { + double d0 = 0.125D; + double d1 = this.p[k1 + k2]; + double d2 = this.p[l1 + k2]; + double d3 = this.p[i2 + k2]; + double d4 = this.p[j2 + k2]; + double d5 = (this.p[k1 + k2 + 1] - d1) * d0; + double d6 = (this.p[l1 + k2 + 1] - d2) * d0; + double d7 = (this.p[i2 + k2 + 1] - d3) * d0; + double d8 = (this.p[j2 + k2 + 1] - d4) * d0; + + for (int l2 = 0; l2 < 8; ++l2) { + double d9 = 0.25D; + double d10 = d1; + double d11 = d2; + double d12 = (d3 - d1) * d9; + double d13 = (d4 - d2) * d9; + + for (int i3 = 0; i3 < 4; ++i3) { + double d14 = 0.25D; + double d15 = (d11 - d10) * d14; + double d16 = d10 - d15; + + for (int j3 = 0; j3 < 4; ++j3) { + if ((d16 += d15) > 0.0D) { + chunksnapshot.a(k * 4 + i3, k2 * 8 + l2, j1 * 4 + j3, Blocks.STONE.getBlockData()); + } else if (k2 * 8 + l2 < this.r.q) { + chunksnapshot.a(k * 4 + i3, k2 * 8 + l2, j1 * 4 + j3, this.s.getBlockData()); + } + } + + d10 += d12; + d11 += d13; + } + + d1 += d5; + d2 += d6; + d3 += d7; + d4 += d8; + } + } + } + } + + } + + public void a(int i, int j, ChunkSnapshot chunksnapshot, BiomeBase[] abiomebase) { + double d0 = 0.03125D; + + this.t = this.l.a(this.t, (double) (i * 16), (double) (j * 16), 16, 16, d0 * 2.0D, d0 * 2.0D, 1.0D); + + for (int k = 0; k < 16; ++k) { + for (int l = 0; l < 16; ++l) { + BiomeBase biomebase = abiomebase[l + k * 16]; + + biomebase.a(this.m, this.h, chunksnapshot, i * 16 + k, j * 16 + l, this.t[l + k * 16]); + } + } + + } + + public Chunk getOrCreateChunk(int i, int j) { + this.h.setSeed((long) i * 341873128712L + (long) j * 132897987541L); + ChunkSnapshot chunksnapshot = new ChunkSnapshot(); + + this.a(i, j, chunksnapshot); + this.B = this.m.getWorldChunkManager().getBiomeBlock(this.B, i * 16, j * 16, 16, 16); + this.a(i, j, chunksnapshot, this.B); + if (this.r.r && this.m.paperSpigotConfig.generateCaves) { // PaperSpigot + this.u.a(this, this.m, i, j, chunksnapshot); + } + + if (this.r.z && this.m.paperSpigotConfig.generateCanyon) { // PaperSpigot + this.z.a(this, this.m, i, j, chunksnapshot); + } + + if (this.r.w && this.n && this.m.paperSpigotConfig.generateMineshaft) { // PaperSpigot + this.x.a(this, this.m, i, j, chunksnapshot); + } + + if (this.r.v && this.n && this.m.paperSpigotConfig.generateVillage) { // PaperSpigot + this.w.a(this, this.m, i, j, chunksnapshot); + } + + if (this.r.u && this.n && this.m.paperSpigotConfig.generateStronghold) { // PaperSpigot + this.v.a(this, this.m, i, j, chunksnapshot); + } + + if (this.r.x && this.n && this.m.paperSpigotConfig.generateTemple) { // PaperSpigot + this.y.a(this, this.m, i, j, chunksnapshot); + } + + if (this.r.y && this.n && this.m.paperSpigotConfig.generateMonument) { // PaperSpigot + this.A.a(this, this.m, i, j, chunksnapshot); + } + + Chunk chunk = new Chunk(this.m, chunksnapshot, i, j); + byte[] abyte = chunk.getBiomeIndex(); + + for (int k = 0; k < abyte.length; ++k) { + abyte[k] = (byte) this.B[k].id; + } + + chunk.initLighting(); + return chunk; + } + + private void a(int i, int j, int k) { + this.g = this.b.a(this.g, i, k, 5, 5, (double) this.r.e, (double) this.r.f, (double) this.r.g); + float f = this.r.a; + float f1 = this.r.b; + + this.d = this.k.a(this.d, i, j, k, 5, 33, 5, (double) (f / this.r.h), (double) (f1 / this.r.i), (double) (f / this.r.j)); + this.e = this.i.a(this.e, i, j, k, 5, 33, 5, (double) f, (double) f1, (double) f); + this.f = this.j.a(this.f, i, j, k, 5, 33, 5, (double) f, (double) f1, (double) f); + boolean flag = false; + boolean flag1 = false; + int l = 0; + int i1 = 0; + + for (int j1 = 0; j1 < 5; ++j1) { + for (int k1 = 0; k1 < 5; ++k1) { + float f2 = 0.0F; + float f3 = 0.0F; + float f4 = 0.0F; + byte b0 = 2; + BiomeBase biomebase = this.B[j1 + 2 + (k1 + 2) * 10]; + + for (int l1 = -b0; l1 <= b0; ++l1) { + for (int i2 = -b0; i2 <= b0; ++i2) { + BiomeBase biomebase1 = this.B[j1 + l1 + 2 + (k1 + i2 + 2) * 10]; + float f5 = this.r.n + biomebase1.an * this.r.m; + float f6 = this.r.p + biomebase1.ao * this.r.o; + + if (this.o == WorldType.AMPLIFIED && f5 > 0.0F) { + f5 = 1.0F + f5 * 2.0F; + f6 = 1.0F + f6 * 4.0F; + } + + float f7 = this.q[l1 + 2 + (i2 + 2) * 5] / (f5 + 2.0F); + + if (biomebase1.an > biomebase.an) { + f7 /= 2.0F; + } + + f2 += f6 * f7; + f3 += f5 * f7; + f4 += f7; + } + } + + f2 /= f4; + f3 /= f4; + f2 = f2 * 0.9F + 0.1F; + f3 = (f3 * 4.0F - 1.0F) / 8.0F; + double d0 = this.g[i1] / 8000.0D; + + if (d0 < 0.0D) { + d0 = -d0 * 0.3D; + } + + d0 = d0 * 3.0D - 2.0D; + if (d0 < 0.0D) { + d0 /= 2.0D; + if (d0 < -1.0D) { + d0 = -1.0D; + } + + d0 /= 1.4D; + d0 /= 2.0D; + } else { + if (d0 > 1.0D) { + d0 = 1.0D; + } + + d0 /= 8.0D; + } + + ++i1; + double d1 = (double) f3; + double d2 = (double) f2; + + d1 += d0 * 0.2D; + d1 = d1 * (double) this.r.k / 8.0D; + double d3 = (double) this.r.k + d1 * 4.0D; + + for (int j2 = 0; j2 < 33; ++j2) { + double d4 = ((double) j2 - d3) * (double) this.r.l * 128.0D / 256.0D / d2; + + if (d4 < 0.0D) { + d4 *= 4.0D; + } + + double d5 = this.e[l] / (double) this.r.d; + double d6 = this.f[l] / (double) this.r.c; + double d7 = (this.d[l] / 10.0D + 1.0D) / 2.0D; + double d8 = MathHelper.b(d5, d6, d7) - d4; + + if (j2 > 29) { + double d9 = (double) ((float) (j2 - 29) / 3.0F); + + d8 = d8 * (1.0D - d9) + -10.0D * d9; + } + + this.p[l] = d8; + ++l; + } + } + } + + } + + public boolean isChunkLoaded(int i, int j) { + return true; + } + + public void getChunkAt(IChunkProvider ichunkprovider, int i, int j) { + BlockFalling.instaFall = true; + int k = i * 16; + int l = j * 16; + BlockPosition blockposition = new BlockPosition(k, 0, l); + BiomeBase biomebase = this.m.getBiome(blockposition.a(16, 0, 16)); + + this.h.setSeed(this.m.getSeed()); + long i1 = this.h.nextLong() / 2L * 2L + 1L; + long j1 = this.h.nextLong() / 2L * 2L + 1L; + + this.h.setSeed((long) i * i1 + (long) j * j1 ^ this.m.getSeed()); + boolean flag = false; + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + + if (this.r.w && this.n && this.m.paperSpigotConfig.generateMineshaft) { // PaperSpigot + this.x.a(this.m, this.h, chunkcoordintpair); + } + + if (this.r.v && this.n && this.m.paperSpigotConfig.generateVillage) { // PaperSpigot + flag = this.w.a(this.m, this.h, chunkcoordintpair); + } + + if (this.r.u && this.n && this.m.paperSpigotConfig.generateStronghold) { // PaperSpigot + this.v.a(this.m, this.h, chunkcoordintpair); + } + + if (this.r.x && this.n && this.m.paperSpigotConfig.generateTemple) { // PaperSpigot + this.y.a(this.m, this.h, chunkcoordintpair); + } + + if (this.r.y && this.n && this.m.paperSpigotConfig.generateMonument) { // PaperSpigot + this.A.a(this.m, this.h, chunkcoordintpair); + } + + int k1; + int l1; + int i2; + + if (biomebase != BiomeBase.DESERT && biomebase != BiomeBase.DESERT_HILLS && this.r.A && !flag && this.h.nextInt(this.r.B) == 0) { + k1 = this.h.nextInt(16) + 8; + l1 = this.h.nextInt(256); + i2 = this.h.nextInt(16) + 8; + (new WorldGenLakes(Blocks.WATER)).generate(this.m, this.h, blockposition.a(k1, l1, i2)); + } + + if (!flag && this.h.nextInt(this.r.D / 10) == 0 && this.r.C) { + k1 = this.h.nextInt(16) + 8; + l1 = this.h.nextInt(this.h.nextInt(248) + 8); + i2 = this.h.nextInt(16) + 8; + if (l1 < this.m.F() || this.h.nextInt(this.r.D / 8) == 0) { + (new WorldGenLakes(Blocks.LAVA)).generate(this.m, this.h, blockposition.a(k1, l1, i2)); + } + } + + if (this.r.s && this.m.paperSpigotConfig.generateDungeon) { // PaperSpigot + for (k1 = 0; k1 < this.r.t; ++k1) { + l1 = this.h.nextInt(16) + 8; + i2 = this.h.nextInt(256); + int j2 = this.h.nextInt(16) + 8; + + (new WorldGenDungeons()).generate(this.m, this.h, blockposition.a(l1, i2, j2)); + } + } + + biomebase.a(this.m, this.h, new BlockPosition(k, 0, l)); + SpawnerCreature.a(this.m, biomebase, k + 8, l + 8, 16, 16, this.h); + blockposition = blockposition.a(8, 0, 8); + + for (k1 = 0; k1 < 16; ++k1) { + for (l1 = 0; l1 < 16; ++l1) { + BlockPosition blockposition1 = this.m.q(blockposition.a(k1, 0, l1)); + BlockPosition blockposition2 = blockposition1.down(); + + if (this.m.v(blockposition2)) { + this.m.setTypeAndData(blockposition2, Blocks.ICE.getBlockData(), 2); + } + + if (this.m.f(blockposition1, true)) { + this.m.setTypeAndData(blockposition1, Blocks.SNOW_LAYER.getBlockData(), 2); + } + } + } + + BlockFalling.instaFall = false; + } + + public boolean a(IChunkProvider ichunkprovider, Chunk chunk, int i, int j) { + boolean flag = false; + + if (this.r.y && this.n && chunk.w() < 3600L) { + flag |= this.A.a(this.m, this.h, new ChunkCoordIntPair(i, j)); + } + + return flag; + } + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) { + return true; + } + + public void c() {} + + public boolean unloadChunks() { + return false; + } + + public boolean canSave() { + return true; + } + + public String getName() { + return "RandomLevelSource"; + } + + public List getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { + BiomeBase biomebase = this.m.getBiome(blockposition); + + if (this.n) { + if (enumcreaturetype == EnumCreatureType.MONSTER && this.y.a(blockposition)) { + return this.y.b(); + } + + if (enumcreaturetype == EnumCreatureType.MONSTER && this.r.y && this.A.a(this.m, blockposition)) { + return this.A.b(); + } + } + + return biomebase.getMobs(enumcreaturetype); + } + + public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition) { + return "Stronghold".equals(s) && this.v != null ? this.v.getNearestGeneratedFeature(world, blockposition) : null; + } + + public int getLoadedChunks() { + return 0; + } + + public void recreateStructures(Chunk chunk, int i, int j) { + if (this.r.w && this.n && this.m.paperSpigotConfig.generateMineshaft) { // PaperSpigot + this.x.a(this, this.m, i, j, (ChunkSnapshot) null); + } + + if (this.r.v && this.n && this.m.paperSpigotConfig.generateVillage) { // PaperSpigot + this.w.a(this, this.m, i, j, (ChunkSnapshot) null); + } + + if (this.r.u && this.n && this.m.paperSpigotConfig.generateStronghold) { // PaperSpigot + this.v.a(this, this.m, i, j, (ChunkSnapshot) null); + } + + if (this.r.x && this.n && this.m.paperSpigotConfig.generateTemple) { // PaperSpigot + this.y.a(this, this.m, i, j, (ChunkSnapshot) null); + } + + if (this.r.y && this.n && this.m.paperSpigotConfig.generateMonument) { // PaperSpigot + this.A.a(this, this.m, i, j, (ChunkSnapshot) null); + } + + } + + public Chunk getChunkAt(BlockPosition blockposition) { + return this.getOrCreateChunk(blockposition.getX() >> 4, blockposition.getZ() >> 4); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderHell.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderHell.java new file mode 100644 index 0000000..0156892 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderHell.java @@ -0,0 +1,396 @@ +package net.minecraft.server; + +import java.util.List; +import java.util.Random; + +public class ChunkProviderHell implements IChunkProvider { + + private final World h; + private final boolean i; + private final Random j; + private double[] k = new double[256]; + private double[] l = new double[256]; + private double[] m = new double[256]; + private double[] n; + private final NoiseGeneratorOctaves o; + private final NoiseGeneratorOctaves p; + private final NoiseGeneratorOctaves q; + private final NoiseGeneratorOctaves r; + private final NoiseGeneratorOctaves s; + public final NoiseGeneratorOctaves a; + public final NoiseGeneratorOctaves b; + private final WorldGenFire t = new WorldGenFire(); + private final WorldGenLightStone1 u = new WorldGenLightStone1(); + private final WorldGenLightStone2 v = new WorldGenLightStone2(); + private final WorldGenerator w; + private final WorldGenHellLava x; + private final WorldGenHellLava y; + private final WorldGenMushrooms z; + private final WorldGenMushrooms A; + private final WorldGenNether B; + private final WorldGenBase C; + double[] c; + double[] d; + double[] e; + double[] f; + double[] g; + + public ChunkProviderHell(World world, boolean flag, long i) { + this.w = new WorldGenMinable(Blocks.QUARTZ_ORE.getBlockData(), 14, BlockPredicate.a(Blocks.NETHERRACK)); + this.x = new WorldGenHellLava(Blocks.FLOWING_LAVA, true); + this.y = new WorldGenHellLava(Blocks.FLOWING_LAVA, false); + this.z = new WorldGenMushrooms(Blocks.BROWN_MUSHROOM); + this.A = new WorldGenMushrooms(Blocks.RED_MUSHROOM); + this.B = new WorldGenNether(); + this.C = new WorldGenCavesHell(); + this.h = world; + this.i = flag; + this.j = new Random(i); + this.o = new NoiseGeneratorOctaves(this.j, 16); + this.p = new NoiseGeneratorOctaves(this.j, 16); + this.q = new NoiseGeneratorOctaves(this.j, 8); + this.r = new NoiseGeneratorOctaves(this.j, 4); + this.s = new NoiseGeneratorOctaves(this.j, 4); + this.a = new NoiseGeneratorOctaves(this.j, 10); + this.b = new NoiseGeneratorOctaves(this.j, 16); + world.b(63); + } + + public void a(int i, int j, ChunkSnapshot chunksnapshot) { + byte b0 = 4; + int k = this.h.F() / 2 + 1; + int l = b0 + 1; + byte b1 = 17; + int i1 = b0 + 1; + + this.n = this.a(this.n, i * b0, 0, j * b0, l, b1, i1); + + for (int j1 = 0; j1 < b0; ++j1) { + for (int k1 = 0; k1 < b0; ++k1) { + for (int l1 = 0; l1 < 16; ++l1) { + double d0 = 0.125D; + double d1 = this.n[((j1 + 0) * i1 + k1 + 0) * b1 + l1 + 0]; + double d2 = this.n[((j1 + 0) * i1 + k1 + 1) * b1 + l1 + 0]; + double d3 = this.n[((j1 + 1) * i1 + k1 + 0) * b1 + l1 + 0]; + double d4 = this.n[((j1 + 1) * i1 + k1 + 1) * b1 + l1 + 0]; + double d5 = (this.n[((j1 + 0) * i1 + k1 + 0) * b1 + l1 + 1] - d1) * d0; + double d6 = (this.n[((j1 + 0) * i1 + k1 + 1) * b1 + l1 + 1] - d2) * d0; + double d7 = (this.n[((j1 + 1) * i1 + k1 + 0) * b1 + l1 + 1] - d3) * d0; + double d8 = (this.n[((j1 + 1) * i1 + k1 + 1) * b1 + l1 + 1] - d4) * d0; + + for (int i2 = 0; i2 < 8; ++i2) { + double d9 = 0.25D; + double d10 = d1; + double d11 = d2; + double d12 = (d3 - d1) * d9; + double d13 = (d4 - d2) * d9; + + for (int j2 = 0; j2 < 4; ++j2) { + double d14 = 0.25D; + double d15 = d10; + double d16 = (d11 - d10) * d14; + + for (int k2 = 0; k2 < 4; ++k2) { + IBlockData iblockdata = null; + + if (l1 * 8 + i2 < k) { + iblockdata = Blocks.LAVA.getBlockData(); + } + + if (d15 > 0.0D) { + iblockdata = Blocks.NETHERRACK.getBlockData(); + } + + int l2 = j2 + j1 * 4; + int i3 = i2 + l1 * 8; + int j3 = k2 + k1 * 4; + + chunksnapshot.a(l2, i3, j3, iblockdata); + d15 += d16; + } + + d10 += d12; + d11 += d13; + } + + d1 += d5; + d2 += d6; + d3 += d7; + d4 += d8; + } + } + } + } + + } + + public void b(int i, int j, ChunkSnapshot chunksnapshot) { + int k = this.h.F() + 1; + double d0 = 0.03125D; + + this.k = this.r.a(this.k, i * 16, j * 16, 0, 16, 16, 1, d0, d0, 1.0D); + this.l = this.r.a(this.l, i * 16, 109, j * 16, 16, 1, 16, d0, 1.0D, d0); + this.m = this.s.a(this.m, i * 16, j * 16, 0, 16, 16, 1, d0 * 2.0D, d0 * 2.0D, d0 * 2.0D); + + for (int l = 0; l < 16; ++l) { + for (int i1 = 0; i1 < 16; ++i1) { + boolean flag = this.k[l + i1 * 16] + this.j.nextDouble() * 0.2D > 0.0D; + boolean flag1 = this.l[l + i1 * 16] + this.j.nextDouble() * 0.2D > 0.0D; + int j1 = (int) (this.m[l + i1 * 16] / 3.0D + 3.0D + this.j.nextDouble() * 0.25D); + int k1 = -1; + IBlockData iblockdata = Blocks.NETHERRACK.getBlockData(); + IBlockData iblockdata1 = Blocks.NETHERRACK.getBlockData(); + + for (int l1 = 127; l1 >= 0; --l1) { + // PaperSpigot start - Configurable flat bedrock worldgen + if (l1 < 127 - (h.paperSpigotConfig.generateFlatBedrock ? 0 : this.j.nextInt(5)) && + l1 > (h.paperSpigotConfig.generateFlatBedrock ? 0 : this.j.nextInt(5))) { + // PaperSpigot end + IBlockData iblockdata2 = chunksnapshot.a(i1, l1, l); + + if (iblockdata2.getBlock() != null && iblockdata2.getBlock().getMaterial() != Material.AIR) { + if (iblockdata2.getBlock() == Blocks.NETHERRACK) { + if (k1 == -1) { + if (j1 <= 0) { + iblockdata = null; + iblockdata1 = Blocks.NETHERRACK.getBlockData(); + } else if (l1 >= k - 4 && l1 <= k + 1) { + iblockdata = Blocks.NETHERRACK.getBlockData(); + iblockdata1 = Blocks.NETHERRACK.getBlockData(); + if (flag1) { + iblockdata = Blocks.GRAVEL.getBlockData(); + iblockdata1 = Blocks.NETHERRACK.getBlockData(); + } + + if (flag) { + iblockdata = Blocks.SOUL_SAND.getBlockData(); + iblockdata1 = Blocks.SOUL_SAND.getBlockData(); + } + } + + if (l1 < k && (iblockdata == null || iblockdata.getBlock().getMaterial() == Material.AIR)) { + iblockdata = Blocks.LAVA.getBlockData(); + } + + k1 = j1; + if (l1 >= k - 1) { + chunksnapshot.a(i1, l1, l, iblockdata); + } else { + chunksnapshot.a(i1, l1, l, iblockdata1); + } + } else if (k1 > 0) { + --k1; + chunksnapshot.a(i1, l1, l, iblockdata1); + } + } + } else { + k1 = -1; + } + } else { + chunksnapshot.a(i1, l1, l, Blocks.BEDROCK.getBlockData()); + } + } + } + } + + } + + public Chunk getOrCreateChunk(int i, int j) { + this.j.setSeed((long) i * 341873128712L + (long) j * 132897987541L); + ChunkSnapshot chunksnapshot = new ChunkSnapshot(); + + this.a(i, j, chunksnapshot); + this.b(i, j, chunksnapshot); + if (this.h.paperSpigotConfig.generateCaves) this.C.a(this, this.h, i, j, chunksnapshot); // PaperSpigot + if (this.i && this.h.paperSpigotConfig.generateFortress) { // PaperSpigot + this.B.a(this, this.h, i, j, chunksnapshot); + } + + Chunk chunk = new Chunk(this.h, chunksnapshot, i, j); + BiomeBase[] abiomebase = this.h.getWorldChunkManager().getBiomeBlock((BiomeBase[]) null, i * 16, j * 16, 16, 16); + byte[] abyte = chunk.getBiomeIndex(); + + for (int k = 0; k < abyte.length; ++k) { + abyte[k] = (byte) abiomebase[k].id; + } + + chunk.l(); + return chunk; + } + + private double[] a(double[] adouble, int i, int j, int k, int l, int i1, int j1) { + if (adouble == null) { + adouble = new double[l * i1 * j1]; + } + + double d0 = 684.412D; + double d1 = 2053.236D; + + this.f = this.a.a(this.f, i, j, k, l, 1, j1, 1.0D, 0.0D, 1.0D); + this.g = this.b.a(this.g, i, j, k, l, 1, j1, 100.0D, 0.0D, 100.0D); + this.c = this.q.a(this.c, i, j, k, l, i1, j1, d0 / 80.0D, d1 / 60.0D, d0 / 80.0D); + this.d = this.o.a(this.d, i, j, k, l, i1, j1, d0, d1, d0); + this.e = this.p.a(this.e, i, j, k, l, i1, j1, d0, d1, d0); + int k1 = 0; + double[] adouble1 = new double[i1]; + + int l1; + + for (l1 = 0; l1 < i1; ++l1) { + adouble1[l1] = Math.cos((double) l1 * 3.141592653589793D * 6.0D / (double) i1) * 2.0D; + double d2 = (double) l1; + + if (l1 > i1 / 2) { + d2 = (double) (i1 - 1 - l1); + } + + if (d2 < 4.0D) { + d2 = 4.0D - d2; + adouble1[l1] -= d2 * d2 * d2 * 10.0D; + } + } + + for (l1 = 0; l1 < l; ++l1) { + for (int i2 = 0; i2 < j1; ++i2) { + double d3 = 0.0D; + + for (int j2 = 0; j2 < i1; ++j2) { + double d4 = 0.0D; + double d5 = adouble1[j2]; + double d6 = this.d[k1] / 512.0D; + double d7 = this.e[k1] / 512.0D; + double d8 = (this.c[k1] / 10.0D + 1.0D) / 2.0D; + + if (d8 < 0.0D) { + d4 = d6; + } else if (d8 > 1.0D) { + d4 = d7; + } else { + d4 = d6 + (d7 - d6) * d8; + } + + d4 -= d5; + double d9; + + if (j2 > i1 - 4) { + d9 = (double) ((float) (j2 - (i1 - 4)) / 3.0F); + d4 = d4 * (1.0D - d9) + -10.0D * d9; + } + + if ((double) j2 < d3) { + d9 = (d3 - (double) j2) / 4.0D; + d9 = MathHelper.a(d9, 0.0D, 1.0D); + d4 = d4 * (1.0D - d9) + -10.0D * d9; + } + + adouble[k1] = d4; + ++k1; + } + } + } + + return adouble; + } + + public boolean isChunkLoaded(int i, int j) { + return true; + } + + public void getChunkAt(IChunkProvider ichunkprovider, int i, int j) { + BlockFalling.instaFall = true; + BlockPosition blockposition = new BlockPosition(i * 16, 0, j * 16); + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + + this.B.a(this.h, this.j, chunkcoordintpair); + + int k; + + for (k = 0; k < 8; ++k) { + this.y.generate(this.h, this.j, blockposition.a(this.j.nextInt(16) + 8, this.j.nextInt(120) + 4, this.j.nextInt(16) + 8)); + } + + for (k = 0; k < this.j.nextInt(this.j.nextInt(10) + 1) + 1; ++k) { + this.t.generate(this.h, this.j, blockposition.a(this.j.nextInt(16) + 8, this.j.nextInt(120) + 4, this.j.nextInt(16) + 8)); + } + + for (k = 0; k < this.j.nextInt(this.j.nextInt(10) + 1); ++k) { + this.u.generate(this.h, this.j, blockposition.a(this.j.nextInt(16) + 8, this.j.nextInt(120) + 4, this.j.nextInt(16) + 8)); + } + + for (k = 0; k < 10; ++k) { + this.v.generate(this.h, this.j, blockposition.a(this.j.nextInt(16) + 8, this.j.nextInt(128), this.j.nextInt(16) + 8)); + } + + if (this.j.nextBoolean()) { + this.z.generate(this.h, this.j, blockposition.a(this.j.nextInt(16) + 8, this.j.nextInt(128), this.j.nextInt(16) + 8)); + } + + if (this.j.nextBoolean()) { + this.A.generate(this.h, this.j, blockposition.a(this.j.nextInt(16) + 8, this.j.nextInt(128), this.j.nextInt(16) + 8)); + } + + for (k = 0; k < 16; ++k) { + this.w.generate(this.h, this.j, blockposition.a(this.j.nextInt(16), this.j.nextInt(108) + 10, this.j.nextInt(16))); + } + + for (k = 0; k < 16; ++k) { + this.x.generate(this.h, this.j, blockposition.a(this.j.nextInt(16), this.j.nextInt(108) + 10, this.j.nextInt(16))); + } + + BlockFalling.instaFall = false; + } + + public boolean a(IChunkProvider ichunkprovider, Chunk chunk, int i, int j) { + return false; + } + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) { + return true; + } + + public void c() {} + + public boolean unloadChunks() { + return false; + } + + public boolean canSave() { + return true; + } + + public String getName() { + return "HellRandomLevelSource"; + } + + public List getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { + if (enumcreaturetype == EnumCreatureType.MONSTER) { + if (this.B.b(blockposition)) { + return this.B.b(); + } + + if (this.B.a(this.h, blockposition) && this.h.getType(blockposition.down()).getBlock() == Blocks.NETHER_BRICK) { + return this.B.b(); + } + } + + BiomeBase biomebase = this.h.getBiome(blockposition); + + return biomebase.getMobs(enumcreaturetype); + } + + public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition) { + return null; + } + + public int getLoadedChunks() { + return 0; + } + + public void recreateStructures(Chunk chunk, int i, int j) { + if (this.h.paperSpigotConfig.generateFortress) this.B.a(this, this.h, i, j, (ChunkSnapshot) null); // PaperSpigot + } + + public Chunk getChunkAt(BlockPosition blockposition) { + return this.getOrCreateChunk(blockposition.getX() >> 4, blockposition.getZ() >> 4); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderServer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderServer.java new file mode 100644 index 0000000..1311bad --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -0,0 +1,466 @@ +package net.minecraft.server; + +import it.unimi.dsi.fastutil.longs.*; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Server; +import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; +import org.bukkit.craftbukkit.util.LongHash; +import org.bukkit.event.world.ChunkUnloadEvent; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.logging.Level; + +// CraftBukkit start +// CraftBukkit end +// TacoSpigot start +// TacoSpigot end + +public class ChunkProviderServer implements IChunkProvider { + + private static final Logger b = LogManager.getLogger(); + public LongSet unloadQueue = new LongArraySet(); // CraftBukkit - LongHashSet // TacoSpigot - LongHashSet -> HashArraySet + public Chunk emptyChunk; + public IChunkProvider chunkProvider; + private IChunkLoader chunkLoader; + public boolean forceChunkLoad = false; // CraftBukkit - true -> false + protected Chunk lastChunkByPos = null; + public Long2ObjectMap chunks = new Long2ObjectOpenHashMap(8192, 0.5f) { + @Override + public Chunk get(long key) { + if (lastChunkByPos != null && key == lastChunkByPos.chunkKey) { + return lastChunkByPos; + } + return lastChunkByPos = super.get(key); + } + + @Override + public Chunk remove(long key) { + if (lastChunkByPos != null && key == lastChunkByPos.chunkKey) { + lastChunkByPos = null; + } + return super.remove(key); + } + }; + public WorldServer world; + + public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, IChunkProvider ichunkprovider) { + this.emptyChunk = new EmptyChunk(worldserver, 0, 0); + this.world = worldserver; + this.chunkLoader = ichunkloader; + this.chunkProvider = ichunkprovider; + } + + // Paper start + public boolean isChunkGenerated(int x, int z) throws IOException { + return this.chunks.containsKey(ChunkCoordIntPair.a(x, z)) || this.chunkLoader.a(world, x, z) != null; + } + // Paper end + + public boolean isChunkLoaded(int i, int j) { + return this.chunks.containsKey(LongHash.toLong(i, j)); // CraftBukkit + } + + // CraftBukkit start - Change return type to Collection and return the values of our chunk map + public java.util.Collection a() { + // return this.chunkList; + return this.chunks.values(); + // CraftBukkit end + } + + public void queueUnload(int i, int j) { + // PaperSpigot start - Asynchronous lighting updates + Chunk chunk = chunks.get(LongHash.toLong(i, j)); + if (chunk != null && chunk.world.paperSpigotConfig.useAsyncLighting && (chunk.pendingLightUpdates.get() > 0 || chunk.world.getTime() - chunk.lightUpdateTime < 20)) { + return; + } + // PaperSpigot end + // PaperSpigot start - Don't unload chunk if it contains an entity that loads chunks + if (chunk != null) { + for (List entities : chunk.entitySlices) { + for (Entity entity : entities) { + if (entity.loadChunks) { + return; + } + } + } + } + // PaperSpigot end + if (this.world.worldProvider.e()) { + if (!this.world.c(i, j)) { + // CraftBukkit start + this.unloadQueue.add(LongHash.toLong(i, j)); // TacoSpigot - directly invoke LongHash + + // Mythic - Avoid double lookup + if (chunk != null) { + chunk.mustSave = true; + } + // CraftBukkit end + } + } else { + // CraftBukkit start + this.unloadQueue.add(LongHash.toLong(i, j)); // TacoSpigot - directly invoke LongHash + + // Mythic - Avoid double lookup + if (chunk != null) { + chunk.mustSave = true; + } + // CraftBukkit end + } + + } + + public void b() { + Iterator iterator = this.chunks.values().iterator(); + + while (iterator.hasNext()) { + Chunk chunk = (Chunk) iterator.next(); + + this.queueUnload(chunk.locX, chunk.locZ); + } + + } + + // CraftBukkit start - Add async variant, provide compatibility + public Chunk getChunkIfLoaded(int x, int z) { + return chunks.get(LongHash.toLong(x, z)); + } + + public Chunk getChunkAt(int i, int j) { + return getChunkAt(i, j, null); + } + + public Chunk getChunkAt(int i, int j, Runnable runnable) { + unloadQueue.remove(LongHash.toLong(i, j)); // TacoSpigot - directly invoke LongHash + Chunk chunk = chunks.get(LongHash.toLong(i, j)); + ChunkRegionLoader loader = null; + + if (this.chunkLoader instanceof ChunkRegionLoader) { + loader = (ChunkRegionLoader) this.chunkLoader; + + } + // We can only use the queue for already generated chunks + if (chunk == null && loader != null && loader.chunkExists(world, i, j)) { + if (runnable != null) { + ChunkIOExecutor.queueChunkLoad(world, loader, this, i, j, runnable); + return null; + } else { + chunk = ChunkIOExecutor.syncChunkLoad(world, loader, this, i, j); + } + } else if (chunk == null) { + chunk = originalGetChunkAt(i, j); + } + + // If we didn't load the chunk async and have a callback run it now + if (runnable != null) { + runnable.run(); + } + + return chunk; + } + public Chunk originalGetChunkAt(int i, int j) { + this.unloadQueue.remove(LongHash.toLong(i, j)); // TacoSpigot - directly invoke LongHash + Chunk chunk = this.chunks.get(LongHash.toLong(i, j)); + boolean newChunk = false; + // CraftBukkit end + + if (chunk == null) { + world.timings.syncChunkLoadTimer.startTiming(); // Spigot + chunk = this.loadChunk(i, j); + if (chunk == null) { + if (this.chunkProvider == null) { + chunk = this.emptyChunk; + } else { + try { + chunk = this.chunkProvider.getOrCreateChunk(i, j); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Exception generating new chunk"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Chunk to be generated"); + + crashreportsystemdetails.a("Location", String.format("%d,%d", Integer.valueOf(i), Integer.valueOf(j))); + crashreportsystemdetails.a("Position hash", Long.valueOf(LongHash.toLong(i, j))); // CraftBukkit - Use LongHash + crashreportsystemdetails.a("Generator", this.chunkProvider.getName()); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + newChunk = true; // CraftBukkit + } + + this.chunks.put(LongHash.toLong(i, j), chunk); + + chunk.addEntities(); + + // CraftBukkit start + Server server = world.getServer(); + if (server != null) { + /* + * If it's a new world, the first few chunks are generated inside + * the World constructor. We can't reliably alter that, so we have + * no way of creating a CraftWorld/CraftServer at that point. + */ + server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, newChunk)); + } + + // Update neighbor counts + for (int x = -2; x < 3; x++) { + for (int z = -2; z < 3; z++) { + if (x == 0 && z == 0) { + continue; + } + + Chunk neighbor = this.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z); + if (neighbor != null) { + neighbor.setNeighborLoaded(-x, -z); + chunk.setNeighborLoaded(x, z); + } + } + } + // CraftBukkit end + chunk.loadNearby(this, this, i, j); + world.timings.syncChunkLoadTimer.stopTiming(); // Spigot + } + + return chunk; + } + + public Chunk getOrCreateChunk(int i, int j) { + // CraftBukkit start + Chunk chunk = this.chunks.get(LongHash.toLong(i, j)); + + chunk = chunk == null ? (!this.world.ad() && !this.forceChunkLoad ? this.emptyChunk : this.getChunkAt(i, j)) : chunk; + + if (chunk == emptyChunk) return chunk; + if (i != chunk.locX || j != chunk.locZ) { + b.error("Chunk (" + chunk.locX + ", " + chunk.locZ + ") stored at (" + i + ", " + j + ") in world '" + world.getWorld().getName() + "'"); + b.error(chunk.getClass().getName()); + Throwable ex = new Throwable(); + ex.fillInStackTrace(); + ex.printStackTrace(); + } + + return chunk; + // CraftBukkit end + } + + public Chunk loadChunk(int i, int j) { + if (this.chunkLoader == null) { + return null; + } else { + try { + Chunk chunk = this.chunkLoader.a(this.world, i, j); + + if (chunk != null) { + chunk.setLastSaved(this.world.getTime()); + if (this.chunkProvider != null) { + world.timings.syncChunkLoadStructuresTimer.startTiming(); // Spigot + this.chunkProvider.recreateStructures(chunk, i, j); + world.timings.syncChunkLoadStructuresTimer.stopTiming(); // Spigot + } + } + + return chunk; + } catch (Exception exception) { + ChunkProviderServer.b.error("Couldn't load chunk", exception); + return null; + } + } + } + + public void saveChunkNOP(Chunk chunk) { + if (this.chunkLoader != null) { + if(!MythicConfiguration.Options.World.Chunks.save) return; + + try { + this.chunkLoader.b(this.world, chunk); + } catch (Exception exception) { + ChunkProviderServer.b.error("Couldn't save entities", exception); + } + + } + } + + public void saveChunk(Chunk chunk) { + if (this.chunkLoader != null) { + if(!MythicConfiguration.Options.World.Chunks.save) return; + + try { + chunk.setLastSaved(this.world.getTime()); + this.chunkLoader.a(this.world, chunk); + } catch (IOException ioexception) { + ChunkProviderServer.b.error("Couldn't save chunk", ioexception); + } catch (ExceptionWorldConflict exceptionworldconflict) { + ChunkProviderServer.b.error("Couldn't save chunk; already in use by another instance of Minecraft?", exceptionworldconflict); + } + + } + } + + public void getChunkAt(IChunkProvider ichunkprovider, int i, int j) { + Chunk chunk = this.getOrCreateChunk(i, j); + + if (!chunk.isDone()) { + chunk.n(); + if (this.chunkProvider != null) { + this.chunkProvider.getChunkAt(ichunkprovider, i, j); + + // CraftBukkit start + BlockSand.instaFall = true; + Random random = new Random(); + random.setSeed(world.getSeed()); + long xRand = random.nextLong() / 2L * 2L + 1L; + long zRand = random.nextLong() / 2L * 2L + 1L; + random.setSeed((long) i * xRand + (long) j * zRand ^ world.getSeed()); + + org.bukkit.World world = this.world.getWorld(); + if (world != null) { + this.world.populating = true; + try { + for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) { + populator.populate(world, random, chunk.bukkitChunk); + } + } finally { + this.world.populating = false; + } + } + BlockSand.instaFall = false; + this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(chunk.bukkitChunk)); + // CraftBukkit end + + chunk.e(); + } + } + + } + + public boolean a(IChunkProvider ichunkprovider, Chunk chunk, int i, int j) { + if (this.chunkProvider != null && this.chunkProvider.a(ichunkprovider, chunk, i, j)) { + Chunk chunk1 = this.getOrCreateChunk(i, j); + + chunk1.e(); + return true; + } else { + return false; + } + } + + public boolean saveChunks(boolean flag, IProgressUpdate iprogressupdate) { + int i = 0; + + // CraftBukkit start + Iterator iterator = this.chunks.values().iterator(); + while (iterator.hasNext()) { + Chunk chunk = (Chunk) iterator.next(); + // CraftBukkit end + + if (flag) { + this.saveChunkNOP(chunk); + } + + if (chunk.a(flag)) { + this.saveChunk(chunk); + chunk.f(false); + ++i; + if (i == 24 && !flag && false) { // Spigot + return false; + } + } + } + + return true; + } + + public void c() { + if (this.chunkLoader != null) { + this.chunkLoader.b(); + } + + } + + public boolean unloadChunks() { + if (!this.world.savingDisabled) { + // CraftBukkit start + Server server = this.world.getServer(); + // TacoSpigot start - use iterator for unloadQueue + LongIterator iterator = unloadQueue.iterator(); + for (int i = 0; i < 100 && iterator.hasNext(); ++i) { + long chunkcoordinates = iterator.next(); + iterator.remove(); + // TacoSpigot end + Chunk chunk = this.chunks.get(chunkcoordinates); + if (chunk == null) continue; + + ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk); + server.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + + if (chunk != null) { + chunk.removeEntities(); + this.saveChunk(chunk); + this.saveChunkNOP(chunk); + this.chunks.remove(chunkcoordinates); // CraftBukkit + } + + // this.unloadQueue.remove(olong); + + // Update neighbor counts + for (int x = -2; x < 3; x++) { + for (int z = -2; z < 3; z++) { + if (x == 0 && z == 0) { + continue; + } + + Chunk neighbor = this.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z); + if (neighbor != null) { + neighbor.setNeighborUnloaded(-x, -z); + chunk.setNeighborUnloaded(x, z); + } + } + } + } + } + // CraftBukkit end + + if (this.chunkLoader != null) { + this.chunkLoader.a(); + } + } + + return this.chunkProvider.unloadChunks(); + } + + public boolean canSave() { + return !this.world.savingDisabled; + } + + public String getName() { + // CraftBukkit - this.chunks.count() -> .size() + return "ServerChunkCache: " + this.chunks.size() + " Drop: " + this.unloadQueue.size(); + } + + public List getMobsFor(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { + return this.chunkProvider.getMobsFor(enumcreaturetype, blockposition); + } + + public BlockPosition findNearestMapFeature(World world, String s, BlockPosition blockposition) { + return this.chunkProvider.findNearestMapFeature(world, s, blockposition); + } + + public int getLoadedChunks() { + // CraftBukkit - this.chunks.count() -> this.chunks.size() + return this.chunks.size(); + } + + public void recreateStructures(Chunk chunk, int i, int j) {} + + public Chunk getChunkAt(BlockPosition blockposition) { + return this.getOrCreateChunk(blockposition.getX() >> 4, blockposition.getZ() >> 4); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkRegionLoader.java new file mode 100644 index 0000000..6b24490 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -0,0 +1,463 @@ +package net.minecraft.server; + +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver { + + private static final Logger a = LogManager.getLogger(); + private Map b = new ConcurrentHashMap(); + private Set c = Collections.newSetFromMap(new ConcurrentHashMap()); + private final File d; + private boolean e = false; + + public ChunkRegionLoader(File file) { + this.d = file; + } + + // CraftBukkit start + public boolean chunkExists(World world, int i, int j) { + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + + if (this.c.contains(chunkcoordintpair)) { + if (this.b.containsKey(chunkcoordintpair)) { + return true; + } + } + + final RegionFile region = RegionFileCache.a(this.d, i, j, false); // PaperSpigot + return region != null && region.chunkExists(i & 31, j & 31); // PaperSpigot + } + // CraftBukkit end + + // CraftBukkit start - Add async variant, provide compatibility + public Chunk a(World world, int i, int j) throws IOException { + world.timings.syncChunkLoadDataTimer.startTiming(); // Spigot + Object[] data = loadChunk(world, i, j); + world.timings.syncChunkLoadDataTimer.stopTiming(); // Spigot + if (data != null) { + Chunk chunk = (Chunk) data[0]; + NBTTagCompound nbttagcompound = (NBTTagCompound) data[1]; + loadEntities(chunk, nbttagcompound.getCompound("Level"), world); + return chunk; + } + + return null; + } + + public Object[] loadChunk(World world, int i, int j) throws IOException { + // CraftBukkit end + ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j); + NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.get(chunkcoordintpair); + + if (nbttagcompound == null) { + DataInputStream datainputstream = RegionFileCache.c(this.d, i, j); + + if (datainputstream == null) { + return null; + } + + nbttagcompound = NBTCompressedStreamTools.a(datainputstream); + } + + return this.a(world, i, j, nbttagcompound); + } + + protected Object[] a(World world, int i, int j, NBTTagCompound nbttagcompound) { // CraftBukkit - return Chunk -> Object[] + if (!nbttagcompound.hasKeyOfType("Level", 10)) { + ChunkRegionLoader.a.error("Chunk file at " + i + "," + j + " is missing level data, skipping"); + return null; + } else { + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level"); + + if (!nbttagcompound1.hasKeyOfType("Sections", 9)) { + ChunkRegionLoader.a.error("Chunk file at " + i + "," + j + " is missing block data, skipping"); + return null; + } else { + Chunk chunk = this.a(world, nbttagcompound1); + + if (!chunk.a(i, j)) { + ChunkRegionLoader.a.error("Chunk file at " + i + "," + j + " is in the wrong location; relocating. (Expected " + i + ", " + j + ", got " + chunk.locX + ", " + chunk.locZ + ")"); + nbttagcompound1.setInt("xPos", i); + nbttagcompound1.setInt("zPos", j); + + // CraftBukkit start - Have to move tile entities since we don't load them at this stage + NBTTagList tileEntities = nbttagcompound.getCompound("Level").getList("TileEntities", 10); + if (tileEntities != null) { + for (int te = 0; te < tileEntities.size(); te++) { + NBTTagCompound tileEntity = (NBTTagCompound) tileEntities.get(te); + int x = tileEntity.getInt("x") - chunk.locX * 16; + int z = tileEntity.getInt("z") - chunk.locZ * 16; + tileEntity.setInt("x", i * 16 + x); + tileEntity.setInt("z", j * 16 + z); + } + } + // CraftBukkit end + chunk = this.a(world, nbttagcompound1); + } + + // CraftBukkit start + Object[] data = new Object[2]; + data[0] = chunk; + data[1] = nbttagcompound; + return data; + // CraftBukkit end + } + } + } + + public void a(World world, Chunk chunk) throws IOException, ExceptionWorldConflict { + world.checkSession(); + + try { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound.set("Level", nbttagcompound1); + this.a(chunk, world, nbttagcompound1); + this.a(chunk.j(), nbttagcompound); + } catch (Exception exception) { + ChunkRegionLoader.a.error("Failed to save chunk", exception); + } + + } + + protected void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) { + if (!this.c.contains(chunkcoordintpair)) { + this.b.put(chunkcoordintpair, nbttagcompound); + } + + FileIOThread.a().a(this); + } + + public boolean c() { + if (this.b.isEmpty()) { + if (this.e) { + ChunkRegionLoader.a.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", new Object[] { this.d.getName()}); + } + + return false; + } else { + ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) this.b.keySet().iterator().next(); + + boolean flag; + + try { + this.c.add(chunkcoordintpair); + NBTTagCompound nbttagcompound = (NBTTagCompound) this.b.remove(chunkcoordintpair); + + if (nbttagcompound != null) { + try { + this.b(chunkcoordintpair, nbttagcompound); + } catch (Exception exception) { + ChunkRegionLoader.a.error("Failed to save chunk", exception); + } + } + + flag = true; + } finally { + this.c.remove(chunkcoordintpair); + } + + return flag; + } + } + + private void b(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { + DataOutputStream dataoutputstream = RegionFileCache.d(this.d, chunkcoordintpair.x, chunkcoordintpair.z); + + NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream); + dataoutputstream.close(); + } + + public void b(World world, Chunk chunk) throws IOException {} + + public void a() {} + + public void b() { + try { + this.e = true; + + while (true) { + if (this.c()) { + continue; + } + } + } finally { + this.e = false; + } + + } + + private void a(Chunk chunk, World world, NBTTagCompound nbttagcompound) { + nbttagcompound.setByte("V", (byte) 1); + nbttagcompound.setInt("xPos", chunk.locX); + nbttagcompound.setInt("zPos", chunk.locZ); + nbttagcompound.setLong("LastUpdate", world.getTime()); + nbttagcompound.setIntArray("HeightMap", chunk.q()); + nbttagcompound.setBoolean("TerrainPopulated", chunk.isDone()); + nbttagcompound.setBoolean("LightPopulated", chunk.u()); + nbttagcompound.setLong("InhabitedTime", chunk.w()); + ChunkSection[] achunksection = chunk.getSections(); + NBTTagList nbttaglist = new NBTTagList(); + boolean flag = !world.worldProvider.o(); + ChunkSection[] achunksection1 = achunksection; + int i = achunksection.length; + + NBTTagCompound nbttagcompound1; + + for (int j = 0; j < i; ++j) { + ChunkSection chunksection = achunksection1[j]; + + if (chunksection != null) { + nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Y", (byte) (chunksection.getYPosition() >> 4 & 255)); + byte[] abyte = new byte[chunksection.getIdArray().length]; + NibbleArray nibblearray = new NibbleArray(); + NibbleArray nibblearray1 = null; + + for (int k = 0; k < chunksection.getIdArray().length; ++k) { + char c0 = chunksection.getIdArray()[k]; + int l = k & 15; + int i1 = k >> 8 & 15; + int j1 = k >> 4 & 15; + + if (c0 >> 12 != 0) { + if (nibblearray1 == null) { + nibblearray1 = new NibbleArray(); + } + + nibblearray1.a(l, i1, j1, c0 >> 12); + } + + abyte[k] = (byte) (c0 >> 4 & 255); + nibblearray.a(l, i1, j1, c0 & 15); + } + + nbttagcompound1.setByteArray("Blocks", abyte); + nbttagcompound1.setByteArray("Data", nibblearray.a()); + if (nibblearray1 != null) { + nbttagcompound1.setByteArray("Add", nibblearray1.a()); + } + + nbttagcompound1.setByteArray("BlockLight", chunksection.getEmittedLightArray().a()); + if (flag) { + nbttagcompound1.setByteArray("SkyLight", chunksection.getSkyLightArray().a()); + } else { + nbttagcompound1.setByteArray("SkyLight", new byte[chunksection.getEmittedLightArray().a().length]); + } + + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Sections", nbttaglist); + nbttagcompound.setByteArray("Biomes", chunk.getBiomeIndex()); + chunk.g(false); + NBTTagList nbttaglist1 = new NBTTagList(); + + Iterator iterator; + + for (i = 0; i < chunk.getEntitySlices().length; ++i) { + iterator = chunk.getEntitySlices()[i].iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + nbttagcompound1 = new NBTTagCompound(); + if (entity.d(nbttagcompound1)) { + chunk.g(true); + nbttaglist1.add(nbttagcompound1); + } + } + } + + nbttagcompound.set("Entities", nbttaglist1); + NBTTagList nbttaglist2 = new NBTTagList(); + + iterator = chunk.getTileEntities().values().iterator(); + + while (iterator.hasNext()) { + TileEntity tileentity = (TileEntity) iterator.next(); + + nbttagcompound1 = new NBTTagCompound(); + tileentity.b(nbttagcompound1); + nbttaglist2.add(nbttagcompound1); + } + + nbttagcompound.set("TileEntities", nbttaglist2); + List list = world.a(chunk, false); + + if (list != null) { + long k1 = world.getTime(); + NBTTagList nbttaglist3 = new NBTTagList(); + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { + NextTickListEntry nextticklistentry = (NextTickListEntry) iterator1.next(); + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); + MinecraftKey minecraftkey = (MinecraftKey) Block.REGISTRY.c(nextticklistentry.a()); + + nbttagcompound2.setString("i", minecraftkey == null ? "" : minecraftkey.toString()); + nbttagcompound2.setInt("x", nextticklistentry.a.getX()); + nbttagcompound2.setInt("y", nextticklistentry.a.getY()); + nbttagcompound2.setInt("z", nextticklistentry.a.getZ()); + nbttagcompound2.setInt("t", (int) (nextticklistentry.b - k1)); + nbttagcompound2.setInt("p", nextticklistentry.c); + nbttaglist3.add(nbttagcompound2); + } + + nbttagcompound.set("TileTicks", nbttaglist3); + } + + } + + private Chunk a(World world, NBTTagCompound nbttagcompound) { + int i = nbttagcompound.getInt("xPos"); + int j = nbttagcompound.getInt("zPos"); + Chunk chunk = new Chunk(world, i, j); + + chunk.a(nbttagcompound.getIntArray("HeightMap")); + chunk.d(nbttagcompound.getBoolean("TerrainPopulated")); + chunk.e(nbttagcompound.getBoolean("LightPopulated")); + chunk.c(nbttagcompound.getLong("InhabitedTime")); + NBTTagList nbttaglist = nbttagcompound.getList("Sections", 10); + byte b0 = 16; + ChunkSection[] achunksection = new ChunkSection[b0]; + boolean flag = !world.worldProvider.o(); + + for (int k = 0; k < nbttaglist.size(); ++k) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(k); + byte b1 = nbttagcompound1.getByte("Y"); + ChunkSection chunksection = new ChunkSection(b1 << 4, flag); + byte[] abyte = nbttagcompound1.getByteArray("Blocks"); + NibbleArray nibblearray = new NibbleArray(nbttagcompound1.getByteArray("Data")); + NibbleArray nibblearray1 = nbttagcompound1.hasKeyOfType("Add", 7) ? new NibbleArray(nbttagcompound1.getByteArray("Add")) : null; + char[] achar = new char[abyte.length]; + + for (int l = 0; l < achar.length; ++l) { + int i1 = l & 15; + int j1 = l >> 8 & 15; + int k1 = l >> 4 & 15; + int l1 = nibblearray1 != null ? nibblearray1.a(i1, j1, k1) : 0; + + // CraftBukkit start - fix broken blocks + // achar[l] = (char) (l1 << 12 | (abyte[l] & 255) << 4 | nibblearray.a(i1, j1, k1)); + + int ex = l1; + int id = (abyte[l] & 255); + int data = nibblearray.a(i1, j1, k1); + int packed = ex << 12 | id << 4 | data; + if (Block.d.a(packed) == null) { + Block block = Block.getById(ex << 8 | id); + if (block != null) { + try { + data = block.toLegacyData(block.fromLegacyData(data)); + } catch (Exception ignored) { + data = block.toLegacyData(block.getBlockData()); + } + packed = ex << 12 | id << 4 | data; + } + } + achar[l] = (char) packed; + // CraftBukkit end + } + + chunksection.a(achar); + chunksection.a(new NibbleArray(nbttagcompound1.getByteArray("BlockLight"))); + if (flag) { + chunksection.b(new NibbleArray(nbttagcompound1.getByteArray("SkyLight"))); + } + + chunksection.recalcBlockCounts(); + achunksection[b1] = chunksection; + } + + chunk.a(achunksection); + if (nbttagcompound.hasKeyOfType("Biomes", 7)) { + chunk.a(nbttagcompound.getByteArray("Biomes")); + } + + // CraftBukkit start - End this method here and split off entity loading to another method + return chunk; + } + + public void loadEntities(Chunk chunk, NBTTagCompound nbttagcompound, World world) { + // CraftBukkit end + world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot + NBTTagList nbttaglist1 = nbttagcompound.getList("Entities", 10); + + if (nbttaglist1 != null) { + for (int i2 = 0; i2 < nbttaglist1.size(); ++i2) { + NBTTagCompound nbttagcompound2 = nbttaglist1.get(i2); + Entity entity = EntityTypes.a(nbttagcompound2, world); + + chunk.g(true); + if (entity != null) { + chunk.a(entity); + Entity entity1 = entity; + + for (NBTTagCompound nbttagcompound3 = nbttagcompound2; nbttagcompound3.hasKeyOfType("Riding", 10); nbttagcompound3 = nbttagcompound3.getCompound("Riding")) { + Entity entity2 = EntityTypes.a(nbttagcompound3.getCompound("Riding"), world); + + if (entity2 != null) { + chunk.a(entity2); + entity1.mount(entity2); + } + + entity1 = entity2; + } + } + } + } + world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot + world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot + NBTTagList nbttaglist2 = nbttagcompound.getList("TileEntities", 10); + + if (nbttaglist2 != null) { + for (int j2 = 0; j2 < nbttaglist2.size(); ++j2) { + NBTTagCompound nbttagcompound4 = nbttaglist2.get(j2); + TileEntity tileentity = TileEntity.c(nbttagcompound4); + + if (tileentity != null) { + chunk.a(tileentity); + } + } + } + world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot + world.timings.syncChunkLoadTileTicksTimer.startTiming(); // Spigot + + if (nbttagcompound.hasKeyOfType("TileTicks", 9)) { + NBTTagList nbttaglist3 = nbttagcompound.getList("TileTicks", 10); + + if (nbttaglist3 != null) { + for (int k2 = 0; k2 < nbttaglist3.size(); ++k2) { + NBTTagCompound nbttagcompound5 = nbttaglist3.get(k2); + Block block; + + if (nbttagcompound5.hasKeyOfType("i", 8)) { + block = Block.getByName(nbttagcompound5.getString("i")); + } else { + block = Block.getById(nbttagcompound5.getInt("i")); + } + + world.b(new BlockPosition(nbttagcompound5.getInt("x"), nbttagcompound5.getInt("y"), nbttagcompound5.getInt("z")), block, nbttagcompound5.getInt("t"), nbttagcompound5.getInt("p")); + } + } + } + world.timings.syncChunkLoadTileTicksTimer.stopTiming(); // Spigot + + // return chunk; // CraftBukkit + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkSection.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkSection.java new file mode 100644 index 0000000..907c57b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ChunkSection.java @@ -0,0 +1,148 @@ +package net.minecraft.server; + +public class ChunkSection { + + private int yPos; + private int nonEmptyBlockCount; + private int tickingBlockCount; + private char[] blockIds; + private NibbleArray emittedLight; + private NibbleArray skyLight; + boolean isDirty; // PaperSpigot + + public ChunkSection(int i, boolean flag) { + this.yPos = i; + this.blockIds = new char[4096]; + this.emittedLight = new NibbleArray(); + if (flag) { + this.skyLight = new NibbleArray(); + } + + } + + // CraftBukkit start + public ChunkSection(int y, boolean flag, char[] blockIds) { + this.yPos = y; + this.blockIds = blockIds; + this.emittedLight = new NibbleArray(); + if (flag) { + this.skyLight = new NibbleArray(); + } + recalcBlockCounts(); + } + // CraftBukkit end + + public IBlockData getType(int i, int j, int k) { + IBlockData iblockdata = (IBlockData) Block.d.a(this.blockIds[j << 8 | k << 4 | i]); + + return iblockdata != null ? iblockdata : Blocks.AIR.getBlockData(); + } + + public void setType(int i, int j, int k, IBlockData iblockdata) { + IBlockData iblockdata1 = this.getType(i, j, k); + Block block = iblockdata1.getBlock(); + Block block1 = iblockdata.getBlock(); + + if (block != Blocks.AIR) { + --this.nonEmptyBlockCount; + if (block.isTicking()) { + --this.tickingBlockCount; + } + } + + if (block1 != Blocks.AIR) { + ++this.nonEmptyBlockCount; + if (block1.isTicking()) { + ++this.tickingBlockCount; + } + } + + this.blockIds[j << 8 | k << 4 | i] = (char) Block.d.b(iblockdata); + isDirty = true; // PaperSpigot + } + + public Block b(int i, int j, int k) { + return this.getType(i, j, k).getBlock(); + } + + public int c(int i, int j, int k) { + IBlockData iblockdata = this.getType(i, j, k); + + return iblockdata.getBlock().toLegacyData(iblockdata); + } + + public boolean a() { + return this.nonEmptyBlockCount == 0; + } + + public boolean shouldTick() { + return this.tickingBlockCount > 0; + } + + public int getYPosition() { + return this.yPos; + } + + public void a(int i, int j, int k, int l) { + this.skyLight.a(i, j, k, l); + isDirty = true; // PaperSpigot + } + + public int d(int i, int j, int k) { + return this.skyLight.a(i, j, k); + } + + public void b(int i, int j, int k, int l) { + this.emittedLight.a(i, j, k, l); + isDirty = true; // PaperSpigot + } + + public int e(int i, int j, int k) { + return this.emittedLight.a(i, j, k); + } + + public void recalcBlockCounts() { + this.nonEmptyBlockCount = 0; + this.tickingBlockCount = 0; + + for (int i = 0; i < 16; ++i) { + for (int j = 0; j < 16; ++j) { + for (int k = 0; k < 16; ++k) { + Block block = this.b(i, j, k); + + if (block != Blocks.AIR) { + ++this.nonEmptyBlockCount; + if (block.isTicking()) { + ++this.tickingBlockCount; + } + } + } + } + } + + } + + public char[] getIdArray() { + return this.blockIds; + } + + public void a(char[] achar) { + this.blockIds = achar; + } + + public NibbleArray getEmittedLightArray() { + return this.emittedLight; + } + + public NibbleArray getSkyLightArray() { + return this.skyLight; + } + + public void a(NibbleArray nibblearray) { + this.emittedLight = nibblearray; + } + + public void b(NibbleArray nibblearray) { + this.skyLight = nibblearray; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java new file mode 100644 index 0000000..b1e8834 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java @@ -0,0 +1,313 @@ +package net.minecraft.server; + +import com.google.common.base.Joiner; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import org.bukkit.craftbukkit.command.VanillaCommandWrapper; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.concurrent.Callable; +import java.util.logging.Level; + +// CraftBukkit start +// CraftBukkit end + +public abstract class CommandBlockListenerAbstract implements ICommandListener { + + private static final SimpleDateFormat a = new SimpleDateFormat("HH:mm:ss"); + private int b; + private boolean c = true; + private IChatBaseComponent d = null; + private String e = ""; + private String f = "@"; + private final CommandObjectiveExecutor g = new CommandObjectiveExecutor(); + protected org.bukkit.command.CommandSender sender; // CraftBukkit - add sender + + public CommandBlockListenerAbstract() {} + + public int j() { + return this.b; + } + + public IChatBaseComponent k() { + return this.d; + } + + public void a(NBTTagCompound nbttagcompound) { + nbttagcompound.setString("Command", this.e); + nbttagcompound.setInt("SuccessCount", this.b); + nbttagcompound.setString("CustomName", this.f); + nbttagcompound.setBoolean("TrackOutput", this.c); + if (this.d != null && this.c) { + nbttagcompound.setString("LastOutput", IChatBaseComponent.ChatSerializer.a(this.d)); + } + + this.g.b(nbttagcompound); + } + + public void b(NBTTagCompound nbttagcompound) { + this.e = nbttagcompound.getString("Command"); + this.b = nbttagcompound.getInt("SuccessCount"); + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.f = nbttagcompound.getString("CustomName"); + } + + if (nbttagcompound.hasKeyOfType("TrackOutput", 1)) { + this.c = nbttagcompound.getBoolean("TrackOutput"); + } + + if (nbttagcompound.hasKeyOfType("LastOutput", 8) && this.c) { + this.d = IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("LastOutput")); + } + + this.g.a(nbttagcompound); + } + + public boolean a(int i, String s) { + return i <= 2; + } + + public void setCommand(String s) { + this.e = s; + this.b = 0; + } + + public String getCommand() { + return this.e; + } + + public void a(World world) { + if (world.isClientSide) { + this.b = 0; + } + + MinecraftServer minecraftserver = MinecraftServer.getServer(); + + if (minecraftserver != null && minecraftserver.O() && minecraftserver.getEnableCommandBlock()) { + ICommandHandler icommandhandler = minecraftserver.getCommandHandler(); + + try { + this.d = null; + // this.b = icommandhandler.a(this, this.e); + // CraftBukkit start - Handle command block commands using Bukkit dispatcher + this.b = executeCommand(this, sender, this.e); + // CraftBukkit end + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Executing command block"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Command to be executed"); + + crashreportsystemdetails.a("Command", new Callable() { + public String a() throws Exception { + return CommandBlockListenerAbstract.this.getCommand(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Name", new Callable() { + public String a() throws Exception { + return CommandBlockListenerAbstract.this.getName(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } else { + this.b = 0; + } + + } + + // CraftBukkit start + public static int executeCommand(ICommandListener sender, org.bukkit.command.CommandSender bSender, String command) { + org.bukkit.command.SimpleCommandMap commandMap = sender.getWorld().getServer().getCommandMap(); + Joiner joiner = Joiner.on(" "); + if (command.startsWith("/")) { + command = command.substring(1); + } + String[] args = command.split(" "); + ArrayList commands = new ArrayList(); + + String cmd = args[0]; + if (cmd.startsWith("minecraft:")) cmd = cmd.substring("minecraft:".length()); + if (cmd.startsWith("bukkit:")) cmd = cmd.substring("bukkit:".length()); + + // Block disallowed commands + if (cmd.equalsIgnoreCase("stop") || cmd.equalsIgnoreCase("kick") || cmd.equalsIgnoreCase("op") + || cmd.equalsIgnoreCase("deop") || cmd.equalsIgnoreCase("ban") || cmd.equalsIgnoreCase("ban-ip") + || cmd.equalsIgnoreCase("pardon") || cmd.equalsIgnoreCase("pardon-ip") || cmd.equalsIgnoreCase("reload")) { + return 0; + } + + // If the world has no players don't run + if (sender.getWorld().players.isEmpty()) { + return 0; + } + + // Handle vanilla commands; + org.bukkit.command.Command commandBlockCommand = commandMap.getCommand(args[0]); + if (sender.getWorld().getServer().getCommandBlockOverride(args[0])) { + commandBlockCommand = commandMap.getCommand("minecraft:" + args[0]); + } + if (commandBlockCommand instanceof VanillaCommandWrapper) { + command = command.trim(); + if (command.startsWith("/")) { + command = command.substring(1); + } + String[] as = command.split(" "); + as = VanillaCommandWrapper.dropFirstArgument(as); + if (!commandBlockCommand.testPermission(bSender)) { + return 0; + } + return ((VanillaCommandWrapper) commandBlockCommand).dispatchVanillaCommand(bSender, sender, as); + } + + // Make sure this is a valid command + if (commandMap.getCommand(args[0]) == null) { + return 0; + } + + commands.add(args); + + // Find positions of command block syntax, if any + WorldServer[] prev = MinecraftServer.getServer().worldServer; + MinecraftServer server = MinecraftServer.getServer(); + server.worldServer = new WorldServer[server.worlds.size()]; + server.worldServer[0] = (WorldServer) sender.getWorld(); + int bpos = 0; + for (int pos = 1; pos < server.worldServer.length; pos++) { + WorldServer world = server.worlds.get(bpos++); + if (server.worldServer[0] == world) { + pos--; + continue; + } + server.worldServer[pos] = world; + } + try { + ArrayList newCommands = new ArrayList(); + for (int i = 0; i < args.length; i++) { + if (PlayerSelector.isPattern(args[i])) { + for (int j = 0; j < commands.size(); j++) { + newCommands.addAll(buildCommands(sender, commands.get(j), i)); + } + ArrayList temp = commands; + commands = newCommands; + newCommands = temp; + newCommands.clear(); + } + } + } finally { + MinecraftServer.getServer().worldServer = prev; + } + + int completed = 0; + + // Now dispatch all of the commands we ended up with + for (int i = 0; i < commands.size(); i++) { + try { + if (commandMap.dispatch(bSender, joiner.join(java.util.Arrays.asList(commands.get(i))))) { + completed++; + } + } catch (Throwable exception) { + if (sender.f() instanceof EntityMinecartCommandBlock) { + MinecraftServer.getServer().server.getLogger().log(Level.WARNING, String.format("MinecartCommandBlock at (%d,%d,%d) failed to handle command", sender.getChunkCoordinates().getX(), sender.getChunkCoordinates().getY(), sender.getChunkCoordinates().getZ()), exception); + } else if (sender instanceof CommandBlockListenerAbstract) { + CommandBlockListenerAbstract listener = (CommandBlockListenerAbstract) sender; + MinecraftServer.getServer().server.getLogger().log(Level.WARNING, String.format("CommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().getX(), listener.getChunkCoordinates().getY(), listener.getChunkCoordinates().getZ()), exception); + } else { + MinecraftServer.getServer().server.getLogger().log(Level.WARNING, String.format("Unknown CommandBlock failed to handle command"), exception); + } + } + } + + return completed; + } + + private static ArrayList buildCommands(ICommandListener sender, String[] args, int pos) { + ArrayList commands = new ArrayList(); + java.util.List players = PlayerSelector.getPlayers(sender, args[pos], EntityPlayer.class); + + if (players != null) { + for (EntityPlayer player : players) { + if (player.world != sender.getWorld()) { + continue; + } + String[] command = args.clone(); + command[pos] = player.getName(); + commands.add(command); + } + } + + return commands; + } + // CraftBukkit end + + public String getName() { + return this.f; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return new ChatComponentText(this.getName()); + } + + public void setName(String s) { + this.f = s; + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + if (this.c && this.getWorld() != null && !this.getWorld().isClientSide) { + this.d = (new ChatComponentText("[" + CommandBlockListenerAbstract.a.format(new Date()) + "] ")).addSibling(ichatbasecomponent); + this.h(); + } + + } + + public boolean getSendCommandFeedback() { + MinecraftServer minecraftserver = MinecraftServer.getServer(); + + return minecraftserver == null || !minecraftserver.O() || minecraftserver.worldServer[0].getGameRules().getBoolean("commandBlockOutput"); + } + + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) { + this.g.a(this, commandobjectiveexecutor_enumcommandresult, i); + } + + public abstract void h(); + + public void b(IChatBaseComponent ichatbasecomponent) { + this.d = ichatbasecomponent; + } + + public void a(boolean flag) { + this.c = flag; + } + + public boolean m() { + return this.c; + } + + public boolean a(EntityHuman entityhuman) { + if (!entityhuman.abilities.canInstantlyBuild) { + return false; + } else { + if (entityhuman.getWorld().isClientSide) { + entityhuman.a(this); + } + + return true; + } + } + + public CommandObjectiveExecutor n() { + return this.g; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandDispatcher.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandDispatcher.java new file mode 100644 index 0000000..fc52287 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandDispatcher.java @@ -0,0 +1,118 @@ +package net.minecraft.server; + +import java.util.Iterator; + +public class CommandDispatcher extends CommandHandler implements ICommandDispatcher { + + public CommandDispatcher() { + this.a((ICommand) (new CommandTime())); + this.a((ICommand) (new CommandGamemode())); + this.a((ICommand) (new CommandDifficulty())); + this.a((ICommand) (new CommandGamemodeDefault())); + this.a((ICommand) (new CommandKill())); + this.a((ICommand) (new CommandToggleDownfall())); + this.a((ICommand) (new CommandWeather())); + this.a((ICommand) (new CommandXp())); + this.a((ICommand) (new CommandTp())); + this.a((ICommand) (new CommandGive())); + this.a((ICommand) (new CommandReplaceItem())); + this.a((ICommand) (new CommandStats())); + this.a((ICommand) (new CommandEffect())); + this.a((ICommand) (new CommandEnchant())); + this.a((ICommand) (new CommandParticle())); + this.a((ICommand) (new CommandMe())); + this.a((ICommand) (new CommandSeed())); + this.a((ICommand) (new CommandHelp())); + this.a((ICommand) (new CommandDebug())); + this.a((ICommand) (new CommandTell())); + this.a((ICommand) (new CommandSay())); + this.a((ICommand) (new CommandSpawnpoint())); + this.a((ICommand) (new CommandSetWorldSpawn())); + this.a((ICommand) (new CommandGamerule())); + this.a((ICommand) (new CommandClear())); + this.a((ICommand) (new CommandTestFor())); + this.a((ICommand) (new CommandSpreadPlayers())); + this.a((ICommand) (new CommandPlaySound())); + this.a((ICommand) (new CommandScoreboard())); + this.a((ICommand) (new CommandExecute())); + this.a((ICommand) (new CommandTrigger())); + this.a((ICommand) (new CommandAchievement())); + this.a((ICommand) (new CommandSummon())); + this.a((ICommand) (new CommandSetBlock())); + this.a((ICommand) (new CommandFill())); + this.a((ICommand) (new CommandClone())); + this.a((ICommand) (new CommandTestForBlocks())); + this.a((ICommand) (new CommandBlockData())); + this.a((ICommand) (new CommandTestForBlock())); + this.a((ICommand) (new CommandTellRaw())); + this.a((ICommand) (new CommandWorldBorder())); + this.a((ICommand) (new CommandTitle())); + this.a((ICommand) (new CommandEntityData())); + if (MinecraftServer.getServer().ae()) { + this.a((ICommand) (new CommandOp())); + this.a((ICommand) (new CommandDeop())); + this.a((ICommand) (new CommandStop())); + this.a((ICommand) (new CommandSaveAll())); + this.a((ICommand) (new CommandSaveOff())); + this.a((ICommand) (new CommandSaveOn())); + this.a((ICommand) (new CommandBanIp())); + this.a((ICommand) (new CommandPardonIP())); + this.a((ICommand) (new CommandBan())); + this.a((ICommand) (new CommandBanList())); + this.a((ICommand) (new CommandPardon())); + this.a((ICommand) (new CommandKick())); + this.a((ICommand) (new CommandList())); + this.a((ICommand) (new CommandWhitelist())); + this.a((ICommand) (new CommandIdleTimeout())); + } else { + this.a((ICommand) (new CommandPublish())); + } + + CommandAbstract.a((ICommandDispatcher) this); + } + + public void a(ICommandListener icommandlistener, ICommand icommand, int i, String s, Object... aobject) { + boolean flag = true; + MinecraftServer minecraftserver = MinecraftServer.getServer(); + + if (!icommandlistener.getSendCommandFeedback()) { + flag = false; + } + + ChatMessage chatmessage = new ChatMessage("chat.type.admin", new Object[] { icommandlistener.getName(), new ChatMessage(s, aobject)}); + + chatmessage.getChatModifier().setColor(EnumChatFormat.GRAY); + chatmessage.getChatModifier().setItalic(Boolean.valueOf(true)); + if (flag) { + Iterator iterator = minecraftserver.getPlayerList().v().iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (entityhuman != icommandlistener && minecraftserver.getPlayerList().isOp(entityhuman.getProfile()) && icommand.canUse(icommandlistener)) { + boolean flag1 = icommandlistener instanceof MinecraftServer && MinecraftServer.getServer().r(); + boolean flag2 = icommandlistener instanceof RemoteControlCommandListener && MinecraftServer.getServer().q(); + + if (flag1 || flag2 || !(icommandlistener instanceof RemoteControlCommandListener) && !(icommandlistener instanceof MinecraftServer)) { + entityhuman.sendMessage(chatmessage); + } + } + } + } + + if (icommandlistener != minecraftserver && minecraftserver.worldServer[0].getGameRules().getBoolean("logAdminCommands") && !org.spigotmc.SpigotConfig.silentCommandBlocks) { // Spigot + minecraftserver.sendMessage(chatmessage); + } + + boolean flag3 = minecraftserver.worldServer[0].getGameRules().getBoolean("sendCommandFeedback"); + + if (icommandlistener instanceof CommandBlockListenerAbstract) { + flag3 = ((CommandBlockListenerAbstract) icommandlistener).m(); + } + + if ((i & 1) != 1 && flag3 || icommandlistener instanceof MinecraftServer) { + icommandlistener.sendMessage(new ChatMessage(s, aobject)); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandExecute.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandExecute.java new file mode 100644 index 0000000..1dc8e36 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandExecute.java @@ -0,0 +1,145 @@ +package net.minecraft.server; + +import java.util.Collection; +import java.util.List; +// CraftBukkit start +import org.bukkit.craftbukkit.command.ProxiedNativeCommandSender; +import org.bukkit.craftbukkit.command.VanillaCommandWrapper; +// CraftBukkit end + +public class CommandExecute extends CommandAbstract { + + public CommandExecute() {} + + public String getCommand() { + return "execute"; + } + + public int a() { + return 2; + } + + public String getUsage(ICommandListener icommandlistener) { + return "commands.execute.usage"; + } + + public void execute(final ICommandListener icommandlistener, String[] astring) throws CommandException { + if (astring.length < 5) { + throw new ExceptionUsage("commands.execute.usage", new Object[0]); + } else { + final Entity entity = a(icommandlistener, astring[0], Entity.class); + final double d0 = b(entity.locX, astring[1], false); + final double d1 = b(entity.locY, astring[2], false); + final double d2 = b(entity.locZ, astring[3], false); + final BlockPosition blockposition = new BlockPosition(d0, d1, d2); + byte b0 = 4; + + if ("detect".equals(astring[4]) && astring.length > 10) { + World world = entity.getWorld(); + double d3 = b(d0, astring[5], false); + double d4 = b(d1, astring[6], false); + double d5 = b(d2, astring[7], false); + Block block = g(icommandlistener, astring[8]); + int i = a(astring[9], -1, 15); + BlockPosition blockposition1 = new BlockPosition(d3, d4, d5); + IBlockData iblockdata = world.getType(blockposition1); + + if (iblockdata.getBlock() != block || i >= 0 && iblockdata.getBlock().toLegacyData(iblockdata) != i) { + throw new CommandException("commands.execute.failed", new Object[] { "detect", entity.getName()}); + } + + b0 = 10; + } + + String s = a(astring, b0); + ICommandListener icommandlistener1 = new ICommandListener() { + public String getName() { + return entity.getName(); + } + + public IChatBaseComponent getScoreboardDisplayName() { + return entity.getScoreboardDisplayName(); + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + icommandlistener.sendMessage(ichatbasecomponent); + } + + public boolean a(int i, String s) { + return icommandlistener.a(i, s); + } + + public BlockPosition getChunkCoordinates() { + return blockposition; + } + + public Vec3D d() { + return new Vec3D(d0, d1, d2); + } + + public World getWorld() { + return entity.world; + } + + public Entity f() { + return entity; + } + + public boolean getSendCommandFeedback() { + MinecraftServer minecraftserver = MinecraftServer.getServer(); + + return minecraftserver == null || minecraftserver.worldServer[0].getGameRules().getBoolean("commandBlockOutput"); + } + + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) { + entity.a(commandobjectiveexecutor_enumcommandresult, i); + } + }; + ICommandHandler icommandhandler = MinecraftServer.getServer().getCommandHandler(); + + try { + // CraftBukkit start + org.bukkit.command.CommandSender sender = null; + if (icommandlistener instanceof DedicatedServer) { + sender = MinecraftServer.getServer().server.getConsoleSender(); + } else if (icommandlistener instanceof CommandBlockListenerAbstract) { + sender = ((CommandBlockListenerAbstract) icommandlistener).sender; + } else if (VanillaCommandWrapper.lastSender != null) { + sender = VanillaCommandWrapper.lastSender; + }else if (icommandlistener.f() != null) { + sender = icommandlistener.f().getBukkitEntity(); + } else { + throw new CommandException("Unhandled executor " + icommandlistener.getClass().getSimpleName(), new Object[0]); + } + int j = CommandBlockListenerAbstract.executeCommand(icommandlistener1, new ProxiedNativeCommandSender(icommandlistener1, sender, entity.getBukkitEntity()), s); + // CraftBukkit end + + if (j < 1) { + throw new CommandException("commands.execute.allInvocationsFailed", new Object[] { s}); + } + } catch (Throwable throwable) { + // CraftBukkit start + if (throwable instanceof CommandException) { + throw (CommandException) throwable; + } + // CraftBukkit end + throw new CommandException("commands.execute.failed", new Object[] { s, entity.getName()}); + } + } + } + + public List tabComplete(ICommandListener icommandlistener, String[] astring, BlockPosition blockposition) { + return astring.length == 1 ? a(astring, MinecraftServer.getServer().getPlayers()) : (astring.length > 1 && astring.length <= 4 ? a(astring, 1, blockposition) : (astring.length > 5 && astring.length <= 8 && "detect".equals(astring[4]) ? a(astring, 5, blockposition) : (astring.length == 9 && "detect".equals(astring[4]) ? a(astring, (Collection) Block.REGISTRY.keySet()) : null))); + } + + public boolean isListStart(String[] astring, int i) { + return i == 0; + } + + // CraftBukkit start - fix decompiler error + @Override + public int compareTo(ICommand o) { + return a((ICommand) o); + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandGamemode.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandGamemode.java new file mode 100644 index 0000000..abd23e7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandGamemode.java @@ -0,0 +1,74 @@ +package net.minecraft.server; + +import java.util.List; + +public class CommandGamemode extends CommandAbstract { + + public CommandGamemode() {} + + public String getCommand() { + return "gamemode"; + } + + public int a() { + return 2; + } + + public String getUsage(ICommandListener icommandlistener) { + return "commands.gamemode.usage"; + } + + public void execute(ICommandListener icommandlistener, String[] astring) throws CommandException { + if (astring.length <= 0) { + throw new ExceptionUsage("commands.gamemode.usage", new Object[0]); + } else { + WorldSettings.EnumGamemode worldsettings_enumgamemode = this.h(icommandlistener, astring[0]); + EntityPlayer entityplayer = astring.length >= 2 ? a(icommandlistener, astring[1]) : b(icommandlistener); + + entityplayer.a(worldsettings_enumgamemode); + // CraftBukkit start - handle event cancelling the change + if (entityplayer.playerInteractManager.getGameMode() != worldsettings_enumgamemode) { + icommandlistener.sendMessage(new ChatComponentText("Failed to set the gamemode of '" + entityplayer.getName() + "'")); + return; + } + // CraftBukkit end + + entityplayer.fallDistance = 0.0F; + if (icommandlistener.getWorld().getGameRules().getBoolean("sendCommandFeedback")) { + entityplayer.sendMessage(new ChatMessage("gameMode.changed", new Object[0])); + } + + ChatMessage chatmessage = new ChatMessage("gameMode." + worldsettings_enumgamemode.b(), new Object[0]); + + if (entityplayer != icommandlistener) { + a(icommandlistener, this, 1, "commands.gamemode.success.other", new Object[] { entityplayer.getName(), chatmessage}); + } else { + a(icommandlistener, this, 1, "commands.gamemode.success.self", new Object[] { chatmessage}); + } + + } + } + + protected WorldSettings.EnumGamemode h(ICommandListener icommandlistener, String s) throws ExceptionInvalidNumber { + return !s.equalsIgnoreCase(WorldSettings.EnumGamemode.SURVIVAL.b()) && !s.equalsIgnoreCase("s") ? (!s.equalsIgnoreCase(WorldSettings.EnumGamemode.CREATIVE.b()) && !s.equalsIgnoreCase("c") ? (!s.equalsIgnoreCase(WorldSettings.EnumGamemode.ADVENTURE.b()) && !s.equalsIgnoreCase("a") ? (!s.equalsIgnoreCase(WorldSettings.EnumGamemode.SPECTATOR.b()) && !s.equalsIgnoreCase("sp") ? WorldSettings.a(a(s, 0, WorldSettings.EnumGamemode.values().length - 2)) : WorldSettings.EnumGamemode.SPECTATOR) : WorldSettings.EnumGamemode.ADVENTURE) : WorldSettings.EnumGamemode.CREATIVE) : WorldSettings.EnumGamemode.SURVIVAL; + } + + public List tabComplete(ICommandListener icommandlistener, String[] astring, BlockPosition blockposition) { + return astring.length == 1 ? a(astring, new String[] { "survival", "creative", "adventure", "spectator"}) : (astring.length == 2 ? a(astring, this.d()) : null); + } + + protected String[] d() { + return MinecraftServer.getServer().getPlayers(); + } + + public boolean isListStart(String[] astring, int i) { + return i == 1; + } + + // CraftBukkit start - fix decompiler error + @Override + public int compareTo(ICommand o) { + return a((ICommand) o); + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandGamerule.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandGamerule.java new file mode 100644 index 0000000..cabbe5b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandGamerule.java @@ -0,0 +1,95 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +public class CommandGamerule extends CommandAbstract { + + public CommandGamerule() {} + + public String getCommand() { + return "gamerule"; + } + + public int a() { + return 2; + } + + public String getUsage(ICommandListener icommandlistener) { + return "commands.gamerule.usage"; + } + + public void execute(ICommandListener icommandlistener, String[] astring) throws CommandException { + GameRules gamerules = icommandlistener.getWorld().getGameRules(); // CraftBukkit - Use current world + String s = astring.length > 0 ? astring[0] : ""; + String s1 = astring.length > 1 ? a(astring, 1) : ""; + + switch (astring.length) { + case 0: + icommandlistener.sendMessage(new ChatComponentText(a((Object[]) gamerules.getGameRules()))); + break; + + case 1: + if (!gamerules.contains(s)) { + throw new CommandException("commands.gamerule.norule", new Object[] { s}); + } + + String s2 = gamerules.get(s); + + icommandlistener.sendMessage((new ChatComponentText(s)).a(" = ").a(s2)); + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.QUERY_RESULT, gamerules.c(s)); + break; + + default: + if (gamerules.a(s, GameRules.EnumGameRuleType.BOOLEAN_VALUE) && !"true".equals(s1) && !"false".equals(s1)) { + throw new CommandException("commands.generic.boolean.invalid", new Object[] { s1}); + } + + gamerules.set(s, s1); + a(gamerules, s); + a(icommandlistener, this, "commands.gamerule.success", new Object[0]); + } + + } + + public static void a(GameRules gamerules, String s) { + if ("reducedDebugInfo".equals(s)) { + int i = gamerules.getBoolean(s) ? 22 : 23; + Iterator iterator = MinecraftServer.getServer().getPlayerList().v().iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityStatus(entityplayer, (byte) i)); + } + } + + } + + public List tabComplete(ICommandListener icommandlistener, String[] astring, BlockPosition blockposition) { + if (astring.length == 1) { + return a(astring, this.d().getGameRules()); + } else { + if (astring.length == 2) { + GameRules gamerules = this.d(); + + if (gamerules.a(astring[0], GameRules.EnumGameRuleType.BOOLEAN_VALUE)) { + return a(astring, new String[] { "true", "false"}); + } + } + + return null; + } + } + + private GameRules d() { + return MinecraftServer.getServer().getWorldServer(0).getGameRules(); + } + + // CraftBukkit start - fix decompile error + @Override + public int compareTo(ICommand o) { + return a((ICommand) o); + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandScoreboard.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandScoreboard.java new file mode 100644 index 0000000..3acb074 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandScoreboard.java @@ -0,0 +1,1011 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class CommandScoreboard extends CommandAbstract { + + // TacoSpigot start - fix compile errors + @Override + public int compareTo(ICommand o) { + return super.a(o); + } + // TacoSpigot end + + public CommandScoreboard() {} + + public String getCommand() { + return "scoreboard"; + } + + public int a() { + return 2; + } + + public String getUsage(ICommandListener icommandlistener) { + return "commands.scoreboard.usage"; + } + + public void execute(ICommandListener icommandlistener, String[] astring) throws CommandException { + if (!this.b(icommandlistener, astring)) { + if (astring.length < 1) { + throw new ExceptionUsage("commands.scoreboard.usage", new Object[0]); + } else { + if (astring[0].equalsIgnoreCase("objectives")) { + if (astring.length == 1) { + throw new ExceptionUsage("commands.scoreboard.objectives.usage", new Object[0]); + } + + if (astring[1].equalsIgnoreCase("list")) { + this.d(icommandlistener); + } else if (astring[1].equalsIgnoreCase("add")) { + if (astring.length < 4) { + throw new ExceptionUsage("commands.scoreboard.objectives.add.usage", new Object[0]); + } + + this.b(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("remove")) { + if (astring.length != 3) { + throw new ExceptionUsage("commands.scoreboard.objectives.remove.usage", new Object[0]); + } + + this.h(icommandlistener, astring[2]); + } else { + if (!astring[1].equalsIgnoreCase("setdisplay")) { + throw new ExceptionUsage("commands.scoreboard.objectives.usage", new Object[0]); + } + + if (astring.length != 3 && astring.length != 4) { + throw new ExceptionUsage("commands.scoreboard.objectives.setdisplay.usage", new Object[0]); + } + + this.j(icommandlistener, astring, 2); + } + } else if (astring[0].equalsIgnoreCase("players")) { + if (astring.length == 1) { + throw new ExceptionUsage("commands.scoreboard.players.usage", new Object[0]); + } + + if (astring[1].equalsIgnoreCase("list")) { + if (astring.length > 3) { + throw new ExceptionUsage("commands.scoreboard.players.list.usage", new Object[0]); + } + + this.k(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("add")) { + if (astring.length < 5) { + throw new ExceptionUsage("commands.scoreboard.players.add.usage", new Object[0]); + } + + this.l(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("remove")) { + if (astring.length < 5) { + throw new ExceptionUsage("commands.scoreboard.players.remove.usage", new Object[0]); + } + + this.l(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("set")) { + if (astring.length < 5) { + throw new ExceptionUsage("commands.scoreboard.players.set.usage", new Object[0]); + } + + this.l(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("reset")) { + if (astring.length != 3 && astring.length != 4) { + throw new ExceptionUsage("commands.scoreboard.players.reset.usage", new Object[0]); + } + + this.m(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("enable")) { + if (astring.length != 4) { + throw new ExceptionUsage("commands.scoreboard.players.enable.usage", new Object[0]); + } + + this.n(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("test")) { + if (astring.length != 5 && astring.length != 6) { + throw new ExceptionUsage("commands.scoreboard.players.test.usage", new Object[0]); + } + + this.o(icommandlistener, astring, 2); + } else { + if (!astring[1].equalsIgnoreCase("operation")) { + throw new ExceptionUsage("commands.scoreboard.players.usage", new Object[0]); + } + + if (astring.length != 7) { + throw new ExceptionUsage("commands.scoreboard.players.operation.usage", new Object[0]); + } + + this.p(icommandlistener, astring, 2); + } + } else { + if (!astring[0].equalsIgnoreCase("teams")) { + throw new ExceptionUsage("commands.scoreboard.usage", new Object[0]); + } + + if (astring.length == 1) { + throw new ExceptionUsage("commands.scoreboard.teams.usage", new Object[0]); + } + + if (astring[1].equalsIgnoreCase("list")) { + if (astring.length > 3) { + throw new ExceptionUsage("commands.scoreboard.teams.list.usage", new Object[0]); + } + + this.f(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("add")) { + if (astring.length < 3) { + throw new ExceptionUsage("commands.scoreboard.teams.add.usage", new Object[0]); + } + + this.c(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("remove")) { + if (astring.length != 3) { + throw new ExceptionUsage("commands.scoreboard.teams.remove.usage", new Object[0]); + } + + this.e(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("empty")) { + if (astring.length != 3) { + throw new ExceptionUsage("commands.scoreboard.teams.empty.usage", new Object[0]); + } + + this.i(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("join")) { + if (astring.length < 4 && (astring.length != 3 || !(icommandlistener instanceof EntityHuman))) { + throw new ExceptionUsage("commands.scoreboard.teams.join.usage", new Object[0]); + } + + this.g(icommandlistener, astring, 2); + } else if (astring[1].equalsIgnoreCase("leave")) { + if (astring.length < 3 && !(icommandlistener instanceof EntityHuman)) { + throw new ExceptionUsage("commands.scoreboard.teams.leave.usage", new Object[0]); + } + + this.h(icommandlistener, astring, 2); + } else { + if (!astring[1].equalsIgnoreCase("option")) { + throw new ExceptionUsage("commands.scoreboard.teams.usage", new Object[0]); + } + + if (astring.length != 4 && astring.length != 5) { + throw new ExceptionUsage("commands.scoreboard.teams.option.usage", new Object[0]); + } + + this.d(icommandlistener, astring, 2); + } + } + + } + } + } + + private boolean b(ICommandListener icommandlistener, String[] astring) throws CommandException { + int i = -1; + + for (int j = 0; j < astring.length; ++j) { + if (this.isListStart(astring, j) && "*".equals(astring[j])) { + if (i >= 0) { + throw new CommandException("commands.scoreboard.noMultiWildcard", new Object[0]); + } + + i = j; + } + } + + if (i < 0) { + return false; + } else { + ArrayList arraylist = Lists.newArrayList(this.d().getPlayers()); + String s = astring[i]; + ArrayList arraylist1 = Lists.newArrayList(); + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + String s1 = (String) iterator.next(); + + astring[i] = s1; + + try { + this.execute(icommandlistener, astring); + arraylist1.add(s1); + } catch (CommandException commandexception) { + ChatMessage chatmessage = new ChatMessage(commandexception.getMessage(), commandexception.getArgs()); + + chatmessage.getChatModifier().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage); + } + } + + astring[i] = s; + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.AFFECTED_ENTITIES, arraylist1.size()); + if (arraylist1.size() == 0) { + throw new ExceptionUsage("commands.scoreboard.allMatchesFailed", new Object[0]); + } else { + return true; + } + } + } + + protected Scoreboard d() { + return MinecraftServer.getServer().getWorldServer(0).getScoreboard(); + } + + protected ScoreboardObjective a(String s, boolean flag) throws CommandException { + Scoreboard scoreboard = this.d(); + ScoreboardObjective scoreboardobjective = scoreboard.getObjective(s); + + if (scoreboardobjective == null) { + throw new CommandException("commands.scoreboard.objectiveNotFound", new Object[] { s}); + } else if (flag && scoreboardobjective.getCriteria().isReadOnly()) { + throw new CommandException("commands.scoreboard.objectiveReadOnly", new Object[] { s}); + } else { + return scoreboardobjective; + } + } + + protected ScoreboardTeam e(String s) throws CommandException { + Scoreboard scoreboard = this.d(); + ScoreboardTeam scoreboardteam = scoreboard.getTeam(s); + + if (scoreboardteam == null) { + throw new CommandException("commands.scoreboard.teamNotFound", new Object[] { s}); + } else { + return scoreboardteam; + } + } + + protected void b(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + String s = astring[i++]; + String s1 = astring[i++]; + Scoreboard scoreboard = this.d(); + IScoreboardCriteria iscoreboardcriteria = (IScoreboardCriteria) IScoreboardCriteria.criteria.get(s1); + + if (iscoreboardcriteria == null) { + throw new ExceptionUsage("commands.scoreboard.objectives.add.wrongType", new Object[] { s1}); + } else if (scoreboard.getObjective(s) != null) { + throw new CommandException("commands.scoreboard.objectives.add.alreadyExists", new Object[] { s}); + } else if (s.length() > 16) { + throw new ExceptionInvalidSyntax("commands.scoreboard.objectives.add.tooLong", new Object[] { s, Integer.valueOf(16)}); + } else if (s.length() == 0) { + throw new ExceptionUsage("commands.scoreboard.objectives.add.usage", new Object[0]); + } else { + if (astring.length > i) { + String s2 = a(icommandlistener, astring, i).c(); + + if (s2.length() > 32) { + throw new ExceptionInvalidSyntax("commands.scoreboard.objectives.add.displayTooLong", new Object[] { s2, Integer.valueOf(32)}); + } + + if (s2.length() > 0) { + scoreboard.registerObjective(s, iscoreboardcriteria).setDisplayName(s2); + } else { + scoreboard.registerObjective(s, iscoreboardcriteria); + } + } else { + scoreboard.registerObjective(s, iscoreboardcriteria); + } + + a(icommandlistener, this, "commands.scoreboard.objectives.add.success", new Object[] { s}); + } + } + + protected void c(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + String s = astring[i++]; + Scoreboard scoreboard = this.d(); + + if (scoreboard.getTeam(s) != null) { + throw new CommandException("commands.scoreboard.teams.add.alreadyExists", new Object[] { s}); + } else if (s.length() > 16) { + throw new ExceptionInvalidSyntax("commands.scoreboard.teams.add.tooLong", new Object[] { s, Integer.valueOf(16)}); + } else if (s.length() == 0) { + throw new ExceptionUsage("commands.scoreboard.teams.add.usage", new Object[0]); + } else { + if (astring.length > i) { + String s1 = a(icommandlistener, astring, i).c(); + + if (s1.length() > 32) { + throw new ExceptionInvalidSyntax("commands.scoreboard.teams.add.displayTooLong", new Object[] { s1, Integer.valueOf(32)}); + } + + if (s1.length() > 0) { + scoreboard.createTeam(s).setDisplayName(s1); + } else { + scoreboard.createTeam(s); + } + } else { + scoreboard.createTeam(s); + } + + a(icommandlistener, this, "commands.scoreboard.teams.add.success", new Object[] { s}); + } + } + + protected void d(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + ScoreboardTeam scoreboardteam = this.e(astring[i++]); + + if (scoreboardteam != null) { + String s = astring[i++].toLowerCase(); + + if (!s.equalsIgnoreCase("color") && !s.equalsIgnoreCase("friendlyfire") && !s.equalsIgnoreCase("seeFriendlyInvisibles") && !s.equalsIgnoreCase("nametagVisibility") && !s.equalsIgnoreCase("deathMessageVisibility")) { + throw new ExceptionUsage("commands.scoreboard.teams.option.usage", new Object[0]); + } else if (astring.length == 4) { + if (s.equalsIgnoreCase("color")) { + throw new ExceptionUsage("commands.scoreboard.teams.option.noValue", new Object[] { s, a(EnumChatFormat.a(true, false))}); + } else if (!s.equalsIgnoreCase("friendlyfire") && !s.equalsIgnoreCase("seeFriendlyInvisibles")) { + if (!s.equalsIgnoreCase("nametagVisibility") && !s.equalsIgnoreCase("deathMessageVisibility")) { + throw new ExceptionUsage("commands.scoreboard.teams.option.usage", new Object[0]); + } else { + throw new ExceptionUsage("commands.scoreboard.teams.option.noValue", new Object[] { s, a((Object[]) ScoreboardTeamBase.EnumNameTagVisibility.a())}); + } + } else { + throw new ExceptionUsage("commands.scoreboard.teams.option.noValue", new Object[] { s, a((Collection) Arrays.asList(new String[] { "true", "false"}))}); + } + } else { + String s1 = astring[i]; + + if (s.equalsIgnoreCase("color")) { + EnumChatFormat enumchatformat = EnumChatFormat.b(s1); + + if (enumchatformat == null || enumchatformat.isFormat()) { + throw new ExceptionUsage("commands.scoreboard.teams.option.noValue", new Object[] { s, a(EnumChatFormat.a(true, false))}); + } + + scoreboardteam.a(enumchatformat); + scoreboardteam.setPrefix(enumchatformat.toString()); + scoreboardteam.setSuffix(EnumChatFormat.RESET.toString()); + } else if (s.equalsIgnoreCase("friendlyfire")) { + if (!s1.equalsIgnoreCase("true") && !s1.equalsIgnoreCase("false")) { + throw new ExceptionUsage("commands.scoreboard.teams.option.noValue", new Object[] { s, a((Collection) Arrays.asList(new String[] { "true", "false"}))}); + } + + scoreboardteam.setAllowFriendlyFire(s1.equalsIgnoreCase("true")); + } else if (s.equalsIgnoreCase("seeFriendlyInvisibles")) { + if (!s1.equalsIgnoreCase("true") && !s1.equalsIgnoreCase("false")) { + throw new ExceptionUsage("commands.scoreboard.teams.option.noValue", new Object[] { s, a((Collection) Arrays.asList(new String[] { "true", "false"}))}); + } + + scoreboardteam.setCanSeeFriendlyInvisibles(s1.equalsIgnoreCase("true")); + } else { + ScoreboardTeamBase.EnumNameTagVisibility scoreboardteambase_enumnametagvisibility; + + if (s.equalsIgnoreCase("nametagVisibility")) { + scoreboardteambase_enumnametagvisibility = ScoreboardTeamBase.EnumNameTagVisibility.a(s1); + if (scoreboardteambase_enumnametagvisibility == null) { + throw new ExceptionUsage("commands.scoreboard.teams.option.noValue", new Object[] { s, a((Object[]) ScoreboardTeamBase.EnumNameTagVisibility.a())}); + } + + scoreboardteam.setNameTagVisibility(scoreboardteambase_enumnametagvisibility); + } else if (s.equalsIgnoreCase("deathMessageVisibility")) { + scoreboardteambase_enumnametagvisibility = ScoreboardTeamBase.EnumNameTagVisibility.a(s1); + if (scoreboardteambase_enumnametagvisibility == null) { + throw new ExceptionUsage("commands.scoreboard.teams.option.noValue", new Object[] { s, a((Object[]) ScoreboardTeamBase.EnumNameTagVisibility.a())}); + } + + scoreboardteam.b(scoreboardteambase_enumnametagvisibility); + } + } + + a(icommandlistener, this, "commands.scoreboard.teams.option.success", new Object[] { s, scoreboardteam.getName(), s1}); + } + } + } + + protected void e(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + ScoreboardTeam scoreboardteam = this.e(astring[i]); + + if (scoreboardteam != null) { + scoreboard.removeTeam(scoreboardteam); + a(icommandlistener, this, "commands.scoreboard.teams.remove.success", new Object[] { scoreboardteam.getName()}); + } + } + + protected void f(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + + if (astring.length > i) { + ScoreboardTeam scoreboardteam = this.e(astring[i]); + + if (scoreboardteam == null) { + return; + } + + Collection collection = scoreboardteam.getPlayerNameSet(); + + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.QUERY_RESULT, collection.size()); + if (collection.size() <= 0) { + throw new CommandException("commands.scoreboard.teams.list.player.empty", new Object[] { scoreboardteam.getName()}); + } + + ChatMessage chatmessage = new ChatMessage("commands.scoreboard.teams.list.player.count", new Object[] { Integer.valueOf(collection.size()), scoreboardteam.getName()}); + + chatmessage.getChatModifier().setColor(EnumChatFormat.DARK_GREEN); + icommandlistener.sendMessage(chatmessage); + icommandlistener.sendMessage(new ChatComponentText(a(collection.toArray()))); + } else { + Collection collection1 = scoreboard.getTeams(); + + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.QUERY_RESULT, collection1.size()); + if (collection1.size() <= 0) { + throw new CommandException("commands.scoreboard.teams.list.empty", new Object[0]); + } + + ChatMessage chatmessage1 = new ChatMessage("commands.scoreboard.teams.list.count", new Object[] { Integer.valueOf(collection1.size())}); + + chatmessage1.getChatModifier().setColor(EnumChatFormat.DARK_GREEN); + icommandlistener.sendMessage(chatmessage1); + Iterator iterator = collection1.iterator(); + + while (iterator.hasNext()) { + ScoreboardTeam scoreboardteam1 = (ScoreboardTeam) iterator.next(); + + icommandlistener.sendMessage(new ChatMessage("commands.scoreboard.teams.list.entry", new Object[] { scoreboardteam1.getName(), scoreboardteam1.getDisplayName(), Integer.valueOf(scoreboardteam1.getPlayerNameSet().size())})); + } + } + + } + + protected void g(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + String s = astring[i++]; + HashSet hashset = Sets.newHashSet(); + HashSet hashset1 = Sets.newHashSet(); + String s1; + + if (icommandlistener instanceof EntityHuman && i == astring.length) { + s1 = b(icommandlistener).getName(); + if (scoreboard.addPlayerToTeam(s1, s)) { + hashset.add(s1); + } else { + hashset1.add(s1); + } + } else { + while (i < astring.length) { + s1 = astring[i++]; + if (s1.startsWith("@")) { + List list = c(icommandlistener, s1); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + if (!entity.world.tacoSpigotConfig.nonPlayerEntitiesOnScoreboards && !(entity instanceof EntityHuman)) continue; // TacoSpigot + String s2 = e(icommandlistener, entity.getUniqueID().toString()); + + if (scoreboard.addPlayerToTeam(s2, s)) { + hashset.add(s2); + } else { + hashset1.add(s2); + } + } + } else { + String s3 = e(icommandlistener, s1); + + if (scoreboard.addPlayerToTeam(s3, s)) { + hashset.add(s3); + } else { + hashset1.add(s3); + } + } + } + } + + if (!hashset.isEmpty()) { + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.AFFECTED_ENTITIES, hashset.size()); + a(icommandlistener, this, "commands.scoreboard.teams.join.success", new Object[] { Integer.valueOf(hashset.size()), s, a(hashset.toArray(new String[hashset.size()]))}); + } + + if (!hashset1.isEmpty()) { + throw new CommandException("commands.scoreboard.teams.join.failure", new Object[] { Integer.valueOf(hashset1.size()), s, a(hashset1.toArray(new String[hashset1.size()]))}); + } + } + + protected void h(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + HashSet hashset = Sets.newHashSet(); + HashSet hashset1 = Sets.newHashSet(); + String s; + + if (icommandlistener instanceof EntityHuman && i == astring.length) { + s = b(icommandlistener).getName(); + if (scoreboard.removePlayerFromTeam(s)) { + hashset.add(s); + } else { + hashset1.add(s); + } + } else { + while (i < astring.length) { + s = astring[i++]; + if (s.startsWith("@")) { + List list = c(icommandlistener, s); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + String s1 = e(icommandlistener, entity.getUniqueID().toString()); + + if (scoreboard.removePlayerFromTeam(s1)) { + hashset.add(s1); + } else { + hashset1.add(s1); + } + } + } else { + String s2 = e(icommandlistener, s); + + if (scoreboard.removePlayerFromTeam(s2)) { + hashset.add(s2); + } else { + hashset1.add(s2); + } + } + } + } + + if (!hashset.isEmpty()) { + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.AFFECTED_ENTITIES, hashset.size()); + a(icommandlistener, this, "commands.scoreboard.teams.leave.success", new Object[] { Integer.valueOf(hashset.size()), a(hashset.toArray(new String[hashset.size()]))}); + } + + if (!hashset1.isEmpty()) { + throw new CommandException("commands.scoreboard.teams.leave.failure", new Object[] { Integer.valueOf(hashset1.size()), a(hashset1.toArray(new String[hashset1.size()]))}); + } + } + + protected void i(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + ScoreboardTeam scoreboardteam = this.e(astring[i]); + + if (scoreboardteam != null) { + ArrayList arraylist = Lists.newArrayList(scoreboardteam.getPlayerNameSet()); + + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.AFFECTED_ENTITIES, arraylist.size()); + if (arraylist.isEmpty()) { + throw new CommandException("commands.scoreboard.teams.empty.alreadyEmpty", new Object[] { scoreboardteam.getName()}); + } else { + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + + scoreboard.removePlayerFromTeam(s, scoreboardteam); + } + + a(icommandlistener, this, "commands.scoreboard.teams.empty.success", new Object[] { Integer.valueOf(arraylist.size()), scoreboardteam.getName()}); + } + } + } + + protected void h(ICommandListener icommandlistener, String s) throws CommandException { + Scoreboard scoreboard = this.d(); + ScoreboardObjective scoreboardobjective = this.a(s, false); + + scoreboard.unregisterObjective(scoreboardobjective); + a(icommandlistener, this, "commands.scoreboard.objectives.remove.success", new Object[] { s}); + } + + protected void d(ICommandListener icommandlistener) throws CommandException { + Scoreboard scoreboard = this.d(); + Collection collection = scoreboard.getObjectives(); + + if (collection.size() <= 0) { + throw new CommandException("commands.scoreboard.objectives.list.empty", new Object[0]); + } else { + ChatMessage chatmessage = new ChatMessage("commands.scoreboard.objectives.list.count", new Object[] { Integer.valueOf(collection.size())}); + + chatmessage.getChatModifier().setColor(EnumChatFormat.DARK_GREEN); + icommandlistener.sendMessage(chatmessage); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); + + icommandlistener.sendMessage(new ChatMessage("commands.scoreboard.objectives.list.entry", new Object[] { scoreboardobjective.getName(), scoreboardobjective.getDisplayName(), scoreboardobjective.getCriteria().getName()})); + } + + } + } + + protected void j(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + String s = astring[i++]; + int j = Scoreboard.getSlotForName(s); + ScoreboardObjective scoreboardobjective = null; + + if (astring.length == 4) { + scoreboardobjective = this.a(astring[i], false); + } + + if (j < 0) { + throw new CommandException("commands.scoreboard.objectives.setdisplay.invalidSlot", new Object[] { s}); + } else { + scoreboard.setDisplaySlot(j, scoreboardobjective); + if (scoreboardobjective != null) { + a(icommandlistener, this, "commands.scoreboard.objectives.setdisplay.successSet", new Object[] { Scoreboard.getSlotName(j), scoreboardobjective.getName()}); + } else { + a(icommandlistener, this, "commands.scoreboard.objectives.setdisplay.successCleared", new Object[] { Scoreboard.getSlotName(j)}); + } + + } + } + + protected void k(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + + if (astring.length > i) { + String s = e(icommandlistener, astring[i]); + Map map = scoreboard.getPlayerObjectives(s); + + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.QUERY_RESULT, map.size()); + if (map.size() <= 0) { + throw new CommandException("commands.scoreboard.players.list.player.empty", new Object[] { s}); + } + + ChatMessage chatmessage = new ChatMessage("commands.scoreboard.players.list.player.count", new Object[] { Integer.valueOf(map.size()), s}); + + chatmessage.getChatModifier().setColor(EnumChatFormat.DARK_GREEN); + icommandlistener.sendMessage(chatmessage); + Iterator iterator = map.values().iterator(); + + while (iterator.hasNext()) { + ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); + + icommandlistener.sendMessage(new ChatMessage("commands.scoreboard.players.list.player.entry", new Object[] { Integer.valueOf(scoreboardscore.getScore()), scoreboardscore.getObjective().getDisplayName(), scoreboardscore.getObjective().getName()})); + } + } else { + Collection collection = scoreboard.getPlayers(); + + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.QUERY_RESULT, collection.size()); + if (collection.size() <= 0) { + throw new CommandException("commands.scoreboard.players.list.empty", new Object[0]); + } + + ChatMessage chatmessage1 = new ChatMessage("commands.scoreboard.players.list.count", new Object[] { Integer.valueOf(collection.size())}); + + chatmessage1.getChatModifier().setColor(EnumChatFormat.DARK_GREEN); + icommandlistener.sendMessage(chatmessage1); + icommandlistener.sendMessage(new ChatComponentText(a(collection.toArray()))); + } + + } + + protected void l(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + String s = astring[i - 1]; + int j = i; + String s1 = e(icommandlistener, astring[i++]); + + if (s1.length() > 40) { + throw new ExceptionInvalidSyntax("commands.scoreboard.players.name.tooLong", new Object[] { s1, Integer.valueOf(40)}); + } else { + ScoreboardObjective scoreboardobjective = this.a(astring[i++], true); + int k = s.equalsIgnoreCase("set") ? a(astring[i++]) : a(astring[i++], 0); + + if (astring.length > i) { + Entity entity = b(icommandlistener, astring[j]); + + try { + NBTTagCompound nbttagcompound = MojangsonParser.parse(a(astring, i)); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + entity.e(nbttagcompound1); + if (!GameProfileSerializer.a(nbttagcompound, nbttagcompound1, true)) { + throw new CommandException("commands.scoreboard.players.set.tagMismatch", new Object[] { s1}); + } + } catch (MojangsonParseException mojangsonparseexception) { + throw new CommandException("commands.scoreboard.players.set.tagError", new Object[] { mojangsonparseexception.getMessage()}); + } + } + + Scoreboard scoreboard = this.d(); + ScoreboardScore scoreboardscore = scoreboard.getPlayerScoreForObjective(s1, scoreboardobjective); + + if (s.equalsIgnoreCase("set")) { + scoreboardscore.setScore(k); + } else if (s.equalsIgnoreCase("add")) { + scoreboardscore.addScore(k); + } else { + scoreboardscore.removeScore(k); + } + + a(icommandlistener, this, "commands.scoreboard.players.set.success", new Object[] { scoreboardobjective.getName(), s1, Integer.valueOf(scoreboardscore.getScore())}); + } + } + + protected void m(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + String s = e(icommandlistener, astring[i++]); + + if (astring.length > i) { + ScoreboardObjective scoreboardobjective = this.a(astring[i++], false); + + scoreboard.resetPlayerScores(s, scoreboardobjective); + a(icommandlistener, this, "commands.scoreboard.players.resetscore.success", new Object[] { scoreboardobjective.getName(), s}); + } else { + scoreboard.resetPlayerScores(s, (ScoreboardObjective) null); + a(icommandlistener, this, "commands.scoreboard.players.reset.success", new Object[] { s}); + } + + } + + protected void n(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + String s = d(icommandlistener, astring[i++]); + + if (s.length() > 40) { + throw new ExceptionInvalidSyntax("commands.scoreboard.players.name.tooLong", new Object[] { s, Integer.valueOf(40)}); + } else { + ScoreboardObjective scoreboardobjective = this.a(astring[i], false); + + if (scoreboardobjective.getCriteria() != IScoreboardCriteria.c) { + throw new CommandException("commands.scoreboard.players.enable.noTrigger", new Object[] { scoreboardobjective.getName()}); + } else { + ScoreboardScore scoreboardscore = scoreboard.getPlayerScoreForObjective(s, scoreboardobjective); + + scoreboardscore.a(false); + a(icommandlistener, this, "commands.scoreboard.players.enable.success", new Object[] { scoreboardobjective.getName(), s}); + } + } + } + + protected void o(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + String s = e(icommandlistener, astring[i++]); + + if (s.length() > 40) { + throw new ExceptionInvalidSyntax("commands.scoreboard.players.name.tooLong", new Object[] { s, Integer.valueOf(40)}); + } else { + ScoreboardObjective scoreboardobjective = this.a(astring[i++], false); + + if (!scoreboard.b(s, scoreboardobjective)) { + throw new CommandException("commands.scoreboard.players.test.notFound", new Object[] { scoreboardobjective.getName(), s}); + } else { + int j = astring[i].equals("*") ? Integer.MIN_VALUE : a(astring[i]); + + ++i; + int k = i < astring.length && !astring[i].equals("*") ? a(astring[i], j) : Integer.MAX_VALUE; + ScoreboardScore scoreboardscore = scoreboard.getPlayerScoreForObjective(s, scoreboardobjective); + + if (scoreboardscore.getScore() >= j && scoreboardscore.getScore() <= k) { + a(icommandlistener, this, "commands.scoreboard.players.test.success", new Object[] { Integer.valueOf(scoreboardscore.getScore()), Integer.valueOf(j), Integer.valueOf(k)}); + } else { + throw new CommandException("commands.scoreboard.players.test.failed", new Object[] { Integer.valueOf(scoreboardscore.getScore()), Integer.valueOf(j), Integer.valueOf(k)}); + } + } + } + } + + protected void p(ICommandListener icommandlistener, String[] astring, int i) throws CommandException { + Scoreboard scoreboard = this.d(); + String s = e(icommandlistener, astring[i++]); + ScoreboardObjective scoreboardobjective = this.a(astring[i++], true); + String s1 = astring[i++]; + String s2 = e(icommandlistener, astring[i++]); + ScoreboardObjective scoreboardobjective1 = this.a(astring[i], false); + + if (s.length() > 40) { + throw new ExceptionInvalidSyntax("commands.scoreboard.players.name.tooLong", new Object[] { s, Integer.valueOf(40)}); + } else if (s2.length() > 40) { + throw new ExceptionInvalidSyntax("commands.scoreboard.players.name.tooLong", new Object[] { s2, Integer.valueOf(40)}); + } else { + ScoreboardScore scoreboardscore = scoreboard.getPlayerScoreForObjective(s, scoreboardobjective); + + if (!scoreboard.b(s2, scoreboardobjective1)) { + throw new CommandException("commands.scoreboard.players.operation.notFound", new Object[] { scoreboardobjective1.getName(), s2}); + } else { + ScoreboardScore scoreboardscore1 = scoreboard.getPlayerScoreForObjective(s2, scoreboardobjective1); + + if (s1.equals("+=")) { + scoreboardscore.setScore(scoreboardscore.getScore() + scoreboardscore1.getScore()); + } else if (s1.equals("-=")) { + scoreboardscore.setScore(scoreboardscore.getScore() - scoreboardscore1.getScore()); + } else if (s1.equals("*=")) { + scoreboardscore.setScore(scoreboardscore.getScore() * scoreboardscore1.getScore()); + } else if (s1.equals("/=")) { + if (scoreboardscore1.getScore() != 0) { + scoreboardscore.setScore(scoreboardscore.getScore() / scoreboardscore1.getScore()); + } + } else if (s1.equals("%=")) { + if (scoreboardscore1.getScore() != 0) { + scoreboardscore.setScore(scoreboardscore.getScore() % scoreboardscore1.getScore()); + } + } else if (s1.equals("=")) { + scoreboardscore.setScore(scoreboardscore1.getScore()); + } else if (s1.equals("<")) { + scoreboardscore.setScore(Math.min(scoreboardscore.getScore(), scoreboardscore1.getScore())); + } else if (s1.equals(">")) { + scoreboardscore.setScore(Math.max(scoreboardscore.getScore(), scoreboardscore1.getScore())); + } else { + if (!s1.equals("><")) { + throw new CommandException("commands.scoreboard.players.operation.invalidOperation", new Object[] { s1}); + } + + int j = scoreboardscore.getScore(); + + scoreboardscore.setScore(scoreboardscore1.getScore()); + scoreboardscore1.setScore(j); + } + + a(icommandlistener, this, "commands.scoreboard.players.operation.success", new Object[0]); + } + } + } + + public List tabComplete(ICommandListener icommandlistener, String[] astring, BlockPosition blockposition) { + if (astring.length == 1) { + return a(astring, new String[] { "objectives", "players", "teams"}); + } else { + if (astring[0].equalsIgnoreCase("objectives")) { + if (astring.length == 2) { + return a(astring, new String[] { "list", "add", "remove", "setdisplay"}); + } + + if (astring[1].equalsIgnoreCase("add")) { + if (astring.length == 4) { + Set set = IScoreboardCriteria.criteria.keySet(); + + return a(astring, (Collection) set); + } + } else if (astring[1].equalsIgnoreCase("remove")) { + if (astring.length == 3) { + return a(astring, (Collection) this.a(false)); + } + } else if (astring[1].equalsIgnoreCase("setdisplay")) { + if (astring.length == 3) { + return a(astring, Scoreboard.h()); + } + + if (astring.length == 4) { + return a(astring, (Collection) this.a(false)); + } + } + } else if (astring[0].equalsIgnoreCase("players")) { + if (astring.length == 2) { + return a(astring, new String[] { "set", "add", "remove", "reset", "list", "enable", "test", "operation"}); + } + + if (!astring[1].equalsIgnoreCase("set") && !astring[1].equalsIgnoreCase("add") && !astring[1].equalsIgnoreCase("remove") && !astring[1].equalsIgnoreCase("reset")) { + if (astring[1].equalsIgnoreCase("enable")) { + if (astring.length == 3) { + return a(astring, MinecraftServer.getServer().getPlayers()); + } + + if (astring.length == 4) { + return a(astring, (Collection) this.e()); + } + } else if (!astring[1].equalsIgnoreCase("list") && !astring[1].equalsIgnoreCase("test")) { + if (astring[1].equalsIgnoreCase("operation")) { + if (astring.length == 3) { + return a(astring, this.d().getPlayers()); + } + + if (astring.length == 4) { + return a(astring, (Collection) this.a(true)); + } + + if (astring.length == 5) { + return a(astring, new String[] { "+=", "-=", "*=", "/=", "%=", "=", "<", ">", "><"}); + } + + if (astring.length == 6) { + return a(astring, MinecraftServer.getServer().getPlayers()); + } + + if (astring.length == 7) { + return a(astring, (Collection) this.a(false)); + } + } + } else { + if (astring.length == 3) { + return a(astring, this.d().getPlayers()); + } + + if (astring.length == 4 && astring[1].equalsIgnoreCase("test")) { + return a(astring, (Collection) this.a(false)); + } + } + } else { + if (astring.length == 3) { + return a(astring, MinecraftServer.getServer().getPlayers()); + } + + if (astring.length == 4) { + return a(astring, (Collection) this.a(true)); + } + } + } else if (astring[0].equalsIgnoreCase("teams")) { + if (astring.length == 2) { + return a(astring, new String[] { "add", "remove", "join", "leave", "empty", "list", "option"}); + } + + if (astring[1].equalsIgnoreCase("join")) { + if (astring.length == 3) { + return a(astring, this.d().getTeamNames()); + } + + if (astring.length >= 4) { + return a(astring, MinecraftServer.getServer().getPlayers()); + } + } else { + if (astring[1].equalsIgnoreCase("leave")) { + return a(astring, MinecraftServer.getServer().getPlayers()); + } + + if (!astring[1].equalsIgnoreCase("empty") && !astring[1].equalsIgnoreCase("list") && !astring[1].equalsIgnoreCase("remove")) { + if (astring[1].equalsIgnoreCase("option")) { + if (astring.length == 3) { + return a(astring, this.d().getTeamNames()); + } + + if (astring.length == 4) { + return a(astring, new String[] { "color", "friendlyfire", "seeFriendlyInvisibles", "nametagVisibility", "deathMessageVisibility"}); + } + + if (astring.length == 5) { + if (astring[3].equalsIgnoreCase("color")) { + return a(astring, EnumChatFormat.a(true, false)); + } + + if (astring[3].equalsIgnoreCase("nametagVisibility") || astring[3].equalsIgnoreCase("deathMessageVisibility")) { + return a(astring, ScoreboardTeamBase.EnumNameTagVisibility.a()); + } + + if (astring[3].equalsIgnoreCase("friendlyfire") || astring[3].equalsIgnoreCase("seeFriendlyInvisibles")) { + return a(astring, new String[] { "true", "false"}); + } + } + } + } else if (astring.length == 3) { + return a(astring, this.d().getTeamNames()); + } + } + } + + return null; + } + } + + protected List a(boolean flag) { + Collection collection = this.d().getObjectives(); + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); + + if (!flag || !scoreboardobjective.getCriteria().isReadOnly()) { + arraylist.add(scoreboardobjective.getName()); + } + } + + return arraylist; + } + + protected List e() { + Collection collection = this.d().getObjectives(); + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); + + if (scoreboardobjective.getCriteria() == IScoreboardCriteria.c) { + arraylist.add(scoreboardobjective.getName()); + } + } + + return arraylist; + } + + public boolean isListStart(String[] astring, int i) { + return !astring[0].equalsIgnoreCase("players") ? (astring[0].equalsIgnoreCase("teams") ? i == 2 : false) : (astring.length > 1 && astring[1].equalsIgnoreCase("operation") ? i == 2 || i == 5 : i == 2); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandSpreadPlayers.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandSpreadPlayers.java new file mode 100644 index 0000000..53c5d92 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandSpreadPlayers.java @@ -0,0 +1,347 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class CommandSpreadPlayers extends CommandAbstract { + + public CommandSpreadPlayers() {} + + public String getCommand() { + return "spreadplayers"; + } + + public int a() { + return 2; + } + + public String getUsage(ICommandListener icommandlistener) { + return "commands.spreadplayers.usage"; + } + + public void execute(ICommandListener icommandlistener, String[] astring) throws CommandException { + if (astring.length < 6) { + throw new ExceptionUsage("commands.spreadplayers.usage", new Object[0]); + } else { + byte b0 = 0; + BlockPosition blockposition = icommandlistener.getChunkCoordinates(); + double d0 = (double) blockposition.getX(); + int i = b0 + 1; + double d1 = b(d0, astring[b0], true); + double d2 = b((double) blockposition.getZ(), astring[i++], true); + double d3 = a(astring[i++], 0.0D); + double d4 = a(astring[i++], d3 + 1.0D); + boolean flag = d(astring[i++]); + ArrayList arraylist = Lists.newArrayList(); + + while (i < astring.length) { + String s = astring[i++]; + + if (PlayerSelector.isPattern(s)) { + List list = PlayerSelector.getPlayers(icommandlistener, s, Entity.class); + + if (list.size() == 0) { + throw new ExceptionEntityNotFound(); + } + + arraylist.addAll(list); + } else { + EntityPlayer entityplayer = MinecraftServer.getServer().getPlayerList().getPlayer(s); + + if (entityplayer == null) { + throw new ExceptionPlayerNotFound(); + } + + arraylist.add(entityplayer); + } + } + + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.AFFECTED_ENTITIES, arraylist.size()); + if (arraylist.isEmpty()) { + throw new ExceptionEntityNotFound(); + } else { + icommandlistener.sendMessage(new ChatMessage("commands.spreadplayers.spreading." + (flag ? "teams" : "players"), new Object[] { Integer.valueOf(arraylist.size()), Double.valueOf(d4), Double.valueOf(d1), Double.valueOf(d2), Double.valueOf(d3)})); + this.a(icommandlistener, arraylist, new CommandSpreadPlayers.Location2D(d1, d2), d3, d4, ((Entity) arraylist.get(0)).world, flag); + } + } + } + + private void a(ICommandListener icommandlistener, List list, CommandSpreadPlayers.Location2D commandspreadplayers_location2d, double d0, double d1, World world, boolean flag) throws CommandException { + Random random = new Random(); + double d2 = commandspreadplayers_location2d.a - d1; + double d3 = commandspreadplayers_location2d.b - d1; + double d4 = commandspreadplayers_location2d.a + d1; + double d5 = commandspreadplayers_location2d.b + d1; + CommandSpreadPlayers.Location2D[] acommandspreadplayers_location2d = this.a(random, flag ? this.b(list) : list.size(), d2, d3, d4, d5); + int i = this.a(commandspreadplayers_location2d, d0, world, random, d2, d3, d4, d5, acommandspreadplayers_location2d, flag); + double d6 = this.a(list, world, acommandspreadplayers_location2d, flag); + + a(icommandlistener, this, "commands.spreadplayers.success." + (flag ? "teams" : "players"), new Object[] { Integer.valueOf(acommandspreadplayers_location2d.length), Double.valueOf(commandspreadplayers_location2d.a), Double.valueOf(commandspreadplayers_location2d.b)}); + if (acommandspreadplayers_location2d.length > 1) { + icommandlistener.sendMessage(new ChatMessage("commands.spreadplayers.info." + (flag ? "teams" : "players"), new Object[] { String.format("%.2f", new Object[] { Double.valueOf(d6)}), Integer.valueOf(i)})); + } + + } + + private int b(List list) { + HashSet hashset = Sets.newHashSet(); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (entity instanceof EntityHuman) { + hashset.add(((EntityHuman) entity).getScoreboardTeam()); + } else { + hashset.add((Object) null); + } + } + + return hashset.size(); + } + + private int a(CommandSpreadPlayers.Location2D commandspreadplayers_location2d, double d0, World world, Random random, double d1, double d2, double d3, double d4, CommandSpreadPlayers.Location2D[] acommandspreadplayers_location2d, boolean flag) throws CommandException { + boolean flag1 = true; + double d5 = 3.4028234663852886E38D; + + int i; + + for (i = 0; i < 10000 && flag1; ++i) { + flag1 = false; + d5 = 3.4028234663852886E38D; + + int j; + CommandSpreadPlayers.Location2D commandspreadplayers_location2d1; + + for (int k = 0; k < acommandspreadplayers_location2d.length; ++k) { + CommandSpreadPlayers.Location2D commandspreadplayers_location2d2 = acommandspreadplayers_location2d[k]; + + j = 0; + commandspreadplayers_location2d1 = new CommandSpreadPlayers.Location2D(); + + for (int l = 0; l < acommandspreadplayers_location2d.length; ++l) { + if (k != l) { + CommandSpreadPlayers.Location2D commandspreadplayers_location2d3 = acommandspreadplayers_location2d[l]; + double d6 = commandspreadplayers_location2d2.a(commandspreadplayers_location2d3); + + d5 = Math.min(d6, d5); + if (d6 < d0) { + ++j; + commandspreadplayers_location2d1.a += commandspreadplayers_location2d3.a - commandspreadplayers_location2d2.a; + commandspreadplayers_location2d1.b += commandspreadplayers_location2d3.b - commandspreadplayers_location2d2.b; + } + } + } + + if (j > 0) { + commandspreadplayers_location2d1.a /= (double) j; + commandspreadplayers_location2d1.b /= (double) j; + double d7 = (double) commandspreadplayers_location2d1.b(); + + if (d7 > 0.0D) { + commandspreadplayers_location2d1.a(); + commandspreadplayers_location2d2.b(commandspreadplayers_location2d1); + } else { + commandspreadplayers_location2d2.a(random, d1, d2, d3, d4); + } + + flag1 = true; + } + + if (commandspreadplayers_location2d2.a(d1, d2, d3, d4)) { + flag1 = true; + } + } + + if (!flag1) { + CommandSpreadPlayers.Location2D[] acommandspreadplayers_location2d1 = acommandspreadplayers_location2d; + int i1 = acommandspreadplayers_location2d.length; + + for (j = 0; j < i1; ++j) { + commandspreadplayers_location2d1 = acommandspreadplayers_location2d1[j]; + if (!commandspreadplayers_location2d1.b(world)) { + commandspreadplayers_location2d1.a(random, d1, d2, d3, d4); + flag1 = true; + } + } + } + } + + if (i >= 10000) { + throw new CommandException("commands.spreadplayers.failure." + (flag ? "teams" : "players"), new Object[] { Integer.valueOf(acommandspreadplayers_location2d.length), Double.valueOf(commandspreadplayers_location2d.a), Double.valueOf(commandspreadplayers_location2d.b), String.format("%.2f", new Object[] { Double.valueOf(d5)})}); + } else { + return i; + } + } + + private double a(List list, World world, CommandSpreadPlayers.Location2D[] acommandspreadplayers_location2d, boolean flag) { + double d0 = 0.0D; + int i = 0; + HashMap hashmap = Maps.newHashMap(); + + for (int j = 0; j < list.size(); ++j) { + Entity entity = (Entity) list.get(j); + CommandSpreadPlayers.Location2D commandspreadplayers_location2d; + + if (flag) { + ScoreboardTeamBase scoreboardteambase = entity instanceof EntityHuman ? ((EntityHuman) entity).getScoreboardTeam() : null; + + if (!hashmap.containsKey(scoreboardteambase)) { + hashmap.put(scoreboardteambase, acommandspreadplayers_location2d[i++]); + } + + commandspreadplayers_location2d = (CommandSpreadPlayers.Location2D) hashmap.get(scoreboardteambase); + } else { + commandspreadplayers_location2d = acommandspreadplayers_location2d[i++]; + } + + entity.enderTeleportTo((double) ((float) MathHelper.floor(commandspreadplayers_location2d.a) + 0.5F), (double) commandspreadplayers_location2d.a(world), (double) MathHelper.floor(commandspreadplayers_location2d.b) + 0.5D); + double d1 = Double.MAX_VALUE; + + for (int k = 0; k < acommandspreadplayers_location2d.length; ++k) { + if (commandspreadplayers_location2d != acommandspreadplayers_location2d[k]) { + double d2 = commandspreadplayers_location2d.a(acommandspreadplayers_location2d[k]); + + d1 = Math.min(d2, d1); + } + } + + d0 += d1; + } + + d0 /= (double) list.size(); + return d0; + } + + private CommandSpreadPlayers.Location2D[] a(Random random, int i, double d0, double d1, double d2, double d3) { + CommandSpreadPlayers.Location2D[] acommandspreadplayers_location2d = new CommandSpreadPlayers.Location2D[i]; + + for (int j = 0; j < acommandspreadplayers_location2d.length; ++j) { + CommandSpreadPlayers.Location2D commandspreadplayers_location2d = new CommandSpreadPlayers.Location2D(); + + commandspreadplayers_location2d.a(random, d0, d1, d2, d3); + acommandspreadplayers_location2d[j] = commandspreadplayers_location2d; + } + + return acommandspreadplayers_location2d; + } + + public List tabComplete(ICommandListener icommandlistener, String[] astring, BlockPosition blockposition) { + return astring.length >= 1 && astring.length <= 2 ? b(astring, 0, blockposition) : null; + } + + // CraftBukkit start - fix decompile error + @Override + public int compareTo(ICommand o) { + return a(o); + } + // CraftBukkit end + + static class Location2D { + + double a; + double b; + + Location2D() {} + + Location2D(double d0, double d1) { + this.a = d0; + this.b = d1; + } + + double a(CommandSpreadPlayers.Location2D commandspreadplayers_location2d) { + double d0 = this.a - commandspreadplayers_location2d.a; + double d1 = this.b - commandspreadplayers_location2d.b; + + return Math.sqrt(d0 * d0 + d1 * d1); + } + + void a() { + double d0 = (double) this.b(); + + this.a /= d0; + this.b /= d0; + } + + float b() { + return MathHelper.sqrt(this.a * this.a + this.b * this.b); + } + + public void b(CommandSpreadPlayers.Location2D commandspreadplayers_location2d) { + this.a -= commandspreadplayers_location2d.a; + this.b -= commandspreadplayers_location2d.b; + } + + public boolean a(double d0, double d1, double d2, double d3) { + boolean flag = false; + + if (this.a < d0) { + this.a = d0; + flag = true; + } else if (this.a > d2) { + this.a = d2; + flag = true; + } + + if (this.b < d1) { + this.b = d1; + flag = true; + } else if (this.b > d3) { + this.b = d3; + flag = true; + } + + return flag; + } + + public int a(World world) { + BlockPosition blockposition = new BlockPosition(this.a, 256.0D, this.b); + + do { + if (blockposition.getY() <= 0) { + return 257; + } + + blockposition = blockposition.down(); + } while (getType(world, blockposition).getBlock().getMaterial() == Material.AIR); // CraftBukkit + + return blockposition.getY() + 1; + } + + public boolean b(World world) { + BlockPosition blockposition = new BlockPosition(this.a, 256.0D, this.b); + + Material material; + + do { + if (blockposition.getY() <= 0) { + return false; + } + + blockposition = blockposition.down(); + material = getType(world, blockposition).getBlock().getMaterial(); // CraftBukkit + } while (material == Material.AIR); + + return !material.isLiquid() && material != Material.FIRE; + } + + public void a(Random random, double d0, double d1, double d2, double d3) { + this.a = MathHelper.a(random, d0, d2); + this.b = MathHelper.a(random, d1, d3); + } + + // CraftBukkit start - add a version of getType which force loads chunks + private static IBlockData getType(World world, BlockPosition position) { + ((ChunkProviderServer) world.chunkProvider).getChunkAt(position.getX() >> 4, position.getZ() >> 4); + return world.getType(position); + } + // CraftBukkit end + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandTp.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandTp.java new file mode 100644 index 0000000..008b8c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CommandTp.java @@ -0,0 +1,132 @@ +package net.minecraft.server; + +import java.util.EnumSet; +import java.util.List; + +public class CommandTp extends CommandAbstract { + + public CommandTp() {} + + public String getCommand() { + return "tp"; + } + + public int a() { + return 2; + } + + public String getUsage(ICommandListener icommandlistener) { + return "commands.tp.usage"; + } + + public void execute(ICommandListener icommandlistener, String[] astring) throws CommandException { + if (astring.length < 1) { + throw new ExceptionUsage("commands.tp.usage", new Object[0]); + } else { + byte b0 = 0; + Object object; + + if (astring.length != 2 && astring.length != 4 && astring.length != 6) { + object = b(icommandlistener); + } else { + object = b(icommandlistener, astring[0]); + b0 = 1; + } + + if (astring.length != 1 && astring.length != 2) { + if (astring.length < b0 + 3) { + throw new ExceptionUsage("commands.tp.usage", new Object[0]); + } else if (((Entity) object).world != null) { + int i = b0 + 1; + CommandAbstract.CommandNumber commandabstract_commandnumber = a(((Entity) object).locX, astring[b0], true); + CommandAbstract.CommandNumber commandabstract_commandnumber1 = a(((Entity) object).locY, astring[i++], 0, 0, false); + CommandAbstract.CommandNumber commandabstract_commandnumber2 = a(((Entity) object).locZ, astring[i++], true); + CommandAbstract.CommandNumber commandabstract_commandnumber3 = a((double) ((Entity) object).yaw, astring.length > i ? astring[i++] : "~", false); + CommandAbstract.CommandNumber commandabstract_commandnumber4 = a((double) ((Entity) object).pitch, astring.length > i ? astring[i] : "~", false); + float f; + + if (object instanceof EntityPlayer) { + EnumSet enumset = EnumSet.noneOf(PacketPlayOutPosition.EnumPlayerTeleportFlags.class); + + if (commandabstract_commandnumber.c()) { + enumset.add(PacketPlayOutPosition.EnumPlayerTeleportFlags.X); + } + + if (commandabstract_commandnumber1.c()) { + enumset.add(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y); + } + + if (commandabstract_commandnumber2.c()) { + enumset.add(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z); + } + + if (commandabstract_commandnumber4.c()) { + enumset.add(PacketPlayOutPosition.EnumPlayerTeleportFlags.X_ROT); + } + + if (commandabstract_commandnumber3.c()) { + enumset.add(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y_ROT); + } + + f = (float) commandabstract_commandnumber3.b(); + if (!commandabstract_commandnumber3.c()) { + f = MathHelper.g(f); + } + + float f1 = (float) commandabstract_commandnumber4.b(); + + if (!commandabstract_commandnumber4.c()) { + f1 = MathHelper.g(f1); + } + + if (f1 > 90.0F || f1 < -90.0F) { + f1 = MathHelper.g(180.0F - f1); + f = MathHelper.g(f + 180.0F); + } + + ((Entity) object).mount((Entity) null); + ((EntityPlayer) object).playerConnection.a(commandabstract_commandnumber.b(), commandabstract_commandnumber1.b(), commandabstract_commandnumber2.b(), f, f1, enumset); + ((Entity) object).f(f); + } else { + float f2 = (float) MathHelper.g(commandabstract_commandnumber3.a()); + + f = (float) MathHelper.g(commandabstract_commandnumber4.a()); + if (f > 90.0F || f < -90.0F) { + f = MathHelper.g(180.0F - f); + f2 = MathHelper.g(f2 + 180.0F); + } + + ((Entity) object).setPositionRotation(commandabstract_commandnumber.a(), commandabstract_commandnumber1.a(), commandabstract_commandnumber2.a(), f2, f); + ((Entity) object).f(f2); + } + + a(icommandlistener, this, "commands.tp.success.coordinates", new Object[] { ((Entity) object).getName(), Double.valueOf(commandabstract_commandnumber.a()), Double.valueOf(commandabstract_commandnumber1.a()), Double.valueOf(commandabstract_commandnumber2.a())}); + } + } else { + Entity entity = b(icommandlistener, astring[astring.length - 1]); + + // CraftBukkit Start + // Use Bukkit teleport method in all cases. It has cross dimensional handling, events + if (((Entity) object).getBukkitEntity().teleport(entity.getBukkitEntity(), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.COMMAND)) { + a(icommandlistener, this, "commands.tp.success", new Object[]{((Entity) object).getName(), entity.getName()}); + // CraftBukkit End + } + } + } + } + + public List tabComplete(ICommandListener icommandlistener, String[] astring, BlockPosition blockposition) { + return astring.length != 1 && astring.length != 2 ? null : a(astring, MinecraftServer.getServer().getPlayers()); + } + + public boolean isListStart(String[] astring, int i) { + return i == 0; + } + + // CraftBukkit start - fix decompile error + @Override + public int compareTo(ICommand o) { + return a((ICommand) o); + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Container.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Container.java new file mode 100644 index 0000000..19cb7d0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Container.java @@ -0,0 +1,628 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +// CraftBukkit start +import java.util.HashMap; +import java.util.Map; + +import net.jafama.FastMath; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.Event.Result; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.InventoryView; +// CraftBukkit end + +public abstract class Container { + + public List b = Lists.newArrayList(); + public List c = Lists.newArrayList(); + public int windowId; + private int dragType = -1; + private int g; + private final Set h = Sets.newHashSet(); + protected List listeners = Lists.newArrayList(); + private Set i = Sets.newHashSet(); + private int tickCount; // Spigot + + // CraftBukkit start + public boolean checkReachable = true; + public abstract InventoryView getBukkitView(); + public void transferTo(Container other, org.bukkit.craftbukkit.entity.CraftHumanEntity player) { + InventoryView source = this.getBukkitView(), destination = other.getBukkitView(); + ((CraftInventory) source.getTopInventory()).getInventory().onClose(player); + ((CraftInventory) source.getBottomInventory()).getInventory().onClose(player); + ((CraftInventory) destination.getTopInventory()).getInventory().onOpen(player); + ((CraftInventory) destination.getBottomInventory()).getInventory().onOpen(player); + } + // CraftBukkit end + + public Container() {} + + protected Slot a(Slot slot) { + slot.rawSlotIndex = this.c.size(); + this.c.add(slot); + this.b.add(null); // CraftBukkit - fix decompile error + return slot; + } + + public void addSlotListener(ICrafting icrafting) { + if (this.listeners.contains(icrafting)) { + throw new IllegalArgumentException("Listener already listening"); + } else { + this.listeners.add(icrafting); + icrafting.a(this, this.a()); + this.b(); + } + } + + public List a() { + ArrayList arraylist = Lists.newArrayList(); + + for (int i = 0; i < this.c.size(); ++i) { + arraylist.add(((Slot) this.c.get(i)).getItem()); + } + + return arraylist; + } + + public void b() { + for (int i = 0; i < this.c.size(); ++i) { + ItemStack itemstack = ((Slot) this.c.get(i)).getItem(); + ItemStack itemstack1 = (ItemStack) this.b.get(i); + + if (!ItemStack.fastMatches(itemstack1, itemstack) || (tickCount % 20 == 0 && !ItemStack.matches(itemstack1, itemstack))) { // Spigot + itemstack1 = itemstack == null ? null : itemstack.cloneItemStack(); + this.b.set(i, itemstack1); + + for (int j = 0; j < this.listeners.size(); ++j) { + ((ICrafting) this.listeners.get(j)).a(this, i, itemstack1); + } + } + } + tickCount++; // Spigot + + } + + public boolean a(EntityHuman entityhuman, int i) { + return false; + } + + public Slot getSlot(IInventory iinventory, int i) { + for (int j = 0; j < this.c.size(); ++j) { + Slot slot = (Slot) this.c.get(j); + + if (slot.a(iinventory, i)) { + return slot; + } + } + + return null; + } + + public Slot getSlot(int i) { + return (Slot) this.c.get(i); + } + + public ItemStack b(EntityHuman entityhuman, int i) { + Slot slot = (Slot) this.c.get(i); + + return slot != null ? slot.getItem() : null; + } + + public ItemStack clickItem(int i, int j, int k, EntityHuman entityhuman) { + ItemStack itemstack = null; + PlayerInventory playerinventory = entityhuman.inventory; + int l; + ItemStack itemstack1; + + if (k == 5) { + int i1 = this.g; + + this.g = c(j); + if ((i1 != 1 || this.g != 2) && i1 != this.g) { + this.d(); + } else if (playerinventory.getCarried() == null) { + this.d(); + } else if (this.g == 0) { + this.dragType = b(j); + if (a(this.dragType, entityhuman)) { + this.g = 1; + this.h.clear(); + } else { + this.d(); + } + } else if (this.g == 1) { + Slot slot = i < this.c.size() ? this.c.get(i) : null; // Paper - Ensure drag in bounds + + if (slot != null && a(slot, playerinventory.getCarried(), true) && slot.isAllowed(playerinventory.getCarried()) && playerinventory.getCarried().count > this.h.size() && this.b(slot)) { + this.h.add(slot); + } + } else if (this.g == 2) { + if (!this.h.isEmpty()) { + itemstack1 = playerinventory.getCarried().cloneItemStack(); + l = playerinventory.getCarried().count; + Iterator iterator = this.h.iterator(); + + Map draggedSlots = new HashMap(); // CraftBukkit - Store slots from drag in map (raw slot id -> new stack) + while (iterator.hasNext()) { + Slot slot1 = (Slot) iterator.next(); + + if (slot1 != null && a(slot1, playerinventory.getCarried(), true) && slot1.isAllowed(playerinventory.getCarried()) && playerinventory.getCarried().count >= this.h.size() && this.b(slot1)) { + ItemStack itemstack2 = itemstack1.cloneItemStack(); + int j1 = slot1.hasItem() ? slot1.getItem().count : 0; + + a(this.h, this.dragType, itemstack2, j1); + if (itemstack2.count > itemstack2.getMaxStackSize()) { + itemstack2.count = itemstack2.getMaxStackSize(); + } + + if (itemstack2.count > slot1.getMaxStackSize(itemstack2)) { + itemstack2.count = slot1.getMaxStackSize(itemstack2); + } + + l -= itemstack2.count - j1; + // slot1.set(itemstack2); + draggedSlots.put(slot1.rawSlotIndex, itemstack2); // CraftBukkit - Put in map instead of setting + } + } + + // CraftBukkit start - InventoryDragEvent + InventoryView view = getBukkitView(); + org.bukkit.inventory.ItemStack newcursor = CraftItemStack.asCraftMirror(itemstack1); + newcursor.setAmount(l); + Map eventmap = new HashMap(); + for (Map.Entry ditem : draggedSlots.entrySet()) { + eventmap.put(ditem.getKey(), CraftItemStack.asBukkitCopy(ditem.getValue())); + } + + // It's essential that we set the cursor to the new value here to prevent item duplication if a plugin closes the inventory. + ItemStack oldCursor = playerinventory.getCarried(); + playerinventory.setCarried(CraftItemStack.asNMSCopy(newcursor)); + + InventoryDragEvent event = new InventoryDragEvent(view, (newcursor.getType() != org.bukkit.Material.AIR ? newcursor : null), CraftItemStack.asBukkitCopy(oldCursor), this.dragType == 1, eventmap); + entityhuman.world.getServer().getPluginManager().callEvent(event); + + // Whether or not a change was made to the inventory that requires an update. + boolean needsUpdate = event.getResult() != Result.DEFAULT; + + if (event.getResult() != Result.DENY) { + for (Map.Entry dslot : draggedSlots.entrySet()) { + view.setItem(dslot.getKey(), CraftItemStack.asBukkitCopy(dslot.getValue())); + } + // The only time the carried item will be set to null is if the inventory is closed by the server. + // If the inventory is closed by the server, then the cursor items are dropped. This is why we change the cursor early. + if (playerinventory.getCarried() != null) { + playerinventory.setCarried(CraftItemStack.asNMSCopy(event.getCursor())); + needsUpdate = true; + } + } else { + playerinventory.setCarried(oldCursor); + } + + if (needsUpdate && entityhuman instanceof EntityPlayer) { + ((EntityPlayer) entityhuman).updateInventory(this); + } + // CraftBukkit end + } + + this.d(); + } else { + this.d(); + } + } else if (this.g != 0) { + this.d(); + } else { + Slot slot2; + int k1; + ItemStack itemstack3; + + if ((k == 0 || k == 1) && (j == 0 || j == 1)) { + if (i == -999) { + if (playerinventory.getCarried() != null) { + if (j == 0) { + entityhuman.drop(playerinventory.getCarried(), true); + playerinventory.setCarried((ItemStack) null); + } + + if (j == 1) { + // CraftBukkit start - Store a reference + ItemStack itemstack4 = playerinventory.getCarried(); + if (itemstack4.count > 0) { + entityhuman.drop(itemstack4.cloneAndSubtract(1), true); + } + + if (itemstack4.count == 0) { + // CraftBukkit end + playerinventory.setCarried((ItemStack) null); + } + } + } + } else if (k == 1) { + if (i < 0) { + return null; + } + + slot2 = (Slot) this.c.get(i); + if (slot2 != null && slot2.isAllowed(entityhuman)) { + itemstack1 = this.b(entityhuman, i); + if (itemstack1 != null) { + Item item = itemstack1.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (slot2.getItem() != null && slot2.getItem().getItem() == item) { + this.a(i, j, true, entityhuman); + } + } + } + } else { + if (i < 0) { + return null; + } + + slot2 = (Slot) this.c.get(i); + if (slot2 != null) { + itemstack1 = slot2.getItem(); + ItemStack itemstack4 = playerinventory.getCarried(); + + if (itemstack1 != null) { + itemstack = itemstack1.cloneItemStack(); + } + + if (itemstack1 == null) { + if (itemstack4 != null && slot2.isAllowed(itemstack4)) { + k1 = j == 0 ? itemstack4.count : 1; + if (k1 > slot2.getMaxStackSize(itemstack4)) { + k1 = slot2.getMaxStackSize(itemstack4); + } + + if (itemstack4.count >= k1) { + slot2.set(itemstack4.cloneAndSubtract(k1)); + } + + if (itemstack4.count == 0) { + playerinventory.setCarried((ItemStack) null); + // CraftBukkit start - Update client cursor if we didn't empty it + } else if (entityhuman instanceof EntityPlayer) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried())); + } + // CraftBukkit end + } + } else if (slot2.isAllowed(entityhuman)) { + if (itemstack4 == null) { + k1 = j == 0 ? itemstack1.count : (itemstack1.count + 1) / 2; + itemstack3 = slot2.a(k1); + playerinventory.setCarried(itemstack3); + if (itemstack1.count == 0) { + slot2.set((ItemStack) null); + } + + slot2.a(entityhuman, playerinventory.getCarried()); + } else if (slot2.isAllowed(itemstack4)) { + if (itemstack1.getItem() == itemstack4.getItem() && itemstack1.getData() == itemstack4.getData() && ItemStack.equals(itemstack1, itemstack4)) { + k1 = j == 0 ? itemstack4.count : 1; + if (k1 > slot2.getMaxStackSize(itemstack4) - itemstack1.count) { + k1 = slot2.getMaxStackSize(itemstack4) - itemstack1.count; + } + + if (k1 > itemstack4.getMaxStackSize() - itemstack1.count) { + k1 = itemstack4.getMaxStackSize() - itemstack1.count; + } + + itemstack4.cloneAndSubtract(k1); + if (itemstack4.count == 0) { + playerinventory.setCarried((ItemStack) null); + // CraftBukkit start - Update client cursor if we didn't empty it + } else if (entityhuman instanceof EntityPlayer) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried())); + } + // CraftBukkit end + + itemstack1.count += k1; + } else if (itemstack4.count <= slot2.getMaxStackSize(itemstack4)) { + slot2.set(itemstack4); + playerinventory.setCarried(itemstack1); + } + } else if (itemstack1.getItem() == itemstack4.getItem() && itemstack4.getMaxStackSize() > 1 && (!itemstack1.usesData() || itemstack1.getData() == itemstack4.getData()) && ItemStack.equals(itemstack1, itemstack4)) { + k1 = itemstack1.count; + // CraftBukkit start - itemstack4.getMaxStackSize() -> maxStack + int maxStack = FastMath.min(itemstack4.getMaxStackSize(), slot2.getMaxStackSize()); + if (k1 > 0 && k1 + itemstack4.count <= maxStack) { + itemstack4.count += k1; + itemstack1 = slot2.a(k1); + if (itemstack1.count == 0) { + slot2.set((ItemStack) null); + } + + slot2.a(entityhuman, playerinventory.getCarried()); + // CraftBukkit start - Update client cursor if we didn't empty it + } else if (entityhuman instanceof EntityPlayer) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, entityhuman.inventory.getCarried())); + } + // CraftBukkit end + } + } + + slot2.f(); + // CraftBukkit start - Make sure the client has the right slot contents + if (entityhuman instanceof EntityPlayer && slot2.getMaxStackSize() != 64) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, slot2.rawSlotIndex, slot2.getItem())); + // Updating a crafting inventory makes the client reset the result slot, have to send it again + if (this.getBukkitView().getType() == InventoryType.WORKBENCH || this.getBukkitView().getType() == InventoryType.CRAFTING) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutSetSlot(this.windowId, 0, this.getSlot(0).getItem())); + } + } + // CraftBukkit end + } + } + } else if (k == 2 && j >= 0 && j < 9) { + slot2 = (Slot) this.c.get(i); + if (slot2.isAllowed(entityhuman)) { + itemstack1 = playerinventory.getItem(j); + boolean flag = itemstack1 == null || slot2.inventory == playerinventory && slot2.isAllowed(itemstack1); + + k1 = -1; + if (!flag) { + k1 = playerinventory.getFirstEmptySlotIndex(); + flag |= k1 > -1; + } + + if (slot2.hasItem() && flag) { + itemstack3 = slot2.getItem(); + playerinventory.setItem(j, itemstack3.cloneItemStack()); + if ((slot2.inventory != playerinventory || !slot2.isAllowed(itemstack1)) && itemstack1 != null) { + if (k1 > -1) { + playerinventory.pickup(itemstack1); + slot2.a(itemstack3.count); + slot2.set((ItemStack) null); + slot2.a(entityhuman, itemstack3); + } + } else { + slot2.a(itemstack3.count); + slot2.set(itemstack1); + slot2.a(entityhuman, itemstack3); + } + } else if (!slot2.hasItem() && itemstack1 != null && slot2.isAllowed(itemstack1)) { + playerinventory.setItem(j, (ItemStack) null); + slot2.set(itemstack1); + } + } + } else if (k == 3 && entityhuman.abilities.canInstantlyBuild && playerinventory.getCarried() == null && i >= 0) { + slot2 = (Slot) this.c.get(i); + if (slot2 != null && slot2.hasItem()) { + itemstack1 = slot2.getItem().cloneItemStack(); + itemstack1.count = itemstack1.getMaxStackSize(); + playerinventory.setCarried(itemstack1); + } + } else if (k == 4 && playerinventory.getCarried() == null && i >= 0) { + slot2 = (Slot) this.c.get(i); + if (slot2 != null && slot2.hasItem() && slot2.isAllowed(entityhuman)) { + itemstack1 = slot2.a(j == 0 ? 1 : slot2.getItem().count); + slot2.a(entityhuman, itemstack1); + entityhuman.drop(itemstack1, true); + } + } else if (k == 6 && i >= 0) { + slot2 = (Slot) this.c.get(i); + itemstack1 = playerinventory.getCarried(); + if (itemstack1 != null && (slot2 == null || !slot2.hasItem() || !slot2.isAllowed(entityhuman))) { + l = j == 0 ? 0 : this.c.size() - 1; + k1 = j == 0 ? 1 : -1; + + for (int l1 = 0; l1 < 2; ++l1) { + for (int i2 = l; i2 >= 0 && i2 < this.c.size() && itemstack1.count < itemstack1.getMaxStackSize(); i2 += k1) { + Slot slot3 = (Slot) this.c.get(i2); + + if (slot3.hasItem() && a(slot3, itemstack1, true) && slot3.isAllowed(entityhuman) && this.a(itemstack1, slot3) && (l1 != 0 || slot3.getItem().count != slot3.getItem().getMaxStackSize())) { + int j2 = FastMath.min(itemstack1.getMaxStackSize() - itemstack1.count, slot3.getItem().count); + ItemStack itemstack5 = slot3.a(j2); + + itemstack1.count += j2; + if (itemstack5.count <= 0) { + slot3.set((ItemStack) null); + } + + slot3.a(entityhuman, itemstack5); + } + } + } + } + + this.b(); + } + } + + return itemstack; + } + + public boolean a(ItemStack itemstack, Slot slot) { + return true; + } + + protected void a(int i, int j, boolean flag, EntityHuman entityhuman) { + this.clickItem(i, j, 1, entityhuman); + } + + public void b(EntityHuman entityhuman) { + PlayerInventory playerinventory = entityhuman.inventory; + + if (playerinventory.getCarried() != null) { + entityhuman.drop(playerinventory.getCarried(), false); + playerinventory.setCarried((ItemStack) null); + } + + } + + public void a(IInventory iinventory) { + this.b(); + } + + public void setItem(int i, ItemStack itemstack) { + this.getSlot(i).set(itemstack); + } + + public boolean c(EntityHuman entityhuman) { + return !this.i.contains(entityhuman); + } + + public void a(EntityHuman entityhuman, boolean flag) { + if (flag) { + this.i.remove(entityhuman); + } else { + this.i.add(entityhuman); + } + + } + + public abstract boolean a(EntityHuman entityhuman); + + protected boolean a(ItemStack itemstack, int i, int j, boolean flag) { + boolean flag1 = false; + int k = i; + + if (flag) { + k = j - 1; + } + + Slot slot; + ItemStack itemstack1; + + if (itemstack.isStackable()) { + while (itemstack.count > 0 && (!flag && k < j || flag && k >= i)) { + slot = (Slot) this.c.get(k); + itemstack1 = slot.getItem(); + if (itemstack1 != null && itemstack1.getItem() == itemstack.getItem() && (!itemstack.usesData() || itemstack.getData() == itemstack1.getData()) && ItemStack.equals(itemstack, itemstack1)) { + int l = itemstack1.count + itemstack.count; + + // CraftBukkit start - itemstack.getMaxStackSize() -> maxStack + int maxStack = FastMath.min(itemstack.getMaxStackSize(), slot.getMaxStackSize()); + if (l <= maxStack) { + itemstack.count = 0; + itemstack1.count = l; + slot.f(); + flag1 = true; + } else if (itemstack1.count < maxStack) { + itemstack.count -= maxStack - itemstack1.count; + itemstack1.count = maxStack; + slot.f(); + flag1 = true; + } + // CraftBukkit end + } + + if (flag) { + --k; + } else { + ++k; + } + } + } + + if (itemstack.count > 0) { + if (flag) { + k = j - 1; + } else { + k = i; + } + + while (!flag && k < j || flag && k >= i) { + slot = (Slot) this.c.get(k); + itemstack1 = slot.getItem(); + if (itemstack1 == null) { + slot.set(itemstack.cloneItemStack()); + slot.f(); + itemstack.count = 0; + flag1 = true; + break; + } + + if (flag) { + --k; + } else { + ++k; + } + } + } + + return flag1; + } + + public static int b(int i) { + return i >> 2 & 3; + } + + public static int c(int i) { + return i & 3; + } + + public static boolean a(int i, EntityHuman entityhuman) { + return i == 0 ? true : (i == 1 ? true : i == 2 && entityhuman.abilities.canInstantlyBuild); + } + + protected void d() { + this.g = 0; + this.h.clear(); + } + + public static boolean a(Slot slot, ItemStack itemstack, boolean flag) { + boolean flag1 = slot == null || !slot.hasItem(); + + if (slot != null && slot.hasItem() && itemstack != null && itemstack.doMaterialsMatch(slot.getItem()) && ItemStack.equals(slot.getItem(), itemstack)) { + flag1 |= slot.getItem().count + (flag ? 0 : itemstack.count) <= itemstack.getMaxStackSize(); + } + + return flag1; + } + + public static void a(Set set, int i, ItemStack itemstack, int j) { + switch (i) { + case 0: + itemstack.count = MathHelper.d((float) itemstack.count / (float) set.size()); + break; + + case 1: + itemstack.count = 1; + break; + + case 2: + itemstack.count = itemstack.getItem().getMaxStackSize(); + } + + itemstack.count += j; + } + + public boolean b(Slot slot) { + return true; + } + + public static int a(TileEntity tileentity) { + return tileentity instanceof IInventory ? b((IInventory) tileentity) : 0; + } + + public static int b(IInventory iinventory) { + if (iinventory == null) { + return 0; + } else { + int i = 0; + float f = 0.0F; + + for (int j = 0; j < iinventory.getSize(); ++j) { + ItemStack itemstack = iinventory.getItem(j); + + if (itemstack != null) { + f += (float) itemstack.count / (float) FastMath.min(iinventory.getMaxStackSize(), itemstack.getMaxStackSize()); + ++i; + } + } + + f /= (float) iinventory.getSize(); + return MathHelper.d(f * 14.0F) + (i > 0 ? 1 : 0); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerAnvil.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerAnvil.java new file mode 100644 index 0000000..759d5b3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerAnvil.java @@ -0,0 +1,398 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Map; + +import net.jafama.FastMath; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit + +public class ContainerAnvil extends Container { + + private static final Logger f = LogManager.getLogger(); + private IInventory g = new InventoryCraftResult(); + private IInventory h = new InventorySubcontainer("Repair", true, 2) { + public void update() { + super.update(); + ContainerAnvil.this.a((IInventory) this); + } + }; + private World i; + private BlockPosition j; + public int a; + private int k; + private String l; + private final EntityHuman m; + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + // CraftBukkit end + + public ContainerAnvil(PlayerInventory playerinventory, final World world, final BlockPosition blockposition, EntityHuman entityhuman) { + this.player = playerinventory; // CraftBukkit + this.j = blockposition; + this.i = world; + this.m = entityhuman; + this.a(new Slot(this.h, 0, 27, 47)); + this.a(new Slot(this.h, 1, 76, 47)); + this.a(new Slot(this.g, 2, 134, 47) { + public boolean isAllowed(ItemStack itemstack) { + return false; + } + + public boolean isAllowed(EntityHuman entityhuman) { + return (entityhuman.abilities.canInstantlyBuild || entityhuman.expLevel >= ContainerAnvil.this.a) && ContainerAnvil.this.a > 0 && this.hasItem(); + } + + public void a(EntityHuman entityhuman, ItemStack itemstack) { + if (!entityhuman.abilities.canInstantlyBuild) { + entityhuman.levelDown(-ContainerAnvil.this.a); + } + + ContainerAnvil.this.h.setItem(0, (ItemStack) null); + if (ContainerAnvil.this.k > 0) { + ItemStack itemstack1 = ContainerAnvil.this.h.getItem(1); + + if (itemstack1 != null && itemstack1.count > ContainerAnvil.this.k) { + itemstack1.count -= ContainerAnvil.this.k; + ContainerAnvil.this.h.setItem(1, itemstack1); + } else { + ContainerAnvil.this.h.setItem(1, (ItemStack) null); + } + } else { + ContainerAnvil.this.h.setItem(1, (ItemStack) null); + } + + ContainerAnvil.this.a = 0; + IBlockData iblockdata = world.getType(blockposition); + + if (!entityhuman.abilities.canInstantlyBuild && !world.isClientSide && iblockdata.getBlock() == Blocks.ANVIL && entityhuman.bc().nextFloat() < 0.12F) { + int i = ((Integer) iblockdata.get(BlockAnvil.DAMAGE)).intValue(); + + ++i; + if (i > 2) { + world.setAir(blockposition); + world.triggerEffect(1020, blockposition, 0); + } else { + world.setTypeAndData(blockposition, iblockdata.set(BlockAnvil.DAMAGE, Integer.valueOf(i)), 2); + world.triggerEffect(1021, blockposition, 0); + } + } else if (!world.isClientSide) { + world.triggerEffect(1021, blockposition, 0); + } + + } + }); + + int i; + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + + } + + public void a(IInventory iinventory) { + super.a(iinventory); + if (iinventory == this.h) { + this.e(); + } + + } + + public void e() { + boolean flag = false; + boolean flag1 = true; + boolean flag2 = true; + boolean flag3 = true; + boolean flag4 = true; + boolean flag5 = true; + boolean flag6 = true; + ItemStack itemstack = this.h.getItem(0); + + this.a = 1; + int i = 0; + byte b0 = 0; + byte b1 = 0; + + if (itemstack == null) { + this.g.setItem(0, (ItemStack) null); + this.a = 0; + } else { + ItemStack itemstack1 = itemstack.cloneItemStack(); + ItemStack itemstack2 = this.h.getItem(1); + Map map = EnchantmentManager.a(itemstack1); + boolean flag7 = false; + int j = b0 + itemstack.getRepairCost() + (itemstack2 == null ? 0 : itemstack2.getRepairCost()); + + this.k = 0; + int k; + + if (itemstack2 != null) { + flag7 = itemstack2.getItem() == Items.ENCHANTED_BOOK && Items.ENCHANTED_BOOK.h(itemstack2).size() > 0; + int l; + int i1; + + if (itemstack1.e() && itemstack1.getItem().a(itemstack, itemstack2)) { + k = FastMath.min(itemstack1.h(), itemstack1.j() / 4); + if (k <= 0) { + this.g.setItem(0, (ItemStack) null); + this.a = 0; + return; + } + + for (l = 0; k > 0 && l < itemstack2.count; ++l) { + i1 = itemstack1.h() - k; + itemstack1.setData(i1); + ++i; + k = FastMath.min(itemstack1.h(), itemstack1.j() / 4); + } + + this.k = l; + } else { + if (!flag7 && (itemstack1.getItem() != itemstack2.getItem() || !itemstack1.e())) { + this.g.setItem(0, (ItemStack) null); + this.a = 0; + return; + } + + int j1; + + if (itemstack1.e() && !flag7) { + k = itemstack.j() - itemstack.h(); + l = itemstack2.j() - itemstack2.h(); + i1 = l + itemstack1.j() * 12 / 100; + int k1 = k + i1; + + j1 = itemstack1.j() - k1; + if (j1 < 0) { + j1 = 0; + } + + if (j1 < itemstack1.getData()) { + itemstack1.setData(j1); + i += 2; + } + } + + Map map1 = EnchantmentManager.a(itemstack2); + Iterator iterator = map1.keySet().iterator(); + + while (iterator.hasNext()) { + i1 = ((Integer) iterator.next()).intValue(); + Enchantment enchantment = Enchantment.getById(i1); + + if (enchantment != null) { + j1 = map.containsKey(Integer.valueOf(i1)) ? ((Integer) map.get(Integer.valueOf(i1))).intValue() : 0; + int l1 = ((Integer) map1.get(Integer.valueOf(i1))).intValue(); + int i2; + + if (j1 == l1) { + ++l1; + i2 = l1; + } else { + i2 = FastMath.max(l1, j1); + } + + l1 = i2; + boolean flag8 = enchantment.canEnchant(itemstack); + + if (this.m.abilities.canInstantlyBuild || itemstack.getItem() == Items.ENCHANTED_BOOK) { + flag8 = true; + } + + Iterator iterator1 = map.keySet().iterator(); + + while (iterator1.hasNext()) { + int j2 = ((Integer) iterator1.next()).intValue(); + + if (j2 != i1 && !enchantment.a(Enchantment.getById(j2))) { + flag8 = false; + ++i; + } + } + + if (flag8) { + if (l1 > enchantment.getMaxLevel()) { + l1 = enchantment.getMaxLevel(); + } + + map.put(Integer.valueOf(i1), Integer.valueOf(l1)); + int k2 = 0; + + switch (enchantment.getRandomWeight()) { + case 1: + k2 = 8; + break; + + case 2: + k2 = 4; + + case 3: + case 4: + case 6: + case 7: + case 8: + case 9: + default: + break; + + case 5: + k2 = 2; + break; + + case 10: + k2 = 1; + } + + if (flag7) { + k2 = FastMath.max(1, k2 / 2); + } + + i += k2 * l1; + } + } + } + } + } + + if (StringUtils.isBlank(this.l)) { + if (itemstack.hasName()) { + b1 = 1; + i += b1; + itemstack1.r(); + } + } else if (!this.l.equals(itemstack.getName())) { + b1 = 1; + i += b1; + itemstack1.c(this.l); + } + + this.a = j + i; + if (i <= 0) { + itemstack1 = null; + } + + if (b1 == i && b1 > 0 && this.a >= 40) { + this.a = 39; + } + + if (this.a >= 40 && !this.m.abilities.canInstantlyBuild) { + itemstack1 = null; + } + + if (itemstack1 != null) { + k = itemstack1.getRepairCost(); + if (itemstack2 != null && k < itemstack2.getRepairCost()) { + k = itemstack2.getRepairCost(); + } + + k = k * 2 + 1; + itemstack1.setRepairCost(k); + EnchantmentManager.a(map, itemstack1); + } + + this.g.setItem(0, itemstack1); + this.b(); + } + } + + public void addSlotListener(ICrafting icrafting) { + super.addSlotListener(icrafting); + icrafting.setContainerData(this, 0, this.a); + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + if (!this.i.isClientSide) { + for (int i = 0; i < this.h.getSize(); ++i) { + ItemStack itemstack = this.h.splitWithoutUpdate(i); + + if (itemstack != null) { + entityhuman.drop(itemstack, false); + } + } + + } + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.i.getType(this.j).getBlock() != Blocks.ANVIL ? false : entityhuman.e((double) this.j.getX() + 0.5D, (double) this.j.getY() + 0.5D, (double) this.j.getZ() + 0.5D) <= 64.0D; + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 2) { + if (!this.a(itemstack1, 3, 39, true)) { + return null; + } + + slot.a(itemstack1, itemstack); + } else if (i != 0 && i != 1) { + if (i >= 3 && i < 39 && !this.a(itemstack1, 0, 2, false)) { + return null; + } + } else if (!this.a(itemstack1, 3, 39, false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + public void a(String s) { + this.l = s; + if (this.getSlot(2).hasItem()) { + ItemStack itemstack = this.getSlot(2).getItem(); + + if (StringUtils.isBlank(s)) { + itemstack.r(); + } else { + itemstack.c(this.l); + } + } + + this.e(); + } + + // CraftBukkit start + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryAnvil(this.h, this.g); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerBeacon.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerBeacon.java new file mode 100644 index 0000000..9c755fa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerBeacon.java @@ -0,0 +1,134 @@ +package net.minecraft.server; + +import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit + +public class ContainerBeacon extends Container { + + private IInventory beacon; + private final ContainerBeacon.SlotBeacon f; + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + // CraftBukkit end + + public ContainerBeacon(IInventory iinventory, IInventory iinventory1) { + player = (PlayerInventory) iinventory; // CraftBukkit - TODO: check this + this.beacon = iinventory1; + this.a((Slot) (this.f = new ContainerBeacon.SlotBeacon(iinventory1, 0, 136, 110))); + byte b0 = 36; + short short0 = 137; + + int i; + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(iinventory, j + i * 9 + 9, b0 + j * 18, short0 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(iinventory, i, b0 + i * 18, 58 + short0)); + } + + } + + public void addSlotListener(ICrafting icrafting) { + super.addSlotListener(icrafting); + icrafting.setContainerData(this, this.beacon); + } + + public IInventory e() { + return this.beacon; + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + if (entityhuman != null && !entityhuman.world.isClientSide) { + ItemStack itemstack = this.f.a(this.f.getMaxStackSize()); + + if (itemstack != null) { + entityhuman.drop(itemstack, false); + } + + } + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.beacon.a(entityhuman); + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 0) { + if (!this.a(itemstack1, 1, 37, true)) { + return null; + } + + slot.a(itemstack1, itemstack); + } else if (!this.f.hasItem() && this.f.isAllowed(itemstack1) && itemstack1.count == 1) { + if (!this.a(itemstack1, 0, 1, false)) { + return null; + } + } else if (i >= 1 && i < 28) { + if (!this.a(itemstack1, 28, 37, false)) { + return null; + } + } else if (i >= 28 && i < 37) { + if (!this.a(itemstack1, 1, 28, false)) { + return null; + } + } else if (!this.a(itemstack1, 1, 37, false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + class SlotBeacon extends Slot { + + public SlotBeacon(IInventory iinventory, int i, int j, int k) { + super(iinventory, i, j, k); + } + + public boolean isAllowed(ItemStack itemstack) { + return itemstack == null ? false : itemstack.getItem() == Items.EMERALD || itemstack.getItem() == Items.DIAMOND || itemstack.getItem() == Items.GOLD_INGOT || itemstack.getItem() == Items.IRON_INGOT; + } + + public int getMaxStackSize() { + return 1; + } + } + + // CraftBukkit start + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryBeacon((TileEntityBeacon) this.beacon); // TODO - check this + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerBrewingStand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerBrewingStand.java new file mode 100644 index 0000000..ba558b8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerBrewingStand.java @@ -0,0 +1,174 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +// CraftBukkit end + +public class ContainerBrewingStand extends Container { + + private IInventory brewingStand; + private final Slot f; + private int g; + + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + // CraftBukkit end + + public ContainerBrewingStand(PlayerInventory playerinventory, IInventory iinventory) { + player = playerinventory; // CraftBukkit + this.brewingStand = iinventory; + this.a((Slot) (new ContainerBrewingStand.SlotPotionBottle(playerinventory.player, iinventory, 0, 56, 46))); + this.a((Slot) (new ContainerBrewingStand.SlotPotionBottle(playerinventory.player, iinventory, 1, 79, 53))); + this.a((Slot) (new ContainerBrewingStand.SlotPotionBottle(playerinventory.player, iinventory, 2, 102, 46))); + this.f = this.a((Slot) (new ContainerBrewingStand.SlotBrewing(iinventory, 3, 79, 17))); + + int i; + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + + } + + public void addSlotListener(ICrafting icrafting) { + super.addSlotListener(icrafting); + icrafting.setContainerData(this, this.brewingStand); + } + + public void b() { + super.b(); + + for (int i = 0; i < this.listeners.size(); ++i) { + ICrafting icrafting = (ICrafting) this.listeners.get(i); + + if (this.g != this.brewingStand.getProperty(0)) { + icrafting.setContainerData(this, 0, this.brewingStand.getProperty(0)); + } + } + + this.g = this.brewingStand.getProperty(0); + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.brewingStand.a(entityhuman); + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if ((i < 0 || i > 2) && i != 3) { + if (!this.f.hasItem() && this.f.isAllowed(itemstack1)) { + if (!this.a(itemstack1, 3, 4, false)) { + return null; + } + } else if (ContainerBrewingStand.SlotPotionBottle.b_(itemstack)) { + if (!this.a(itemstack1, 0, 3, false)) { + return null; + } + } else if (i >= 4 && i < 31) { + if (!this.a(itemstack1, 31, 40, false)) { + return null; + } + } else if (i >= 31 && i < 40) { + if (!this.a(itemstack1, 4, 31, false)) { + return null; + } + } else if (!this.a(itemstack1, 4, 40, false)) { + return null; + } + } else { + if (!this.a(itemstack1, 4, 40, true)) { + return null; + } + + slot.a(itemstack1, itemstack); + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + class SlotBrewing extends Slot { + + public SlotBrewing(IInventory iinventory, int i, int j, int k) { + super(iinventory, i, j, k); + } + + public boolean isAllowed(ItemStack itemstack) { + return itemstack != null ? itemstack.getItem().l(itemstack) : false; + } + + public int getMaxStackSize() { + return 64; + } + } + + static class SlotPotionBottle extends Slot { + + private EntityHuman a; + + public SlotPotionBottle(EntityHuman entityhuman, IInventory iinventory, int i, int j, int k) { + super(iinventory, i, j, k); + this.a = entityhuman; + } + + public boolean isAllowed(ItemStack itemstack) { + return b_(itemstack); + } + + public int getMaxStackSize() { + return 1; + } + + public void a(EntityHuman entityhuman, ItemStack itemstack) { + if (itemstack.getItem() == Items.POTION && itemstack.getData() > 0) { + this.a.b((Statistic) AchievementList.B); + } + + super.a(entityhuman, itemstack); + } + + public static boolean b_(ItemStack itemstack) { + return itemstack != null && (itemstack.getItem() == Items.POTION || itemstack.getItem() == Items.GLASS_BOTTLE); + } + } + + // CraftBukkit start + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryBrewer inventory = new CraftInventoryBrewer(this.brewingStand); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerChest.java new file mode 100644 index 0000000..5a33217 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerChest.java @@ -0,0 +1,107 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +// CraftBukkit end + +public class ContainerChest extends Container { + + private IInventory container; + private int f; + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventory inventory; + if (this.container instanceof PlayerInventory) { + inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryPlayer((PlayerInventory) this.container); + } else if (this.container instanceof InventoryLargeChest) { + inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) this.container); + } else { + inventory = new CraftInventory(this.container); + } + + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end + + public ContainerChest(IInventory iinventory, IInventory iinventory1, EntityHuman entityhuman) { + this.container = iinventory1; + this.f = iinventory1.getSize() / 9; + iinventory1.startOpen(entityhuman); + int i = (this.f - 4) * 18; + + // CraftBukkit start - Save player + // TODO: Should we check to make sure it really is an InventoryPlayer? + this.player = (PlayerInventory) iinventory; + // CraftBukkit end + + int j; + int k; + + for (j = 0; j < this.f; ++j) { + for (k = 0; k < 9; ++k) { + this.a(new Slot(iinventory1, k + j * 9, 8 + k * 18, 18 + j * 18)); + } + } + + for (j = 0; j < 3; ++j) { + for (k = 0; k < 9; ++k) { + this.a(new Slot(iinventory, k + j * 9 + 9, 8 + k * 18, 103 + j * 18 + i)); + } + } + + for (j = 0; j < 9; ++j) { + this.a(new Slot(iinventory, j, 8 + j * 18, 161 + i)); + } + + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.container.a(entityhuman); + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i < this.f * 9) { + if (!this.a(itemstack1, this.f * 9, this.c.size(), true)) { + return null; + } + } else if (!this.a(itemstack1, 0, this.f * 9, false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + } + + return itemstack; + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.container.closeContainer(entityhuman); + } + + public IInventory e() { + return this.container; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerDispenser.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerDispenser.java new file mode 100644 index 0000000..8862b2a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerDispenser.java @@ -0,0 +1,93 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +// CraftBukkit end + +public class ContainerDispenser extends Container { + + public IInventory items; + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + // CraftBukkit end + + public ContainerDispenser(IInventory iinventory, IInventory iinventory1) { + this.items = iinventory1; + // CraftBukkit start - Save player + // TODO: Should we check to make sure it really is an InventoryPlayer? + this.player = (PlayerInventory)iinventory; + // CraftBukkit end + + int i; + int j; + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + this.a(new Slot(iinventory1, j + i * 3, 62 + j * 18, 17 + i * 18)); + } + } + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 9; ++j) { + this.a(new Slot(iinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(iinventory, i, 8 + i * 18, 142)); + } + + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.items.a(entityhuman); + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i < 9) { + if (!this.a(itemstack1, 9, 45, true)) { + return null; + } + } else if (!this.a(itemstack1, 0, 9, false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + // CraftBukkit start + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventory inventory = new CraftInventory(this.items); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerEnchantTable.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerEnchantTable.java new file mode 100644 index 0000000..5c473be --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerEnchantTable.java @@ -0,0 +1,376 @@ +package net.minecraft.server; + +import java.util.List; +import java.util.Random; + +// CraftBukkit start +import java.util.Map; + +import org.bukkit.craftbukkit.inventory.CraftInventoryEnchanting; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.enchantment.EnchantItemEvent; +import org.bukkit.event.enchantment.PrepareItemEnchantEvent; +import org.bukkit.entity.Player; +// CraftBukkit end + +public class ContainerEnchantTable extends Container { + + // CraftBukkit - make type specific (changed from IInventory) + public InventorySubcontainer enchantSlots = new InventorySubcontainer("Enchant", true, 2) { + public int getMaxStackSize() { + return 64; + } + + public void update() { + super.update(); + ContainerEnchantTable.this.a((IInventory) this); + } + }; + private World world; + private BlockPosition position; + private Random k = new Random(); + public int f; + public int[] costs = new int[3]; + public int[] h = new int[] { -1, -1, -1}; + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private Player player; + // CraftBukkit end + + public ContainerEnchantTable(PlayerInventory playerinventory, World world, BlockPosition blockposition) { + this.world = world; + this.position = blockposition; + this.f = playerinventory.player.cj(); + this.a(new Slot(this.enchantSlots, 0, 15, 47) { + public boolean isAllowed(ItemStack itemstack) { + return true; + } + + public int getMaxStackSize() { + return 1; + } + }); + this.a(new Slot(this.enchantSlots, 1, 35, 47) { + public boolean isAllowed(ItemStack itemstack) { + return itemstack.getItem() == Items.DYE && EnumColor.fromInvColorIndex(itemstack.getData()) == EnumColor.BLUE; + } + }); + + int i; + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + + // CraftBukkit start + player = (Player) playerinventory.player.getBukkitEntity(); + // CraftBukkit end + } + + public void addSlotListener(ICrafting icrafting) { + super.addSlotListener(icrafting); + icrafting.setContainerData(this, 0, this.costs[0]); + icrafting.setContainerData(this, 1, this.costs[1]); + icrafting.setContainerData(this, 2, this.costs[2]); + icrafting.setContainerData(this, 3, this.f & -16); + icrafting.setContainerData(this, 4, this.h[0]); + icrafting.setContainerData(this, 5, this.h[1]); + icrafting.setContainerData(this, 6, this.h[2]); + } + + public void b() { + super.b(); + + for (int i = 0; i < this.listeners.size(); ++i) { + ICrafting icrafting = (ICrafting) this.listeners.get(i); + + icrafting.setContainerData(this, 0, this.costs[0]); + icrafting.setContainerData(this, 1, this.costs[1]); + icrafting.setContainerData(this, 2, this.costs[2]); + icrafting.setContainerData(this, 3, this.f & -16); + icrafting.setContainerData(this, 4, this.h[0]); + icrafting.setContainerData(this, 5, this.h[1]); + icrafting.setContainerData(this, 6, this.h[2]); + } + + } + + public void a(IInventory iinventory) { + if (iinventory == this.enchantSlots) { + ItemStack itemstack = iinventory.getItem(0); + int i; + + if (itemstack != null) { // CraftBukkit - relax condition + if (!this.world.isClientSide) { + i = 0; + + int j; + + for (j = -1; j <= 1; ++j) { + for (int k = -1; k <= 1; ++k) { + if ((j != 0 || k != 0) && this.world.isEmpty(this.position.a(k, 0, j)) && this.world.isEmpty(this.position.a(k, 1, j))) { + if (this.world.getType(this.position.a(k * 2, 0, j * 2)).getBlock() == Blocks.BOOKSHELF) { + ++i; + } + + if (this.world.getType(this.position.a(k * 2, 1, j * 2)).getBlock() == Blocks.BOOKSHELF) { + ++i; + } + + if (k != 0 && j != 0) { + if (this.world.getType(this.position.a(k * 2, 0, j)).getBlock() == Blocks.BOOKSHELF) { + ++i; + } + + if (this.world.getType(this.position.a(k * 2, 1, j)).getBlock() == Blocks.BOOKSHELF) { + ++i; + } + + if (this.world.getType(this.position.a(k, 0, j * 2)).getBlock() == Blocks.BOOKSHELF) { + ++i; + } + + if (this.world.getType(this.position.a(k, 1, j * 2)).getBlock() == Blocks.BOOKSHELF) { + ++i; + } + } + } + } + } + + this.k.setSeed((long) this.f); + + for (j = 0; j < 3; ++j) { + this.costs[j] = EnchantmentManager.a(this.k, j, i, itemstack); + this.h[j] = -1; + if (this.costs[j] < j + 1) { + this.costs[j] = 0; + } + } + + // CraftBukkit start + CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); + PrepareItemEnchantEvent event = new PrepareItemEnchantEvent(player, this.getBukkitView(), this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), item, this.costs, i); + event.setCancelled(!itemstack.v()); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + for (i = 0; i < 3; ++i) { + this.costs[i] = 0; + } + return; + } + // CraftBukkit end + + for (j = 0; j < 3; ++j) { + if (this.costs[j] > 0) { + List list = this.a(itemstack, j, this.costs[j]); + + if (list != null && !list.isEmpty()) { + WeightedRandomEnchant weightedrandomenchant = (WeightedRandomEnchant) list.get(this.k.nextInt(list.size())); + + this.h[j] = weightedrandomenchant.enchantment.id | weightedrandomenchant.level << 8; + } + } + } + + this.b(); + } + } else { + for (i = 0; i < 3; ++i) { + this.costs[i] = 0; + this.h[i] = -1; + } + } + } + + } + + public boolean a(EntityHuman entityhuman, int i) { + ItemStack itemstack = this.enchantSlots.getItem(0); + ItemStack itemstack1 = this.enchantSlots.getItem(1); + int j = i + 1; + + if ((itemstack1 == null || itemstack1.count < j) && !entityhuman.abilities.canInstantlyBuild) { + return false; + } else if (this.costs[i] > 0 && itemstack != null && (entityhuman.expLevel >= j && entityhuman.expLevel >= this.costs[i] || entityhuman.abilities.canInstantlyBuild)) { + if (!this.world.isClientSide) { + List list = this.a(itemstack, i, this.costs[i]); + // CraftBukkit start - Provide an empty enchantment list + if (list == null) { + list = new java.util.ArrayList(); + } + // CraftBukkit end + boolean flag = itemstack.getItem() == Items.BOOK; + + if (list != null) { + // CraftBukkit start + Map enchants = new java.util.HashMap(); + for (Object obj : list) { + WeightedRandomEnchant instance = (WeightedRandomEnchant) obj; + enchants.put(org.bukkit.enchantments.Enchantment.getById(instance.enchantment.id), instance.level); + } + CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); + + EnchantItemEvent event = new EnchantItemEvent((Player) entityhuman.getBukkitEntity(), this.getBukkitView(), this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), item, this.costs[i], enchants, i); + this.world.getServer().getPluginManager().callEvent(event); + + int level = event.getExpLevelCost(); + if (event.isCancelled() || (level > entityhuman.expLevel && !entityhuman.abilities.canInstantlyBuild) || event.getEnchantsToAdd().isEmpty()) { + return false; + } + if (flag) { + itemstack.setItem(Items.ENCHANTED_BOOK); + } + + for (Map.Entry entry : event.getEnchantsToAdd().entrySet()) { + try { + if (flag) { + int enchantId = entry.getKey().getId(); + if (Enchantment.getById(enchantId) == null) { + continue; + } + + WeightedRandomEnchant enchantment = new WeightedRandomEnchant(Enchantment.getById(enchantId), entry.getValue()); + Items.ENCHANTED_BOOK.a(itemstack, enchantment); + } else { + item.addUnsafeEnchantment(entry.getKey(), entry.getValue()); + } + } catch (IllegalArgumentException e) { + /* Just swallow invalid enchantments */ + } + } + + entityhuman.enchantDone(j); + // CraftBukkit end + + // CraftBukkit - TODO: let plugins change this + if (!entityhuman.abilities.canInstantlyBuild) { + itemstack1.count -= j; + if (itemstack1.count <= 0) { + this.enchantSlots.setItem(1, (ItemStack) null); + } + } + + entityhuman.b(StatisticList.W); + this.enchantSlots.update(); + this.f = entityhuman.cj(); + this.a(this.enchantSlots); + } + } + + return true; + } else { + return false; + } + } + + private List a(ItemStack itemstack, int i, int j) { + this.k.setSeed((long) (this.f + i)); + List list = EnchantmentManager.b(this.k, itemstack, j); + + if (itemstack.getItem() == Items.BOOK && list != null && list.size() > 1) { + list.remove(this.k.nextInt(list.size())); + } + + return list; + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + // CraftBukkit Start - If an enchantable was opened from a null location, set the world to the player's world, preventing a crash + if(this.world == null) { + this.world = entityhuman.getWorld(); + } + // CraftBukkit end + if (!this.world.isClientSide) { + for (int i = 0; i < this.enchantSlots.getSize(); ++i) { + ItemStack itemstack = this.enchantSlots.splitWithoutUpdate(i); + + if (itemstack != null) { + entityhuman.drop(itemstack, false); + } + } + + } + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.world.getType(this.position).getBlock() != Blocks.ENCHANTING_TABLE ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 0) { + if (!this.a(itemstack1, 2, 38, true)) { + return null; + } + } else if (i == 1) { + if (!this.a(itemstack1, 2, 38, true)) { + return null; + } + } else if (itemstack1.getItem() == Items.DYE && EnumColor.fromInvColorIndex(itemstack1.getData()) == EnumColor.BLUE) { + if (!this.a(itemstack1, 1, 2, true)) { + return null; + } + } else { + if (((Slot) this.c.get(0)).hasItem() || !((Slot) this.c.get(0)).isAllowed(itemstack1)) { + return null; + } + + if (itemstack1.hasTag() && itemstack1.count == 1) { + ((Slot) this.c.get(0)).set(itemstack1.cloneItemStack()); + itemstack1.count = 0; + } else if (itemstack1.count >= 1) { + // Spigot start + ItemStack clone = itemstack1.cloneItemStack(); + clone.count = 1; + ((Slot) this.c.get(0)).set(clone); + // Spigot end + --itemstack1.count; + } + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + // CraftBukkit start + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryEnchanting inventory = new CraftInventoryEnchanting(this.enchantSlots); + bukkitEntity = new CraftInventoryView(this.player, inventory, this); + return bukkitEntity; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerFurnace.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerFurnace.java new file mode 100644 index 0000000..04cccbb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerFurnace.java @@ -0,0 +1,141 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +// CraftBukkit end + +public class ContainerFurnace extends Container { + + private final IInventory furnace; + private int f; + private int g; + private int h; + private int i; + + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryFurnace inventory = new CraftInventoryFurnace((TileEntityFurnace) this.furnace); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end + + public ContainerFurnace(PlayerInventory playerinventory, IInventory iinventory) { + this.furnace = iinventory; + this.a(new Slot(iinventory, 0, 56, 17)); + this.a((Slot) (new SlotFurnaceFuel(iinventory, 1, 56, 53))); + this.a((Slot) (new SlotFurnaceResult(playerinventory.player, iinventory, 2, 116, 35))); + this.player = playerinventory; // CraftBukkit - save player + + int i; + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + + } + + public void addSlotListener(ICrafting icrafting) { + super.addSlotListener(icrafting); + icrafting.setContainerData(this, this.furnace); + } + + public void b() { + super.b(); + + for (int i = 0; i < this.listeners.size(); ++i) { + ICrafting icrafting = (ICrafting) this.listeners.get(i); + + if (this.f != this.furnace.getProperty(2)) { + icrafting.setContainerData(this, 2, this.furnace.getProperty(2)); + } + + if (this.h != this.furnace.getProperty(0)) { + icrafting.setContainerData(this, 0, this.furnace.getProperty(0)); + } + + if (this.i != this.furnace.getProperty(1)) { + icrafting.setContainerData(this, 1, this.furnace.getProperty(1)); + } + + if (this.g != this.furnace.getProperty(3)) { + icrafting.setContainerData(this, 3, this.furnace.getProperty(3)); + } + } + + this.f = this.furnace.getProperty(2); + this.h = this.furnace.getProperty(0); + this.i = this.furnace.getProperty(1); + this.g = this.furnace.getProperty(3); + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.furnace.a(entityhuman); + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 2) { + if (!this.a(itemstack1, 3, 39, true)) { + return null; + } + + slot.a(itemstack1, itemstack); + } else if (i != 1 && i != 0) { + if (RecipesFurnace.getInstance().getResult(itemstack1) != null) { + if (!this.a(itemstack1, 0, 1, false)) { + return null; + } + } else if (TileEntityFurnace.isFuel(itemstack1)) { + if (!this.a(itemstack1, 1, 2, false)) { + return null; + } + } else if (i >= 3 && i < 30) { + if (!this.a(itemstack1, 30, 39, false)) { + return null; + } + } else if (i >= 30 && i < 39 && !this.a(itemstack1, 3, 30, false)) { + return null; + } + } else if (!this.a(itemstack1, 3, 39, false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerHopper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerHopper.java new file mode 100644 index 0000000..6fc7187 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerHopper.java @@ -0,0 +1,87 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +// CraftBukkit end + +public class ContainerHopper extends Container { + + private final IInventory hopper; + + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventory inventory = new CraftInventory(this.hopper); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end + + public ContainerHopper(PlayerInventory playerinventory, IInventory iinventory, EntityHuman entityhuman) { + this.hopper = iinventory; + this.player = playerinventory; // CraftBukkit - save player + iinventory.startOpen(entityhuman); + byte b0 = 51; + + int i; + + for (i = 0; i < iinventory.getSize(); ++i) { + this.a(new Slot(iinventory, i, 44 + i * 18, 20)); + } + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, i * 18 + b0)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 58 + b0)); + } + + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.hopper.a(entityhuman); + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i < this.hopper.getSize()) { + if (!this.a(itemstack1, this.hopper.getSize(), this.c.size(), true)) { + return null; + } + } else if (!this.a(itemstack1, 0, this.hopper.getSize(), false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + } + + return itemstack; + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.hopper.closeContainer(entityhuman); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerHorse.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerHorse.java new file mode 100644 index 0000000..155591a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerHorse.java @@ -0,0 +1,113 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.inventory.InventoryView; +// CraftBukkit end + +public class ContainerHorse extends Container { + + private IInventory a; + private EntityHorse f; + + // CraftBukkit start + org.bukkit.craftbukkit.inventory.CraftInventoryView bukkitEntity; + PlayerInventory player; + + @Override + public InventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryHorse(this.a); + return bukkitEntity = new CraftInventoryView(player.player.getBukkitEntity(), inventory, this); + } + + public ContainerHorse(IInventory iinventory, final IInventory iinventory1, final EntityHorse entityhorse, EntityHuman entityhuman) { + player = (PlayerInventory) iinventory; + // CraftBukkit end + this.a = iinventory1; + this.f = entityhorse; + byte b0 = 3; + + iinventory1.startOpen(entityhuman); + int i = (b0 - 4) * 18; + + this.a(new Slot(iinventory1, 0, 8, 18) { + public boolean isAllowed(ItemStack itemstack) { + return super.isAllowed(itemstack) && itemstack.getItem() == Items.SADDLE && !this.hasItem(); + } + }); + this.a(new Slot(iinventory1, 1, 8, 36) { + public boolean isAllowed(ItemStack itemstack) { + return super.isAllowed(itemstack) && entityhorse.cO() && EntityHorse.a(itemstack.getItem()); + } + }); + int j; + int k; + + if (entityhorse.hasChest()) { + for (j = 0; j < b0; ++j) { + for (k = 0; k < 5; ++k) { + this.a(new Slot(iinventory1, 2 + k + j * 5, 80 + k * 18, 18 + j * 18)); + } + } + } + + for (j = 0; j < 3; ++j) { + for (k = 0; k < 9; ++k) { + this.a(new Slot(iinventory, k + j * 9 + 9, 8 + k * 18, 102 + j * 18 + i)); + } + } + + for (j = 0; j < 9; ++j) { + this.a(new Slot(iinventory, j, 8 + j * 18, 160 + i)); + } + + } + + public boolean a(EntityHuman entityhuman) { + return this.a.a(entityhuman) && this.f.isAlive() && this.f.g((Entity) entityhuman) < 8.0F; + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i < this.a.getSize()) { + if (!this.a(itemstack1, this.a.getSize(), this.c.size(), true)) { + return null; + } + } else if (this.getSlot(1).isAllowed(itemstack1) && !this.getSlot(1).hasItem()) { + if (!this.a(itemstack1, 1, 2, false)) { + return null; + } + } else if (this.getSlot(0).isAllowed(itemstack1)) { + if (!this.a(itemstack1, 0, 1, false)) { + return null; + } + } else if (this.a.getSize() <= 2 || !this.a(itemstack1, 2, this.a.getSize(), false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + } + + return itemstack; + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.a.closeContainer(entityhuman); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerMerchant.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerMerchant.java new file mode 100644 index 0000000..f8aa2ae --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerMerchant.java @@ -0,0 +1,132 @@ +package net.minecraft.server; + +import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit + +public class ContainerMerchant extends Container { + + private IMerchant merchant; + private InventoryMerchant f; + private final World g; + + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity == null) { + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), new org.bukkit.craftbukkit.inventory.CraftInventoryMerchant((InventoryMerchant) f), this); + } + return bukkitEntity; + } + // CraftBukkit end + + public ContainerMerchant(PlayerInventory playerinventory, IMerchant imerchant, World world) { + this.merchant = imerchant; + this.g = world; + this.f = new InventoryMerchant(playerinventory.player, imerchant); + this.a(new Slot(this.f, 0, 36, 53)); + this.a(new Slot(this.f, 1, 62, 53)); + this.a((Slot) (new SlotMerchantResult(playerinventory.player, imerchant, this.f, 2, 120, 53))); + this.player = playerinventory; // CraftBukkit - save player + + int i; + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + + } + + public InventoryMerchant e() { + return this.f; + } + + public void addSlotListener(ICrafting icrafting) { + super.addSlotListener(icrafting); + } + + public void b() { + super.b(); + } + + public void a(IInventory iinventory) { + this.f.h(); + super.a(iinventory); + } + + public void d(int i) { + this.f.d(i); + } + + public boolean a(EntityHuman entityhuman) { + return this.merchant.v_() == entityhuman; + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 2) { + if (!this.a(itemstack1, 3, 39, true)) { + return null; + } + + slot.a(itemstack1, itemstack); + } else if (i != 0 && i != 1) { + if (i >= 3 && i < 30) { + if (!this.a(itemstack1, 30, 39, false)) { + return null; + } + } else if (i >= 30 && i < 39 && !this.a(itemstack1, 3, 30, false)) { + return null; + } + } else if (!this.a(itemstack1, 3, 39, false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + this.merchant.a_((EntityHuman) null); + super.b(entityhuman); + if (!this.g.isClientSide) { + ItemStack itemstack = this.f.splitWithoutUpdate(0); + + if (itemstack != null) { + entityhuman.drop(itemstack, false); + } + + itemstack = this.f.splitWithoutUpdate(1); + if (itemstack != null) { + entityhuman.drop(itemstack, false); + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerPlayer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerPlayer.java new file mode 100644 index 0000000..a86f896 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerPlayer.java @@ -0,0 +1,168 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +// CraftBukkit end + +public class ContainerPlayer extends Container { + + public InventoryCrafting craftInventory = new InventoryCrafting(this, 2, 2); + public IInventory resultInventory = new InventoryCraftResult(); + public boolean g; + private final EntityHuman h; + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + // CraftBukkit end + + public ContainerPlayer(final PlayerInventory playerinventory, boolean flag, EntityHuman entityhuman) { + this.g = flag; + this.h = entityhuman; + this.resultInventory = new InventoryCraftResult(); // CraftBukkit - moved to before InventoryCrafting construction + this.craftInventory = new InventoryCrafting(this, 2, 2, playerinventory.player); // CraftBukkit - pass player + this.craftInventory.resultInventory = this.resultInventory; // CraftBukkit - let InventoryCrafting know about its result slot + this.player = playerinventory; // CraftBukkit - save player + this.a((Slot) (new SlotResult(playerinventory.player, this.craftInventory, this.resultInventory, 0, 144, 36))); + + // CraftBukkit - fixed multiple decompiler errors below, good luck + int j; + + for (int i = 0; i < 2; ++i) { + for (j = 0; j < 2; ++j) { + this.a(new Slot(this.craftInventory, j + i * 2, 88 + j * 18, 26 + i * 18)); + } + } + + for (int ii = 0; ii < 4; ++ii) { + final int i = ii; + this.a(new Slot(playerinventory, playerinventory.getSize() - 1 - ii, 8, 8 + ii * 18) { + public int getMaxStackSize() { + return 1; + } + + public boolean isAllowed(ItemStack itemstack) { + return itemstack == null ? false : (itemstack.getItem() instanceof ItemArmor ? ((ItemArmor) itemstack.getItem()).b == i : (itemstack.getItem() != Item.getItemOf(Blocks.PUMPKIN) && itemstack.getItem() != Items.SKULL ? false : i == 0)); + } + }); + } + + for (int i = 0; i < 3; ++i) { + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + (i + 1) * 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (int i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + + // this.a((IInventory) this.craftInventory); // CraftBukkit - unneeded since it just sets result slot to empty + } + + public void a(IInventory iinventory) { + // this.resultInventory.setItem(0, CraftingManager.getInstance().craft(this.craftInventory, this.h.world)); + // CraftBukkit start (Note: the following line would cause an error if called during construction) + CraftingManager.getInstance().lastCraftView = getBukkitView(); + ItemStack craftResult = CraftingManager.getInstance().craft(this.craftInventory, this.h.world); + this.resultInventory.setItem(0, craftResult); + if (super.listeners.size() < 1) { + return; + } + + EntityPlayer player = (EntityPlayer) super.listeners.get(0); // TODO: Is this _always_ correct? Seems like it. + player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.activeContainer.windowId, 0, craftResult)); + // CraftBukkit end + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + + for (int i = 0; i < 4; ++i) { + ItemStack itemstack = this.craftInventory.splitWithoutUpdate(i); + + if (itemstack != null) { + entityhuman.drop(itemstack, false); + } + } + + this.resultInventory.setItem(0, (ItemStack) null); + } + + public boolean a(EntityHuman entityhuman) { + return true; + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 0) { + if (!this.a(itemstack1, 9, 45, true)) { + return null; + } + + slot.a(itemstack1, itemstack); + } else if (i >= 1 && i < 5) { + if (!this.a(itemstack1, 9, 45, false)) { + return null; + } + } else if (i >= 5 && i < 9) { + if (!this.a(itemstack1, 9, 45, false)) { + return null; + } + } else if (itemstack.getItem() instanceof ItemArmor && !((Slot) this.c.get(5 + ((ItemArmor) itemstack.getItem()).b)).hasItem()) { + int j = 5 + ((ItemArmor) itemstack.getItem()).b; + + if (!this.a(itemstack1, j, j + 1, false)) { + return null; + } + } else if (i >= 9 && i < 36) { + if (!this.a(itemstack1, 36, 45, false)) { + return null; + } + } else if (i >= 36 && i < 45) { + if (!this.a(itemstack1, 9, 36, false)) { + return null; + } + } else if (!this.a(itemstack1, 9, 45, false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + public boolean a(ItemStack itemstack, Slot slot) { + return slot.inventory != this.resultInventory && super.a(itemstack, slot); + } + + // CraftBukkit start + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftInventory, this.resultInventory); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerWorkbench.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerWorkbench.java new file mode 100644 index 0000000..48d524e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ContainerWorkbench.java @@ -0,0 +1,147 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +// CraftBukkit end + +public class ContainerWorkbench extends Container { + + public InventoryCrafting craftInventory; // CraftBukkit - move initialization into constructor + public IInventory resultInventory; // CraftBukkit - move initialization into constructor + private World g; + private BlockPosition h; + // CraftBukkit start + private CraftInventoryView bukkitEntity = null; + private PlayerInventory player; + // CraftBukkit end + + public ContainerWorkbench(PlayerInventory playerinventory, World world, BlockPosition blockposition) { + // CraftBukkit start - Switched order of IInventory construction and stored player + this.resultInventory = new InventoryCraftResult(); + this.craftInventory = new InventoryCrafting(this, 3, 3, playerinventory.player); // CraftBukkit - pass player + this.craftInventory.resultInventory = this.resultInventory; + this.player = playerinventory; + // CraftBukkit end + this.g = world; + this.h = blockposition; + this.a((Slot) (new SlotResult(playerinventory.player, this.craftInventory, this.resultInventory, 0, 124, 35))); + + int i; + int j; + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 3; ++j) { + this.a(new Slot(this.craftInventory, j + i * 3, 30 + j * 18, 17 + i * 18)); + } + } + + for (i = 0; i < 3; ++i) { + for (j = 0; j < 9; ++j) { + this.a(new Slot(playerinventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(playerinventory, i, 8 + i * 18, 142)); + } + + this.a((IInventory) this.craftInventory); + } + + public void a(IInventory iinventory) { + // this.resultInventory.setItem(0, CraftingManager.getInstance().craft(this.craftInventory, this.g)); + // CraftBukkit start + CraftingManager.getInstance().lastCraftView = getBukkitView(); + ItemStack craftResult = CraftingManager.getInstance().craft(this.craftInventory, this.g); + this.resultInventory.setItem(0, craftResult); + if (super.listeners.size() < 1) { + return; + } + // See CraftBukkit PR #39 + if (craftResult != null && craftResult.getItem() == Items.FILLED_MAP) { + return; + } + EntityPlayer player = (EntityPlayer) super.listeners.get(0); // TODO: Is this _always_ correct? Seems like it. + player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.activeContainer.windowId, 0, craftResult)); + // CraftBukkit end + } + + public void b(EntityHuman entityhuman) { + super.b(entityhuman); + if (!this.g.isClientSide) { + for (int i = 0; i < 9; ++i) { + ItemStack itemstack = this.craftInventory.splitWithoutUpdate(i); + + if (itemstack != null) { + entityhuman.drop(itemstack, false); + } + } + + } + } + + public boolean a(EntityHuman entityhuman) { + if (!this.checkReachable) return true; // CraftBukkit + return this.g.getType(this.h).getBlock() != Blocks.CRAFTING_TABLE ? false : entityhuman.e((double) this.h.getX() + 0.5D, (double) this.h.getY() + 0.5D, (double) this.h.getZ() + 0.5D) <= 64.0D; + } + + public ItemStack b(EntityHuman entityhuman, int i) { + ItemStack itemstack = null; + Slot slot = (Slot) this.c.get(i); + + if (slot != null && slot.hasItem()) { + ItemStack itemstack1 = slot.getItem(); + + itemstack = itemstack1.cloneItemStack(); + if (i == 0) { + if (!this.a(itemstack1, 10, 46, true)) { + return null; + } + + slot.a(itemstack1, itemstack); + } else if (i >= 10 && i < 37) { + if (!this.a(itemstack1, 37, 46, false)) { + return null; + } + } else if (i >= 37 && i < 46) { + if (!this.a(itemstack1, 10, 37, false)) { + return null; + } + } else if (!this.a(itemstack1, 10, 46, false)) { + return null; + } + + if (itemstack1.count == 0) { + slot.set((ItemStack) null); + } else { + slot.f(); + } + + if (itemstack1.count == itemstack.count) { + return null; + } + + slot.a(entityhuman, itemstack1); + } + + return itemstack; + } + + public boolean a(ItemStack itemstack, Slot slot) { + return slot.inventory != this.resultInventory && super.a(itemstack, slot); + } + + // CraftBukkit start + @Override + public CraftInventoryView getBukkitView() { + if (bukkitEntity != null) { + return bukkitEntity; + } + + CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftInventory, this.resultInventory); + bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); + return bukkitEntity; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CraftingManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CraftingManager.java new file mode 100644 index 0000000..544ff0a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CraftingManager.java @@ -0,0 +1,325 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class CraftingManager { + + private static final CraftingManager a = new CraftingManager(); + public List recipes = Lists.newArrayList(); + // CraftBukkit start + public IRecipe lastRecipe; + public org.bukkit.inventory.InventoryView lastCraftView; + // CraftBukkit end + + public static CraftingManager getInstance() { + return CraftingManager.a; + } + + public CraftingManager() { + (new RecipesTools()).a(this); + (new RecipesWeapons()).a(this); + (new RecipeIngots()).a(this); + (new RecipesFood()).a(this); + (new RecipesCrafting()).a(this); + (new RecipesArmor()).a(this); + (new RecipesDyes()).a(this); + this.recipes.add(new RecipeArmorDye()); + this.recipes.add(new RecipeBookClone()); + this.recipes.add(new RecipeMapClone()); + this.recipes.add(new RecipeMapExtend()); + this.recipes.add(new RecipeFireworks()); + this.recipes.add(new RecipeRepair()); + (new RecipesBanner()).a(this); + this.registerShapedRecipe(new ItemStack(Items.PAPER, 3), new Object[] { "###", Character.valueOf('#'), Items.REEDS}); + this.registerShapelessRecipe(new ItemStack(Items.BOOK, 1), new Object[] { Items.PAPER, Items.PAPER, Items.PAPER, Items.LEATHER}); + this.registerShapelessRecipe(new ItemStack(Items.WRITABLE_BOOK, 1), new Object[] { Items.BOOK, new ItemStack(Items.DYE, 1, EnumColor.BLACK.getInvColorIndex()), Items.FEATHER}); + this.registerShapedRecipe(new ItemStack(Blocks.FENCE, 3), new Object[] { "W#W", "W#W", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.OAK.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.BIRCH_FENCE, 3), new Object[] { "W#W", "W#W", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.BIRCH.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.SPRUCE_FENCE, 3), new Object[] { "W#W", "W#W", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.SPRUCE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.JUNGLE_FENCE, 3), new Object[] { "W#W", "W#W", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.JUNGLE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.ACACIA_FENCE, 3), new Object[] { "W#W", "W#W", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, 4 + BlockWood.EnumLogVariant.ACACIA.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Blocks.DARK_OAK_FENCE, 3), new Object[] { "W#W", "W#W", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, 4 + BlockWood.EnumLogVariant.DARK_OAK.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Blocks.COBBLESTONE_WALL, 6, BlockCobbleWall.EnumCobbleVariant.NORMAL.a()), new Object[] { "###", "###", Character.valueOf('#'), Blocks.COBBLESTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.COBBLESTONE_WALL, 6, BlockCobbleWall.EnumCobbleVariant.MOSSY.a()), new Object[] { "###", "###", Character.valueOf('#'), Blocks.MOSSY_COBBLESTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.NETHER_BRICK_FENCE, 6), new Object[] { "###", "###", Character.valueOf('#'), Blocks.NETHER_BRICK}); + this.registerShapedRecipe(new ItemStack(Blocks.FENCE_GATE, 1), new Object[] { "#W#", "#W#", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.OAK.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.BIRCH_FENCE_GATE, 1), new Object[] { "#W#", "#W#", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.BIRCH.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.SPRUCE_FENCE_GATE, 1), new Object[] { "#W#", "#W#", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.SPRUCE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.JUNGLE_FENCE_GATE, 1), new Object[] { "#W#", "#W#", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.JUNGLE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.ACACIA_FENCE_GATE, 1), new Object[] { "#W#", "#W#", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, 4 + BlockWood.EnumLogVariant.ACACIA.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Blocks.DARK_OAK_FENCE_GATE, 1), new Object[] { "#W#", "#W#", Character.valueOf('#'), Items.STICK, Character.valueOf('W'), new ItemStack(Blocks.PLANKS, 1, 4 + BlockWood.EnumLogVariant.DARK_OAK.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Blocks.JUKEBOX, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Blocks.PLANKS, Character.valueOf('X'), Items.DIAMOND}); + this.registerShapedRecipe(new ItemStack(Items.LEAD, 2), new Object[] { "~~ ", "~O ", " ~", Character.valueOf('~'), Items.STRING, Character.valueOf('O'), Items.SLIME}); + this.registerShapedRecipe(new ItemStack(Blocks.NOTEBLOCK, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Blocks.PLANKS, Character.valueOf('X'), Items.REDSTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.BOOKSHELF, 1), new Object[] { "###", "XXX", "###", Character.valueOf('#'), Blocks.PLANKS, Character.valueOf('X'), Items.BOOK}); + this.registerShapedRecipe(new ItemStack(Blocks.SNOW, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.SNOWBALL}); + this.registerShapedRecipe(new ItemStack(Blocks.SNOW_LAYER, 6), new Object[] { "###", Character.valueOf('#'), Blocks.SNOW}); + this.registerShapedRecipe(new ItemStack(Blocks.CLAY, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.CLAY_BALL}); + this.registerShapedRecipe(new ItemStack(Blocks.BRICK_BLOCK, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.BRICK}); + this.registerShapedRecipe(new ItemStack(Blocks.GLOWSTONE, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.GLOWSTONE_DUST}); + this.registerShapedRecipe(new ItemStack(Blocks.QUARTZ_BLOCK, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.QUARTZ}); + this.registerShapedRecipe(new ItemStack(Blocks.WOOL, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.STRING}); + this.registerShapedRecipe(new ItemStack(Blocks.TNT, 1), new Object[] { "X#X", "#X#", "X#X", Character.valueOf('X'), Items.GUNPOWDER, Character.valueOf('#'), Blocks.SAND}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_SLAB, 6, BlockDoubleStepAbstract.EnumStoneSlabVariant.COBBLESTONE.a()), new Object[] { "###", Character.valueOf('#'), Blocks.COBBLESTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_SLAB, 6, BlockDoubleStepAbstract.EnumStoneSlabVariant.STONE.a()), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.STONE, BlockStone.EnumStoneVariant.STONE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_SLAB, 6, BlockDoubleStepAbstract.EnumStoneSlabVariant.SAND.a()), new Object[] { "###", Character.valueOf('#'), Blocks.SANDSTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_SLAB, 6, BlockDoubleStepAbstract.EnumStoneSlabVariant.BRICK.a()), new Object[] { "###", Character.valueOf('#'), Blocks.BRICK_BLOCK}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_SLAB, 6, BlockDoubleStepAbstract.EnumStoneSlabVariant.SMOOTHBRICK.a()), new Object[] { "###", Character.valueOf('#'), Blocks.STONEBRICK}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_SLAB, 6, BlockDoubleStepAbstract.EnumStoneSlabVariant.NETHERBRICK.a()), new Object[] { "###", Character.valueOf('#'), Blocks.NETHER_BRICK}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_SLAB, 6, BlockDoubleStepAbstract.EnumStoneSlabVariant.QUARTZ.a()), new Object[] { "###", Character.valueOf('#'), Blocks.QUARTZ_BLOCK}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_SLAB2, 6, BlockDoubleStoneStepAbstract.EnumStoneSlab2Variant.RED_SANDSTONE.a()), new Object[] { "###", Character.valueOf('#'), Blocks.RED_SANDSTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.WOODEN_SLAB, 6, 0), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.OAK.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.WOODEN_SLAB, 6, BlockWood.EnumLogVariant.BIRCH.a()), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.BIRCH.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.WOODEN_SLAB, 6, BlockWood.EnumLogVariant.SPRUCE.a()), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.SPRUCE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.WOODEN_SLAB, 6, BlockWood.EnumLogVariant.JUNGLE.a()), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.JUNGLE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.WOODEN_SLAB, 6, 4 + BlockWood.EnumLogVariant.ACACIA.a() - 4), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, 4 + BlockWood.EnumLogVariant.ACACIA.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Blocks.WOODEN_SLAB, 6, 4 + BlockWood.EnumLogVariant.DARK_OAK.a() - 4), new Object[] { "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, 4 + BlockWood.EnumLogVariant.DARK_OAK.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Blocks.LADDER, 3), new Object[] { "# #", "###", "# #", Character.valueOf('#'), Items.STICK}); + this.registerShapedRecipe(new ItemStack(Items.WOODEN_DOOR, 3), new Object[] { "##", "##", "##", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.OAK.a())}); + this.registerShapedRecipe(new ItemStack(Items.SPRUCE_DOOR, 3), new Object[] { "##", "##", "##", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.SPRUCE.a())}); + this.registerShapedRecipe(new ItemStack(Items.BIRCH_DOOR, 3), new Object[] { "##", "##", "##", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.BIRCH.a())}); + this.registerShapedRecipe(new ItemStack(Items.JUNGLE_DOOR, 3), new Object[] { "##", "##", "##", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.JUNGLE.a())}); + this.registerShapedRecipe(new ItemStack(Items.ACACIA_DOOR, 3), new Object[] { "##", "##", "##", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.ACACIA.a())}); + this.registerShapedRecipe(new ItemStack(Items.DARK_OAK_DOOR, 3), new Object[] { "##", "##", "##", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.DARK_OAK.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.TRAPDOOR, 2), new Object[] { "###", "###", Character.valueOf('#'), Blocks.PLANKS}); + this.registerShapedRecipe(new ItemStack(Items.IRON_DOOR, 3), new Object[] { "##", "##", "##", Character.valueOf('#'), Items.IRON_INGOT}); + this.registerShapedRecipe(new ItemStack(Blocks.IRON_TRAPDOOR, 1), new Object[] { "##", "##", Character.valueOf('#'), Items.IRON_INGOT}); + this.registerShapedRecipe(new ItemStack(Items.SIGN, 3), new Object[] { "###", "###", " X ", Character.valueOf('#'), Blocks.PLANKS, Character.valueOf('X'), Items.STICK}); + this.registerShapedRecipe(new ItemStack(Items.CAKE, 1), new Object[] { "AAA", "BEB", "CCC", Character.valueOf('A'), Items.MILK_BUCKET, Character.valueOf('B'), Items.SUGAR, Character.valueOf('C'), Items.WHEAT, Character.valueOf('E'), Items.EGG}); + this.registerShapedRecipe(new ItemStack(Items.SUGAR, 1), new Object[] { "#", Character.valueOf('#'), Items.REEDS}); + this.registerShapedRecipe(new ItemStack(Blocks.PLANKS, 4, BlockWood.EnumLogVariant.OAK.a()), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG, 1, BlockWood.EnumLogVariant.OAK.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.PLANKS, 4, BlockWood.EnumLogVariant.SPRUCE.a()), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG, 1, BlockWood.EnumLogVariant.SPRUCE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.PLANKS, 4, BlockWood.EnumLogVariant.BIRCH.a()), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG, 1, BlockWood.EnumLogVariant.BIRCH.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.PLANKS, 4, BlockWood.EnumLogVariant.JUNGLE.a()), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG, 1, BlockWood.EnumLogVariant.JUNGLE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.PLANKS, 4, 4 + BlockWood.EnumLogVariant.ACACIA.a() - 4), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG2, 1, BlockWood.EnumLogVariant.ACACIA.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Blocks.PLANKS, 4, 4 + BlockWood.EnumLogVariant.DARK_OAK.a() - 4), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.LOG2, 1, BlockWood.EnumLogVariant.DARK_OAK.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Items.STICK, 4), new Object[] { "#", "#", Character.valueOf('#'), Blocks.PLANKS}); + this.registerShapedRecipe(new ItemStack(Blocks.TORCH, 4), new Object[] { "X", "#", Character.valueOf('X'), Items.COAL, Character.valueOf('#'), Items.STICK}); + this.registerShapedRecipe(new ItemStack(Blocks.TORCH, 4), new Object[] { "X", "#", Character.valueOf('X'), new ItemStack(Items.COAL, 1, 1), Character.valueOf('#'), Items.STICK}); + this.registerShapedRecipe(new ItemStack(Items.BOWL, 4), new Object[] { "# #", " # ", Character.valueOf('#'), Blocks.PLANKS}); + this.registerShapedRecipe(new ItemStack(Items.GLASS_BOTTLE, 3), new Object[] { "# #", " # ", Character.valueOf('#'), Blocks.GLASS}); + this.registerShapedRecipe(new ItemStack(Blocks.RAIL, 16), new Object[] { "X X", "X#X", "X X", Character.valueOf('X'), Items.IRON_INGOT, Character.valueOf('#'), Items.STICK}); + this.registerShapedRecipe(new ItemStack(Blocks.GOLDEN_RAIL, 6), new Object[] { "X X", "X#X", "XRX", Character.valueOf('X'), Items.GOLD_INGOT, Character.valueOf('R'), Items.REDSTONE, Character.valueOf('#'), Items.STICK}); + this.registerShapedRecipe(new ItemStack(Blocks.ACTIVATOR_RAIL, 6), new Object[] { "XSX", "X#X", "XSX", Character.valueOf('X'), Items.IRON_INGOT, Character.valueOf('#'), Blocks.REDSTONE_TORCH, Character.valueOf('S'), Items.STICK}); + this.registerShapedRecipe(new ItemStack(Blocks.DETECTOR_RAIL, 6), new Object[] { "X X", "X#X", "XRX", Character.valueOf('X'), Items.IRON_INGOT, Character.valueOf('R'), Items.REDSTONE, Character.valueOf('#'), Blocks.STONE_PRESSURE_PLATE}); + this.registerShapedRecipe(new ItemStack(Items.MINECART, 1), new Object[] { "# #", "###", Character.valueOf('#'), Items.IRON_INGOT}); + this.registerShapedRecipe(new ItemStack(Items.CAULDRON, 1), new Object[] { "# #", "# #", "###", Character.valueOf('#'), Items.IRON_INGOT}); + this.registerShapedRecipe(new ItemStack(Items.BREWING_STAND, 1), new Object[] { " B ", "###", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('B'), Items.BLAZE_ROD}); + this.registerShapedRecipe(new ItemStack(Blocks.LIT_PUMPKIN, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.PUMPKIN, Character.valueOf('B'), Blocks.TORCH}); + this.registerShapedRecipe(new ItemStack(Items.CHEST_MINECART, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.CHEST, Character.valueOf('B'), Items.MINECART}); + this.registerShapedRecipe(new ItemStack(Items.FURNACE_MINECART, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.FURNACE, Character.valueOf('B'), Items.MINECART}); + this.registerShapedRecipe(new ItemStack(Items.TNT_MINECART, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.TNT, Character.valueOf('B'), Items.MINECART}); + this.registerShapedRecipe(new ItemStack(Items.HOPPER_MINECART, 1), new Object[] { "A", "B", Character.valueOf('A'), Blocks.HOPPER, Character.valueOf('B'), Items.MINECART}); + this.registerShapedRecipe(new ItemStack(Items.BOAT, 1), new Object[] { "# #", "###", Character.valueOf('#'), Blocks.PLANKS}); + this.registerShapedRecipe(new ItemStack(Items.BUCKET, 1), new Object[] { "# #", " # ", Character.valueOf('#'), Items.IRON_INGOT}); + this.registerShapedRecipe(new ItemStack(Items.FLOWER_POT, 1), new Object[] { "# #", " # ", Character.valueOf('#'), Items.BRICK}); + this.registerShapelessRecipe(new ItemStack(Items.FLINT_AND_STEEL, 1), new Object[] { new ItemStack(Items.IRON_INGOT, 1), new ItemStack(Items.FLINT, 1)}); + this.registerShapedRecipe(new ItemStack(Items.BREAD, 1), new Object[] { "###", Character.valueOf('#'), Items.WHEAT}); + this.registerShapedRecipe(new ItemStack(Blocks.OAK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.OAK.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.BIRCH_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.BIRCH.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.SPRUCE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.SPRUCE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.JUNGLE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, BlockWood.EnumLogVariant.JUNGLE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.ACACIA_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, 4 + BlockWood.EnumLogVariant.ACACIA.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Blocks.DARK_OAK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), new ItemStack(Blocks.PLANKS, 1, 4 + BlockWood.EnumLogVariant.DARK_OAK.a() - 4)}); + this.registerShapedRecipe(new ItemStack(Items.FISHING_ROD, 1), new Object[] { " #", " #X", "# X", Character.valueOf('#'), Items.STICK, Character.valueOf('X'), Items.STRING}); + this.registerShapedRecipe(new ItemStack(Items.CARROT_ON_A_STICK, 1), new Object[] { "# ", " X", Character.valueOf('#'), Items.FISHING_ROD, Character.valueOf('X'), Items.CARROT}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.COBBLESTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.BRICK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.BRICK_BLOCK}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_BRICK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.STONEBRICK}); + this.registerShapedRecipe(new ItemStack(Blocks.NETHER_BRICK_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.NETHER_BRICK}); + this.registerShapedRecipe(new ItemStack(Blocks.SANDSTONE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.SANDSTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.RED_SANDSTONE_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.RED_SANDSTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.QUARTZ_STAIRS, 4), new Object[] { "# ", "## ", "###", Character.valueOf('#'), Blocks.QUARTZ_BLOCK}); + this.registerShapedRecipe(new ItemStack(Items.PAINTING, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.STICK, Character.valueOf('X'), Blocks.WOOL}); + this.registerShapedRecipe(new ItemStack(Items.ITEM_FRAME, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.STICK, Character.valueOf('X'), Items.LEATHER}); + this.registerShapedRecipe(new ItemStack(Items.GOLDEN_APPLE, 1, 0), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.GOLD_INGOT, Character.valueOf('X'), Items.APPLE}); + this.registerShapedRecipe(new ItemStack(Items.GOLDEN_APPLE, 1, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Blocks.GOLD_BLOCK, Character.valueOf('X'), Items.APPLE}); + this.registerShapedRecipe(new ItemStack(Items.GOLDEN_CARROT, 1, 0), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.GOLD_NUGGET, Character.valueOf('X'), Items.CARROT}); + this.registerShapedRecipe(new ItemStack(Items.SPECKLED_MELON, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.GOLD_NUGGET, Character.valueOf('X'), Items.MELON}); + this.registerShapedRecipe(new ItemStack(Blocks.LEVER, 1), new Object[] { "X", "#", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('X'), Items.STICK}); + this.registerShapedRecipe(new ItemStack(Blocks.TRIPWIRE_HOOK, 2), new Object[] { "I", "S", "#", Character.valueOf('#'), Blocks.PLANKS, Character.valueOf('S'), Items.STICK, Character.valueOf('I'), Items.IRON_INGOT}); + this.registerShapedRecipe(new ItemStack(Blocks.REDSTONE_TORCH, 1), new Object[] { "X", "#", Character.valueOf('#'), Items.STICK, Character.valueOf('X'), Items.REDSTONE}); + this.registerShapedRecipe(new ItemStack(Items.REPEATER, 1), new Object[] { "#X#", "III", Character.valueOf('#'), Blocks.REDSTONE_TORCH, Character.valueOf('X'), Items.REDSTONE, Character.valueOf('I'), new ItemStack(Blocks.STONE, 1, BlockStone.EnumStoneVariant.STONE.a())}); + this.registerShapedRecipe(new ItemStack(Items.COMPARATOR, 1), new Object[] { " # ", "#X#", "III", Character.valueOf('#'), Blocks.REDSTONE_TORCH, Character.valueOf('X'), Items.QUARTZ, Character.valueOf('I'), new ItemStack(Blocks.STONE, 1, BlockStone.EnumStoneVariant.STONE.a())}); + this.registerShapedRecipe(new ItemStack(Items.CLOCK, 1), new Object[] { " # ", "#X#", " # ", Character.valueOf('#'), Items.GOLD_INGOT, Character.valueOf('X'), Items.REDSTONE}); + this.registerShapedRecipe(new ItemStack(Items.COMPASS, 1), new Object[] { " # ", "#X#", " # ", Character.valueOf('#'), Items.IRON_INGOT, Character.valueOf('X'), Items.REDSTONE}); + this.registerShapedRecipe(new ItemStack(Items.MAP, 1), new Object[] { "###", "#X#", "###", Character.valueOf('#'), Items.PAPER, Character.valueOf('X'), Items.COMPASS}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_BUTTON, 1), new Object[] { "#", Character.valueOf('#'), new ItemStack(Blocks.STONE, 1, BlockStone.EnumStoneVariant.STONE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.WOODEN_BUTTON, 1), new Object[] { "#", Character.valueOf('#'), Blocks.PLANKS}); + this.registerShapedRecipe(new ItemStack(Blocks.STONE_PRESSURE_PLATE, 1), new Object[] { "##", Character.valueOf('#'), new ItemStack(Blocks.STONE, 1, BlockStone.EnumStoneVariant.STONE.a())}); + this.registerShapedRecipe(new ItemStack(Blocks.WOODEN_PRESSURE_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Blocks.PLANKS}); + this.registerShapedRecipe(new ItemStack(Blocks.HEAVY_WEIGHTED_PRESSURE_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Items.IRON_INGOT}); + this.registerShapedRecipe(new ItemStack(Blocks.LIGHT_WEIGHTED_PRESSURE_PLATE, 1), new Object[] { "##", Character.valueOf('#'), Items.GOLD_INGOT}); + this.registerShapedRecipe(new ItemStack(Blocks.DISPENSER, 1), new Object[] { "###", "#X#", "#R#", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('X'), Items.BOW, Character.valueOf('R'), Items.REDSTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.DROPPER, 1), new Object[] { "###", "# #", "#R#", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('R'), Items.REDSTONE}); + this.registerShapedRecipe(new ItemStack(Blocks.PISTON, 1), new Object[] { "TTT", "#X#", "#R#", Character.valueOf('#'), Blocks.COBBLESTONE, Character.valueOf('X'), Items.IRON_INGOT, Character.valueOf('R'), Items.REDSTONE, Character.valueOf('T'), Blocks.PLANKS}); + this.registerShapedRecipe(new ItemStack(Blocks.STICKY_PISTON, 1), new Object[] { "S", "P", Character.valueOf('S'), Items.SLIME, Character.valueOf('P'), Blocks.PISTON}); + this.registerShapedRecipe(new ItemStack(Items.BED, 1), new Object[] { "###", "XXX", Character.valueOf('#'), Blocks.WOOL, Character.valueOf('X'), Blocks.PLANKS}); + this.registerShapedRecipe(new ItemStack(Blocks.ENCHANTING_TABLE, 1), new Object[] { " B ", "D#D", "###", Character.valueOf('#'), Blocks.OBSIDIAN, Character.valueOf('B'), Items.BOOK, Character.valueOf('D'), Items.DIAMOND}); + this.registerShapedRecipe(new ItemStack(Blocks.ANVIL, 1), new Object[] { "III", " i ", "iii", Character.valueOf('I'), Blocks.IRON_BLOCK, Character.valueOf('i'), Items.IRON_INGOT}); + this.registerShapedRecipe(new ItemStack(Items.LEATHER), new Object[] { "##", "##", Character.valueOf('#'), Items.RABBIT_HIDE}); + this.registerShapelessRecipe(new ItemStack(Items.ENDER_EYE, 1), new Object[] { Items.ENDER_PEARL, Items.BLAZE_POWDER}); + this.registerShapelessRecipe(new ItemStack(Items.FIRE_CHARGE, 3), new Object[] { Items.GUNPOWDER, Items.BLAZE_POWDER, Items.COAL}); + this.registerShapelessRecipe(new ItemStack(Items.FIRE_CHARGE, 3), new Object[] { Items.GUNPOWDER, Items.BLAZE_POWDER, new ItemStack(Items.COAL, 1, 1)}); + this.registerShapedRecipe(new ItemStack(Blocks.DAYLIGHT_DETECTOR), new Object[] { "GGG", "QQQ", "WWW", Character.valueOf('G'), Blocks.GLASS, Character.valueOf('Q'), Items.QUARTZ, Character.valueOf('W'), Blocks.WOODEN_SLAB}); + this.registerShapedRecipe(new ItemStack(Blocks.HOPPER), new Object[] { "I I", "ICI", " I ", Character.valueOf('I'), Items.IRON_INGOT, Character.valueOf('C'), Blocks.CHEST}); + this.registerShapedRecipe(new ItemStack(Items.ARMOR_STAND, 1), new Object[] { "///", " / ", "/_/", Character.valueOf('/'), Items.STICK, Character.valueOf('_'), new ItemStack(Blocks.STONE_SLAB, 1, BlockDoubleStepAbstract.EnumStoneSlabVariant.STONE.a())}); + sort(); + } + + // CraftBukkit start + public void sort() { + Collections.sort(this.recipes, new Comparator() { + public int a(IRecipe irecipe, IRecipe irecipe1) { + return irecipe instanceof ShapelessRecipes && irecipe1 instanceof ShapedRecipes ? 1 : (irecipe1 instanceof ShapelessRecipes && irecipe instanceof ShapedRecipes ? -1 : (irecipe1.a() < irecipe.a() ? -1 : (irecipe1.a() > irecipe.a() ? 1 : 0))); + } + + public int compare(Object object, Object object1) { + return this.a((IRecipe) object, (IRecipe) object1); + } + }); + } + + public ShapedRecipes registerShapedRecipe(ItemStack itemstack, Object... aobject) { + String s = ""; + int i = 0; + int j = 0; + int k = 0; + + if (aobject[i] instanceof String[]) { + String[] astring = (String[]) ((String[]) aobject[i++]); + + for (int l = 0; l < astring.length; ++l) { + String s1 = astring[l]; + + ++k; + j = s1.length(); + s = s + s1; + } + } else { + while (aobject[i] instanceof String) { + String s2 = (String) aobject[i++]; + + ++k; + j = s2.length(); + s = s + s2; + } + } + + HashMap hashmap; + + for (hashmap = Maps.newHashMap(); i < aobject.length; i += 2) { + Character character = (Character) aobject[i]; + ItemStack itemstack1 = null; + + if (aobject[i + 1] instanceof Item) { + itemstack1 = new ItemStack((Item) aobject[i + 1]); + } else if (aobject[i + 1] instanceof Block) { + itemstack1 = new ItemStack((Block) aobject[i + 1], 1, 32767); + } else if (aobject[i + 1] instanceof ItemStack) { + itemstack1 = (ItemStack) aobject[i + 1]; + } + + hashmap.put(character, itemstack1); + } + + ItemStack[] aitemstack = new ItemStack[j * k]; + + for (int i1 = 0; i1 < j * k; ++i1) { + char c0 = s.charAt(i1); + + if (hashmap.containsKey(Character.valueOf(c0))) { + aitemstack[i1] = ((ItemStack) hashmap.get(Character.valueOf(c0))).cloneItemStack(); + } else { + aitemstack[i1] = null; + } + } + + ShapedRecipes shapedrecipes = new ShapedRecipes(j, k, aitemstack, itemstack); + + this.recipes.add(shapedrecipes); + return shapedrecipes; + } + + public void registerShapelessRecipe(ItemStack itemstack, Object... aobject) { + ArrayList arraylist = Lists.newArrayList(); + Object[] aobject1 = aobject; + int i = aobject.length; + + for (int j = 0; j < i; ++j) { + Object object = aobject1[j]; + + if (object instanceof ItemStack) { + arraylist.add(((ItemStack) object).cloneItemStack()); + } else if (object instanceof Item) { + arraylist.add(new ItemStack((Item) object)); + } else { + if (!(object instanceof Block)) { + throw new IllegalArgumentException("Invalid shapeless recipe: unknown type " + object.getClass().getName() + "!"); + } + + arraylist.add(new ItemStack((Block) object)); + } + } + + this.recipes.add(new ShapelessRecipes(itemstack, arraylist)); + } + + public void a(IRecipe irecipe) { + this.recipes.add(irecipe); + } + + public ItemStack craft(InventoryCrafting inventorycrafting, World world) { + Iterator iterator = this.recipes.iterator(); + + IRecipe irecipe; + + do { + if (!iterator.hasNext()) { + inventorycrafting.currentRecipe = null; // CraftBukkit - Clear recipe when no recipe is found + return null; + } + + irecipe = (IRecipe) iterator.next(); + } while (!irecipe.a(inventorycrafting, world)); + + // CraftBukkit start - INVENTORY_PRE_CRAFT event + inventorycrafting.currentRecipe = irecipe; + ItemStack result = irecipe.craftItem(inventorycrafting); + return CraftEventFactory.callPreCraftEvent(inventorycrafting, result, lastCraftView, false); + // CraftBukkit end + } + + public ItemStack[] b(InventoryCrafting inventorycrafting, World world) { + Iterator iterator = this.recipes.iterator(); + + while (iterator.hasNext()) { + IRecipe irecipe = (IRecipe) iterator.next(); + + if (irecipe.a(inventorycrafting, world)) { + return irecipe.b(inventorycrafting); + } + } + + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + aitemstack[i] = inventorycrafting.getItem(i); + } + + return aitemstack; + } + + public List getRecipes() { + return this.recipes; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CrashReport.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CrashReport.java new file mode 100644 index 0000000..741c419 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/CrashReport.java @@ -0,0 +1,317 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.io.File; +import java.io.FileWriter; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Callable; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class CrashReport { + + private static final Logger a = LogManager.getLogger(); + private final String b; + private final Throwable c; + private final CrashReportSystemDetails d = new CrashReportSystemDetails(this, "System Details"); + private final List e = Lists.newArrayList(); + private File f; + private boolean g = true; + private StackTraceElement[] h = new StackTraceElement[0]; + + public CrashReport(String s, Throwable throwable) { + this.b = s; + this.c = throwable; + this.h(); + } + + private void h() { + this.d.a("Minecraft Version", new Callable() { + public String a() { + return "1.8.8"; + } + + public Object call() throws Exception { + return this.a(); + } + }); + this.d.a("Operating System", new Callable() { + public String a() { + return System.getProperty("os.name") + " (" + System.getProperty("os.arch") + ") version " + System.getProperty("os.version"); + } + + public Object call() throws Exception { + return this.a(); + } + }); + this.d.a("Java Version", new Callable() { + public String a() { + return System.getProperty("java.version") + ", " + System.getProperty("java.vendor"); + } + + public Object call() throws Exception { + return this.a(); + } + }); + this.d.a("Java VM Version", new Callable() { + public String a() { + return System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor"); + } + + public Object call() throws Exception { + return this.a(); + } + }); + this.d.a("Memory", new Callable() { + public String a() { + Runtime runtime = Runtime.getRuntime(); + long i = runtime.maxMemory(); + long j = runtime.totalMemory(); + long k = runtime.freeMemory(); + long l = i / 1024L / 1024L; + long i1 = j / 1024L / 1024L; + long j1 = k / 1024L / 1024L; + + return k + " bytes (" + j1 + " MB) / " + j + " bytes (" + i1 + " MB) up to " + i + " bytes (" + l + " MB)"; + } + + public Object call() throws Exception { + return this.a(); + } + }); + this.d.a("JVM Flags", new Callable() { + public String a() { + RuntimeMXBean runtimemxbean = ManagementFactory.getRuntimeMXBean(); + List list = runtimemxbean.getInputArguments(); + int i = 0; + StringBuilder stringbuilder = new StringBuilder(); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + + if (s.startsWith("-X")) { + if (i++ > 0) { + stringbuilder.append(" "); + } + + stringbuilder.append(s); + } + } + + return String.format("%d total; %s", new Object[] { Integer.valueOf(i), stringbuilder.toString()}); + } + + public Object call() throws Exception { + return this.a(); + } + }); + this.d.a("IntCache", new Callable() { + public String a() throws Exception { + return IntCache.b(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + this.d.a("CraftBukkit Information", (Callable) (new org.bukkit.craftbukkit.CraftCrashReport())); // CraftBukkit + } + + public String a() { + return this.b; + } + + public Throwable b() { + return this.c; + } + + public void a(StringBuilder stringbuilder) { + if ((this.h == null || this.h.length <= 0) && this.e.size() > 0) { + this.h = (StackTraceElement[]) ArrayUtils.subarray(((CrashReportSystemDetails) this.e.get(0)).a(), 0, 1); + } + + if (this.h != null && this.h.length > 0) { + stringbuilder.append("-- Head --\n"); + stringbuilder.append("Stacktrace:\n"); + StackTraceElement[] astacktraceelement = this.h; + int i = astacktraceelement.length; + + for (int j = 0; j < i; ++j) { + StackTraceElement stacktraceelement = astacktraceelement[j]; + + stringbuilder.append("\t").append("at ").append(stacktraceelement.toString()); + stringbuilder.append("\n"); + } + + stringbuilder.append("\n"); + } + + Iterator iterator = this.e.iterator(); + + while (iterator.hasNext()) { + CrashReportSystemDetails crashreportsystemdetails = (CrashReportSystemDetails) iterator.next(); + + crashreportsystemdetails.a(stringbuilder); + stringbuilder.append("\n\n"); + } + + this.d.a(stringbuilder); + } + + public String d() { + StringWriter stringwriter = null; + PrintWriter printwriter = null; + Object object = this.c; + + if (((Throwable) object).getMessage() == null) { + if (object instanceof NullPointerException) { + object = new NullPointerException(this.b); + } else if (object instanceof StackOverflowError) { + object = new StackOverflowError(this.b); + } else if (object instanceof OutOfMemoryError) { + object = new OutOfMemoryError(this.b); + } + + ((Throwable) object).setStackTrace(this.c.getStackTrace()); + } + + String s = ((Throwable) object).toString(); + + try { + stringwriter = new StringWriter(); + printwriter = new PrintWriter(stringwriter); + ((Throwable) object).printStackTrace(printwriter); + s = stringwriter.toString(); + } finally { + IOUtils.closeQuietly(stringwriter); + IOUtils.closeQuietly(printwriter); + } + + return s; + } + + public String e() { + StringBuilder stringbuilder = new StringBuilder(); + + stringbuilder.append("---- Minecraft Crash Report ----\n"); + stringbuilder.append("// "); + stringbuilder.append(i()); + stringbuilder.append("\n\n"); + stringbuilder.append("Time: "); + stringbuilder.append((new SimpleDateFormat()).format(new Date())); + stringbuilder.append("\n"); + stringbuilder.append("Description: "); + stringbuilder.append(this.b); + stringbuilder.append("\n\n"); + stringbuilder.append(this.d()); + stringbuilder.append("\n\nA detailed walkthrough of the error, its code path and all known details is as follows:\n"); + + for (int i = 0; i < 87; ++i) { + stringbuilder.append("-"); + } + + stringbuilder.append("\n\n"); + this.a(stringbuilder); + return stringbuilder.toString(); + } + + public boolean a(File file) { + if (this.f != null) { + return false; + } else { + if (file.getParentFile() != null) { + file.getParentFile().mkdirs(); + } + + try { + FileWriter filewriter = new FileWriter(file); + + filewriter.write(this.e()); + filewriter.close(); + this.f = file; + return true; + } catch (Throwable throwable) { + CrashReport.a.error("Could not save crash report to " + file, throwable); + return false; + } + } + } + + public CrashReportSystemDetails g() { + return this.d; + } + + public CrashReportSystemDetails a(String s) { + return this.a(s, 1); + } + + public CrashReportSystemDetails a(String s, int i) { + CrashReportSystemDetails crashreportsystemdetails = new CrashReportSystemDetails(this, s); + + if (this.g) { + int j = crashreportsystemdetails.a(i); + StackTraceElement[] astacktraceelement = this.c.getStackTrace(); + StackTraceElement stacktraceelement = null; + StackTraceElement stacktraceelement1 = null; + int k = astacktraceelement.length - j; + + if (k < 0) { + System.out.println("Negative index in crash report handler (" + astacktraceelement.length + "/" + j + ")"); + } + + if (astacktraceelement != null && 0 <= k && k < astacktraceelement.length) { + stacktraceelement = astacktraceelement[k]; + if (astacktraceelement.length + 1 - j < astacktraceelement.length) { + stacktraceelement1 = astacktraceelement[astacktraceelement.length + 1 - j]; + } + } + + this.g = crashreportsystemdetails.a(stacktraceelement, stacktraceelement1); + if (j > 0 && !this.e.isEmpty()) { + CrashReportSystemDetails crashreportsystemdetails1 = (CrashReportSystemDetails) this.e.get(this.e.size() - 1); + + crashreportsystemdetails1.b(j); + } else if (astacktraceelement != null && astacktraceelement.length >= j && 0 <= k && k < astacktraceelement.length) { + this.h = new StackTraceElement[k]; + System.arraycopy(astacktraceelement, 0, this.h, 0, this.h.length); + } else { + this.g = false; + } + } + + this.e.add(crashreportsystemdetails); + return crashreportsystemdetails; + } + + private static String i() { + String[] astring = new String[] { "Who set us up the TNT?", "Everything\'s going to plan. No, really, that was supposed to happen.", "Uh... Did I do that?", "Oops.", "Why did you do that?", "I feel sad now :(", "My bad.", "I\'m sorry, Dave.", "I let you down. Sorry :(", "On the bright side, I bought you a teddy bear!", "Daisy, daisy...", "Oh - I know what I did wrong!", "Hey, that tickles! Hehehe!", "I blame Dinnerbone.", "You should try our sister game, Minceraft!", "Don\'t be sad. I\'ll do better next time, I promise!", "Don\'t be sad, have a hug! <3", "I just don\'t know what went wrong :(", "Shall we play a game?", "Quite honestly, I wouldn\'t worry myself about that.", "I bet Cylons wouldn\'t have this problem.", "Sorry :(", "Surprise! Haha. Well, this is awkward.", "Would you like a cupcake?", "Hi. I\'m Minecraft, and I\'m a crashaholic.", "Ooh. Shiny.", "This doesn\'t make any sense!", "Why is it breaking :(", "Don\'t do that.", "Ouch. That hurt :(", "You\'re mean.", "This is a token for 1 free hug. Redeem at your nearest Mojangsta: [~~HUG~~]", "There are four lights!", "But it works on my machine."}; + + try { + return astring[(int) (System.nanoTime() % (long) astring.length)]; + } catch (Throwable throwable) { + return "Witty comment unavailable :("; + } + } + + public static CrashReport a(Throwable throwable, String s) { + CrashReport crashreport; + + if (throwable instanceof ReportedException) { + crashreport = ((ReportedException) throwable).a(); + } else { + crashreport = new CrashReport(s, throwable); + } + + return crashreport; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DataWatcher.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DataWatcher.java new file mode 100644 index 0000000..1fbbfaa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DataWatcher.java @@ -0,0 +1,396 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.apache.commons.lang3.ObjectUtils; +// TacoSpigot start +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntIterator; +// TacoSpigot end + +public class DataWatcher { + + private final Entity a; + private boolean b = true; + // Spigot Start + // TacoSpigot start - use fastutil instead of trove + private static final Object2IntMap> classToId = new Object2IntOpenHashMap(10, 0.5f); + private final Int2ObjectMap dataValues = new Int2ObjectOpenHashMap(10, 0.5f); + // These exist as an attempt at backwards compatability for (broken) NMS plugins + private static final Map, Integer> c = classToId; + private final Map d = dataValues; + // TacoSpigot end + // Spigot End + private boolean e; + private ReadWriteLock f = new ReentrantReadWriteLock(); + + public DataWatcher(Entity entity) { + this.a = entity; + } + + public void a(int i, T t0) { + int integer = classToId.get(t0.getClass()); // Spigot + + if (integer == -1) { // Spigot + throw new IllegalArgumentException("Unknown data type: " + t0.getClass()); + } else if (i > 31) { + throw new IllegalArgumentException("Data value id is too big with " + i + "! (Max is " + 31 + ")"); + } else if (this.dataValues.containsKey(i)) { // Spigot + throw new IllegalArgumentException("Duplicate id value for " + i + "!"); + } else { + DataWatcher.WatchableObject datawatcher_watchableobject = new DataWatcher.WatchableObject(integer, i, t0); // Spigot + + this.f.writeLock().lock(); + this.dataValues.put(i, datawatcher_watchableobject); // Spigot + this.f.writeLock().unlock(); + this.b = false; + } + } + + public void add(int i, int j) { + DataWatcher.WatchableObject datawatcher_watchableobject = new DataWatcher.WatchableObject(j, i, (Object) null); + + this.f.writeLock().lock(); + this.dataValues.put(i, datawatcher_watchableobject); // Spigot + this.f.writeLock().unlock(); + this.b = false; + } + + public byte getByte(int i) { + return ((Byte) this.j(i).b()).byteValue(); + } + + public short getShort(int i) { + return ((Short) this.j(i).b()).shortValue(); + } + + public int getInt(int i) { + return ((Integer) this.j(i).b()).intValue(); + } + + public float getFloat(int i) { + return ((Float) this.j(i).b()).floatValue(); + } + + public String getString(int i) { + return (String) this.j(i).b(); + } + + public ItemStack getItemStack(int i) { + return (ItemStack) this.j(i).b(); + } + + private DataWatcher.WatchableObject j(int i) { + this.f.readLock().lock(); + + DataWatcher.WatchableObject datawatcher_watchableobject; + + try { + datawatcher_watchableobject = (DataWatcher.WatchableObject) this.dataValues.get(i); // Spigot + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Getting synched entity data"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Synched entity data"); + + crashreportsystemdetails.a("Data ID", (Object) Integer.valueOf(i)); + throw new ReportedException(crashreport); + } + + this.f.readLock().unlock(); + return datawatcher_watchableobject; + } + + public Vector3f h(int i) { + return (Vector3f) this.j(i).b(); + } + + public void watch(int i, T t0) { + DataWatcher.WatchableObject datawatcher_watchableobject = this.j(i); + + if (ObjectUtils.notEqual(t0, datawatcher_watchableobject.b())) { + datawatcher_watchableobject.a(t0); + this.a.i(i); + datawatcher_watchableobject.a(true); + this.e = true; + } + + } + + public void update(int i) { + this.j(i).d = true; + this.e = true; + } + + public boolean a() { + return this.e; + } + + public static void a(List list, PacketDataSerializer packetdataserializer) throws IOException { + if (list != null) { + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + DataWatcher.WatchableObject datawatcher_watchableobject = (DataWatcher.WatchableObject) iterator.next(); + + a(packetdataserializer, datawatcher_watchableobject); + } + } + + packetdataserializer.writeByte(127); + } + + public List b() { + ArrayList arraylist = null; + + if (this.e) { + this.f.readLock().lock(); + Iterator iterator = this.dataValues.values().iterator(); // Spigot // TacoSpigot + + while (iterator.hasNext()) { + DataWatcher.WatchableObject datawatcher_watchableobject = (DataWatcher.WatchableObject) iterator.next(); + + if (datawatcher_watchableobject.d()) { + datawatcher_watchableobject.a(false); + if (arraylist == null) { + arraylist = Lists.newArrayList(); + } + + // Spigot start - copy ItemStacks to prevent ConcurrentModificationExceptions + if ( datawatcher_watchableobject.b() instanceof ItemStack ) + { + datawatcher_watchableobject = new WatchableObject( + datawatcher_watchableobject.c(), + datawatcher_watchableobject.a(), + ( (ItemStack) datawatcher_watchableobject.b() ).cloneItemStack() + ); + } + // Spigot end + + arraylist.add(datawatcher_watchableobject); + } + } + + this.f.readLock().unlock(); + } + + this.e = false; + return arraylist; + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.f.readLock().lock(); + Iterator iterator = this.dataValues.values().iterator(); // Spigot // TacoSpigot + + while (iterator.hasNext()) { + DataWatcher.WatchableObject datawatcher_watchableobject = (DataWatcher.WatchableObject) iterator.next(); + + a(packetdataserializer, datawatcher_watchableobject); + } + + this.f.readLock().unlock(); + packetdataserializer.writeByte(127); + } + + public List c() { + ArrayList arraylist = Lists.newArrayList(); // Spigot + + this.f.readLock().lock(); + + arraylist.addAll(this.dataValues.values()); // Spigot // TacoSpigot + // Spigot start - copy ItemStacks to prevent ConcurrentModificationExceptions + for ( int i = 0; i < arraylist.size(); i++ ) + { + WatchableObject watchableobject = (WatchableObject) arraylist.get( i ); + if ( watchableobject.b() instanceof ItemStack ) + { + watchableobject = new WatchableObject( + watchableobject.c(), + watchableobject.a(), + ( (ItemStack) watchableobject.b() ).cloneItemStack() + ); + arraylist.set( i, watchableobject ); + } + } + // Spigot end + + this.f.readLock().unlock(); + return arraylist; + } + + private static void a(PacketDataSerializer packetdataserializer, DataWatcher.WatchableObject datawatcher_watchableobject) throws IOException { + int i = (datawatcher_watchableobject.c() << 5 | datawatcher_watchableobject.a() & 31) & 255; + + packetdataserializer.writeByte(i); + switch (datawatcher_watchableobject.c()) { + case 0: + packetdataserializer.writeByte(((Byte) datawatcher_watchableobject.b()).byteValue()); + break; + + case 1: + packetdataserializer.writeShort(((Short) datawatcher_watchableobject.b()).shortValue()); + break; + + case 2: + packetdataserializer.writeInt(((Integer) datawatcher_watchableobject.b()).intValue()); + break; + + case 3: + packetdataserializer.writeFloat(((Float) datawatcher_watchableobject.b()).floatValue()); + break; + + case 4: + packetdataserializer.a((String) datawatcher_watchableobject.b()); + break; + + case 5: + ItemStack itemstack = (ItemStack) datawatcher_watchableobject.b(); + + packetdataserializer.a(itemstack); + break; + + case 6: + BlockPosition blockposition = (BlockPosition) datawatcher_watchableobject.b(); + + packetdataserializer.writeInt(blockposition.getX()); + packetdataserializer.writeInt(blockposition.getY()); + packetdataserializer.writeInt(blockposition.getZ()); + break; + + case 7: + Vector3f vector3f = (Vector3f) datawatcher_watchableobject.b(); + + packetdataserializer.writeFloat(vector3f.getX()); + packetdataserializer.writeFloat(vector3f.getY()); + packetdataserializer.writeFloat(vector3f.getZ()); + } + + } + + public static List b(PacketDataSerializer packetdataserializer) throws IOException { + ArrayList arraylist = null; + + for (byte b0 = packetdataserializer.readByte(); b0 != 127; b0 = packetdataserializer.readByte()) { + if (arraylist == null) { + arraylist = Lists.newArrayList(); + } + + int i = (b0 & 224) >> 5; + int j = b0 & 31; + DataWatcher.WatchableObject datawatcher_watchableobject = null; + + switch (i) { + case 0: + datawatcher_watchableobject = new DataWatcher.WatchableObject(i, j, Byte.valueOf(packetdataserializer.readByte())); + break; + + case 1: + datawatcher_watchableobject = new DataWatcher.WatchableObject(i, j, Short.valueOf(packetdataserializer.readShort())); + break; + + case 2: + datawatcher_watchableobject = new DataWatcher.WatchableObject(i, j, Integer.valueOf(packetdataserializer.readInt())); + break; + + case 3: + datawatcher_watchableobject = new DataWatcher.WatchableObject(i, j, Float.valueOf(packetdataserializer.readFloat())); + break; + + case 4: + datawatcher_watchableobject = new DataWatcher.WatchableObject(i, j, packetdataserializer.c(32767)); + break; + + case 5: + datawatcher_watchableobject = new DataWatcher.WatchableObject(i, j, packetdataserializer.i()); + break; + + case 6: + int k = packetdataserializer.readInt(); + int l = packetdataserializer.readInt(); + int i1 = packetdataserializer.readInt(); + + datawatcher_watchableobject = new DataWatcher.WatchableObject(i, j, new BlockPosition(k, l, i1)); + break; + + case 7: + float f = packetdataserializer.readFloat(); + float f1 = packetdataserializer.readFloat(); + float f2 = packetdataserializer.readFloat(); + + datawatcher_watchableobject = new DataWatcher.WatchableObject(i, j, new Vector3f(f, f1, f2)); + } + + arraylist.add(datawatcher_watchableobject); + } + + return arraylist; + } + + public boolean d() { + return this.b; + } + + public void e() { + this.e = false; + } + + static { + // Spigot Start - remove valueOf + classToId.put(Byte.class, 0); + classToId.put(Short.class, 1); + classToId.put(Integer.class, 2); + classToId.put(Float.class, 3); + classToId.put(String.class, 4); + classToId.put(ItemStack.class, 5); + classToId.put(BlockPosition.class, 6); + classToId.put(Vector3f.class, 7); + // Spigot End + } + + public static class WatchableObject { + + private final int a; + private final int b; + private Object c; + private boolean d; + + public WatchableObject(int i, int j, Object object) { + this.b = j; + this.c = object; + this.a = i; + this.d = true; + } + + public int a() { + return this.b; + } + + public void a(Object object) { + this.c = object; + } + + public Object b() { + return this.c; + } + + public int c() { + return this.a; + } + + public boolean d() { + return this.d; + } + + public void a(boolean flag) { + this.d = flag; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DedicatedServer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DedicatedServer.java new file mode 100644 index 0000000..9ff408d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DedicatedServer.java @@ -0,0 +1,658 @@ +package net.minecraft.server; + +import co.aikar.timings.SpigotTimings; +import com.google.common.collect.Lists; +import me.levansj01.mythicspigot.MythicCore; +import net.jafama.FastMath; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.craftbukkit.LoggerOutputStream; +import org.bukkit.craftbukkit.util.Waitable; +import org.bukkit.event.server.RemoteServerCommandEvent; +import org.bukkit.event.server.ServerCommandEvent; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.net.InetAddress; +import java.net.Proxy; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +// CraftBukkit start +// CraftBukkit end + +public class DedicatedServer extends MinecraftServer implements IMinecraftServer { + + private static final Logger LOGGER = LogManager.getLogger(); + private final List l = Collections.synchronizedList(Lists.newArrayList()); // CraftBukkit - fix decompile error + private RemoteStatusListener m; + private RemoteControlListener n; + public PropertyManager propertyManager; + private boolean generateStructures; + private WorldSettings.EnumGamemode r; + private boolean s; + + // CraftBukkit start - Signature changed + public DedicatedServer(joptsimple.OptionSet options) { + super(options, Proxy.NO_PROXY, DedicatedServer.a); + // CraftBukkit end + Thread thread = new Thread("Server Infinisleeper") { + { + this.setDaemon(true); + this.start(); + } + + public void run() { + while (true) { + try { + Thread.sleep(2147483647L); + } catch (InterruptedException interruptedexception) { + } + } + } + }; + } + + protected boolean init() throws IOException { + Thread thread = new Thread("Server console handler") { + public void run() { + // CraftBukkit start + if (!org.bukkit.craftbukkit.Main.useConsole) { + return; + } + // CraftBukkit end + + jline.console.ConsoleReader bufferedreader = reader; // CraftBukkit + String s; + + try { + // CraftBukkit start - JLine disabling compatibility + while (!isStopped() && isRunning()) { + if (org.bukkit.craftbukkit.Main.useJline) { + s = bufferedreader.readLine(">", null); + } else { + s = bufferedreader.readLine(); + } + if (s != null && s.trim().length() > 0) { // Trim to filter lines which are just spaces + issueCommand(s, DedicatedServer.this); + } + // CraftBukkit end + } + } catch (IOException ioexception) { + DedicatedServer.LOGGER.error("Exception handling console input", ioexception); + } + + } + }; + + // CraftBukkit start - TODO: handle command-line logging arguments + java.util.logging.Logger global = java.util.logging.Logger.getLogger(""); + global.setUseParentHandlers(false); + for (java.util.logging.Handler handler : global.getHandlers()) { + global.removeHandler(handler); + } + global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler()); + + final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()); + for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) { + if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) { + logger.removeAppender(appender); + } + } + + new Thread(new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader)).start(); + + System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true)); + System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true)); + // CraftBukkit end + + thread.setDaemon(true); + thread.start(); + DedicatedServer.LOGGER.info("Starting minecraft server version 1.8.8"); + if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) { + DedicatedServer.LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); + } + + DedicatedServer.LOGGER.info("Loading properties"); + this.propertyManager = new PropertyManager(this.options); // CraftBukkit - CLI argument support + + if (this.T()) { + this.c("127.0.0.1"); + } else { + this.setOnlineMode(this.propertyManager.getBoolean("online-mode", true)); + this.c(this.propertyManager.getString("server-ip", "")); + } + + this.setSpawnAnimals(this.propertyManager.getBoolean("spawn-animals", true)); + this.setSpawnNPCs(this.propertyManager.getBoolean("spawn-npcs", true)); + this.setPVP(this.propertyManager.getBoolean("pvp", true)); + this.setAllowFlight(this.propertyManager.getBoolean("allow-flight", false)); + this.setResourcePack(this.propertyManager.getString("resource-pack", ""), this.propertyManager.getString("resource-pack-hash", "")); + this.setMotd(this.propertyManager.getString("motd", "A Minecraft Server")); + this.setForceGamemode(this.propertyManager.getBoolean("force-gamemode", false)); + this.setIdleTimeout(this.propertyManager.getInt("player-idle-timeout", 0)); + if (this.propertyManager.getInt("difficulty", 1) < 0) { + this.propertyManager.setProperty("difficulty", Integer.valueOf(0)); + } else if (this.propertyManager.getInt("difficulty", 1) > 3) { + this.propertyManager.setProperty("difficulty", Integer.valueOf(3)); + } + + this.generateStructures = this.propertyManager.getBoolean("generate-structures", true); + int i = this.propertyManager.getInt("gamemode", WorldSettings.EnumGamemode.SURVIVAL.getId()); + + this.r = WorldSettings.a(i); + DedicatedServer.LOGGER.info("Default game type: " + this.r); + InetAddress inetaddress = null; + + if (this.getServerIp().length() > 0) { + inetaddress = InetAddress.getByName(this.getServerIp()); + } + + if (this.R() < 0) { + this.setPort(this.propertyManager.getInt("server-port", 25565)); + } + // Spigot start + this.a(new DedicatedPlayerList(this)); + org.spigotmc.SpigotConfig.init((File) options.valueOf("spigot-settings")); + org.spigotmc.SpigotConfig.registerCommands(); + // Spigot end + // PaperSpigot start + org.github.paperspigot.PaperSpigotConfig.init((File) options.valueOf("paper-settings")); + org.github.paperspigot.PaperSpigotConfig.registerCommands(); + // PaperSpigot end + + // Mythic - Load MythicSpigot + MythicCore.getCore().load(); + + DedicatedServer.LOGGER.info("Generating keypair"); + this.a(MinecraftEncryption.b()); + DedicatedServer.LOGGER.info("Starting Minecraft server on " + (this.getServerIp().length() == 0 ? "*" : this.getServerIp()) + ":" + this.R()); + + if (!org.spigotmc.SpigotConfig.lateBind) { + try { + this.aq().a(inetaddress, this.R()); + } catch (IOException ioexception) { + DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!"); + DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString()); + DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?"); + return false; + } + } + + // Spigot Start - Move DedicatedPlayerList up and bring plugin loading from CraftServer to here + // this.a((PlayerList) (new DedicatedPlayerList(this))); // CraftBukkit + server.loadPlugins(); + server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); + // Spigot End + + if (!this.getOnlineMode()) { + DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!"); + DedicatedServer.LOGGER.warn("The server will make no attempt to authenticate usernames. Beware."); + // Spigot start + if (org.spigotmc.SpigotConfig.bungee) { + DedicatedServer.LOGGER.warn("Whilst this makes it possible to use BungeeCord, unless access to your server is properly restricted, it also opens up the ability for hackers to connect with any username they choose."); + DedicatedServer.LOGGER.warn("Please see http://www.spigotmc.org/wiki/firewall-guide/ for further information."); + } else { + DedicatedServer.LOGGER.warn("While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose."); + } + // Spigot end + DedicatedServer.LOGGER.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); + } + + if (this.aR()) { + this.getUserCache().c(); + } + + if (!NameReferencingFileConverter.a(this.propertyManager)) { + return false; + } else { + this.convertable = new WorldLoaderServer(server.getWorldContainer()); // CraftBukkit - moved from MinecraftServer constructor + long j = System.nanoTime(); + + if (this.U() == null) { + this.setWorld(this.propertyManager.getString("level-name", "world")); + } + + String s = this.propertyManager.getString("level-seed", ""); + String s1 = this.propertyManager.getString("level-type", "DEFAULT"); + String s2 = this.propertyManager.getString("generator-settings", ""); + long k = (new Random()).nextLong(); + + if (s.length() > 0) { + try { + long l = Long.parseLong(s); + + if (l != 0L) { + k = l; + } + } catch (NumberFormatException numberformatexception) { + k = s.hashCode(); + } + } + + WorldType worldtype = WorldType.getType(s1); + + if (worldtype == null) { + worldtype = WorldType.NORMAL; + } + + this.aB(); + this.getEnableCommandBlock(); + this.p(); + this.getSnooperEnabled(); + this.aK(); + this.c(this.propertyManager.getInt("max-build-height", 256)); + this.c((this.getMaxBuildHeight() + 8) / 16 * 16); + this.c(MathHelper.clamp(this.getMaxBuildHeight(), 64, 256)); + this.propertyManager.setProperty("max-build-height", Integer.valueOf(this.getMaxBuildHeight())); + DedicatedServer.LOGGER.info("Preparing level \"" + this.U() + "\""); + this.a(this.U(), this.U(), k, worldtype, s2); + long i1 = System.nanoTime() - j; + String s3 = String.format("%.3fs", Double.valueOf((double) i1 / 1.0E9D)); + + DedicatedServer.LOGGER.info("Done (" + s3 + ")! For help, type \"help\" or \"?\""); + if (this.propertyManager.getBoolean("enable-query", false)) { + DedicatedServer.LOGGER.info("Starting GS4 status listener"); + this.m = new RemoteStatusListener(this); + this.m.a(); + } + + if (this.propertyManager.getBoolean("enable-rcon", false)) { + DedicatedServer.LOGGER.info("Starting remote control listener"); + this.n = new RemoteControlListener(this); + this.n.a(); + 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().a(inetaddress, this.R()); + } catch (IOException ioexception) { + DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!"); + DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString()); + DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?"); + return false; + } + } + + if (false && this.aS() > 0L) { // Spigot - disable + Thread thread1 = new Thread(new ThreadWatchdog(this)); + + thread1.setName("Server Watchdog"); + thread1.setDaemon(true); + thread1.start(); + } + + return true; + } + } + + // CraftBukkit start + public PropertyManager getPropertyManager() { + return this.propertyManager; + } + // CraftBukkit end + + public void setGamemode(WorldSettings.EnumGamemode worldsettings_enumgamemode) { + super.setGamemode(worldsettings_enumgamemode); + this.r = worldsettings_enumgamemode; + } + + public boolean getGenerateStructures() { + return this.generateStructures; + } + + public WorldSettings.EnumGamemode getGamemode() { + return this.r; + } + + public EnumDifficulty getDifficulty() { + return EnumDifficulty.getById(this.propertyManager.getInt("difficulty", EnumDifficulty.NORMAL.a())); + } + + public boolean isHardcore() { + return this.propertyManager.getBoolean("hardcore", false); + } + + protected void a(CrashReport crashreport) {} + + public CrashReport b(CrashReport crashreport) { + crashreport = super.b(crashreport); + crashreport.g().a("Is Modded", new Callable() { + public String a() throws Exception { + String s = DedicatedServer.this.getServerModName(); + + return !s.equals("vanilla") ? "Definitely; Server brand changed to '" + s + "'" : "Unknown (can't tell)"; + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreport.g().a("Type", new Callable() { + public String a() throws Exception { + return "Dedicated Server (map_server.txt)"; + } + + public Object call() throws Exception { + return this.a(); + } + }); + return crashreport; + } + + protected void z() { + System.exit(0); + } + + public void B() { // CraftBukkit - fix decompile error + super.B(); + this.aO(); + } + + public boolean getAllowNether() { + return this.propertyManager.getBoolean("allow-nether", true); + } + + public boolean getSpawnMonsters() { + return this.propertyManager.getBoolean("spawn-monsters", true); + } + + public void a(MojangStatisticsGenerator mojangstatisticsgenerator) { + mojangstatisticsgenerator.a("whitelist_enabled", Boolean.valueOf(this.aP().getHasWhitelist())); + mojangstatisticsgenerator.a("whitelist_count", Integer.valueOf(this.aP().getWhitelisted().length)); + super.a(mojangstatisticsgenerator); + } + + public boolean getSnooperEnabled() { + return this.propertyManager.getBoolean("snooper-enabled", true); + } + + public void issueCommand(String s, ICommandListener icommandlistener) { + this.l.add(new ServerCommand(s, icommandlistener)); + } + + public void aO() { + SpigotTimings.serverCommandTimer.startTiming(); // Spigot + while (!this.l.isEmpty()) { + ServerCommand servercommand = this.l.remove(0); + + // CraftBukkit start - ServerCommand for preprocessing + ServerCommandEvent event = new ServerCommandEvent(console, servercommand.command); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) continue; + servercommand = new ServerCommand(event.getCommand(), servercommand.source); + + // this.getCommandHandler().a(servercommand.source, servercommand.command); // Called in dispatchServerCommand + server.dispatchServerCommand(console, servercommand); + // CraftBukkit end + } + + SpigotTimings.serverCommandTimer.stopTiming(); // Spigot + } + + public boolean ae() { + return true; + } + + public boolean ai() { + return this.propertyManager.getBoolean("use-native-transport", true); + } + + public DedicatedPlayerList aP() { + return (DedicatedPlayerList) super.getPlayerList(); + } + + public int a(String s, int i) { + return this.propertyManager.getInt(s, i); + } + + public String a(String s, String s1) { + return this.propertyManager.getString(s, s1); + } + + public boolean a(String s, boolean flag) { + return this.propertyManager.getBoolean(s, flag); + } + + public void a(String s, Object object) { + this.propertyManager.setProperty(s, object); + } + + public void a() { + this.propertyManager.savePropertiesFile(); + } + + public String b() { + File file = this.propertyManager.c(); + + return file != null ? file.getAbsolutePath() : "No settings file"; + } + + public void aQ() { + ServerGUI.a(this); + this.s = true; + } + + public boolean as() { + return this.s; + } + + public String a(WorldSettings.EnumGamemode worldsettings_enumgamemode, boolean flag) { + return ""; + } + + public boolean getEnableCommandBlock() { + return this.propertyManager.getBoolean("enable-command-block", false); + } + + public int getSpawnProtection() { + return this.propertyManager.getInt("spawn-protection", super.getSpawnProtection()); + } + + public boolean a(World world, BlockPosition blockposition, EntityHuman entityhuman) { + if (world.worldProvider.getDimension() != 0) { + return false; + } else if (this.aP().getOPs().isEmpty()) { + return false; + } else if (this.aP().isOp(entityhuman.getProfile())) { + return false; + } else if (this.getSpawnProtection() <= 0) { + return false; + } else { + BlockPosition blockposition1 = world.getSpawn(); + int i = MathHelper.a(blockposition.getX() - blockposition1.getX()); + int j = MathHelper.a(blockposition.getZ() - blockposition1.getZ()); + int k = FastMath.max(i, j); + + return k <= this.getSpawnProtection(); + } + } + + public int p() { + return this.propertyManager.getInt("op-permission-level", 4); + } + + public void setIdleTimeout(int i) { + super.setIdleTimeout(i); + this.propertyManager.setProperty("player-idle-timeout", Integer.valueOf(i)); + this.a(); + } + + public boolean q() { + return this.propertyManager.getBoolean("broadcast-rcon-to-ops", true); + } + + public boolean r() { + return this.propertyManager.getBoolean("broadcast-console-to-ops", true); + } + + public boolean aB() { + return this.propertyManager.getBoolean("announce-player-achievements", true); + } + + public int aI() { + int i = this.propertyManager.getInt("max-world-size", super.aI()); + + if (i < 1) { + i = 1; + } else if (i > super.aI()) { + i = super.aI(); + } + + return i; + } + + public int aK() { + return this.propertyManager.getInt("network-compression-threshold", super.aK()); + } + + protected boolean aR() { + server.getLogger().info( "**** Beginning UUID conversion, this may take A LONG time ****"); // Spigot, let the user know whats up! + boolean flag = false; + + int i; + + for (i = 0; !flag && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the user banlist, retrying in a few seconds"); + this.aU(); + } + + flag = NameReferencingFileConverter.a(this); + } + + boolean flag1 = false; + + for (i = 0; !flag1 && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the ip banlist, retrying in a few seconds"); + this.aU(); + } + + flag1 = NameReferencingFileConverter.b(this); + } + + boolean flag2 = false; + + for (i = 0; !flag2 && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the op list, retrying in a few seconds"); + this.aU(); + } + + flag2 = NameReferencingFileConverter.c(this); + } + + boolean flag3 = false; + + for (i = 0; !flag3 && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the whitelist, retrying in a few seconds"); + this.aU(); + } + + flag3 = NameReferencingFileConverter.d(this); + } + + boolean flag4 = false; + + for (i = 0; !flag4 && i <= 2; ++i) { + if (i > 0) { + DedicatedServer.LOGGER.warn("Encountered a problem while converting the player save files, retrying in a few seconds"); + this.aU(); + } + + flag4 = NameReferencingFileConverter.a(this, this.propertyManager); + } + + return flag || flag1 || flag2 || flag3 || flag4; + } + + private void aU() { + try { + Thread.sleep(5000L); + } catch (InterruptedException interruptedexception) { + } + } + + public long aS() { + return this.propertyManager.getLong("max-tick-time", TimeUnit.MINUTES.toMillis(1L)); + } + + public String getPlugins() { + // CraftBukkit start - Whole method + StringBuilder result = new StringBuilder(); + org.bukkit.plugin.Plugin[] plugins = server.getPluginManager().getPlugins(); + + result.append(server.getName()); + result.append(" on Bukkit "); + result.append(server.getBukkitVersion()); + + if (plugins.length > 0 && server.getQueryPlugins()) { + result.append(": "); + + for (int i = 0; i < plugins.length; i++) { + if (i > 0) { + result.append("; "); + } + + result.append(plugins[i].getDescription().getName()); + result.append(" "); + result.append(plugins[i].getDescription().getVersion().replaceAll(";", ",")); + } + } + + return result.toString(); + // CraftBukkit end + } + + // CraftBukkit start - fire RemoteServerCommandEvent + public String executeRemoteCommand(final String s) { + Waitable waitable = new Waitable() { + @Override + protected String evaluate() { + RemoteControlCommandListener.getInstance().i(); + // Event changes start + RemoteServerCommandEvent event = new RemoteServerCommandEvent(remoteConsole, s); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return ""; + } + // Event change end + ServerCommand serverCommand = new ServerCommand(event.getCommand(), RemoteControlCommandListener.getInstance()); + server.dispatchServerCommand(remoteConsole, serverCommand); + return RemoteControlCommandListener.getInstance().j(); + } + }; + processQueue.add(waitable); + try { + return waitable.get(); + } catch (java.util.concurrent.ExecutionException e) { + throw new RuntimeException("Exception processing rcon command " + s, e.getCause()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // Maintain interrupted state + throw new RuntimeException("Interrupted processing rcon command " + s, e); + } + // CraftBukkit end + } + + public PlayerList getPlayerList() { + return this.aP(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenseBehaviorItem.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenseBehaviorItem.java new file mode 100644 index 0000000..35a3ff8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenseBehaviorItem.java @@ -0,0 +1,104 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +// CraftBukkit end + +public class DispenseBehaviorItem implements IDispenseBehavior { + + public DispenseBehaviorItem() {} + + public final ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) { + ItemStack itemstack1 = this.b(isourceblock, itemstack); + + this.a(isourceblock); + this.a(isourceblock, BlockDispenser.b(isourceblock.f())); + return itemstack1; + } + + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + IPosition iposition = BlockDispenser.a(isourceblock); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + + // CraftBukkit start + if (!a(isourceblock.getWorld(), itemstack1, 6, enumdirection, isourceblock)) { + itemstack.count++; + } + // CraftBukkit end + return itemstack; + } + + // CraftBukkit start - void -> boolean return, IPosition -> ISourceBlock last argument + public static boolean a(World world, ItemStack itemstack, int i, EnumDirection enumdirection, ISourceBlock isourceblock) { + IPosition iposition = BlockDispenser.a(isourceblock); + // CraftBukkit end + double d0 = iposition.getX(); + double d1 = iposition.getY(); + double d2 = iposition.getZ(); + + if (enumdirection.k() == EnumDirection.EnumAxis.Y) { + d1 -= 0.125D; + } else { + d1 -= 0.15625D; + } + + EntityItem entityitem = new EntityItem(world, d0, d1, d2, itemstack); + double d3 = world.random.nextDouble() * 0.1D + 0.2D; + + entityitem.motX = (double) enumdirection.getAdjacentX() * d3; + entityitem.motY = 0.20000000298023224D; + entityitem.motZ = (double) enumdirection.getAdjacentZ() * d3; + entityitem.motX += world.random.nextGaussian() * 0.007499999832361937D * (double) i; + entityitem.motY += world.random.nextGaussian() * 0.007499999832361937D * (double) i; + entityitem.motZ += world.random.nextGaussian() * 0.007499999832361937D * (double) i; + + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(entityitem.motX, entityitem.motY, entityitem.motZ)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return false; + } + + entityitem.setItemStack(CraftItemStack.asNMSCopy(event.getItem())); + entityitem.motX = event.getVelocity().getX(); + entityitem.motY = event.getVelocity().getY(); + entityitem.motZ = event.getVelocity().getZ(); + + if (!event.getItem().getType().equals(craftItem.getType())) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior.getClass() != DispenseBehaviorItem.class) { + idispensebehavior.a(isourceblock, eventStack); + } else { + world.addEntity(entityitem); + } + return false; + } + + world.addEntity(entityitem); + + return true; + // CraftBukkit end + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } + + protected void a(ISourceBlock isourceblock, EnumDirection enumdirection) { + isourceblock.getWorld().triggerEffect(2000, isourceblock.getBlockPosition(), this.a(enumdirection)); + } + + private int a(EnumDirection enumdirection) { + return enumdirection.getAdjacentX() + 1 + (enumdirection.getAdjacentZ() + 1) * 3; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenseBehaviorProjectile.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenseBehaviorProjectile.java new file mode 100644 index 0000000..5cb0363 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenseBehaviorProjectile.java @@ -0,0 +1,66 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +// CraftBukkit end + +public abstract class DispenseBehaviorProjectile extends DispenseBehaviorItem { + + public DispenseBehaviorProjectile() {} + + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + IPosition iposition = BlockDispenser.a(isourceblock); + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + IProjectile iprojectile = this.a(world, iposition); + + // iprojectile.shoot((double) enumdirection.getAdjacentX(), (double) ((float) enumdirection.getAdjacentY() + 0.1F), (double) enumdirection.getAdjacentZ(), this.b(), this.a()); + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) enumdirection.getAdjacentX(), (double) ((float) enumdirection.getAdjacentY() + 0.1F), (double) enumdirection.getAdjacentZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.count++; + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.count++; + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + iprojectile.shoot(event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.getPower(), this.a()); + ((Entity) iprojectile).projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) isourceblock.getTileEntity()); + // CraftBukkit end + world.addEntity((Entity) iprojectile); + // itemstack.a(1); // CraftBukkit - Handled during event processing + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1002, isourceblock.getBlockPosition(), 0); + } + + protected abstract IProjectile a(World world, IPosition iposition); + + protected float a() { + return 6.0F; + } + + protected float getPower() { + return 1.1F; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenserRegistry.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenserRegistry.java new file mode 100644 index 0000000..cc7a1e3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/DispenserRegistry.java @@ -0,0 +1,667 @@ +package net.minecraft.server; + +import com.mojang.authlib.GameProfile; +import java.io.PrintStream; +import java.util.Random; +import java.util.UUID; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +// CraftBukkit end + +public class DispenserRegistry { + + private static final PrintStream a = System.out; + private static boolean b = false; + private static final Logger c = LogManager.getLogger(); + + public static boolean a() { + return DispenserRegistry.b; + } + + static void b() { + BlockDispenser.REGISTRY.a(Items.ARROW, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition) { + EntityArrow entityarrow = new EntityArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); + + entityarrow.fromPlayer = 1; + return entityarrow; + } + }); + BlockDispenser.REGISTRY.a(Items.EGG, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition) { + return new EntityEgg(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } + }); + BlockDispenser.REGISTRY.a(Items.SNOWBALL, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition) { + return new EntitySnowball(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } + }); + BlockDispenser.REGISTRY.a(Items.EXPERIENCE_BOTTLE, new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition) { + return new EntityThrownExpBottle(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } + + protected float a() { + return super.a() * 0.5F; + } + + protected float getPower() { + return super.getPower() * 1.25F; + } + }); + BlockDispenser.REGISTRY.a(Items.POTION, new IDispenseBehavior() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + public ItemStack a(ISourceBlock isourceblock, final ItemStack itemstack) { + return ItemPotion.f(itemstack.getData()) ? (new DispenseBehaviorProjectile() { + protected IProjectile a(World world, IPosition iposition) { + return new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), itemstack.cloneItemStack()); + } + + protected float a() { + return super.a() * 0.5F; + } + + protected float getPower() { + return super.getPower() * 1.25F; + } + }).a(isourceblock, itemstack) : this.b.a(isourceblock, itemstack); + } + }); + BlockDispenser.REGISTRY.a(Items.SPAWN_EGG, new DispenseBehaviorItem() { + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); + double d1 = (double) ((float) isourceblock.getBlockPosition().getY() + 0.2F); + double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); + // Entity entity = ItemMonsterEgg.a(isourceblock.getWorld(), itemstack.getData(), d0, d1, d2); + + // CraftBukkit start + World world = isourceblock.getWorld(); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.count++; + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.count++; + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); + + Entity entity = ItemMonsterEgg.spawnCreature(isourceblock.getWorld(), itemstack.getData(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG); + + if (entity instanceof EntityLiving && itemstack.hasName()) { + ((EntityInsentient) entity).setCustomName(itemstack.getName()); + } + + // itemstack.a(1); // Handled during event processing + // CraftBukkit end + return itemstack; + } + }); + BlockDispenser.REGISTRY.a(Items.FIREWORKS, new DispenseBehaviorItem() { + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); + double d1 = (double) ((float) isourceblock.getBlockPosition().getY() + 0.2F); + double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); + // CraftBukkit start + World world = isourceblock.getWorld(); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.count++; + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.count++; + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); + EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1); + + isourceblock.getWorld().addEntity(entityfireworks); + // itemstack.a(1); // Handled during event processing + // CraftBukkit end + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1002, isourceblock.getBlockPosition(), 0); + } + }); + BlockDispenser.REGISTRY.a(Items.FIRE_CHARGE, new DispenseBehaviorItem() { + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + IPosition iposition = BlockDispenser.a(isourceblock); + double d0 = iposition.getX() + (double) ((float) enumdirection.getAdjacentX() * 0.3F); + double d1 = iposition.getY() + (double) ((float) enumdirection.getAdjacentY() * 0.3F); + double d2 = iposition.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 0.3F); + World world = isourceblock.getWorld(); + Random random = world.random; + double d3 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentX(); + double d4 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentY(); + double d5 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentZ(); + + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d3, d4, d5)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.count++; + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.count++; + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + EntitySmallFireball entitysmallfireball = new EntitySmallFireball(world, d0, d1, d2, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); + entitysmallfireball.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) isourceblock.getTileEntity()); + + world.addEntity(entitysmallfireball); + // itemstack.a(1); // Handled during event processing + // CraftBukkit end + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1009, isourceblock.getBlockPosition(), 0); + } + }); + BlockDispenser.REGISTRY.a(Items.BOAT, new DispenseBehaviorItem() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + World world = isourceblock.getWorld(); + double d0 = isourceblock.getX() + (double) ((float) enumdirection.getAdjacentX() * 1.125F); + double d1 = isourceblock.getY() + (double) ((float) enumdirection.getAdjacentY() * 1.125F); + double d2 = isourceblock.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 1.125F); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + Material material = world.getType(blockposition).getBlock().getMaterial(); + double d3; + + if (Material.WATER.equals(material)) { + d3 = 1.0D; + } else { + if (!Material.AIR.equals(material) || !Material.WATER.equals(world.getType(blockposition.down()).getBlock().getMaterial())) { + return this.b.a(isourceblock, itemstack); + } + + d3 = 0.0D; + } + + // EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.count++; + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.count++; + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + EntityBoat entityboat = new EntityBoat(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); + // CraftBukkit end + + world.addEntity(entityboat); + // itemstack.a(1); // CraftBukkit - handled during event processing + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } + }); + DispenseBehaviorItem dispensebehavioritem = new DispenseBehaviorItem() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + ItemBucket itembucket = (ItemBucket) itemstack.getItem(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + + // CraftBukkit start + World world = isourceblock.getWorld(); + int x = blockposition.getX(); + int y = blockposition.getY(); + int z = blockposition.getZ(); + if (world.isEmpty(blockposition) || !world.getType(blockposition).getBlock().getMaterial().isBuildable()) { + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); + } + // CraftBukkit end + + if (itembucket.a(isourceblock.getWorld(), blockposition)) { + // CraftBukkit start - Handle stacked buckets + Item item = Items.BUCKET; + if (--itemstack.count == 0) { + itemstack.setItem(Items.BUCKET); + itemstack.count = 1; + } else if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { + this.b.a(isourceblock, new ItemStack(item)); + } + // CraftBukkit end + return itemstack; + } else { + return this.b.a(isourceblock, itemstack); + } + } + }; + + BlockDispenser.REGISTRY.a(Items.LAVA_BUCKET, dispensebehavioritem); + BlockDispenser.REGISTRY.a(Items.WATER_BUCKET, dispensebehavioritem); + BlockDispenser.REGISTRY.a(Items.BUCKET, new DispenseBehaviorItem() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + Material material = block.getMaterial(); + Item item; + + if (Material.WATER.equals(material) && block instanceof BlockFluids && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0) { + item = Items.WATER_BUCKET; + } else { + if (!Material.LAVA.equals(material) || !(block instanceof BlockFluids) || ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() != 0) { + return super.b(isourceblock, itemstack); + } + + item = Items.LAVA_BUCKET; + } + + // CraftBukkit start + org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + world.setAir(blockposition); + if (--itemstack.count == 0) { + itemstack.setItem(item); + itemstack.count = 1; + } else if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { + this.b.a(isourceblock, new ItemStack(item)); + } + + return itemstack; + } + }); + BlockDispenser.REGISTRY.a(Items.FLINT_AND_STEEL, new DispenseBehaviorItem() { + private boolean b = true; + + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + if (world.isEmpty(blockposition)) { + // CraftBukkit start - Ignition by dispensing flint and steel + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()).isCancelled()) { + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + if (itemstack.isDamaged(1, world.random)) { + itemstack.count = 0; + } + } + // CraftBukkit end + } else if (world.getType(blockposition).getBlock() == Blocks.TNT) { + Blocks.TNT.postBreak(world, blockposition, Blocks.TNT.getBlockData().set(BlockTNT.EXPLODE, Boolean.valueOf(true))); + world.setAir(blockposition); + } else { + this.b = false; + } + + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + if (this.b) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } else { + isourceblock.getWorld().triggerEffect(1001, isourceblock.getBlockPosition(), 0); + } + + } + }); + BlockDispenser.REGISTRY.a(Items.DYE, new DispenseBehaviorItem() { + private boolean b = true; + + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + if (EnumColor.WHITE == EnumColor.fromInvColorIndex(itemstack.getData())) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); // Spigot + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + if (ItemDye.a(itemstack, world, blockposition)) { + if (!world.isClientSide) { + world.triggerEffect(2005, blockposition, 0); + } + } else { + this.b = false; + } + + return itemstack; + } else { + return super.b(isourceblock, itemstack); + } + } + + protected void a(ISourceBlock isourceblock) { + if (this.b) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } else { + isourceblock.getWorld().triggerEffect(1001, isourceblock.getBlockPosition(), 0); + } + + } + }); + BlockDispenser.REGISTRY.a(Item.getItemOf(Blocks.TNT), new DispenseBehaviorItem() { + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + // EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); + + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + // PaperSpigot start - Fix cannons + double y = blockposition.getY(); + if (!world.paperSpigotConfig.fixCannons) y += 0.5; + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX() + 0.5, y, blockposition.getZ() + 0.5)); + // PaperSpigot end + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.count++; + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.count++; + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(block.getLocation(), world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLiving) null); // PaperSpigot + // CraftBukkit end + + world.addEntity(entitytntprimed); + world.makeSound(entitytntprimed, "game.tnt.primed", 1.0F, 1.0F); + // --itemstack.count; // CraftBukkit - handled above + return itemstack; + } + }); + BlockDispenser.REGISTRY.a(Items.SKULL, new DispenseBehaviorItem() { + private boolean b = true; + + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + BlockSkull blockskull = Blocks.SKULL; + + if (world.isEmpty(blockposition) && blockskull.b(world, blockposition, itemstack)) { + if (!world.isClientSide) { + world.setTypeAndData(blockposition, blockskull.getBlockData().set(BlockSkull.FACING, EnumDirection.UP), 3); + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntitySkull) { + if (itemstack.getData() == 3) { + GameProfile gameprofile = null; + + if (itemstack.hasTag()) { + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound.hasKeyOfType("SkullOwner", 10)) { + gameprofile = GameProfileSerializer.deserialize(nbttagcompound.getCompound("SkullOwner")); + } else if (nbttagcompound.hasKeyOfType("SkullOwner", 8)) { + String s = nbttagcompound.getString("SkullOwner"); + + if (!UtilColor.b(s)) { + gameprofile = new GameProfile((UUID) null, s); + } + } + } + + ((TileEntitySkull) tileentity).setGameProfile(gameprofile); + } else { + ((TileEntitySkull) tileentity).setSkullType(itemstack.getData()); + } + + ((TileEntitySkull) tileentity).setRotation(enumdirection.opposite().b() * 4); + Blocks.SKULL.a(world, blockposition, (TileEntitySkull) tileentity); + } + + --itemstack.count; + } + } else { + this.b = false; + } + + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + if (this.b) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } else { + isourceblock.getWorld().triggerEffect(1001, isourceblock.getBlockPosition(), 0); + } + + } + }); + BlockDispenser.REGISTRY.a(Item.getItemOf(Blocks.PUMPKIN), new DispenseBehaviorItem() { + private boolean b = true; + + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + World world = isourceblock.getWorld(); + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + BlockPumpkin blockpumpkin = (BlockPumpkin) Blocks.PUMPKIN; + + if (world.isEmpty(blockposition) && blockpumpkin.e(world, blockposition)) { + if (!world.isClientSide) { + world.setTypeAndData(blockposition, blockpumpkin.getBlockData(), 3); + } + + --itemstack.count; + } else { + this.b = false; + } + + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + if (this.b) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } else { + isourceblock.getWorld().triggerEffect(1001, isourceblock.getBlockPosition(), 0); + } + + } + }); + } + + public static void c() { + if (!DispenserRegistry.b) { + DispenserRegistry.b = true; + if (DispenserRegistry.c.isDebugEnabled()) { + d(); + } + + Block.S(); + BlockFire.l(); + Item.t(); + StatisticList.a(); + b(); + } + } + + private static void d() { + System.setErr(new RedirectStream("STDERR", System.err)); + System.setOut(new RedirectStream("STDOUT", DispenserRegistry.a)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EULA.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EULA.java new file mode 100644 index 0000000..6ede27d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EULA.java @@ -0,0 +1,63 @@ +package net.minecraft.server; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.Properties; +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class EULA { + + private static final Logger a = LogManager.getLogger(); + private final File b; + private final boolean c; + + public EULA(File file) { + this.b = file; + this.c = this.a(file); + } + + private boolean a(File file) { + FileInputStream fileinputstream = null; + boolean flag = false; + + try { + Properties properties = new Properties(); + + fileinputstream = new FileInputStream(file); + properties.load(fileinputstream); + flag = Boolean.parseBoolean(properties.getProperty("eula", "false")); + } catch (Exception exception) { + EULA.a.warn("Failed to load " + file); + this.b(); + } finally { + IOUtils.closeQuietly(fileinputstream); + } + + return flag; + } + + public boolean a() { + return this.c; + } + + public void b() { + FileOutputStream fileoutputstream = null; + + try { + Properties properties = new Properties(); + + fileoutputstream = new FileOutputStream(this.b); + properties.setProperty("eula", "false"); + properties.store(fileoutputstream, "By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula)." + + "\nand also agreeing that tacos are tasty."); // TacoSpigot - fix lag + } catch (Exception exception) { + EULA.a.warn("Failed to save " + this.b, exception); + } finally { + IOUtils.closeQuietly(fileoutputstream); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Enchantment.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Enchantment.java new file mode 100644 index 0000000..0f61eec --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Enchantment.java @@ -0,0 +1,141 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; + +public abstract class Enchantment { + + // CraftBukkit - update CraftEnchant.getName(i) if this changes + private static final Enchantment[] byId = new Enchantment[256]; + public static final Enchantment[] b; + private static final Map E = Maps.newHashMap(); + public static final Enchantment PROTECTION_ENVIRONMENTAL = new EnchantmentProtection(0, new MinecraftKey("protection"), 10, 0); + public static final Enchantment PROTECTION_FIRE = new EnchantmentProtection(1, new MinecraftKey("fire_protection"), 5, 1); + public static final Enchantment PROTECTION_FALL = new EnchantmentProtection(2, new MinecraftKey("feather_falling"), 5, 2); + public static final Enchantment PROTECTION_EXPLOSIONS = new EnchantmentProtection(3, new MinecraftKey("blast_protection"), 2, 3); + public static final Enchantment PROTECTION_PROJECTILE = new EnchantmentProtection(4, new MinecraftKey("projectile_protection"), 5, 4); + public static final Enchantment OXYGEN = new EnchantmentOxygen(5, new MinecraftKey("respiration"), 2); + public static final Enchantment WATER_WORKER = new EnchantmentWaterWorker(6, new MinecraftKey("aqua_affinity"), 2); + public static final Enchantment THORNS = new EnchantmentThorns(7, new MinecraftKey("thorns"), 1); + public static final Enchantment DEPTH_STRIDER = new EnchantmentDepthStrider(8, new MinecraftKey("depth_strider"), 2); + public static final Enchantment DAMAGE_ALL = new EnchantmentWeaponDamage(16, new MinecraftKey("sharpness"), 10, 0); + public static final Enchantment DAMAGE_UNDEAD = new EnchantmentWeaponDamage(17, new MinecraftKey("smite"), 5, 1); + public static final Enchantment DAMAGE_ARTHROPODS = new EnchantmentWeaponDamage(18, new MinecraftKey("bane_of_arthropods"), 5, 2); + public static final Enchantment KNOCKBACK = new EnchantmentKnockback(19, new MinecraftKey("knockback"), 5); + public static final Enchantment FIRE_ASPECT = new EnchantmentFire(20, new MinecraftKey("fire_aspect"), 2); + public static final Enchantment LOOT_BONUS_MOBS = new EnchantmentLootBonus(21, new MinecraftKey("looting"), 2, EnchantmentSlotType.WEAPON); + public static final Enchantment DIG_SPEED = new EnchantmentDigging(32, new MinecraftKey("efficiency"), 10); + public static final Enchantment SILK_TOUCH = new EnchantmentSilkTouch(33, new MinecraftKey("silk_touch"), 1); + public static final Enchantment DURABILITY = new EnchantmentDurability(34, new MinecraftKey("unbreaking"), 5); + public static final Enchantment LOOT_BONUS_BLOCKS = new EnchantmentLootBonus(35, new MinecraftKey("fortune"), 2, EnchantmentSlotType.DIGGER); + public static final Enchantment ARROW_DAMAGE = new EnchantmentArrowDamage(48, new MinecraftKey("power"), 10); + public static final Enchantment ARROW_KNOCKBACK = new EnchantmentArrowKnockback(49, new MinecraftKey("punch"), 2); + public static final Enchantment ARROW_FIRE = new EnchantmentFlameArrows(50, new MinecraftKey("flame"), 2); + public static final Enchantment ARROW_INFINITE = new EnchantmentInfiniteArrows(51, new MinecraftKey("infinity"), 1); + public static final Enchantment LUCK = new EnchantmentLootBonus(61, new MinecraftKey("luck_of_the_sea"), 2, EnchantmentSlotType.FISHING_ROD); + public static final Enchantment LURE = new EnchantmentLure(62, new MinecraftKey("lure"), 2, EnchantmentSlotType.FISHING_ROD); + public final int id; + private final int weight; + public EnchantmentSlotType slot; + protected String name; + + public static Enchantment getById(int i) { + return i >= 0 && i < Enchantment.byId.length ? Enchantment.byId[i] : null; + } + + protected Enchantment(int i, MinecraftKey minecraftkey, int j, EnchantmentSlotType enchantmentslottype) { + this.id = i; + this.weight = j; + this.slot = enchantmentslottype; + if (Enchantment.byId[i] != null) { + throw new IllegalArgumentException("Duplicate enchantment id!"); + } else { + Enchantment.byId[i] = this; + Enchantment.E.put(minecraftkey, this); + } + + org.bukkit.enchantments.Enchantment.registerEnchantment(new org.bukkit.craftbukkit.enchantments.CraftEnchantment(this)); // CraftBukkit + } + + public static Enchantment getByName(String s) { + return (Enchantment) Enchantment.E.get(new MinecraftKey(s)); + } + + public static Set getEffects() { + return Enchantment.E.keySet(); + } + + public int getRandomWeight() { + return this.weight; + } + + public int getStartLevel() { + return 1; + } + + public int getMaxLevel() { + return 1; + } + + public int a(int i) { + return 1 + i * 10; + } + + public int b(int i) { + return this.a(i) + 5; + } + + public int a(int i, DamageSource damagesource) { + return 0; + } + + public float a(int i, EnumMonsterType enummonstertype) { + return 0.0F; + } + + public boolean a(Enchantment enchantment) { + return this != enchantment; + } + + public Enchantment c(String s) { + this.name = s; + return this; + } + + public String a() { + return "enchantment." + this.name; + } + + public String d(int i) { + String s = LocaleI18n.get(this.a()); + + return s + " " + LocaleI18n.get("enchantment.level." + i); + } + + public boolean canEnchant(ItemStack itemstack) { + return this.slot.canEnchant(itemstack.getItem()); + } + + public void a(EntityLiving entityliving, Entity entity, int i) {} + + public void b(EntityLiving entityliving, Entity entity, int i) {} + + static { + ArrayList arraylist = Lists.newArrayList(); + Enchantment[] aenchantment = Enchantment.byId; + int i = aenchantment.length; + + for (int j = 0; j < i; ++j) { + Enchantment enchantment = aenchantment[j]; + + if (enchantment != null) { + arraylist.add(enchantment); + } + } + + b = (Enchantment[]) arraylist.toArray(new Enchantment[arraylist.size()]); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EnchantmentManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EnchantmentManager.java new file mode 100644 index 0000000..9865681 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EnchantmentManager.java @@ -0,0 +1,450 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +public class EnchantmentManager { + + private static final Random a = new Random(); + private static final EnchantmentManager.EnchantmentModifierProtection b = new EnchantmentManager.EnchantmentModifierProtection((EnchantmentManager.SyntheticClass_1) null); + private static final EnchantmentManager.EnchantmentModifierDamage c = new EnchantmentManager.EnchantmentModifierDamage((EnchantmentManager.SyntheticClass_1) null); + private static final EnchantmentManager.EnchantmentModifierThorns d = new EnchantmentManager.EnchantmentModifierThorns((EnchantmentManager.SyntheticClass_1) null); + private static final EnchantmentManager.EnchantmentModifierArthropods e = new EnchantmentManager.EnchantmentModifierArthropods((EnchantmentManager.SyntheticClass_1) null); + + public static int getEnchantmentLevel(int i, ItemStack itemstack) { + if (itemstack == null) { + return 0; + } else { + NBTTagList nbttaglist = itemstack.getEnchantments(); + + if (nbttaglist == null) { + return 0; + } else { + for (int j = 0; j < nbttaglist.size(); ++j) { + short short0 = nbttaglist.get(j).getShort("id"); + short short1 = nbttaglist.get(j).getShort("lvl"); + + if (short0 == i) { + return short1; + } + } + + return 0; + } + } + } + + public static Map a(ItemStack itemstack) { + LinkedHashMap linkedhashmap = Maps.newLinkedHashMap(); + NBTTagList nbttaglist = itemstack.getItem() == Items.ENCHANTED_BOOK ? Items.ENCHANTED_BOOK.h(itemstack) : itemstack.getEnchantments(); + + if (nbttaglist != null) { + for (int i = 0; i < nbttaglist.size(); ++i) { + short short0 = nbttaglist.get(i).getShort("id"); + short short1 = nbttaglist.get(i).getShort("lvl"); + + linkedhashmap.put(Integer.valueOf(short0), Integer.valueOf(short1)); + } + } + + return linkedhashmap; + } + + public static void a(Map map, ItemStack itemstack) { + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = map.keySet().iterator(); + + while (iterator.hasNext()) { + int i = ((Integer) iterator.next()).intValue(); + Enchantment enchantment = Enchantment.getById(i); + + if (enchantment != null) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + nbttagcompound.setShort("id", (short) i); + nbttagcompound.setShort("lvl", (short) ((Integer) map.get(Integer.valueOf(i))).intValue()); + nbttaglist.add(nbttagcompound); + if (itemstack.getItem() == Items.ENCHANTED_BOOK) { + Items.ENCHANTED_BOOK.a(itemstack, new WeightedRandomEnchant(enchantment, ((Integer) map.get(Integer.valueOf(i))).intValue())); + } + } + } + + if (nbttaglist.size() > 0) { + if (itemstack.getItem() != Items.ENCHANTED_BOOK) { + itemstack.a("ench", (NBTBase) nbttaglist); + } + } else if (itemstack.hasTag()) { + itemstack.getTag().remove("ench"); + } + + } + + public static int a(int i, ItemStack[] aitemstack) { + if (aitemstack == null) { + return 0; + } else { + int j = 0; + ItemStack[] aitemstack1 = aitemstack; + int k = aitemstack.length; + + for (int l = 0; l < k; ++l) { + ItemStack itemstack = aitemstack1[l]; + int i1 = getEnchantmentLevel(i, itemstack); + + if (i1 > j) { + j = i1; + } + } + + return j; + } + } + + private static void a(EnchantmentManager.EnchantmentModifier enchantmentmanager_enchantmentmodifier, ItemStack itemstack) { + if (itemstack != null) { + NBTTagList nbttaglist = itemstack.getEnchantments(); + + if (nbttaglist != null) { + for (int i = 0; i < nbttaglist.size(); ++i) { + short short0 = nbttaglist.get(i).getShort("id"); + short short1 = nbttaglist.get(i).getShort("lvl"); + + if (Enchantment.getById(short0) != null) { + enchantmentmanager_enchantmentmodifier.a(Enchantment.getById(short0), short1); + } + } + + } + } + } + + private static void a(EnchantmentManager.EnchantmentModifier enchantmentmanager_enchantmentmodifier, ItemStack[] aitemstack) { + ItemStack[] aitemstack1 = aitemstack; + int i = aitemstack.length; + + for (int j = 0; j < i; ++j) { + ItemStack itemstack = aitemstack1[j]; + + a(enchantmentmanager_enchantmentmodifier, itemstack); + } + + } + + public static int a(ItemStack[] aitemstack, DamageSource damagesource) { + EnchantmentManager.b.a = 0; + EnchantmentManager.b.b = damagesource; + a((EnchantmentManager.EnchantmentModifier) EnchantmentManager.b, aitemstack); + if (EnchantmentManager.b.a > 25) { + EnchantmentManager.b.a = 25; + } else if (EnchantmentManager.b.a < 0) { + EnchantmentManager.b.a = 0; + } + + return (EnchantmentManager.b.a + 1 >> 1) + EnchantmentManager.a.nextInt((EnchantmentManager.b.a >> 1) + 1); + } + + public static float a(ItemStack itemstack, EnumMonsterType enummonstertype) { + EnchantmentManager.c.a = 0.0F; + EnchantmentManager.c.b = enummonstertype; + a((EnchantmentManager.EnchantmentModifier) EnchantmentManager.c, itemstack); + return EnchantmentManager.c.a; + } + + public static void a(EntityLiving entityliving, Entity entity) { + EnchantmentManager.d.b = entity; + EnchantmentManager.d.a = entityliving; + if (entityliving != null) { + a((EnchantmentManager.EnchantmentModifier) EnchantmentManager.d, entityliving.getEquipment()); + } + + if (entity instanceof EntityHuman) { + a((EnchantmentManager.EnchantmentModifier) EnchantmentManager.d, entityliving.bA()); + } + + } + + public static void b(EntityLiving entityliving, Entity entity) { + EnchantmentManager.e.a = entityliving; + EnchantmentManager.e.b = entity; + if (entityliving != null) { + a((EnchantmentManager.EnchantmentModifier) EnchantmentManager.e, entityliving.getEquipment()); + } + + if (entityliving instanceof EntityHuman) { + a((EnchantmentManager.EnchantmentModifier) EnchantmentManager.e, entityliving.bA()); + } + + } + + public static int a(EntityLiving entityliving) { + return getEnchantmentLevel(Enchantment.KNOCKBACK.id, entityliving.bA()); + } + + public static int getFireAspectEnchantmentLevel(EntityLiving entityliving) { + return getEnchantmentLevel(Enchantment.FIRE_ASPECT.id, entityliving.bA()); + } + + public static int getOxygenEnchantmentLevel(Entity entity) { + return a(Enchantment.OXYGEN.id, entity.getEquipment()); + } + + public static int b(Entity entity) { + return a(Enchantment.DEPTH_STRIDER.id, entity.getEquipment()); + } + + public static int getDigSpeedEnchantmentLevel(EntityLiving entityliving) { + return getEnchantmentLevel(Enchantment.DIG_SPEED.id, entityliving.bA()); + } + + public static boolean hasSilkTouchEnchantment(EntityLiving entityliving) { + return getEnchantmentLevel(Enchantment.SILK_TOUCH.id, entityliving.bA()) > 0; + } + + public static int getBonusBlockLootEnchantmentLevel(EntityLiving entityliving) { + return getEnchantmentLevel(Enchantment.LOOT_BONUS_BLOCKS.id, entityliving.bA()); + } + + public static int g(EntityLiving entityliving) { + return getEnchantmentLevel(Enchantment.LUCK.id, entityliving.bA()); + } + + public static int h(EntityLiving entityliving) { + return getEnchantmentLevel(Enchantment.LURE.id, entityliving.bA()); + } + + public static int getBonusMonsterLootEnchantmentLevel(EntityLiving entityliving) { + return getEnchantmentLevel(Enchantment.LOOT_BONUS_MOBS.id, entityliving.bA()); + } + + public static boolean j(EntityLiving entityliving) { + return a(Enchantment.WATER_WORKER.id, entityliving.getEquipment()) > 0; + } + + public static ItemStack a(Enchantment enchantment, EntityLiving entityliving) { + ItemStack[] aitemstack = entityliving.getEquipment(); + int i = aitemstack.length; + + for (int j = 0; j < i; ++j) { + ItemStack itemstack = aitemstack[j]; + + if (itemstack != null && getEnchantmentLevel(enchantment.id, itemstack) > 0) { + return itemstack; + } + } + + return null; + } + + public static int a(Random random, int i, int j, ItemStack itemstack) { + Item item = itemstack.getItem(); + int k = item.b(); + + if (k <= 0) { + return 0; + } else { + if (j > 15) { + j = 15; + } + + int l = random.nextInt(8) + 1 + (j >> 1) + random.nextInt(j + 1); + + return i == 0 ? Math.max(l / 3, 1) : (i == 1 ? l * 2 / 3 + 1 : Math.max(l, j * 2)); + } + } + + public static ItemStack a(Random random, ItemStack itemstack, int i) { + List list = b(random, itemstack, i); + boolean flag = itemstack.getItem() == Items.BOOK; + + if (flag) { + itemstack.setItem(Items.ENCHANTED_BOOK); + } + + if (list != null) { + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + WeightedRandomEnchant weightedrandomenchant = (WeightedRandomEnchant) iterator.next(); + + if (flag) { + Items.ENCHANTED_BOOK.a(itemstack, weightedrandomenchant); + } else { + itemstack.addEnchantment(weightedrandomenchant.enchantment, weightedrandomenchant.level); + } + } + } + + return itemstack; + } + + public static List b(Random random, ItemStack itemstack, int i) { + Item item = itemstack.getItem(); + int j = item.b(); + + if (j <= 0) { + return null; + } else { + j /= 2; + j = 1 + random.nextInt((j >> 1) + 1) + random.nextInt((j >> 1) + 1); + int k = j + i; + float f = (random.nextFloat() + random.nextFloat() - 1.0F) * 0.15F; + int l = (int) ((float) k * (1.0F + f) + 0.5F); + + if (l < 1) { + l = 1; + } + + ArrayList arraylist = null; + Map map = b(l, itemstack); + + if (map != null && !map.isEmpty()) { + WeightedRandomEnchant weightedrandomenchant = (WeightedRandomEnchant) WeightedRandom.a(random, map.values()); + + if (weightedrandomenchant != null) { + arraylist = Lists.newArrayList(); + arraylist.add(weightedrandomenchant); + + for (int i1 = l; random.nextInt(50) <= i1; i1 >>= 1) { + Iterator iterator = map.keySet().iterator(); + + while (iterator.hasNext()) { + Integer integer = (Integer) iterator.next(); + boolean flag = true; + Iterator iterator1 = arraylist.iterator(); + + while (true) { + if (iterator1.hasNext()) { + WeightedRandomEnchant weightedrandomenchant1 = (WeightedRandomEnchant) iterator1.next(); + + if (weightedrandomenchant1.enchantment.a(Enchantment.getById(integer.intValue()))) { + continue; + } + + flag = false; + } + + if (!flag) { + iterator.remove(); + } + break; + } + } + + if (!map.isEmpty()) { + WeightedRandomEnchant weightedrandomenchant2 = (WeightedRandomEnchant) WeightedRandom.a(random, map.values()); + + arraylist.add(weightedrandomenchant2); + } + } + } + } + + return arraylist; + } + } + + public static Map b(int i, ItemStack itemstack) { + Item item = itemstack.getItem(); + HashMap hashmap = null; + boolean flag = itemstack.getItem() == Items.BOOK; + Enchantment[] aenchantment = Enchantment.b; + int j = aenchantment.length; + + for (int k = 0; k < j; ++k) { + Enchantment enchantment = aenchantment[k]; + + if (enchantment != null && (enchantment.slot.canEnchant(item) || flag)) { + for (int l = enchantment.getStartLevel(); l <= enchantment.getMaxLevel(); ++l) { + if (i >= enchantment.a(l) && i <= enchantment.b(l)) { + if (hashmap == null) { + hashmap = Maps.newHashMap(); + } + + hashmap.put(Integer.valueOf(enchantment.id), new WeightedRandomEnchant(enchantment, l)); + } + } + } + } + + return hashmap; + } + + static class SyntheticClass_1 { } + + static final class EnchantmentModifierArthropods implements EnchantmentManager.EnchantmentModifier { + + public EntityLiving a; + public Entity b; + + private EnchantmentModifierArthropods() {} + + public void a(Enchantment enchantment, int i) { + enchantment.a(this.a, this.b, i); + } + + EnchantmentModifierArthropods(EnchantmentManager.SyntheticClass_1 enchantmentmanager_syntheticclass_1) { + this(); + } + } + + static final class EnchantmentModifierThorns implements EnchantmentManager.EnchantmentModifier { + + public EntityLiving a; + public Entity b; + + private EnchantmentModifierThorns() {} + + public void a(Enchantment enchantment, int i) { + enchantment.b(this.a, this.b, i); + } + + EnchantmentModifierThorns(EnchantmentManager.SyntheticClass_1 enchantmentmanager_syntheticclass_1) { + this(); + } + } + + static final class EnchantmentModifierDamage implements EnchantmentManager.EnchantmentModifier { + + public float a; + public EnumMonsterType b; + + private EnchantmentModifierDamage() {} + + public void a(Enchantment enchantment, int i) { + this.a += enchantment.a(i, this.b); + } + + EnchantmentModifierDamage(EnchantmentManager.SyntheticClass_1 enchantmentmanager_syntheticclass_1) { + this(); + } + } + + static final class EnchantmentModifierProtection implements EnchantmentManager.EnchantmentModifier { + + public int a; + public DamageSource b; + + private EnchantmentModifierProtection() {} + + public void a(Enchantment enchantment, int i) { + this.a += enchantment.a(i, this.b); + } + + EnchantmentModifierProtection(EnchantmentManager.SyntheticClass_1 enchantmentmanager_syntheticclass_1) { + this(); + } + } + + interface EnchantmentModifier { + + void a(Enchantment enchantment, int i); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EnchantmentThorns.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EnchantmentThorns.java new file mode 100644 index 0000000..913e5e4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EnchantmentThorns.java @@ -0,0 +1,54 @@ +package net.minecraft.server; + +import java.util.Random; + +public class EnchantmentThorns extends Enchantment { + + public EnchantmentThorns(int i, MinecraftKey minecraftkey, int j) { + super(i, minecraftkey, j, EnchantmentSlotType.ARMOR_TORSO); + this.c("thorns"); + } + + public int a(int i) { + return 10 + 20 * (i - 1); + } + + public int b(int i) { + return super.a(i) + 50; + } + + public int getMaxLevel() { + return 3; + } + + public boolean canEnchant(ItemStack itemstack) { + return itemstack.getItem() instanceof ItemArmor ? true : super.canEnchant(itemstack); + } + + public void b(EntityLiving entityliving, Entity entity, int i) { + Random random = entityliving.bc(); + ItemStack itemstack = EnchantmentManager.a(Enchantment.THORNS, entityliving); + + if (entity != null && a(i, random)) { // CraftBukkit + if (entity != null) { + entity.damageEntity(DamageSource.a(entityliving), (float) b(i, random)); + entity.makeSound("damage.thorns", 0.5F, 1.0F); + } + + if (itemstack != null) { + itemstack.damage(3, entityliving); + } + } else if (itemstack != null) { + itemstack.damage(1, entityliving); + } + + } + + public static boolean a(int i, Random random) { + return i <= 0 ? false : random.nextFloat() < 0.15F * (float) i; + } + + public static int b(int i, Random random) { + return i > 10 ? i - 10 : 1 + random.nextInt(4); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Entity.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Entity.java new file mode 100644 index 0000000..8e75f17 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Entity.java @@ -0,0 +1,2319 @@ +package net.minecraft.server; + +import co.aikar.timings.SpigotTimings; +import co.aikar.timings.Timing; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import me.levansj01.mythicspigot.kb.KBProfile; +import me.levansj01.mythicspigot.kb.KBSet; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.TravelAgent; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.Hanging; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Painting; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.entity.EntityCombustByEntityEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.hanging.HangingBreakByEntityEvent; +import org.bukkit.event.painting.PaintingBreakByEntityEvent; +import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; +import org.bukkit.event.vehicle.VehicleEnterEvent; +import org.bukkit.event.vehicle.VehicleExitEvent; +import org.bukkit.plugin.PluginManager; +import org.spigotmc.event.entity.EntityDismountEvent; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.logging.Level; + +// CraftBukkit start +// CraftBukkit end +// PaperSpigot start +// PaperSpigot end + +public abstract class Entity implements ICommandListener { + + // CraftBukkit start + private static final int CURRENT_LEVEL = 2; + static boolean isLevelAtLeast(NBTTagCompound tag, int level) { + return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level; + } + // CraftBukikt end + + private static final AxisAlignedBB a = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 0.0D, 0.0D, 0.0D); + private static int entityCount; + private int id; + public double j; + public boolean k; + public Entity passenger; + public Entity vehicle; + public boolean attachedToPlayer; + public World world; + public double lastX; + public double lastY; + public double lastZ; + public double locX; + public double locY; + public double locZ; + public double motX; + public double motY; + public double motZ; + public float yaw; + public float pitch; + public float lastYaw; + public float lastPitch; + private AxisAlignedBB boundingBox; + public boolean onGround; + public boolean positionChanged; + public boolean E; + public boolean F; + public boolean velocityChanged; + protected boolean H; + private boolean g; + public boolean dead; + public float width; + public float length; + public float L; + public float M; + public float N; + public float fallDistance; + private int h; + public double P; + public double Q; + public double R; + public float S; + public boolean noclip; + public float U; + protected Random random; + public int ticksLived; + public int maxFireTicks; + public int fireTicks; + public boolean inWater; // Spigot - protected -> public // PAIL + public int noDamageTicks; + protected boolean justCreated; + protected boolean fireProof; + protected DataWatcher datawatcher; + private double ar; + private double as; + public boolean ad; + // PaperSpigot start - EAR: Fix bug with teleporting entities + public boolean isAddedToChunk() { + int chunkX = MathHelper.floor(locX / 16.0D); + int chunkY = MathHelper.floor(locY / 16.0D); + int chunkZ = MathHelper.floor(locZ / 16.0D); + + return ad && getChunkX() == chunkX && getChunkY() == chunkY || getChunkZ() == chunkZ; + } + public int ae; public int getChunkX() { return ae; } // PAIL + public int af; public int getChunkY() { return af; } // PAIL + public int ag; public int getChunkZ() { return ag; } // PAIL + // PaperSpigot end + public boolean ah; + public boolean ai; + public int portalCooldown; + protected boolean ak; + protected int al; + public int dimension; + protected BlockPosition an; + protected Vec3D ao; + protected EnumDirection ap; + private boolean invulnerable; + protected UUID uniqueID; + private final CommandObjectiveExecutor au; + public boolean valid; // CraftBukkit + public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only + public boolean forceExplosionKnockback; // CraftBukkit - SPIGOT-949 + public boolean inUnloadedChunk = false; // PaperSpigot - Remove entities in unloaded chunks + public boolean loadChunks = false; // PaperSpigot - Entities can load chunks they move through and keep them loaded + + // Spigot start + public Timing tickTimer = SpigotTimings.getEntityTimings(this); // Spigot + public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); + public final boolean defaultActivationState; + public long activatedTick = Integer.MIN_VALUE; + public boolean fromMobSpawner; + public void inactiveTick() { } + // Spigot end + + public int getId() { + return this.id; + } + + public void d(int i) { + this.id = i; + } + + public void G() { + this.die(); + } + + // Mythic - Vanilla KB Profile for all entities by default + public KBProfile getKBProfile() { + return MythicCore.getCore().getKBManager().getVanillaProfile(); + } + + public Entity(World world) { + this.id = Entity.entityCount++; + this.j = 1.0D; + this.boundingBox = Entity.a; + this.width = 0.6F; + this.length = 1.8F; + this.h = 1; + this.random = new Random(); + this.maxFireTicks = 1; + this.justCreated = true; + this.uniqueID = MathHelper.a(this.random); + this.au = new CommandObjectiveExecutor(); + this.world = world; + this.setPosition(0.0D, 0.0D, 0.0D); + if (world != null) { + this.dimension = world.worldProvider.getDimension(); + // Spigot start + this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, world.spigotConfig); + } else { + this.defaultActivationState = false; + } + // Spigot end + + this.datawatcher = new DataWatcher(this); + this.datawatcher.a(0, Byte.valueOf((byte) 0)); + this.datawatcher.a(1, Short.valueOf((short) 300)); + this.datawatcher.a(3, Byte.valueOf((byte) 0)); + this.datawatcher.a(2, ""); + this.datawatcher.a(4, Byte.valueOf((byte) 0)); + this.h(); + } + + protected abstract void h(); + + public DataWatcher getDataWatcher() { + return this.datawatcher; + } + + public boolean equals(Object object) { + return object instanceof Entity && ((Entity) object).id == this.id; + } + + public int hashCode() { + return this.id; + } + + public void die() { + this.dead = true; + } + + public void setSize(float f, float f1) { + if (f != this.width || f1 != this.length) { + float f2 = this.width; + + this.width = f; + this.length = f1; + this.a(new AxisAlignedBB(this.getBoundingBox().a, this.getBoundingBox().b, this.getBoundingBox().c, this.getBoundingBox().a + (double) this.width, this.getBoundingBox().b + (double) this.length, this.getBoundingBox().c + (double) this.width)); + if (this.width > f2 && !this.justCreated && !this.world.isClientSide) { + this.move(f2 - this.width, 0.0D, f2 - this.width); + } + } + + } + + protected void setYawPitch(float f, float f1) { + // CraftBukkit start - yaw was sometimes set to NaN, so we need to set it back to 0 + if (Float.isNaN(f)) { + f = 0; + } + + if (f == Float.POSITIVE_INFINITY || f == Float.NEGATIVE_INFINITY) { + if (this instanceof EntityPlayer) { + this.world.getServer().getLogger().warning(this.getName() + " was caught trying to crash the server with an invalid yaw"); + ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite yaw (Hacking?)"); //Spigot "Nope" -> Descriptive reason + } + f = 0; + } + + // pitch was sometimes set to NaN, so we need to set it back to 0 + if (Float.isNaN(f1)) { + f1 = 0; + } + + if (f1 == Float.POSITIVE_INFINITY || f1 == Float.NEGATIVE_INFINITY) { + if (this instanceof EntityPlayer) { + this.world.getServer().getLogger().warning(this.getName() + " was caught trying to crash the server with an invalid pitch"); + ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Infinite pitch (Hacking?)"); //Spigot "Nope" -> Descriptive reason + } + f1 = 0; + } + // CraftBukkit end + + this.yaw = f % 360.0F; + this.pitch = f1 % 360.0F; + } + + public void setPosition(double d0, double d1, double d2) { + this.locX = d0; + this.locY = d1; + this.locZ = d2; + float f = this.width / 2.0F; + float f1 = this.length; + + this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); + } + + public void t_() { + this.K(); + } + + /** + * PaperSpigot - Checks if the feature is enabled and the entity is above the nether world bedrock height + */ + private boolean paperNetherCheck() { + return this.world.paperSpigotConfig.netherVoidTopDamage && this.world.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER && this.locY >= 128.0D; + } + + public void K() { + this.world.methodProfiler.a("entityBaseTick"); + if (this.vehicle != null && this.vehicle.dead) { + this.vehicle = null; + } + + this.L = this.M; + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + this.lastPitch = this.pitch; + this.lastYaw = this.yaw; + if (!this.world.isClientSide && this.world instanceof WorldServer) { + this.world.methodProfiler.a("portal"); + MinecraftServer minecraftserver = ((WorldServer) this.world).getMinecraftServer(); + int i = this.L(); + + if (this.ak) { + if (true || minecraftserver.getAllowNether()) { // CraftBukkit + if (this.vehicle == null && this.al++ >= i) { + this.al = i; + this.portalCooldown = this.aq(); + byte b0; + + if (this.world.worldProvider.getDimension() == -1) { + b0 = 0; + } else { + b0 = -1; + } + + this.c(b0); + } + + this.ak = false; + } + } else { + if (this.al > 0) { + this.al -= 4; + } + + if (this.al < 0) { + this.al = 0; + } + } + + if (this.portalCooldown > 0) { + --this.portalCooldown; + } + + this.world.methodProfiler.b(); + } + + this.Y(); + this.W(); + if (this.world.isClientSide) { + this.fireTicks = 0; + } else if (this.fireTicks > 0) { + if (this.fireProof) { + this.fireTicks -= 4; + if (this.fireTicks < 0) { + this.fireTicks = 0; + } + } else { + if (this.fireTicks % 20 == 0) { + KBProfile kb = this.getKBProfile(); + final int lastNoDamageTicks = this.noDamageTicks; + this.damageEntity(DamageSource.BURN, 1.0F); + if (kb.isFire()) this.noDamageTicks = lastNoDamageTicks; + } + + --this.fireTicks; + } + } + + if (this.ab()) { + this.burnFromLava(); + this.fallDistance *= 0.5F; + } + + if (this.locY < -64.0D || paperNetherCheck()) { // PaperSpigot - Configurable top-of-nether void damage + this.O(); + } + + if (!this.world.isClientSide) { + this.b(0, this.fireTicks > 0); + } + + this.justCreated = false; + this.world.methodProfiler.b(); + } + + public int L() { + return 0; + } + + protected void burnFromLava() { + if (!this.fireProof) { + this.damageEntity(DamageSource.LAVA, 4.0F); + + // CraftBukkit start - Fallen in lava TODO: this event spams! + if (this instanceof EntityLiving) { + if (fireTicks <= 0) { + // not on fire yet + // TODO: shouldn't be sending null for the block + org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k); + org.bukkit.entity.Entity damagee = this.getBukkitEntity(); + EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15); + this.world.getServer().getPluginManager().callEvent(combustEvent); + + if (!combustEvent.isCancelled()) { + this.setOnFire(combustEvent.getDuration()); + } + } else { + // This will be called every single tick the entity is in lava, so don't throw an event + this.setOnFire(15); + } + return; + } + // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls + this.setOnFire(15); + } + } + + public void setOnFire(int i) { + int j = i * 20; + + j = EnchantmentProtection.a(this, j); + if (this.fireTicks < j) { + this.fireTicks = j; + } + + } + + public void extinguish() { + this.fireTicks = 0; + } + + protected void O() { + this.die(); + } + + public boolean c(double d0, double d1, double d2) { + AxisAlignedBB axisalignedbb = this.getBoundingBox().c(d0, d1, d2); + + return this.b(axisalignedbb); + } + + private boolean b(AxisAlignedBB axisalignedbb) { + return this.world.getCubes(this, axisalignedbb).isEmpty() && !this.world.containsLiquid(axisalignedbb); + } + + /** + * PaperSpigot - Load surrounding chunks the entity is moving through + */ + public void loadChunks() { + for (int cx = (int) locX >> 4; cx <= (int) (locX + motX) >> 4; ++cx) { + for (int cz = (int) locZ >> 4; cz <= (int) (locZ + motZ) >> 4; ++cz) { + ((ChunkProviderServer) world.chunkProvider).getChunkAt(cx, cz); + } + } + } + + + public void move(double d0, double d1, double d2) { + if (this.loadChunks) loadChunks(); // PaperSpigot - Load chunks + if (this.noclip) { + this.a(this.getBoundingBox().c(d0, d1, d2)); + this.recalcPosition(); + } else { + // CraftBukkit start - Don't do anything if we aren't moving + // We need to do this regardless of whether or not we are moving thanks to portals + try { + this.checkBlockCollisions(); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Checking entity block collision"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being checked for collision"); + + this.appendEntityCrashDetails(crashreportsystemdetails); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + // Check if we're moving + if (d0 == 0 && d1 == 0 && d2 == 0 && this.vehicle == null && this.passenger == null) { + return; + } + // CraftBukkit end + this.world.methodProfiler.a("move"); + double d3 = this.locX; + double d4 = this.locY; + double d5 = this.locZ; + + if (this.H) { + this.H = false; + d0 *= 0.25D; + d1 *= 0.05000000074505806D; + d2 *= 0.25D; + this.motX = 0.0D; + this.motY = 0.0D; + this.motZ = 0.0D; + } + + double d6 = d0; + double d7 = d1; + double d8 = d2; + boolean flag = this.onGround && this.isSneaking() && this instanceof EntityHuman; + + if (flag) { + double d9; + + for (d9 = 0.05D; d0 != 0.0D && this.world.getCubes(this, this.getBoundingBox().c(d0, -1.0D, 0.0D)).isEmpty(); d6 = d0) { + if (d0 < d9 && d0 >= -d9) { + d0 = 0.0D; + } else if (d0 > 0.0D) { + d0 -= d9; + } else { + d0 += d9; + } + } + + for (; d2 != 0.0D && this.world.getCubes(this, this.getBoundingBox().c(0.0D, -1.0D, d2)).isEmpty(); d8 = d2) { + if (d2 < d9 && d2 >= -d9) { + d2 = 0.0D; + } else if (d2 > 0.0D) { + d2 -= d9; + } else { + d2 += d9; + } + } + + for (; d0 != 0.0D && d2 != 0.0D && this.world.getCubes(this, this.getBoundingBox().c(d0, -1.0D, d2)).isEmpty(); d8 = d2) { + if (d0 < d9 && d0 >= -d9) { + d0 = 0.0D; + } else if (d0 > 0.0D) { + d0 -= d9; + } else { + d0 += d9; + } + + d6 = d0; + if (d2 < d9 && d2 >= -d9) { + d2 = 0.0D; + } else if (d2 > 0.0D) { + d2 -= d9; + } else { + d2 += d9; + } + } + } + + // TacoSpigot start - do axis by axis scan if the entity is travelling a large area + AxisAlignedBB totalArea = this.getBoundingBox().a(d0, d1, d2); + 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; + + List list = this.world.getCubes(this, axisScan ? this.getBoundingBox().a(0, d1, 0) : totalArea); + // TacoSpigot end + + AxisAlignedBB axisalignedbb = this.getBoundingBox(); + + AxisAlignedBB axisalignedbb1; + + for (Iterator iterator = list.iterator(); iterator.hasNext(); d1 = axisalignedbb1.b(this.getBoundingBox(), d1)) { + axisalignedbb1 = (AxisAlignedBB) iterator.next(); + } + + this.a(this.getBoundingBox().c(0.0D, d1, 0.0D)); + boolean flag1 = this.onGround || d7 != d1 && d7 < 0.0D; + + AxisAlignedBB axisalignedbb2; + Iterator iterator1; + + 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(axisScan) list = this.world.getCubes(this, this.getBoundingBox().a(0, 0, d2)); // TacoSpigot - get z axis blocks + + for (iterator1 = list.iterator(); iterator1.hasNext(); d2 = axisalignedbb2.c(this.getBoundingBox(), d2)) { + axisalignedbb2 = (AxisAlignedBB) iterator1.next(); + } + + this.a(this.getBoundingBox().c(0.0D, 0.0D, d2)); + + if(axisScan) list = this.world.getCubes(this, this.getBoundingBox().a(d0, 0, 0)); // TacoSpigot - get x axis blocks + + for (iterator1 = list.iterator(); iterator1.hasNext(); d0 = axisalignedbb2.a(this.getBoundingBox(), d0)) { + axisalignedbb2 = (AxisAlignedBB) iterator1.next(); + } + + this.a(this.getBoundingBox().c(d0, 0.0D, 0.0D)); + + } else { + if(axisScan) list = this.world.getCubes(this, this.getBoundingBox().a(d0, 0, 0)); // TacoSpigot - get x axis blocks + + for (iterator1 = list.iterator(); iterator1.hasNext(); d0 = axisalignedbb2.a(this.getBoundingBox(), d0)) { + axisalignedbb2 = (AxisAlignedBB) iterator1.next(); + } + + this.a(this.getBoundingBox().c(d0, 0.0D, 0.0D)); + + if(axisScan) list = this.world.getCubes(this, this.getBoundingBox().a(0, 0, d2)); // TacoSpigot - get z axis blocks + + for (iterator1 = list.iterator(); iterator1.hasNext(); d2 = axisalignedbb2.c(this.getBoundingBox(), d2)) { + axisalignedbb2 = (AxisAlignedBB) iterator1.next(); + } + + this.a(this.getBoundingBox().c(0.0D, 0.0D, d2)); + } + + if (this.S > 0.0F && flag1 && (d6 != d0 || d8 != d2)) { + double d10 = d0; + double d11 = d1; + double d12 = d2; + AxisAlignedBB axisalignedbb3 = this.getBoundingBox(); + + this.a(axisalignedbb); + d1 = this.S; + List list1 = this.world.getCubes(this, this.getBoundingBox().a(d6, d1, d8)); + AxisAlignedBB axisalignedbb4 = this.getBoundingBox(); + AxisAlignedBB axisalignedbb5 = axisalignedbb4.a(d6, 0.0D, d8); + double d13 = d1; + + AxisAlignedBB axisalignedbb6; + + for (Iterator iterator2 = list1.iterator(); iterator2.hasNext(); d13 = axisalignedbb6.b(axisalignedbb5, d13)) { + axisalignedbb6 = (AxisAlignedBB) iterator2.next(); + } + + axisalignedbb4 = axisalignedbb4.c(0.0D, d13, 0.0D); + double d14 = d6; + + AxisAlignedBB axisalignedbb7; + + for (Iterator iterator3 = list1.iterator(); iterator3.hasNext(); d14 = axisalignedbb7.a(axisalignedbb4, d14)) { + axisalignedbb7 = (AxisAlignedBB) iterator3.next(); + } + + axisalignedbb4 = axisalignedbb4.c(d14, 0.0D, 0.0D); + double d15 = d8; + + AxisAlignedBB axisalignedbb8; + + for (Iterator iterator4 = list1.iterator(); iterator4.hasNext(); d15 = axisalignedbb8.c(axisalignedbb4, d15)) { + axisalignedbb8 = (AxisAlignedBB) iterator4.next(); + } + + axisalignedbb4 = axisalignedbb4.c(0.0D, 0.0D, d15); + AxisAlignedBB axisalignedbb9 = this.getBoundingBox(); + double d16 = d1; + + AxisAlignedBB axisalignedbb10; + + for (Iterator iterator5 = list1.iterator(); iterator5.hasNext(); d16 = axisalignedbb10.b(axisalignedbb9, d16)) { + axisalignedbb10 = (AxisAlignedBB) iterator5.next(); + } + + axisalignedbb9 = axisalignedbb9.c(0.0D, d16, 0.0D); + double d17 = d6; + + AxisAlignedBB axisalignedbb11; + + for (Iterator iterator6 = list1.iterator(); iterator6.hasNext(); d17 = axisalignedbb11.a(axisalignedbb9, d17)) { + axisalignedbb11 = (AxisAlignedBB) iterator6.next(); + } + + axisalignedbb9 = axisalignedbb9.c(d17, 0.0D, 0.0D); + double d18 = d8; + + AxisAlignedBB axisalignedbb12; + + for (Iterator iterator7 = list1.iterator(); iterator7.hasNext(); d18 = axisalignedbb12.c(axisalignedbb9, d18)) { + axisalignedbb12 = (AxisAlignedBB) iterator7.next(); + } + + axisalignedbb9 = axisalignedbb9.c(0.0D, 0.0D, d18); + double d19 = d14 * d14 + d15 * d15; + double d20 = d17 * d17 + d18 * d18; + + if (d19 > d20) { + d0 = d14; + d2 = d15; + d1 = -d13; + this.a(axisalignedbb4); + } else { + d0 = d17; + d2 = d18; + d1 = -d16; + this.a(axisalignedbb9); + } + + AxisAlignedBB axisalignedbb13; + + for (Iterator iterator8 = list1.iterator(); iterator8.hasNext(); d1 = axisalignedbb13.b(this.getBoundingBox(), d1)) { + axisalignedbb13 = (AxisAlignedBB) iterator8.next(); + } + + this.a(this.getBoundingBox().c(0.0D, d1, 0.0D)); + if (d10 * d10 + d12 * d12 >= d0 * d0 + d2 * d2) { + d0 = d10; + d1 = d11; + d2 = d12; + this.a(axisalignedbb3); + } + } + + this.world.methodProfiler.b(); + this.world.methodProfiler.a("rest"); + this.recalcPosition(); + this.positionChanged = d6 != d0 || d8 != d2; + this.E = d7 != d1; + this.onGround = this.E && d7 < 0.0D; + this.F = this.positionChanged || this.E; + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY - 0.20000000298023224D); + int k = MathHelper.floor(this.locZ); + BlockPosition blockposition = new BlockPosition(i, j, k); + Block block = this.world.getType(blockposition).getBlock(); + + if (block.getMaterial() == Material.AIR) { + Block block1 = this.world.getType(blockposition.down()).getBlock(); + + if (block1 instanceof BlockFence || block1 instanceof BlockCobbleWall || block1 instanceof BlockFenceGate) { + block = block1; + blockposition = blockposition.down(); + } + } + + this.a(d1, this.onGround, block, blockposition); + if (d6 != d0) { + this.motX = 0.0D; + } + + if (d8 != d2) { + this.motZ = 0.0D; + } + + if (d7 != d1) { + block.a(this.world, this); + } + + // CraftBukkit start + if (positionChanged && getBukkitEntity() instanceof Vehicle) { + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); + org.bukkit.block.Block bl = this.world.getWorld().getBlockAt(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)); + + if (d6 > d0) { + bl = bl.getRelative(BlockFace.EAST); + } else if (d6 < d0) { + bl = bl.getRelative(BlockFace.WEST); + } else if (d8 > d2) { + bl = bl.getRelative(BlockFace.SOUTH); + } else if (d8 < d2) { + bl = bl.getRelative(BlockFace.NORTH); + } + + VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl); + world.getServer().getPluginManager().callEvent(event); + } + // CraftBukkit end + + if (this.s_() && !flag && this.vehicle == null) { + double d21 = this.locX - d3; + double d22 = this.locY - d4; + double d23 = this.locZ - d5; + + if (block != Blocks.LADDER) { + d22 = 0.0D; + } + + if (block != null && this.onGround) { + // block.a(this.world, blockposition, this); // CraftBukkit moved down + } + + this.M = (float) ((double) this.M + (double) MathHelper.sqrt(d21 * d21 + d23 * d23) * 0.6D); + this.N = (float) ((double) this.N + (double) MathHelper.sqrt(d21 * d21 + d22 * d22 + d23 * d23) * 0.6D); + if (this.N > (float) this.h && block.getMaterial() != Material.AIR) { + this.h = (int) this.N + 1; + if (this.V()) { + float f = MathHelper.sqrt(this.motX * this.motX * 0.20000000298023224D + this.motY * this.motY + this.motZ * this.motZ * 0.20000000298023224D) * 0.35F; + + if (f > 1.0F) { + f = 1.0F; + } + + this.makeSound(this.P(), f, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); + } + + this.a(blockposition, block); + block.a(this.world, blockposition, this); // CraftBukkit moved from above + } + } + + // CraftBukkit start - Move to the top of the method + /* + try { + this.checkBlockCollisions(); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Checking entity block collision"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being checked for collision"); + + this.appendEntityCrashDetails(crashreportsystemdetails); + throw new ReportedException(crashreport); + } + */ + // CraftBukkit end + + boolean flag2 = this.U(); + + if (this.world.e(this.getBoundingBox().shrink(0.001D, 0.001D, 0.001D))) { + this.burn(1); + if (!flag2) { + ++this.fireTicks; + // CraftBukkit start - Not on fire yet + if (this.fireTicks <= 0) { // Only throw events on the first combust, otherwise it spams + EntityCombustEvent event = new EntityCombustEvent(getBukkitEntity(), 8); + world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + setOnFire(event.getDuration()); + } + } else { + // CraftBukkit end + this.setOnFire(8); + } + } + } else if (this.fireTicks <= 0) { + this.fireTicks = -this.maxFireTicks; + } + + if (flag2 && this.fireTicks > 0) { + this.makeSound("random.fizz", 0.7F, 1.6F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); + this.fireTicks = -this.maxFireTicks; + } + + this.world.methodProfiler.b(); + } + } + + private void recalcPosition() { + this.locX = (this.getBoundingBox().a + this.getBoundingBox().d) / 2.0D; + this.locY = this.getBoundingBox().b; + this.locZ = (this.getBoundingBox().c + this.getBoundingBox().f) / 2.0D; + } + + protected String P() { + return "game.neutral.swim"; + } + + protected void checkBlockCollisions() { + BlockPosition blockposition = new BlockPosition(this.getBoundingBox().a + 0.001D, this.getBoundingBox().b + 0.001D, this.getBoundingBox().c + 0.001D); + BlockPosition blockposition1 = new BlockPosition(this.getBoundingBox().d - 0.001D, this.getBoundingBox().e - 0.001D, this.getBoundingBox().f - 0.001D); + + if (this.world.areChunksLoadedBetween(blockposition, blockposition1)) { + for (int i = blockposition.getX(); i <= blockposition1.getX(); ++i) { + for (int j = blockposition.getY(); j <= blockposition1.getY(); ++j) { + for (int k = blockposition.getZ(); k <= blockposition1.getZ(); ++k) { + BlockPosition blockposition2 = new BlockPosition(i, j, k); + IBlockData iblockdata = this.world.getType(blockposition2); + + try { + iblockdata.getBlock().a(this.world, blockposition2, iblockdata, this); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Colliding entity with block"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being collided with"); + + CrashReportSystemDetails.a(crashreportsystemdetails, blockposition2, iblockdata); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + } + } + } + + } + + protected void a(BlockPosition blockposition, Block block) { + Block.StepSound block_stepsound = block.stepSound; + + if (this.world.getType(blockposition.up()).getBlock() == Blocks.SNOW_LAYER) { + block_stepsound = Blocks.SNOW_LAYER.stepSound; + this.makeSound(block_stepsound.getStepSound(), block_stepsound.getVolume1() * 0.15F, block_stepsound.getVolume2()); + } else if (!block.getMaterial().isLiquid()) { + this.makeSound(block_stepsound.getStepSound(), block_stepsound.getVolume1() * 0.15F, block_stepsound.getVolume2()); + } + + } + + public void makeSound(String s, float f, float f1) { + if (!this.R()) { + this.world.makeSound(this, s, f, f1); + } + + } + + public boolean R() { + return this.datawatcher.getByte(4) == 1; + } + + public void b(boolean flag) { + this.datawatcher.watch(4, Byte.valueOf((byte) (flag ? 1 : 0))); + } + + protected boolean s_() { + return true; + } + + protected void a(double d0, boolean flag, Block block, BlockPosition blockposition) { + if (flag) { + if (this.fallDistance > 0.0F) { + if (block != null) { + block.fallOn(this.world, blockposition, this, this.fallDistance); + } else { + this.e(this.fallDistance, 1.0F); + } + + this.fallDistance = 0.0F; + } + } else if (d0 < 0.0D) { + this.fallDistance = (float) ((double) this.fallDistance - d0); + } + + } + + public AxisAlignedBB S() { + return null; + } + + protected void burn(float i) { // CraftBukkit - int -> float + if (!this.fireProof) { + this.damageEntity(DamageSource.FIRE, i); + } + + } + + public final boolean isFireProof() { + return this.fireProof; + } + + public void e(float f, float f1) { + if (this.passenger != null) { + this.passenger.e(f, f1); + } + + } + + public boolean U() { + return this.inWater || this.world.isRainingAt(new BlockPosition(this.locX, this.locY, this.locZ)) || this.world.isRainingAt(new BlockPosition(this.locX, this.locY + (double) this.length, this.locZ)); + } + + public boolean V() { + return this.inWater; + } + + public boolean W() { + if (this.world.a(this.getBoundingBox().grow(0.0D, -0.4000000059604645D, 0.0D).shrink(0.001D, 0.001D, 0.001D), Material.WATER, this)) { + if (!this.inWater && !this.justCreated) { + this.X(); + } + + this.fallDistance = 0.0F; + this.inWater = true; + this.fireTicks = 0; + } else { + this.inWater = false; + } + + return this.inWater; + } + + protected void X() { + float f = MathHelper.sqrt(this.motX * this.motX * 0.20000000298023224D + this.motY * this.motY + this.motZ * this.motZ * 0.20000000298023224D) * 0.2F; + + if (f > 1.0F) { + f = 1.0F; + } + + this.makeSound(this.aa(), f, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); + float f1 = (float) MathHelper.floor(this.getBoundingBox().b); + + int i; + float f2; + float f3; + + 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); + } + + 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); + } + + } + + public void Y() { + if (this.isSprinting() && !this.V()) { + this.Z(); + } + + } + + protected void Z() { + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY - 0.20000000298023224D); + int k = MathHelper.floor(this.locZ); + BlockPosition blockposition = new BlockPosition(i, j, k); + IBlockData iblockdata = this.world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block.b() != -1) { + this.world.addParticle(EnumParticle.BLOCK_CRACK, this.locX + ((double) this.random.nextFloat() - 0.5D) * (double) this.width, this.getBoundingBox().b + 0.1D, this.locZ + ((double) this.random.nextFloat() - 0.5D) * (double) this.width, -this.motX * 4.0D, 1.5D, -this.motZ * 4.0D, Block.getCombinedId(iblockdata)); + } + + } + + protected String aa() { + return "game.neutral.swim.splash"; + } + + public boolean a(Material material) { + double d0 = this.locY + (double) this.getHeadHeight(); + BlockPosition blockposition = new BlockPosition(this.locX, d0, this.locZ); + IBlockData iblockdata = this.world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block.getMaterial() == material) { + float f = BlockFluids.b(iblockdata.getBlock().toLegacyData(iblockdata)) - 0.11111111F; + float f1 = (float) (blockposition.getY() + 1) - f; + boolean flag = d0 < (double) f1; + + return (flag || !(this instanceof EntityHuman)) && flag; + } else { + return false; + } + } + + public boolean ab() { + return this.world.a(this.getBoundingBox().grow(-0.10000000149011612D, -0.4000000059604645D, -0.10000000149011612D), Material.LAVA); + } + + public void a(float f, float f1, float f2) { + float f3 = f * f + f1 * f1; + + if (f3 >= 1.0E-4F) { + f3 = MathHelper.c(f3); + if (f3 < 1.0F) { + f3 = 1.0F; + } + + f3 = f2 / f3; + f *= f3; + f1 *= f3; + float f4 = MathHelper.sin(this.yaw * 3.1415927F / 180.0F); + float f5 = MathHelper.cos(this.yaw * 3.1415927F / 180.0F); + + this.motX += f * f5 - f1 * f4; + this.motZ += f1 * f5 + f * f4; + } + } + + public float c(float f) { + BlockPosition blockposition = new BlockPosition(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ); + + return this.world.isLoaded(blockposition) ? this.world.o(blockposition) : 0.0F; + } + + public void spawnIn(World world) { + // CraftBukkit start + if (world == null) { + die(); + this.world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(); + return; + } + // CraftBukkit end + this.world = world; + } + + public void setLocation(double d0, double d1, double d2, float f, float f1) { + this.lastX = this.locX = d0; + this.lastY = this.locY = d1; + this.lastZ = this.locZ = d2; + this.lastYaw = this.yaw = f; + this.lastPitch = this.pitch = f1; + double d3 = this.lastYaw - f; + + if (d3 < -180.0D) { + this.lastYaw += 360.0F; + } + + if (d3 >= 180.0D) { + this.lastYaw -= 360.0F; + } + + this.setPosition(this.locX, this.locY, this.locZ); + this.setYawPitch(f, f1); + } + + public void setPositionRotation(BlockPosition blockposition, float f, float f1) { + this.setPositionRotation((double) blockposition.getX() + 0.5D, blockposition.getY(), (double) blockposition.getZ() + 0.5D, f, f1); + } + + public void setPositionRotation(double d0, double d1, double d2, float f, float f1) { + this.P = this.lastX = this.locX = d0; + this.Q = this.lastY = this.locY = d1; + this.R = this.lastZ = this.locZ = d2; + this.yaw = f; + this.pitch = f1; + this.setPosition(this.locX, this.locY, this.locZ); + } + + public float g(Entity entity) { + float f = (float) (this.locX - entity.locX); + float f1 = (float) (this.locY - entity.locY); + float f2 = (float) (this.locZ - entity.locZ); + + return MathHelper.c(f * f + f1 * f1 + f2 * f2); + } + + public double e(double d0, double d1, double d2) { + double d3 = this.locX - d0; + double d4 = this.locY - d1; + double d5 = this.locZ - d2; + + return d3 * d3 + d4 * d4 + d5 * d5; + } + + public double b(BlockPosition blockposition) { + return blockposition.c(this.locX, this.locY, this.locZ); + } + + public double c(BlockPosition blockposition) { + return blockposition.d(this.locX, this.locY, this.locZ); + } + + public double f(double d0, double d1, double d2) { + double d3 = this.locX - d0; + double d4 = this.locY - d1; + double d5 = this.locZ - d2; + + return MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); + } + + public double h(Entity entity) { + double d0 = this.locX - entity.locX; + double d1 = this.locY - entity.locY; + double d2 = this.locZ - entity.locZ; + + return d0 * d0 + d1 * d1 + d2 * d2; + } + + public void d(EntityHuman entityhuman) {} + + int numCollisions = 0; // Spigot + public void collide(Entity entity) { + if (MythicConfiguration.Options.Server.entityCollisions && entity.passenger != this && entity.vehicle != this) { + if (!entity.noclip && !this.noclip) { + double d0 = entity.locX - this.locX; + double d1 = entity.locZ - this.locZ; + double d2 = MathHelper.a(d0, d1); + + if (d2 >= 0.009999999776482582D) { + d2 = MathHelper.sqrt(d2); + d0 /= d2; + d1 /= d2; + double d3 = 1.0D / d2; + + if (d3 > 1.0D) { + d3 = 1.0D; + } + + d0 *= d3; + d1 *= d3; + d0 *= 0.05000000074505806D; + d1 *= 0.05000000074505806D; + d0 *= 1.0F - this.U; + d1 *= 1.0F - this.U; + if (this.passenger == null) { + this.g(-d0, 0.0D, -d1); + } + + if (entity.passenger == null) { + entity.g(d0, 0.0D, d1); + } + } + + } + } + } + + public void g(double d0, double d1, double d2) { + this.motX += d0; + this.motY += d1; + this.motZ += d2; + this.ai = true; + } + + protected void ac() { + this.velocityChanged = true; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + this.ac(); + return false; + } + } + + public Vec3D d(float f) { + if (f == 1.0F) { + return this.f(this.pitch, this.yaw); + } else { + float f1 = this.lastPitch + (this.pitch - this.lastPitch) * f; + float f2 = this.lastYaw + (this.yaw - this.lastYaw) * f; + + return this.f(f1, f2); + } + } + + protected final Vec3D f(float f, float f1) { + float f2 = MathHelper.cos(-f1 * 0.017453292F - 3.1415927F); + float f3 = MathHelper.sin(-f1 * 0.017453292F - 3.1415927F); + float f4 = -MathHelper.cos(-f * 0.017453292F); + float f5 = MathHelper.sin(-f * 0.017453292F); + + return new Vec3D(f3 * f4, f5, f2 * f4); + } + + public boolean ad() { + return false; + } + + public boolean ae() { + return false; + } + + public void b(Entity entity, int i) {} + + public boolean c(NBTTagCompound nbttagcompound) { + String s = this.ag(); + + if (!this.dead && s != null) { + nbttagcompound.setString("id", s); + this.e(nbttagcompound); + return true; + } else { + return false; + } + } + + public boolean d(NBTTagCompound nbttagcompound) { + String s = this.ag(); + + if (!this.dead && s != null && this.passenger == null) { + nbttagcompound.setString("id", s); + this.e(nbttagcompound); + return true; + } else { + return false; + } + } + + public void e(NBTTagCompound nbttagcompound) { + try { + nbttagcompound.set("Pos", this.a(this.locX, this.locY, this.locZ)); + nbttagcompound.set("Motion", this.a(this.motX, this.motY, this.motZ)); + + // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero + // TODO: make sure this is the best way to address this. + if (Float.isNaN(this.yaw)) { + this.yaw = 0; + } + + if (Float.isNaN(this.pitch)) { + this.pitch = 0; + } + // CraftBukkit end + + nbttagcompound.set("Rotation", this.a(this.yaw, this.pitch)); + nbttagcompound.setFloat("FallDistance", this.fallDistance); + nbttagcompound.setShort("Fire", (short) this.fireTicks); + nbttagcompound.setShort("Air", (short) this.getAirTicks()); + nbttagcompound.setBoolean("OnGround", this.onGround); + nbttagcompound.setInt("Dimension", this.dimension); + nbttagcompound.setBoolean("Invulnerable", this.invulnerable); + nbttagcompound.setInt("PortalCooldown", this.portalCooldown); + nbttagcompound.setLong("UUIDMost", this.getUniqueID().getMostSignificantBits()); + nbttagcompound.setLong("UUIDLeast", this.getUniqueID().getLeastSignificantBits()); + // CraftBukkit start + nbttagcompound.setLong("WorldUUIDLeast", this.world.getDataManager().getUUID().getLeastSignificantBits()); + nbttagcompound.setLong("WorldUUIDMost", this.world.getDataManager().getUUID().getMostSignificantBits()); + nbttagcompound.setInt("Bukkit.updateLevel", CURRENT_LEVEL); + nbttagcompound.setInt("Spigot.ticksLived", this.ticksLived); + // CraftBukkit end + if (this.getCustomName() != null && this.getCustomName().length() > 0) { + nbttagcompound.setString("CustomName", this.getCustomName()); + nbttagcompound.setBoolean("CustomNameVisible", this.getCustomNameVisible()); + } + + this.au.b(nbttagcompound); + if (this.R()) { + nbttagcompound.setBoolean("Silent", this.R()); + } + + this.b(nbttagcompound); + if (this.vehicle != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + if (this.vehicle.c(nbttagcompound1)) { + nbttagcompound.set("Riding", nbttagcompound1); + } + } + + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Saving entity NBT"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being saved"); + + this.appendEntityCrashDetails(crashreportsystemdetails); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + + public void f(NBTTagCompound nbttagcompound) { + try { + NBTTagList nbttaglist = nbttagcompound.getList("Pos", 6); + NBTTagList nbttaglist1 = nbttagcompound.getList("Motion", 6); + NBTTagList nbttaglist2 = nbttagcompound.getList("Rotation", 5); + + this.motX = nbttaglist1.d(0); + this.motY = nbttaglist1.d(1); + this.motZ = nbttaglist1.d(2); + + /* CraftBukkit start - Moved section down + if (Math.abs(this.motX) > 10.0D) { + this.motX = 0.0D; + } + + if (Math.abs(this.motY) > 10.0D) { + this.motY = 0.0D; + } + + if (Math.abs(this.motZ) > 10.0D) { + this.motZ = 0.0D; + } + // CraftBukkit end */ + + this.lastX = this.P = this.locX = nbttaglist.d(0); + this.lastY = this.Q = this.locY = nbttaglist.d(1); + this.lastZ = this.R = this.locZ = nbttaglist.d(2); + this.lastYaw = this.yaw = nbttaglist2.e(0); + this.lastPitch = this.pitch = nbttaglist2.e(1); + this.f(this.yaw); + this.g(this.yaw); + this.fallDistance = nbttagcompound.getFloat("FallDistance"); + this.fireTicks = nbttagcompound.getShort("Fire"); + this.setAirTicks(nbttagcompound.getShort("Air")); + this.onGround = nbttagcompound.getBoolean("OnGround"); + this.dimension = nbttagcompound.getInt("Dimension"); + this.invulnerable = nbttagcompound.getBoolean("Invulnerable"); + this.portalCooldown = nbttagcompound.getInt("PortalCooldown"); + 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.setPosition(this.locX, this.locY, this.locZ); + this.setYawPitch(this.yaw, this.pitch); + if (nbttagcompound.hasKeyOfType("CustomName", 8) && nbttagcompound.getString("CustomName").length() > 0) { + this.setCustomName(nbttagcompound.getString("CustomName")); + } + + this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible")); + this.au.a(nbttagcompound); + this.b(nbttagcompound.getBoolean("Silent")); + this.a(nbttagcompound); + if (this.af()) { + this.setPosition(this.locX, this.locY, this.locZ); + } + + // CraftBukkit start + if (this instanceof EntityLiving) { + EntityLiving entity = (EntityLiving) this; + + this.ticksLived = nbttagcompound.getInt("Spigot.ticksLived"); + + // Reset the persistence for tamed animals + if (entity instanceof EntityTameableAnimal && !isLevelAtLeast(nbttagcompound, 2) && !nbttagcompound.getBoolean("PersistenceRequired")) { + EntityInsentient entityinsentient = (EntityInsentient) entity; + entityinsentient.persistent = !entityinsentient.isTypeNotPersistent(); + } + } + // CraftBukkit end + + // CraftBukkit start - Exempt Vehicles from notch's sanity check + if (!(getBukkitEntity() instanceof Vehicle)) { + if (Math.abs(this.motX) > 10.0D) { + this.motX = 0.0D; + } + + if (Math.abs(this.motY) > 10.0D) { + this.motY = 0.0D; + } + + if (Math.abs(this.motZ) > 10.0D) { + this.motZ = 0.0D; + } + } + // CraftBukkit end + + // CraftBukkit start - Reset world + if (this instanceof EntityPlayer) { + Server server = Bukkit.getServer(); + org.bukkit.World bworld = null; + + // TODO: Remove World related checks, replaced with WorldUID + String worldName = nbttagcompound.getString("world"); + + if (nbttagcompound.hasKey("WorldUUIDMost") && nbttagcompound.hasKey("WorldUUIDLeast")) { + UUID uid = new UUID(nbttagcompound.getLong("WorldUUIDMost"), nbttagcompound.getLong("WorldUUIDLeast")); + bworld = server.getWorld(uid); + } else { + bworld = server.getWorld(worldName); + } + + if (bworld == null) { + EntityPlayer entityPlayer = (EntityPlayer) this; + bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(entityPlayer.dimension).getWorld(); + } + + spawnIn(bworld == null? null : ((CraftWorld) bworld).getHandle()); + } + // CraftBukkit end + + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Loading entity NBT"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded"); + + this.appendEntityCrashDetails(crashreportsystemdetails); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + + protected boolean af() { + return true; + } + + protected final String ag() { + return EntityTypes.b(this); + } + + protected abstract void a(NBTTagCompound nbttagcompound); + + protected abstract void b(NBTTagCompound nbttagcompound); + + public void ah() {} + + protected NBTTagList a(double... adouble) { + NBTTagList nbttaglist = new NBTTagList(); + double[] adouble1 = adouble; + int i = adouble.length; + + for (int j = 0; j < i; ++j) { + double d0 = adouble1[j]; + + nbttaglist.add(new NBTTagDouble(d0)); + } + + return nbttaglist; + } + + protected NBTTagList a(float... afloat) { + NBTTagList nbttaglist = new NBTTagList(); + float[] afloat1 = afloat; + int i = afloat.length; + + for (int j = 0; j < i; ++j) { + float f = afloat1[j]; + + nbttaglist.add(new NBTTagFloat(f)); + } + + return nbttaglist; + } + + public EntityItem a(Item item, int i) { + return this.a(item, i, 0.0F); + } + + public EntityItem a(Item item, int i, float f) { + return this.a(new ItemStack(item, i, 0), f); + } + + public EntityItem a(ItemStack itemstack, float f) { + if (itemstack.count != 0 && itemstack.getItem() != null) { + // CraftBukkit start - Capture drops for death event + if (this instanceof EntityLiving && ((EntityLiving) this).drops != null) { + ((EntityLiving) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); + return null; + } + // CraftBukkit end + EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY + (double) f, this.locZ, itemstack); + + // Mythic - Hide items for practice + if(MythicConfiguration.Options.Tracking.Hide.items && this instanceof EntityPlayer) { + entityitem.dropper = this; + } + + entityitem.p(); + this.world.addEntity(entityitem); + return entityitem; + } else { + return null; + } + } + + public boolean isAlive() { + return !this.dead; + } + + public boolean inBlock() { + if (this.noclip) { + return false; + } else { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); + + for (int i = 0; i < 8; ++i) { + int j = MathHelper.floor(this.locY + (double) (((float) ((i >> 0) % 2) - 0.5F) * 0.1F) + (double) this.getHeadHeight()); + int k = MathHelper.floor(this.locX + (double) (((float) ((i >> 1) % 2) - 0.5F) * this.width * 0.8F)); + int l = MathHelper.floor(this.locZ + (double) (((float) ((i >> 2) % 2) - 0.5F) * this.width * 0.8F)); + + if (blockposition_mutableblockposition.getX() != k || blockposition_mutableblockposition.getY() != j || blockposition_mutableblockposition.getZ() != l) { + blockposition_mutableblockposition.c(k, j, l); + if (this.world.getType(blockposition_mutableblockposition).getBlock().w()) { + return true; + } + } + } + + return false; + } + } + + public boolean e(EntityHuman entityhuman) { + return false; + } + + public AxisAlignedBB j(Entity entity) { + return null; + } + + public void ak() { + if (this.vehicle.dead) { + this.vehicle = null; + } else { + this.motX = 0.0D; + this.motY = 0.0D; + this.motZ = 0.0D; + this.t_(); + if (this.vehicle != null) { + this.vehicle.al(); + this.as += this.vehicle.yaw - this.vehicle.lastYaw; + + for (this.ar += this.vehicle.pitch - this.vehicle.lastPitch; this.as >= 180.0D; this.as -= 360.0D) { + } + + while (this.as < -180.0D) { + this.as += 360.0D; + } + + while (this.ar >= 180.0D) { + this.ar -= 360.0D; + } + + while (this.ar < -180.0D) { + this.ar += 360.0D; + } + + double d0 = this.as * 0.5D; + double d1 = this.ar * 0.5D; + float f = 10.0F; + + if (d0 > (double) f) { + d0 = f; + } + + if (d0 < (double) (-f)) { + d0 = -f; + } + + if (d1 > (double) f) { + d1 = f; + } + + if (d1 < (double) (-f)) { + d1 = -f; + } + + this.as -= d0; + this.ar -= d1; + } + } + } + + public void al() { + if (this.passenger != null) { + this.passenger.setPosition(this.locX, this.locY + this.an() + this.passenger.am(), this.locZ); + } + } + + public double am() { + return 0.0D; + } + + public double an() { + return (double) this.length * 0.75D; + } + + // CraftBukkit start + protected CraftEntity bukkitEntity; + + public CraftEntity getBukkitEntity() { + if (bukkitEntity == null) { + bukkitEntity = CraftEntity.getEntity(world.getServer(), this); + } + return bukkitEntity; + } + + public void mount(Entity entity) { + Entity originalVehicle = this.vehicle; + Entity originalPassenger = this.vehicle == null ? null : this.vehicle.passenger; + PluginManager pluginManager = Bukkit.getPluginManager(); + getBukkitEntity(); // make sure bukkitEntity is initialised + // CraftBukkit end + this.ar = 0.0D; + this.as = 0.0D; + if (entity == null) { + if (this.vehicle != null) { + // CraftBukkit start + if ((this.bukkitEntity instanceof LivingEntity) && (this.vehicle.getBukkitEntity() instanceof Vehicle)) { + VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.bukkitEntity); + pluginManager.callEvent(event); + + if (event.isCancelled() || vehicle != originalVehicle) { + return; + } + } + // CraftBukkit end + // PaperSpigot start - make EntityDismountEvent cancellable + EntityDismountEvent dismountEvent = new EntityDismountEvent(this.getBukkitEntity(), this.vehicle.getBukkitEntity()); // Spigot + pluginManager.callEvent(dismountEvent); + if (dismountEvent.isCancelled()) return; + // PaperSpigot end + this.setPositionRotation(this.vehicle.locX, this.vehicle.getBoundingBox().b + (double) this.vehicle.length, this.vehicle.locZ, this.yaw, this.pitch); + this.vehicle.passenger = null; + } + + this.vehicle = null; + } else { + // CraftBukkit start + if ((this.bukkitEntity instanceof LivingEntity) && (entity.getBukkitEntity() instanceof Vehicle) && entity.world.isChunkLoaded((int) entity.locX >> 4, (int) entity.locZ >> 4, true)) { + // It's possible to move from one vehicle to another. We need to check if they're already in a vehicle, and fire an exit event if they are. + VehicleExitEvent exitEvent = null; + if (this.vehicle != null && this.vehicle.getBukkitEntity() instanceof Vehicle) { + exitEvent = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.bukkitEntity); + pluginManager.callEvent(exitEvent); + + if (exitEvent.isCancelled() || this.vehicle != originalVehicle || (this.vehicle != null && this.vehicle.passenger != originalPassenger)) { + return; + } + } + + VehicleEnterEvent event = new VehicleEnterEvent((Vehicle) entity.getBukkitEntity(), this.bukkitEntity); + pluginManager.callEvent(event); + + // If a plugin messes with the vehicle or the vehicle's passenger + if (event.isCancelled() || this.vehicle != originalVehicle || (this.vehicle != null && this.vehicle.passenger != originalPassenger)) { + // If we only cancelled the enterevent then we need to put the player in a decent position. + if (exitEvent != null && this.vehicle == originalVehicle && this.vehicle != null && this.vehicle.passenger == originalPassenger) { + this.setPositionRotation(this.vehicle.locX, this.vehicle.getBoundingBox().b + (double) this.vehicle.length, this.vehicle.locZ, this.yaw, this.pitch); + this.vehicle.passenger = null; + this.vehicle = null; + } + return; + } + } + // CraftBukkit end + // Spigot Start + if ( entity.world.isChunkLoaded( (int) entity.locX >> 4, (int) entity.locZ >> 4, true ) ) + { + org.spigotmc.event.entity.EntityMountEvent event = new org.spigotmc.event.entity.EntityMountEvent( this.getBukkitEntity(), entity.getBukkitEntity() ); + pluginManager.callEvent( event ); + if ( event.isCancelled() ) + { + return; + } + } + // Spigot End + + if (this.vehicle != null) { + this.vehicle.passenger = null; + } + + if (entity != null) { + for (Entity entity1 = entity.vehicle; entity1 != null; entity1 = entity1.vehicle) { + if (entity1 == this) { + return; + } + } + } + + this.vehicle = entity; + entity.passenger = this; + } + } + + public float ao() { + return 0.1F; + } + + public Vec3D ap() { + return null; + } + + public void d(BlockPosition blockposition) { + if (this.portalCooldown > 0) { + this.portalCooldown = this.aq(); + } else { + if (!this.world.isClientSide && !blockposition.equals(this.an)) { + this.an = blockposition; + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = Blocks.PORTAL.f(this.world, blockposition); + double d0 = shapedetector_shapedetectorcollection.b().k() == EnumDirection.EnumAxis.X ? (double) shapedetector_shapedetectorcollection.a().getZ() : (double) shapedetector_shapedetectorcollection.a().getX(); + double d1 = shapedetector_shapedetectorcollection.b().k() == EnumDirection.EnumAxis.X ? this.locZ : this.locX; + + d1 = Math.abs(MathHelper.c(d1 - (double) (shapedetector_shapedetectorcollection.b().e().c() == EnumDirection.EnumAxisDirection.NEGATIVE ? 1 : 0), d0, d0 - (double) shapedetector_shapedetectorcollection.d())); + double d2 = MathHelper.c(this.locY - 1.0D, shapedetector_shapedetectorcollection.a().getY(), shapedetector_shapedetectorcollection.a().getY() - shapedetector_shapedetectorcollection.e()); + + this.ao = new Vec3D(d1, d2, 0.0D); + this.ap = shapedetector_shapedetectorcollection.b(); + } + + this.ak = true; + } + } + + public int aq() { + return 300; + } + + public ItemStack[] getEquipment() { + return null; + } + + public void setEquipment(int i, ItemStack itemstack) {} + + public boolean isBurning() { + boolean flag = this.world != null && this.world.isClientSide; + + return !this.fireProof && (this.fireTicks > 0 || flag && this.g(0)); + } + + public boolean au() { + return this.vehicle != null; + } + + public boolean isSneaking() { + return this.g(1); + } + + public void setSneaking(boolean flag) { + this.b(1, flag); + } + + public boolean isSprinting() { + return this.g(3); + } + + public void setSprinting(boolean flag) { + this.b(3, flag); + } + + public boolean isInvisible() { + return this.g(5); + } + + public void setInvisible(boolean flag) { + this.b(5, flag); + } + + public void f(boolean flag) { + this.b(4, flag); + } + + protected boolean g(int i) { + return (this.datawatcher.getByte(0) & 1 << i) != 0; + } + + protected void b(int i, boolean flag) { + byte b0 = this.datawatcher.getByte(0); + + if (flag) { + this.datawatcher.watch(0, Byte.valueOf((byte) (b0 | 1 << i))); + } else { + this.datawatcher.watch(0, Byte.valueOf((byte) (b0 & ~(1 << i)))); + } + + } + + public int getAirTicks() { + return this.datawatcher.getShort(1); + } + + public void setAirTicks(int i) { + this.datawatcher.watch(1, Short.valueOf((short) i)); + } + + public void onLightningStrike(EntityLightning entitylightning) { + // CraftBukkit start + final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity(); + final org.bukkit.entity.Entity stormBukkitEntity = entitylightning.getBukkitEntity(); + final PluginManager pluginManager = Bukkit.getPluginManager(); + + if (thisBukkitEntity instanceof Hanging) { + HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity); + PaintingBreakByEntityEvent paintingEvent = null; + + if (thisBukkitEntity instanceof Painting) { + paintingEvent = new PaintingBreakByEntityEvent((Painting) thisBukkitEntity, stormBukkitEntity); + } + + pluginManager.callEvent(hangingEvent); + + if (paintingEvent != null) { + paintingEvent.setCancelled(hangingEvent.isCancelled()); + pluginManager.callEvent(paintingEvent); + } + + if (hangingEvent.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { + return; + } + } + + if (this.fireProof) { + return; + } + CraftEventFactory.entityDamage = entitylightning; + if (!this.damageEntity(DamageSource.LIGHTNING, 5.0F)) { + CraftEventFactory.entityDamage = null; + return; + } + // CraftBukkit end + ++this.fireTicks; + if (this.fireTicks == 0) { + // CraftBukkit start - Call a combust event when lightning strikes + EntityCombustByEntityEvent entityCombustEvent = new EntityCombustByEntityEvent(stormBukkitEntity, thisBukkitEntity, 8); + pluginManager.callEvent(entityCombustEvent); + if (!entityCombustEvent.isCancelled()) { + this.setOnFire(entityCombustEvent.getDuration()); + } + // CraftBukkit end + } + + } + + public void a(EntityLiving entityliving) {} + + protected boolean j(double d0, double d1, double d2) { + BlockPosition blockposition = new BlockPosition(d0, d1, d2); + double d3 = d0 - (double) blockposition.getX(); + double d4 = d1 - (double) blockposition.getY(); + double d5 = d2 - (double) blockposition.getZ(); + List list = this.world.a(this.getBoundingBox()); + + if (list.isEmpty() && !this.world.u(blockposition)) { + return false; + } else { + byte b0 = 3; + double d6 = 9999.0D; + + if (!this.world.u(blockposition.west()) && d3 < d6) { + d6 = d3; + b0 = 0; + } + + if (!this.world.u(blockposition.east()) && 1.0D - d3 < d6) { + d6 = 1.0D - d3; + b0 = 1; + } + + if (!this.world.u(blockposition.up()) && 1.0D - d4 < d6) { + d6 = 1.0D - d4; + b0 = 3; + } + + if (!this.world.u(blockposition.north()) && d5 < d6) { + d6 = d5; + b0 = 4; + } + + if (!this.world.u(blockposition.south()) && 1.0D - d5 < d6) { + d6 = 1.0D - d5; + b0 = 5; + } + + float f = this.random.nextFloat() * 0.2F + 0.1F; + + if (b0 == 0) { + this.motX = -f; + } + + if (b0 == 1) { + this.motX = f; + } + + if (b0 == 3) { + this.motY = f; + } + + if (b0 == 4) { + this.motZ = -f; + } + + if (b0 == 5) { + this.motZ = f; + } + + return true; + } + } + + public void aA() { + this.H = true; + this.fallDistance = 0.0F; + } + + public String getName() { + if (this.hasCustomName()) { + return this.getCustomName(); + } else { + String s = EntityTypes.b(this); + + if (s == null) { + s = "generic"; + } + + return LocaleI18n.get("entity." + s + ".name"); + } + } + + public Entity[] aB() { + return null; + } + + public boolean k(Entity entity) { + return this == entity; + } + + public float getHeadRotation() { + return 0.0F; + } + + public void f(float f) {} + + public void g(float f) {} + + public boolean aD() { + return true; + } + + public boolean l(Entity entity) { + return false; + } + + public String toString() { + return String.format("%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f]", this.getClass().getSimpleName(), this.getName(), Integer.valueOf(this.id), this.world == null ? "~NULL~" : this.world.getWorldData().getName(), Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ)); + } + + public boolean isInvulnerable(DamageSource damagesource) { + return this.invulnerable && damagesource != DamageSource.OUT_OF_WORLD && !damagesource.u(); + } + + public void m(Entity entity) { + this.setPositionRotation(entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch); + } + + public void n(Entity entity) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + entity.e(nbttagcompound); + this.f(nbttagcompound); + this.portalCooldown = entity.portalCooldown; + this.an = entity.an; + this.ao = entity.ao; + this.ap = entity.ap; + } + + public void c(int i) { + if (!this.world.isClientSide && !this.dead) { + this.world.methodProfiler.a("changeDimension"); + MinecraftServer minecraftserver = MinecraftServer.getServer(); + // CraftBukkit start - Move logic into new function "teleportToLocation" + // int j = this.dimension; + // WorldServer worldserver = minecraftserver.getWorldServer(j); + // WorldServer worldserver1 = minecraftserver.getWorldServer(i); + WorldServer exitWorld = null; + if (this.dimension < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // Plugins must specify exit from custom Bukkit worlds + // Only target existing worlds (compensate for allow-nether/allow-end as false) + for (WorldServer world : minecraftserver.worlds) { + if (world.dimension == i) { + exitWorld = world; + } + } + } + + Location enter = this.getBukkitEntity().getLocation(); + Location exit = exitWorld != null ? minecraftserver.getPlayerList().calculateTarget(enter, minecraftserver.getWorldServer(i)) : null; + boolean useTravelAgent = exitWorld != null && !(this.dimension == 1 && exitWorld.dimension == 1); // don't use agent for custom worlds or return from THE_END + + TravelAgent agent = exit != null ? (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().getTravelAgent() : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins + EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit, agent); + event.useTravelAgent(useTravelAgent); + event.getEntity().getServer().getPluginManager().callEvent(event); + if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !this.isAlive()) { + return; + } + exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo(); + this.teleportTo(exit, true); + } + } + + public void teleportTo(Location exit, boolean portal) { + if (true) { + WorldServer worldserver = ((CraftWorld) getBukkitEntity().getLocation().getWorld()).getHandle(); + WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); + int i = worldserver1.dimension; + // CraftBukkit end + + this.dimension = i; + /* CraftBukkit start - TODO: Check if we need this + if (j == 1 && i == 1) { + worldserver1 = minecraftserver.getWorldServer(0); + this.dimension = 0; + } + // CraftBukkit end */ + + this.world.kill(this); + this.dead = false; + this.world.methodProfiler.a("reposition"); + // CraftBukkit start - Ensure chunks are loaded in case TravelAgent is not used which would initially cause chunks to load during find/create + // minecraftserver.getPlayerList().changeWorld(this, j, worldserver, worldserver1); + boolean before = worldserver1.chunkProviderServer.forceChunkLoad; + worldserver1.chunkProviderServer.forceChunkLoad = true; + worldserver1.getMinecraftServer().getPlayerList().repositionEntity(this, exit, portal); + worldserver1.chunkProviderServer.forceChunkLoad = before; + // CraftBukkit end + this.world.methodProfiler.c("reloading"); + Entity entity = EntityTypes.createEntityByName(EntityTypes.b(this), worldserver1); + + if (entity != null) { + entity.n(this); + /* CraftBukkit start - We need to do this... + if (j == 1 && i == 1) { + BlockPosition blockposition = this.world.r(worldserver1.getSpawn()); + + entity.setPositionRotation(blockposition, entity.yaw, entity.pitch); + } + // CraftBukkit end */ + + worldserver1.addEntity(entity); + // CraftBukkit start - Forward the CraftEntity to the new entity + this.getBukkitEntity().setHandle(entity); + entity.bukkitEntity = this.getBukkitEntity(); + + if (this instanceof EntityInsentient) { + ((EntityInsentient)this).unleash(true, false); // Unleash to prevent duping of leads. + } + // CraftBukkit end + } + + this.dead = true; + this.world.methodProfiler.b(); + worldserver.j(); + worldserver1.j(); + this.world.methodProfiler.b(); + } + } + + public float a(Explosion explosion, World world, BlockPosition blockposition, IBlockData iblockdata) { + return iblockdata.getBlock().a(this); + } + + public boolean a(Explosion explosion, World world, BlockPosition blockposition, IBlockData iblockdata, float f) { + return true; + } + + public int aE() { + return 3; + } + + public Vec3D aG() { + return this.ao; + } + + public EnumDirection aH() { + return this.ap; + } + + public boolean aI() { + return false; + } + + public void appendEntityCrashDetails(CrashReportSystemDetails crashreportsystemdetails) { + crashreportsystemdetails.a("Entity Type", new Callable() { + public String a() throws Exception { + return EntityTypes.b(Entity.this) + " (" + Entity.this.getClass().getCanonicalName() + ")"; + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Entity ID", Integer.valueOf(this.id)); + crashreportsystemdetails.a("Entity Name", new Callable() { + public String a() throws Exception { + return Entity.this.getName(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Entity's Exact location", String.format("%.2f, %.2f, %.2f", Double.valueOf(this.locX), Double.valueOf(this.locY), Double.valueOf(this.locZ))); + crashreportsystemdetails.a("Entity's Block location", CrashReportSystemDetails.a(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ))); + crashreportsystemdetails.a("Entity's Momentum", String.format("%.2f, %.2f, %.2f", Double.valueOf(this.motX), Double.valueOf(this.motY), Double.valueOf(this.motZ))); + crashreportsystemdetails.a("Entity's Rider", new Callable() { + public String a() throws Exception { + return Entity.this.passenger.toString(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Entity's Vehicle", new Callable() { + public String a() throws Exception { + return Entity.this.vehicle.toString(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + } + + public UUID getUniqueID() { + return this.uniqueID; + } + + public boolean aL() { + return true; + } + + public IChatBaseComponent getScoreboardDisplayName() { + ChatComponentText chatcomponenttext = new ChatComponentText(this.getName()); + + chatcomponenttext.getChatModifier().setChatHoverable(this.aQ()); + chatcomponenttext.getChatModifier().setInsertion(this.getUniqueID().toString()); + return chatcomponenttext; + } + + public void setCustomName(String s) { + // CraftBukkit start - Add a sane limit for name length + if (s.length() > 256) { + s = s.substring(0, 256); + } + // CraftBukkit end + this.datawatcher.watch(2, s); + } + + public String getCustomName() { + return this.datawatcher.getString(2); + } + + public boolean hasCustomName() { + return this.datawatcher.getString(2).length() > 0; + } + + public void setCustomNameVisible(boolean flag) { + this.datawatcher.watch(3, Byte.valueOf((byte) (flag ? 1 : 0))); + } + + public boolean getCustomNameVisible() { + return this.datawatcher.getByte(3) == 1; + } + + public void enderTeleportTo(double d0, double d1, double d2) { + this.setPositionRotation(d0, d1, d2, this.yaw, this.pitch); + } + + public void i(int i) {} + + public EnumDirection getDirection() { + return EnumDirection.fromType2(MathHelper.floor((double) (this.yaw * 4.0F / 360.0F) + 0.5D) & 3); + } + + protected ChatHoverable aQ() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + String s = EntityTypes.b(this); + + nbttagcompound.setString("id", this.getUniqueID().toString()); + if (s != null) { + nbttagcompound.setString("type", s); + } + + nbttagcompound.setString("name", this.getName()); + return new ChatHoverable(ChatHoverable.EnumHoverAction.SHOW_ENTITY, new ChatComponentText(nbttagcompound.toString())); + } + + public boolean a(EntityPlayer entityplayer) { + return true; + } + + public AxisAlignedBB getBoundingBox() { + return this.boundingBox; + } + + public void a(AxisAlignedBB axisalignedbb) { + // CraftBukkit start - block invalid bounding boxes + double a = axisalignedbb.a, + b = axisalignedbb.b, + c = axisalignedbb.c, + d = axisalignedbb.d, + e = axisalignedbb.e, + f = axisalignedbb.f; + double len = axisalignedbb.d - axisalignedbb.a; + if (len < 0) d = a; + if (len > 64) d = a + 64.0; + + len = axisalignedbb.e - axisalignedbb.b; + if (len < 0) e = b; + if (len > 64) e = b + 64.0; + + len = axisalignedbb.f - axisalignedbb.c; + if (len < 0) f = c; + if (len > 64) f = c + 64.0; + this.boundingBox = new AxisAlignedBB(a, b, c, d, e, f); + // CraftBukkit end + } + + public float getHeadHeight() { + return this.length * 0.85F; + } + + public boolean aT() { + return this.g; + } + + public void h(boolean flag) { + this.g = flag; + } + + public boolean d(int i, ItemStack itemstack) { + return false; + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) {} + + public boolean a(int i, String s) { + return true; + } + + public BlockPosition getChunkCoordinates() { + return new BlockPosition(this.locX, this.locY + 0.5D, this.locZ); + } + + public Vec3D d() { + return new Vec3D(this.locX, this.locY, this.locZ); + } + + public World getWorld() { + return this.world; + } + + public Entity f() { + return this; + } + + public boolean getSendCommandFeedback() { + return false; + } + + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) { + this.au.a(this, commandobjectiveexecutor_enumcommandresult, i); + } + + public CommandObjectiveExecutor aU() { + return this.au; + } + + public void o(Entity entity) { + this.au.a(entity.aU()); + } + + public NBTTagCompound getNBTTag() { + return null; + } + + public boolean a(EntityHuman entityhuman, Vec3D vec3d) { + return false; + } + + public boolean aW() { + return false; + } + + protected void a(EntityLiving entityliving, Entity entity) { + if (entity instanceof EntityLiving) { + EnchantmentManager.a((EntityLiving) entity, entityliving); + } + + EnchantmentManager.b(entityliving, entity); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityAgeable.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityAgeable.java new file mode 100644 index 0000000..09d4335 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityAgeable.java @@ -0,0 +1,191 @@ +package net.minecraft.server; + +public abstract class EntityAgeable extends EntityCreature { + + protected int a; + protected int b; + protected int c; + private float bm = -1.0F; + private float bn; + public boolean ageLocked = false; // CraftBukkit + + // Spigot start + @Override + public void inactiveTick() + { + super.inactiveTick(); + if ( this.world.isClientSide || this.ageLocked ) + { // CraftBukkit + this.a( this.isBaby() ); + } else + { + int i = this.getAge(); + + if ( i < 0 ) + { + ++i; + this.setAgeRaw( i ); + } else if ( i > 0 ) + { + --i; + this.setAgeRaw( i ); + } + } + } + // Spigot end + + public EntityAgeable(World world) { + super(world); + } + + public abstract EntityAgeable createChild(EntityAgeable entityageable); + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.SPAWN_EGG) { + if (!this.world.isClientSide) { + Class oclass = EntityTypes.a(itemstack.getData()); + + if (oclass != null && this.getClass() == oclass) { + EntityAgeable entityageable = this.createChild(this); + + if (entityageable != null) { + entityageable.setAgeRaw(-24000); + entityageable.setPositionRotation(this.locX, this.locY, this.locZ, 0.0F, 0.0F); + this.world.addEntity(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit + if (itemstack.hasName()) { + entityageable.setCustomName(itemstack.getName()); + } + + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + if (itemstack.count == 0) { // CraftBukkit - allow less than 0 stacks as "infinite" + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + } + } + } + } + + return true; + } else { + return false; + } + } + + protected void h() { + super.h(); + this.datawatcher.a(12, Byte.valueOf((byte) 0)); + } + + public int getAge() { + return this.world.isClientSide ? this.datawatcher.getByte(12) : this.a; + } + + public void setAge(int i, boolean flag) { + int j = this.getAge(); + int k = j; + + j += i * 20; + if (j > 0) { + j = 0; + if (k < 0) { + this.n(); + } + } + + int l = j - k; + + this.setAgeRaw(j); + if (flag) { + this.b += l; + if (this.c == 0) { + this.c = 40; + } + } + + if (this.getAge() == 0) { + this.setAgeRaw(this.b); + } + + } + + public void setAge(int i) { + this.setAge(i, false); + } + + public void setAgeRaw(int i) { + this.datawatcher.watch(12, Byte.valueOf((byte) MathHelper.clamp(i, -1, 1))); + this.a = i; + this.a(this.isBaby()); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("Age", this.getAge()); + nbttagcompound.setInt("ForcedAge", this.b); + nbttagcompound.setBoolean("AgeLocked", this.ageLocked); // CraftBukkit + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setAgeRaw(nbttagcompound.getInt("Age")); + this.b = nbttagcompound.getInt("ForcedAge"); + this.ageLocked = nbttagcompound.getBoolean("AgeLocked"); // CraftBukkit + } + + public void m() { + super.m(); + 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.c; + } + + this.a(this.isBaby()); + } else { + int i = this.getAge(); + + if (i < 0) { + ++i; + this.setAgeRaw(i); + if (i == 0) { + this.n(); + } + } else if (i > 0) { + --i; + this.setAgeRaw(i); + } + } + + } + + protected void n() {} + + public boolean isBaby() { + return this.getAge() < 0; + } + + public void a(boolean flag) { + this.a(flag ? 0.5F : 1.0F); + } + + public final void setSize(float f, float f1) { // CraftBukkit - protected to public + boolean flag = this.bm > 0.0F; + + this.bm = f; + this.bn = f1; + if (!flag) { + this.a(1.0F); + } + + } + + protected final void a(float f) { + super.setSize(this.bm * f, this.bn * f); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityAnimal.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityAnimal.java new file mode 100644 index 0000000..a831529 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityAnimal.java @@ -0,0 +1,144 @@ +package net.minecraft.server; + +public abstract class EntityAnimal extends EntityAgeable implements IAnimal { + + protected Block bn; + private int bm; + private EntityHuman bo; + + public EntityAnimal(World world) { + super(world); + this.bn = Blocks.GRASS; + } + + protected void E() { + if (this.getAge() != 0) { + this.bm = 0; + } + + super.E(); + } + + public void m() { + super.m(); + if (this.getAge() != 0) { + this.bm = 0; + } + + if (this.bm > 0) { + --this.bm; + if (this.bm % 10 == 0) { + double d0 = this.random.nextGaussian() * 0.02D; + 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]); + } + } + + } + + /* CraftBukkit start + // Function disabled as it has no special function anymore after + // setSitting is disabled. + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + this.bm = 0; + return super.damageEntity(damagesource, f); + } + } + // CraftBukkit end */ + + public float a(BlockPosition blockposition) { + return this.world.getType(blockposition.down()).getBlock() == Blocks.GRASS ? 10.0F : this.world.o(blockposition) - 0.5F; + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("InLove", this.bm); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.bm = nbttagcompound.getInt("InLove"); + } + + public boolean bR() { + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.getBoundingBox().b); + int k = MathHelper.floor(this.locZ); + BlockPosition blockposition = new BlockPosition(i, j, k); + + return this.world.getType(blockposition.down()).getBlock() == this.bn && this.world.k(blockposition) > 8 && super.bR(); + } + + public int w() { + return 120; + } + + protected boolean isTypeNotPersistent() { + return false; + } + + protected int getExpValue(EntityHuman entityhuman) { + return 1 + this.world.random.nextInt(3); + } + + public boolean d(ItemStack itemstack) { + return itemstack == null ? false : itemstack.getItem() == Items.WHEAT; + } + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null) { + if (this.d(itemstack) && this.getAge() == 0 && this.bm <= 0) { + this.a(entityhuman, itemstack); + this.c(entityhuman); + return true; + } + + if (this.isBaby() && this.d(itemstack)) { + this.a(entityhuman, itemstack); + this.setAge((int) ((float) (-this.getAge() / 20) * 0.1F), true); + return true; + } + } + + return super.a(entityhuman); + } + + protected void a(EntityHuman entityhuman, ItemStack itemstack) { + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + if (itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + } + + } + + public void c(EntityHuman entityhuman) { + this.bm = 600; + this.bo = entityhuman; + this.world.broadcastEntityEffect(this, (byte) 18); + } + + public EntityHuman cq() { + return this.bo; + } + + public boolean isInLove() { + return this.bm > 0; + } + + public void cs() { + this.bm = 0; + } + + public boolean mate(EntityAnimal entityanimal) { + return entityanimal == this ? false : (entityanimal.getClass() != this.getClass() ? false : this.isInLove() && entityanimal.isInLove()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityArmorStand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityArmorStand.java new file mode 100644 index 0000000..7be0351 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityArmorStand.java @@ -0,0 +1,716 @@ +package net.minecraft.server; + +import java.util.List; + +// CraftBukkit start +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.craftbukkit.CraftEquipmentSlot; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; +// CraftBukkit end + +public class EntityArmorStand extends EntityLiving { + + private static final Vector3f a = new Vector3f(0.0F, 0.0F, 0.0F); + private static final Vector3f b = new Vector3f(0.0F, 0.0F, 0.0F); + private static final Vector3f c = new Vector3f(-10.0F, 0.0F, -10.0F); + private static final Vector3f d = new Vector3f(-15.0F, 0.0F, 10.0F); + private static final Vector3f e = new Vector3f(-1.0F, 0.0F, -1.0F); + private static final Vector3f f = new Vector3f(1.0F, 0.0F, 1.0F); + private final ItemStack[] items; + private boolean h; + private long i; + private int bi; + private boolean bj; + public Vector3f headPose; + public Vector3f bodyPose; + public Vector3f leftArmPose; + public Vector3f rightArmPose; + public Vector3f leftLegPose; + public Vector3f rightLegPose; + + public EntityArmorStand(World world) { + super(world); + this.items = new ItemStack[5]; + this.headPose = EntityArmorStand.a; + this.bodyPose = EntityArmorStand.b; + this.leftArmPose = EntityArmorStand.c; + this.rightArmPose = EntityArmorStand.d; + this.leftLegPose = EntityArmorStand.e; + this.rightLegPose = EntityArmorStand.f; + this.b(true); + this.noclip = this.hasGravity(); + this.setSize(0.5F, 1.975F); + } + + public EntityArmorStand(World world, double d0, double d1, double d2) { + this(world); + this.setPosition(d0, d1, d2); + } + + public boolean bM() { + return super.bM() && !this.hasGravity(); + } + + protected void h() { + super.h(); + this.datawatcher.a(10, Byte.valueOf((byte) 0)); + this.datawatcher.a(11, EntityArmorStand.a); + this.datawatcher.a(12, EntityArmorStand.b); + this.datawatcher.a(13, EntityArmorStand.c); + this.datawatcher.a(14, EntityArmorStand.d); + this.datawatcher.a(15, EntityArmorStand.e); + this.datawatcher.a(16, EntityArmorStand.f); + } + + public ItemStack bA() { + return this.items[0]; + } + + public ItemStack getEquipment(int i) { + return this.items[i]; + } + + public void setEquipment(int i, ItemStack itemstack) { + this.items[i] = itemstack; + } + + public ItemStack[] getEquipment() { + return this.items; + } + + public boolean d(int i, ItemStack itemstack) { + int j; + + if (i == 99) { + j = 0; + } else { + j = i - 100 + 1; + if (j < 0 || j >= this.items.length) { + return false; + } + } + + if (itemstack != null && EntityInsentient.c(itemstack) != j && (j != 4 || !(itemstack.getItem() instanceof ItemBlock))) { + return false; + } else { + this.setEquipment(j, itemstack); + return true; + } + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.items.length; ++i) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + if (this.items[i] != null) { + this.items[i].save(nbttagcompound1); + } + + nbttaglist.add(nbttagcompound1); + } + + nbttagcompound.set("Equipment", nbttaglist); + if (this.getCustomNameVisible() && (this.getCustomName() == null || this.getCustomName().length() == 0)) { + nbttagcompound.setBoolean("CustomNameVisible", this.getCustomNameVisible()); + } + + nbttagcompound.setBoolean("Invisible", this.isInvisible()); + nbttagcompound.setBoolean("Small", this.isSmall()); + nbttagcompound.setBoolean("ShowArms", this.hasArms()); + nbttagcompound.setInt("DisabledSlots", this.bi); + nbttagcompound.setBoolean("NoGravity", this.hasGravity()); + nbttagcompound.setBoolean("NoBasePlate", this.hasBasePlate()); + if (this.s()) { + nbttagcompound.setBoolean("Marker", this.s()); + } + + nbttagcompound.set("Pose", this.z()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("Equipment", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("Equipment", 10); + + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = ItemStack.createStack(nbttaglist.get(i)); + } + } + + this.setInvisible(nbttagcompound.getBoolean("Invisible")); + this.setSmall(nbttagcompound.getBoolean("Small")); + this.setArms(nbttagcompound.getBoolean("ShowArms")); + this.bi = nbttagcompound.getInt("DisabledSlots"); + this.setGravity(nbttagcompound.getBoolean("NoGravity")); + this.setBasePlate(nbttagcompound.getBoolean("NoBasePlate")); + this.n(nbttagcompound.getBoolean("Marker")); + this.bj = !this.s(); + this.noclip = this.hasGravity(); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Pose"); + + this.h(nbttagcompound1); + } + + private void h(NBTTagCompound nbttagcompound) { + NBTTagList nbttaglist = nbttagcompound.getList("Head", 5); + + if (nbttaglist.size() > 0) { + this.setHeadPose(new Vector3f(nbttaglist)); + } else { + this.setHeadPose(EntityArmorStand.a); + } + + NBTTagList nbttaglist1 = nbttagcompound.getList("Body", 5); + + if (nbttaglist1.size() > 0) { + this.setBodyPose(new Vector3f(nbttaglist1)); + } else { + this.setBodyPose(EntityArmorStand.b); + } + + NBTTagList nbttaglist2 = nbttagcompound.getList("LeftArm", 5); + + if (nbttaglist2.size() > 0) { + this.setLeftArmPose(new Vector3f(nbttaglist2)); + } else { + this.setLeftArmPose(EntityArmorStand.c); + } + + NBTTagList nbttaglist3 = nbttagcompound.getList("RightArm", 5); + + if (nbttaglist3.size() > 0) { + this.setRightArmPose(new Vector3f(nbttaglist3)); + } else { + this.setRightArmPose(EntityArmorStand.d); + } + + NBTTagList nbttaglist4 = nbttagcompound.getList("LeftLeg", 5); + + if (nbttaglist4.size() > 0) { + this.setLeftLegPose(new Vector3f(nbttaglist4)); + } else { + this.setLeftLegPose(EntityArmorStand.e); + } + + NBTTagList nbttaglist5 = nbttagcompound.getList("RightLeg", 5); + + if (nbttaglist5.size() > 0) { + this.setRightLegPose(new Vector3f(nbttaglist5)); + } else { + this.setRightLegPose(EntityArmorStand.f); + } + + } + + private NBTTagCompound z() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + if (!EntityArmorStand.a.equals(this.headPose)) { + nbttagcompound.set("Head", this.headPose.a()); + } + + if (!EntityArmorStand.b.equals(this.bodyPose)) { + nbttagcompound.set("Body", this.bodyPose.a()); + } + + if (!EntityArmorStand.c.equals(this.leftArmPose)) { + nbttagcompound.set("LeftArm", this.leftArmPose.a()); + } + + if (!EntityArmorStand.d.equals(this.rightArmPose)) { + nbttagcompound.set("RightArm", this.rightArmPose.a()); + } + + if (!EntityArmorStand.e.equals(this.leftLegPose)) { + nbttagcompound.set("LeftLeg", this.leftLegPose.a()); + } + + if (!EntityArmorStand.f.equals(this.rightLegPose)) { + nbttagcompound.set("RightLeg", this.rightLegPose.a()); + } + + return nbttagcompound; + } + + public boolean ae() { + return false; + } + + protected void s(Entity entity) {} + + protected void bL() { + List list = this.world.getEntities(this, this.getBoundingBox()); + + if (list != null && !list.isEmpty()) { + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + + if (entity instanceof EntityMinecartAbstract && ((EntityMinecartAbstract) entity).s() == EntityMinecartAbstract.EnumMinecartType.RIDEABLE && this.h(entity) <= 0.2D) { + entity.collide(this); + } + } + } + + } + + public boolean a(EntityHuman entityhuman, Vec3D vec3d) { + if (this.s()) { + return false; + } else if (!this.world.isClientSide && !entityhuman.isSpectator()) { + byte b0 = 0; + ItemStack itemstack = entityhuman.bZ(); + boolean flag = itemstack != null; + + if (flag && itemstack.getItem() instanceof ItemArmor) { + ItemArmor itemarmor = (ItemArmor) itemstack.getItem(); + + if (itemarmor.b == 3) { + b0 = 1; + } else if (itemarmor.b == 2) { + b0 = 2; + } else if (itemarmor.b == 1) { + b0 = 3; + } else if (itemarmor.b == 0) { + b0 = 4; + } + } + + if (flag && (itemstack.getItem() == Items.SKULL || itemstack.getItem() == Item.getItemOf(Blocks.PUMPKIN))) { + b0 = 4; + } + + double d0 = 0.1D; + double d1 = 0.9D; + double d2 = 0.4D; + double d3 = 1.6D; + byte b1 = 0; + boolean flag1 = this.isSmall(); + double d4 = flag1 ? vec3d.b * 2.0D : vec3d.b; + + if (d4 >= 0.1D && d4 < 0.1D + (flag1 ? 0.8D : 0.45D) && this.items[1] != null) { + b1 = 1; + } else if (d4 >= 0.9D + (flag1 ? 0.3D : 0.0D) && d4 < 0.9D + (flag1 ? 1.0D : 0.7D) && this.items[3] != null) { + b1 = 3; + } else if (d4 >= 0.4D && d4 < 0.4D + (flag1 ? 1.0D : 0.8D) && this.items[2] != null) { + b1 = 2; + } else if (d4 >= 1.6D && this.items[4] != null) { + b1 = 4; + } + + boolean flag2 = this.items[b1] != null; + + if ((this.bi & 1 << b1) != 0 || (this.bi & 1 << b0) != 0) { + b1 = b0; + if ((this.bi & 1 << b0) != 0) { + if ((this.bi & 1) != 0) { + return true; + } + + b1 = 0; + } + } + + if (flag && b0 == 0 && !this.hasArms()) { + return true; + } else { + if (flag) { + this.a(entityhuman, b0); + } else if (flag2) { + this.a(entityhuman, b1); + } + + return true; + } + } else { + return true; + } + } + + private void a(EntityHuman entityhuman, int i) { + ItemStack itemstack = this.items[i]; + + if (itemstack == null || (this.bi & 1 << i + 8) == 0) { + if (itemstack != null || (this.bi & 1 << i + 16) == 0) { + int j = entityhuman.inventory.itemInHandIndex; + ItemStack itemstack1 = entityhuman.inventory.getItem(j); + ItemStack itemstack2; + + // CraftBukkit start + org.bukkit.inventory.ItemStack armorStandItem = CraftItemStack.asCraftMirror(itemstack); + org.bukkit.inventory.ItemStack playerHeldItem = CraftItemStack.asCraftMirror(itemstack1); + + Player player = (Player) entityhuman.getBukkitEntity(); + ArmorStand self = (ArmorStand) this.getBukkitEntity(); + + EquipmentSlot slot = CraftEquipmentSlot.getSlot(i); + PlayerArmorStandManipulateEvent armorStandManipulateEvent = new PlayerArmorStandManipulateEvent(player,self,playerHeldItem,armorStandItem,slot); + this.world.getServer().getPluginManager().callEvent(armorStandManipulateEvent); + + if (armorStandManipulateEvent.isCancelled()) { + return; + } + // CraftBukkit end + + if (entityhuman.abilities.canInstantlyBuild && (itemstack == null || itemstack.getItem() == Item.getItemOf(Blocks.AIR)) && itemstack1 != null) { + itemstack2 = itemstack1.cloneItemStack(); + itemstack2.count = 1; + this.setEquipment(i, itemstack2); + } else if (itemstack1 != null && itemstack1.count > 1) { + if (itemstack == null) { + itemstack2 = itemstack1.cloneItemStack(); + itemstack2.count = 1; + this.setEquipment(i, itemstack2); + --itemstack1.count; + } + } else { + this.setEquipment(i, itemstack1); + entityhuman.inventory.setItem(j, itemstack); + } + } + } + } + + public boolean damageEntity(DamageSource damagesource, float f) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { + return false; + } + // CraftBukkit end + if (this.world.isClientSide || this.dead) { + return false; + } else if (DamageSource.OUT_OF_WORLD.equals(damagesource)) { // PaperSpigot + this.die(); + return false; + } else if (!this.isInvulnerable(damagesource) && !this.h && !this.s()) { + if (damagesource.isExplosion()) { + this.D(); + this.die(); + return false; + } else if (DamageSource.FIRE.equals(damagesource)) { + if (!this.isBurning()) { + this.setOnFire(5); + } else { + this.a(0.15F); + } + + return false; + } else if (DamageSource.BURN.equals(damagesource) && this.getHealth() > 0.5F) { + this.a(4.0F); + return false; + } else { + boolean flag = "arrow".equals(damagesource.p()); + boolean flag1 = "player".equals(damagesource.p()); + + if (!flag1 && !flag) { + return false; + } else { + if (damagesource.i() instanceof EntityArrow) { + damagesource.i().die(); + } + + if (damagesource.getEntity() instanceof EntityHuman && !((EntityHuman) damagesource.getEntity()).abilities.mayBuild) { + return false; + } else if (damagesource.u()) { + this.A(); + this.die(); + return false; + } else { + long i = this.world.getTime(); + + if (i - this.i > 5L && !flag) { + this.i = i; + } else { + this.C(); + this.A(); + this.die(); + } + + return false; + } + } + } + } else { + return false; + } + } + + private void A() { + if (this.world instanceof WorldServer) { + ((WorldServer) this.world).a(EnumParticle.BLOCK_DUST, this.locX, this.locY + (double) this.length / 1.5D, this.locZ, 10, (double) (this.width / 4.0F), (double) (this.length / 4.0F), (double) (this.width / 4.0F), 0.05D, new int[] { Block.getCombinedId(Blocks.PLANKS.getBlockData())}); + } + + } + + private void a(float f) { + float f1 = this.getHealth(); + + f1 -= f; + if (f1 <= 0.5F) { + this.D(); + this.die(); + } else { + this.setHealth(f1); + } + + } + + private void C() { + Block.a(this.world, new BlockPosition(this), new ItemStack(Items.ARMOR_STAND)); + this.D(); + } + + private void D() { + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null && this.items[i].count > 0) { + if (this.items[i] != null) { + Block.a(this.world, (new BlockPosition(this)).up(), this.items[i]); + } + + this.items[i] = null; + } + } + + } + + protected float h(float f, float f1) { + this.aJ = this.lastYaw; + this.aI = this.yaw; + return 0.0F; + } + + public float getHeadHeight() { + return this.isBaby() ? this.length * 0.5F : this.length * 0.9F; + } + + public void g(float f, float f1) { + if (!this.hasGravity()) { + super.g(f, f1); + } + } + + public void t_() { + super.t_(); + Vector3f vector3f = this.datawatcher.h(11); + + if (!this.headPose.equals(vector3f)) { + this.setHeadPose(vector3f); + } + + Vector3f vector3f1 = this.datawatcher.h(12); + + if (!this.bodyPose.equals(vector3f1)) { + this.setBodyPose(vector3f1); + } + + Vector3f vector3f2 = this.datawatcher.h(13); + + if (!this.leftArmPose.equals(vector3f2)) { + this.setLeftArmPose(vector3f2); + } + + Vector3f vector3f3 = this.datawatcher.h(14); + + if (!this.rightArmPose.equals(vector3f3)) { + this.setRightArmPose(vector3f3); + } + + Vector3f vector3f4 = this.datawatcher.h(15); + + if (!this.leftLegPose.equals(vector3f4)) { + this.setLeftLegPose(vector3f4); + } + + Vector3f vector3f5 = this.datawatcher.h(16); + + if (!this.rightLegPose.equals(vector3f5)) { + this.setRightLegPose(vector3f5); + } + + boolean flag = this.s(); + + if (!this.bj && flag) { + this.a(false); + } else { + if (!this.bj || flag) { + return; + } + + this.a(true); + } + + this.bj = flag; + } + + private void a(boolean flag) { + double d0 = this.locX; + double d1 = this.locY; + double d2 = this.locZ; + + if (flag) { + this.setSize(0.5F, 1.975F); + } else { + this.setSize(0.0F, 0.0F); + } + + this.setPosition(d0, d1, d2); + } + + protected void B() { + this.setInvisible(this.h); + } + + public void setInvisible(boolean flag) { + this.h = flag; + super.setInvisible(flag); + } + + public boolean isBaby() { + return this.isSmall(); + } + + public void G() { + this.die(); + } + + public boolean aW() { + return this.isInvisible(); + } + + public void setSmall(boolean flag) { + byte b0 = this.datawatcher.getByte(10); + + if (flag) { + b0 = (byte) (b0 | 1); + } else { + b0 &= -2; + } + + this.datawatcher.watch(10, Byte.valueOf(b0)); + } + + public boolean isSmall() { + return (this.datawatcher.getByte(10) & 1) != 0; + } + + public void setGravity(boolean flag) { + byte b0 = this.datawatcher.getByte(10); + + if (flag) { + b0 = (byte) (b0 | 2); + } else { + b0 &= -3; + } + + this.datawatcher.watch(10, Byte.valueOf(b0)); + } + + public boolean hasGravity() { + return (this.datawatcher.getByte(10) & 2) != 0; + } + + public void setArms(boolean flag) { + byte b0 = this.datawatcher.getByte(10); + + if (flag) { + b0 = (byte) (b0 | 4); + } else { + b0 &= -5; + } + + this.datawatcher.watch(10, Byte.valueOf(b0)); + } + + public boolean hasArms() { + return (this.datawatcher.getByte(10) & 4) != 0; + } + + public void setBasePlate(boolean flag) { + byte b0 = this.datawatcher.getByte(10); + + if (flag) { + b0 = (byte) (b0 | 8); + } else { + b0 &= -9; + } + + this.datawatcher.watch(10, Byte.valueOf(b0)); + } + + public boolean hasBasePlate() { + return (this.datawatcher.getByte(10) & 8) != 0; + } + + // PAIL + public void n(boolean flag) { // CraftBukkit - public + byte b0 = this.datawatcher.getByte(10); + + if (flag) { + b0 = (byte) (b0 | 16); + } else { + b0 &= -17; + } + + this.datawatcher.watch(10, Byte.valueOf(b0)); + } + + // PAIL + public boolean s() { + return (this.datawatcher.getByte(10) & 16) != 0; + } + + public void setHeadPose(Vector3f vector3f) { + this.headPose = vector3f; + this.datawatcher.watch(11, vector3f); + } + + public void setBodyPose(Vector3f vector3f) { + this.bodyPose = vector3f; + this.datawatcher.watch(12, vector3f); + } + + public void setLeftArmPose(Vector3f vector3f) { + this.leftArmPose = vector3f; + this.datawatcher.watch(13, vector3f); + } + + public void setRightArmPose(Vector3f vector3f) { + this.rightArmPose = vector3f; + this.datawatcher.watch(14, vector3f); + } + + public void setLeftLegPose(Vector3f vector3f) { + this.leftLegPose = vector3f; + this.datawatcher.watch(15, vector3f); + } + + public void setRightLegPose(Vector3f vector3f) { + this.rightLegPose = vector3f; + this.datawatcher.watch(16, vector3f); + } + + public Vector3f t() { + return this.headPose; + } + + public Vector3f u() { + return this.bodyPose; + } + + public boolean ad() { + return super.ad() && !this.s(); + } + + // 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; + super.move(motX, motY, motZ); + } + // TacoSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityArrow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityArrow.java new file mode 100644 index 0000000..60fe6b9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityArrow.java @@ -0,0 +1,522 @@ +package net.minecraft.server; + +import me.levansj01.mythicspigot.MythicConfiguration; +import net.techcable.tacospigot.event.entity.ArrowCollideEvent; +import org.bukkit.Bukkit; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.entity.EntityCombustByEntityEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; + +import java.util.List; + +// CraftBukkit start +// CraftBukkit end +// TacoSpigot start +// TacoSpigot end + +public class EntityArrow extends Entity implements IProjectile { + + private int d = -1; + private int e = -1; + private int f = -1; + private Block g; + private int h; + public boolean inGround = false; // Spigot - private -> public + public int fromPlayer; + public int shake; + public Entity shooter; + private int ar; + private int as; + private double damage = 2.0D; + public int knockbackStrength; + + // Spigot Start + @Override + public void inactiveTick() + { + if ( this.inGround ) + { + this.ar += 1; // Despawn counter. First int after shooter + } + super.inactiveTick(); + } + // Spigot End + + public EntityArrow(World world) { + super(world); + this.j = 10.0D; + this.setSize(0.5F, 0.5F); + } + + public EntityArrow(World world, double d0, double d1, double d2) { + super(world); + this.j = 10.0D; + this.setSize(0.5F, 0.5F); + this.setPosition(d0, d1, d2); + } + + public EntityArrow(World world, EntityLiving entityliving, EntityLiving entityliving1, float f, float f1) { + super(world); + this.j = 10.0D; + this.shooter = entityliving; + this.projectileSource = (LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit + if (entityliving instanceof EntityHuman) { + this.fromPlayer = 1; + } + + this.locY = entityliving.locY + (double) entityliving.getHeadHeight() - 0.10000000149011612D; + double d0 = entityliving1.locX - entityliving.locX; + double d1 = entityliving1.getBoundingBox().b + (double) (entityliving1.length / 3.0F) - this.locY; + double d2 = entityliving1.locZ - entityliving.locZ; + double d3 = MathHelper.sqrt(d0 * d0 + d2 * d2); + + if (d3 >= 1.0E-7D) { + float f2 = (float) (MathHelper.b(d2, d0) * 180.0D / 3.1415927410125732D) - 90.0F; + float f3 = (float) (-(MathHelper.b(d1, d3) * 180.0D / 3.1415927410125732D)); + double d4 = d0 / d3; + double d5 = d2 / d3; + + this.setPositionRotation(entityliving.locX + d4, this.locY, entityliving.locZ + d5, f2, f3); + float f4 = (float) (d3 * 0.20000000298023224D); + + this.shoot(d0, d1 + (double) f4, d2, f, f1); + } + } + + public EntityArrow(World world, EntityLiving entityliving, float f) { + super(world); + this.j = 10.0D; + this.shooter = entityliving; + this.projectileSource = (LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit + if (entityliving instanceof EntityHuman) { + this.fromPlayer = 1; + } + + this.setSize(0.5F, 0.5F); + this.setPositionRotation(entityliving.locX, entityliving.locY + (double) entityliving.getHeadHeight(), entityliving.locZ, entityliving.yaw, entityliving.pitch); + this.locX -= MathHelper.cos(this.yaw / 180.0F * 3.1415927F) * 0.16F; + this.locY -= 0.10000000149011612D; + this.locZ -= MathHelper.sin(this.yaw / 180.0F * 3.1415927F) * 0.16F; + this.setPosition(this.locX, this.locY, this.locZ); + this.motX = -MathHelper.sin(this.yaw / 180.0F * 3.1415927F) * MathHelper.cos(this.pitch / 180.0F * 3.1415927F); + this.motZ = MathHelper.cos(this.yaw / 180.0F * 3.1415927F) * MathHelper.cos(this.pitch / 180.0F * 3.1415927F); + this.motY = -MathHelper.sin(this.pitch / 180.0F * 3.1415927F); + this.shoot(this.motX, this.motY, this.motZ, f * 1.5F, 1.0F); + } + + protected void h() { + this.datawatcher.a(16, Byte.valueOf((byte) 0)); + } + + public void shoot(double d0, double d1, double d2, float f, float f1) { + float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + + d0 /= f2; + d1 /= f2; + d2 /= f2; + d0 += this.random.nextGaussian() * (double) (this.random.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double) f1; + d1 += this.random.nextGaussian() * (double) (this.random.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double) f1; + d2 += this.random.nextGaussian() * (double) (this.random.nextBoolean() ? -1 : 1) * 0.007499999832361937D * (double) f1; + d0 *= f; + d1 *= f; + d2 *= f; + this.motX = d0; + this.motY = d1; + this.motZ = d2; + float f3 = MathHelper.sqrt(d0 * d0 + d2 * d2); + + this.lastYaw = this.yaw = (float) (MathHelper.b(d0, d2) * 180.0D / 3.1415927410125732D); + this.lastPitch = this.pitch = (float) (MathHelper.b(d1, f3) * 180.0D / 3.1415927410125732D); + this.ar = 0; + } + + public void t_() { + super.t_(); + if (this.lastPitch == 0.0F && this.lastYaw == 0.0F) { + float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + + this.lastYaw = this.yaw = (float) (MathHelper.b(this.motX, this.motZ) * 180.0D / 3.1415927410125732D); + this.lastPitch = this.pitch = (float) (MathHelper.b(this.motY, f) * 180.0D / 3.1415927410125732D); + } + + BlockPosition blockposition = new BlockPosition(this.d, this.e, this.f); + IBlockData iblockdata = this.world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block.getMaterial() != Material.AIR) { + block.updateShape(this.world, blockposition); + AxisAlignedBB axisalignedbb = block.a(this.world, blockposition, iblockdata); + + if (axisalignedbb != null && axisalignedbb.a(new Vec3D(this.locX, this.locY, this.locZ))) { + this.inGround = true; + } + } + + if (this.shake > 0) { + --this.shake; + } + + if (this.inGround) { + int i = block.toLegacyData(iblockdata); + + if (block == this.g && i == this.h) { + ++this.ar; + if (this.ar >= world.spigotConfig.arrowDespawnRate) { // Spigot - First int after shooter + this.die(); + } + } else { + this.inGround = false; + this.motX *= this.random.nextFloat() * 0.2F; + this.motY *= this.random.nextFloat() * 0.2F; + this.motZ *= this.random.nextFloat() * 0.2F; + this.ar = 0; + this.as = 0; + } + + } else { + ++this.as; + Vec3D vec3d = new Vec3D(this.locX, this.locY, this.locZ); + Vec3D vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, vec3d1, false, true, false); + + vec3d = new Vec3D(this.locX, this.locY, this.locZ); + vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + if (movingobjectposition != null) { + vec3d1 = new Vec3D(movingobjectposition.pos.a, movingobjectposition.pos.b, movingobjectposition.pos.c); + } + + Entity entity = null; + List list = this.world.getEntities(this, this.getBoundingBox().a(this.motX, this.motY, this.motZ).grow(1.0D, 1.0D, 1.0D)); + double d0 = 0.0D; + + int j; + float f1; + + for (j = 0; j < list.size(); ++j) { + Entity entity1 = (Entity) list.get(j); + + if (entity1.ad() && (entity1 != this.shooter || this.as >= 5)) { + f1 = 0.3F; + AxisAlignedBB axisalignedbb1 = entity1.getBoundingBox().grow(f1, f1, f1); + MovingObjectPosition movingobjectposition1 = axisalignedbb1.a(vec3d, vec3d1); + + if (movingobjectposition1 != null) { + double d1 = vec3d.distanceSquared(movingobjectposition1.pos); + + if (d1 < d0 || d0 == 0.0D) { + entity = entity1; + d0 = d1; + } + } + } + } + + if (entity != null) { + movingobjectposition = new MovingObjectPosition(entity); + } + + if (movingobjectposition != null && movingobjectposition.entity != null && movingobjectposition.entity instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) movingobjectposition.entity; + + if (entityhuman.abilities.isInvulnerable || this.shooter instanceof EntityHuman && !((EntityHuman) this.shooter).a(entityhuman)) { + movingobjectposition = null; + } + } + + float f2; + float f3; + + // PaperSpigot start - Allow arrows to fly through vanished players the shooter can't see + if (movingobjectposition != null && movingobjectposition.entity instanceof EntityPlayer && shooter != null && shooter instanceof EntityPlayer) { + if (!((EntityPlayer) shooter).getBukkitEntity().canSee(((EntityPlayer) movingobjectposition.entity).getBukkitEntity())) { + movingobjectposition = null; + } + } + // PaperSpigot end + // TacoSpigot start - call better event + if (movingobjectposition != null && movingobjectposition.entity != null) { + ArrowCollideEvent collideEvent = new ArrowCollideEvent((Arrow) getBukkitEntity(), movingobjectposition.entity.getBukkitEntity()); + Bukkit.getPluginManager().callEvent(collideEvent); + if (collideEvent.isCancelled()) movingobjectposition = null; + } + // TacoSpigot end + if (movingobjectposition != null) { + org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); // CraftBukkit - Call event + if (movingobjectposition.entity != null) { + f2 = MathHelper.sqrt(this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ); + int k = MathHelper.f((double) f2 * this.damage); + + if (this.isCritical()) { + k += this.random.nextInt(k / 2 + 2); + } + + DamageSource damagesource; + + if (this.shooter == null) { + damagesource = DamageSource.arrow(this, this); + } else { + damagesource = DamageSource.arrow(this, this.shooter); + } + + // CraftBukkit start - Moved damage call + if (movingobjectposition.entity.damageEntity(damagesource, (float) k)) { + if (this.isBurning() && !(movingobjectposition.entity instanceof EntityEnderman) && (!(movingobjectposition.entity instanceof EntityPlayer) || !(this.shooter instanceof EntityPlayer) || this.world.pvpMode)) { // CraftBukkit - abide by pvp setting if destination is a player + EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 5); + org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); + if (!combustEvent.isCancelled()) { + movingobjectposition.entity.setOnFire(combustEvent.getDuration()); + } + // CraftBukkit end + } + + // if (movingobjectposition.entity.damageEntity(damagesource, (float) k)) { // CraftBukkit - moved up + if (movingobjectposition.entity instanceof EntityLiving) { + EntityLiving entityliving = (EntityLiving) movingobjectposition.entity; + + if (!this.world.isClientSide) { + entityliving.o(entityliving.bv() + 1); + } + + if (this.knockbackStrength > 0) { + f3 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + if (f3 > 0.0F) { + movingobjectposition.entity.g(this.motX * (double) this.knockbackStrength * 0.6000000238418579D / (double) f3, 0.1D, this.motZ * (double) this.knockbackStrength * 0.6000000238418579D / (double) f3); + } + } + + if (this.shooter instanceof EntityLiving) { + EnchantmentManager.a(entityliving, this.shooter); + EnchantmentManager.b((EntityLiving) this.shooter, entityliving); + } + + if (this.shooter != null && movingobjectposition.entity != this.shooter && movingobjectposition.entity instanceof EntityHuman && this.shooter instanceof EntityPlayer) { + ((EntityPlayer) this.shooter).playerConnection.sendPacket(new PacketPlayOutGameStateChange(6, 0.0F)); + } + } + + this.makeSound("random.bowhit", 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); + if (!(movingobjectposition.entity instanceof EntityEnderman)) { + this.die(); + } + } else { + this.motX *= -0.10000000149011612D; + this.motY *= -0.10000000149011612D; + this.motZ *= -0.10000000149011612D; + this.yaw += 180.0F; + this.lastYaw += 180.0F; + this.as = 0; + } + } else { + BlockPosition blockposition1 = movingobjectposition.a(); + + this.d = blockposition1.getX(); + this.e = blockposition1.getY(); + this.f = blockposition1.getZ(); + IBlockData iblockdata1 = this.world.getType(blockposition1); + + this.g = iblockdata1.getBlock(); + this.h = this.g.toLegacyData(iblockdata1); + this.motX = (float) (movingobjectposition.pos.a - this.locX); + this.motY = (float) (movingobjectposition.pos.b - this.locY); + this.motZ = (float) (movingobjectposition.pos.c - this.locZ); + f1 = MathHelper.sqrt(this.motX * this.motX + this.motY * this.motY + this.motZ * this.motZ); + this.locX -= this.motX / (double) f1 * 0.05000000074505806D; + this.locY -= this.motY / (double) f1 * 0.05000000074505806D; + this.locZ -= this.motZ / (double) f1 * 0.05000000074505806D; + this.makeSound("random.bowhit", 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); + this.inGround = true; + this.shake = 7; + this.setCritical(false); + if (this.g.getMaterial() != Material.AIR) { + this.g.a(this.world, blockposition1, iblockdata1, this); + } + } + } + + 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); + } + } + + this.locX += this.motX; + this.locY += this.motY; + this.locZ += this.motZ; + f2 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + this.yaw = (float) (MathHelper.b(this.motX, this.motZ) * 180.0D / 3.1415927410125732D); + + for (this.pitch = (float) (MathHelper.b(this.motY, f2) * 180.0D / 3.1415927410125732D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + } + + while (this.pitch - this.lastPitch >= 180.0F) { + this.lastPitch += 360.0F; + } + + while (this.yaw - this.lastYaw < -180.0F) { + this.lastYaw -= 360.0F; + } + + while (this.yaw - this.lastYaw >= 180.0F) { + this.lastYaw += 360.0F; + } + + this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; + this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + float f4 = 0.99F; + + f1 = 0.05F; + 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); + } + + f4 = 0.6F; + } + + if (this.U()) { + this.extinguish(); + } + + this.motX *= f4; + this.motY *= f4; + this.motZ *= f4; + this.motY -= f1; + this.setPosition(this.locX, this.locY, this.locZ); + this.checkBlockCollisions(); + } + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setShort("xTile", (short) this.d); + nbttagcompound.setShort("yTile", (short) this.e); + nbttagcompound.setShort("zTile", (short) this.f); + nbttagcompound.setShort("life", (short) this.ar); + MinecraftKey minecraftkey = Block.REGISTRY.c(this.g); + + nbttagcompound.setString("inTile", minecraftkey == null ? "" : minecraftkey.toString()); + nbttagcompound.setByte("inData", (byte) this.h); + nbttagcompound.setByte("shake", (byte) this.shake); + nbttagcompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + nbttagcompound.setByte("pickup", (byte) this.fromPlayer); + nbttagcompound.setDouble("damage", this.damage); + } + + public void a(NBTTagCompound nbttagcompound) { + this.d = nbttagcompound.getShort("xTile"); + this.e = nbttagcompound.getShort("yTile"); + this.f = nbttagcompound.getShort("zTile"); + this.ar = nbttagcompound.getShort("life"); + if (nbttagcompound.hasKeyOfType("inTile", 8)) { + this.g = Block.getByName(nbttagcompound.getString("inTile")); + } else { + this.g = Block.getById(nbttagcompound.getByte("inTile") & 255); + } + + this.h = nbttagcompound.getByte("inData") & 255; + this.shake = nbttagcompound.getByte("shake") & 255; + this.inGround = nbttagcompound.getByte("inGround") == 1; + if (nbttagcompound.hasKeyOfType("damage", 99)) { + this.damage = nbttagcompound.getDouble("damage"); + } + + if (nbttagcompound.hasKeyOfType("pickup", 99)) { + this.fromPlayer = nbttagcompound.getByte("pickup"); + } else if (nbttagcompound.hasKeyOfType("player", 99)) { + this.fromPlayer = nbttagcompound.getBoolean("player") ? 1 : 0; + } + + } + + public void d(EntityHuman entityhuman) { + if (!this.world.isClientSide && this.inGround && this.shake <= 0) { + // CraftBukkit start + ItemStack itemstack = new ItemStack(Items.ARROW); + if (this.fromPlayer == 1 && entityhuman.inventory.canHold(itemstack) > 0) { + EntityItem item = new EntityItem(this.world, this.locX, this.locY, this.locZ, itemstack); + + PlayerPickupItemEvent event = new PlayerPickupItemEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), new org.bukkit.craftbukkit.entity.CraftItem(this.world.getServer(), this, item), 0); + // event.setCancelled(!entityhuman.canPickUpLoot); TODO + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + } + // CraftBukkit end + boolean flag = this.fromPlayer == 1 || this.fromPlayer == 2 && entityhuman.abilities.canInstantlyBuild; + + if (this.fromPlayer == 1 && !entityhuman.inventory.pickup(new ItemStack(Items.ARROW, 1))) { + flag = false; + } + + if (flag) { + this.makeSound("random.pop", 0.2F, ((this.random.nextFloat() - this.random.nextFloat()) * 0.7F + 1.0F) * 2.0F); + entityhuman.receive(this, 1); + this.die(); + } + + } + } + + protected boolean s_() { + return false; + } + + public void b(double d0) { + this.damage = d0; + } + + public double j() { + return this.damage; + } + + public void setKnockbackStrength(int i) { + this.knockbackStrength = i; + } + + public boolean aD() { + return false; + } + + public float getHeadHeight() { + return 0.0F; + } + + public void setCritical(boolean flag) { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1))); + } else { + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2))); + } + + } + + public boolean isCritical() { + byte b0 = this.datawatcher.getByte(16); + + return (b0 & 1) != 0; + } + + // CraftBukkit start + public boolean isInGround() { + return inGround; + } + // CraftBukkit end + + // Mythic - Hide projectiles for practice + public boolean a(EntityPlayer entityplayer) { + if(!super.a(entityplayer)) return false; + + if(MythicConfiguration.Options.Tracking.Hide.projectiles) { + if (shooter instanceof EntityPlayer) { + EntityPlayer otherPlayer = (EntityPlayer) shooter; + return entityplayer.getBukkitEntity().canSee(otherPlayer.getBukkitEntity()); + } + } + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityBoat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityBoat.java new file mode 100644 index 0000000..0e6f8c0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityBoat.java @@ -0,0 +1,501 @@ +package net.minecraft.server; + +import java.util.List; + +// CraftBukkit start +import org.bukkit.Location; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.vehicle.VehicleDamageEvent; +import org.bukkit.event.vehicle.VehicleDestroyEvent; +import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; +import org.bukkit.event.vehicle.VehicleMoveEvent; +// CraftBukkit end + +public class EntityBoat extends Entity { + + private boolean a; + private double b; + private int c; + private double d; + private double e; + private double f; + private double g; + private double h; + + // CraftBukkit start + public double maxSpeed = 0.4D; + public double occupiedDeceleration = 0.2D; + public double unoccupiedDeceleration = -1; + public boolean landBoats = false; + + @Override + public void collide(Entity entity) { + org.bukkit.entity.Entity hitEntity = (entity == null) ? null : entity.getBukkitEntity(); + + VehicleEntityCollisionEvent event = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), hitEntity); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + + super.collide(entity); + } + // CraftBukkit end + + public EntityBoat(World world) { + super(world); + this.a = true; + this.b = 0.07D; + this.k = true; + this.setSize(1.5F, 0.6F); + } + + protected boolean s_() { + return false; + } + + protected void h() { + this.datawatcher.a(17, new Integer(0)); + this.datawatcher.a(18, new Integer(1)); + this.datawatcher.a(19, new Float(0.0F)); + } + + public AxisAlignedBB j(Entity entity) { + return entity.getBoundingBox(); + } + + public AxisAlignedBB S() { + return this.getBoundingBox(); + } + + public boolean ae() { + return true; + } + + public EntityBoat(World world, double d0, double d1, double d2) { + this(world); + this.setPosition(d0, d1, d2); + this.motX = 0.0D; + this.motY = 0.0D; + this.motZ = 0.0D; + this.lastX = d0; + this.lastY = d1; + this.lastZ = d2; + + this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleCreateEvent((Vehicle) this.getBukkitEntity())); // CraftBukkit + } + + public double an() { + return -0.3D; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else if (!this.world.isClientSide && !this.dead) { + if (this.passenger != null && this.passenger == damagesource.getEntity() && damagesource instanceof EntityDamageSourceIndirect) { + return false; + } else { + // CraftBukkit start + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); + org.bukkit.entity.Entity attacker = (damagesource.getEntity() == null) ? null : damagesource.getEntity().getBukkitEntity(); + + VehicleDamageEvent event = new VehicleDamageEvent(vehicle, attacker, (double) f); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return true; + } + // f = event.getDamage(); // TODO Why don't we do this? + // CraftBukkit end + + this.b(-this.m()); + this.a(10); + this.setDamage(this.j() + f * 10.0F); + this.ac(); + boolean flag = damagesource.getEntity() instanceof EntityHuman && ((EntityHuman) damagesource.getEntity()).abilities.canInstantlyBuild; + + if (flag || this.j() > 40.0F) { + // CraftBukkit start + VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker); + this.world.getServer().getPluginManager().callEvent(destroyEvent); + + if (destroyEvent.isCancelled()) { + this.setDamage(40F); // Maximize damage so this doesn't get triggered again right away + return true; + } + // CraftBukkit end + if (this.passenger != null) { + this.passenger.mount(this); + } + + if (!flag && this.world.getGameRules().getBoolean("doEntityDrops")) { + this.a(Items.BOAT, 1, 0.0F); + } + + this.die(); + } + + return true; + } + } else { + return true; + } + } + + public boolean ad() { + return !this.dead; + } + + public void t_() { + // CraftBukkit start + double prevX = this.locX; + double prevY = this.locY; + double prevZ = this.locZ; + float prevYaw = this.yaw; + float prevPitch = this.pitch; + // CraftBukkit end + super.t_(); + if (this.l() > 0) { + this.a(this.l() - 1); + } + + if (this.j() > 0.0F) { + this.setDamage(this.j() - 1.0F); + } + + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + byte b0 = 5; + double d0 = 0.0D; + + for (int i = 0; i < b0; ++i) { + double d1 = this.getBoundingBox().b + (this.getBoundingBox().e - this.getBoundingBox().b) * (double) (i + 0) / (double) b0 - 0.125D; + double d2 = this.getBoundingBox().b + (this.getBoundingBox().e - this.getBoundingBox().b) * (double) (i + 1) / (double) b0 - 0.125D; + AxisAlignedBB axisalignedbb = new AxisAlignedBB(this.getBoundingBox().a, d1, this.getBoundingBox().c, this.getBoundingBox().d, d2, this.getBoundingBox().f); + + if (this.world.b(axisalignedbb, Material.WATER)) { + d0 += 1.0D / (double) b0; + } + } + + double d3 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + double d4; + double d5; + int j; + + if (d3 > 0.2975D) { + d4 = Math.cos((double) this.yaw * 3.141592653589793D / 180.0D); + d5 = Math.sin((double) this.yaw * 3.141592653589793D / 180.0D); + + for (j = 0; (double) j < 1.0D + d3 * 60.0D; ++j) { + double d6 = (double) (this.random.nextFloat() * 2.0F - 1.0F); + double d7 = (double) (this.random.nextInt(2) * 2 - 1) * 0.7D; + double d8; + double d9; + + 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]); + } 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]); + } + } + } + + double d10; + double d11; + + if (this.world.isClientSide && this.a) { + if (this.c > 0) { + d4 = this.locX + (this.d - this.locX) / (double) this.c; + d5 = this.locY + (this.e - this.locY) / (double) this.c; + d10 = this.locZ + (this.f - this.locZ) / (double) this.c; + d11 = MathHelper.g(this.g - (double) this.yaw); + this.yaw = (float) ((double) this.yaw + d11 / (double) this.c); + this.pitch = (float) ((double) this.pitch + (this.h - (double) this.pitch) / (double) this.c); + --this.c; + this.setPosition(d4, d5, d10); + this.setYawPitch(this.yaw, this.pitch); + } else { + d4 = this.locX + this.motX; + d5 = this.locY + this.motY; + d10 = this.locZ + this.motZ; + this.setPosition(d4, d5, d10); + if (this.onGround) { + this.motX *= 0.5D; + this.motY *= 0.5D; + this.motZ *= 0.5D; + } + + this.motX *= 0.9900000095367432D; + this.motY *= 0.949999988079071D; + this.motZ *= 0.9900000095367432D; + } + + } else { + if (d0 < 1.0D) { + d4 = d0 * 2.0D - 1.0D; + this.motY += 0.03999999910593033D * d4; + } else { + if (this.motY < 0.0D) { + this.motY /= 2.0D; + } + + this.motY += 0.007000000216066837D; + } + + if (this.passenger instanceof EntityLiving) { + EntityLiving entityliving = (EntityLiving) this.passenger; + float f = this.passenger.yaw + -entityliving.aZ * 90.0F; + + this.motX += -Math.sin((double) (f * 3.1415927F / 180.0F)) * this.b * (double) entityliving.ba * 0.05000000074505806D; + this.motZ += Math.cos((double) (f * 3.1415927F / 180.0F)) * this.b * (double) entityliving.ba * 0.05000000074505806D; + } + // CraftBukkit start - Support unoccupied deceleration + else if (unoccupiedDeceleration >= 0) { + this.motX *= unoccupiedDeceleration; + this.motZ *= unoccupiedDeceleration; + // Kill lingering speed + if (motX <= 0.00001) { + motX = 0; + } + if (motZ <= 0.00001) { + motZ = 0; + } + } + // CraftBukkit end + + d4 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + if (d4 > 0.35D) { + d5 = 0.35D / d4; + this.motX *= d5; + this.motZ *= d5; + d4 = 0.35D; + } + + if (d4 > d3 && this.b < 0.35D) { + this.b += (0.35D - this.b) / 35.0D; + if (this.b > 0.35D) { + this.b = 0.35D; + } + } else { + this.b -= (this.b - 0.07D) / 35.0D; + if (this.b < 0.07D) { + this.b = 0.07D; + } + } + + int k; + + for (k = 0; k < 4; ++k) { + int l = MathHelper.floor(this.locX + ((double) (k % 2) - 0.5D) * 0.8D); + + j = MathHelper.floor(this.locZ + ((double) (k / 2) - 0.5D) * 0.8D); + + for (int i1 = 0; i1 < 2; ++i1) { + int j1 = MathHelper.floor(this.locY) + i1; + BlockPosition blockposition = new BlockPosition(l, j1, j); + Block block = this.world.getType(blockposition).getBlock(); + + if (block == Blocks.SNOW_LAYER) { + // CraftBukkit start + if (CraftEventFactory.callEntityChangeBlockEvent(this, l, j1, j, Blocks.AIR, 0).isCancelled()) { + continue; + } + // CraftBukkit end + this.world.setAir(blockposition); + this.positionChanged = false; + } else if (block == Blocks.WATERLILY) { + // CraftBukkit start + if (CraftEventFactory.callEntityChangeBlockEvent(this, l, j1, j, Blocks.AIR, 0).isCancelled()) { + continue; + } + // CraftBukkit end + this.world.setAir(blockposition, true); + this.positionChanged = false; + } + } + } + + if (this.onGround && !this.landBoats) { // CraftBukkit + this.motX *= 0.5D; + this.motY *= 0.5D; + this.motZ *= 0.5D; + } + + this.move(this.motX, this.motY, this.motZ); + if (this.positionChanged && d3 > 0.2975D) { + if (!this.world.isClientSide && !this.dead) { + // CraftBukkit start + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); + VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, null); + this.world.getServer().getPluginManager().callEvent(destroyEvent); + if (!destroyEvent.isCancelled()) { + this.die(); + if (this.world.getGameRules().getBoolean("doEntityDrops")) { + breakNaturally(); // PaperSpigot + } + } // CraftBukkit end + } + } else { + this.motX *= 0.9900000095367432D; + this.motY *= 0.949999988079071D; + this.motZ *= 0.9900000095367432D; + } + + this.pitch = 0.0F; + d5 = (double) this.yaw; + d10 = this.lastX - this.locX; + d11 = this.lastZ - this.locZ; + if (d10 * d10 + d11 * d11 > 0.001D) { + d5 = (double) ((float) (MathHelper.b(d11, d10) * 180.0D / 3.141592653589793D)); + } + + double d12 = MathHelper.g(d5 - (double) this.yaw); + + if (d12 > 20.0D) { + d12 = 20.0D; + } + + if (d12 < -20.0D) { + d12 = -20.0D; + } + + this.yaw = (float) ((double) this.yaw + d12); + this.setYawPitch(this.yaw, this.pitch); + + // CraftBukkit start + org.bukkit.Server server = this.world.getServer(); + org.bukkit.World bworld = this.world.getWorld(); + + Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); + Location to = new Location(bworld, this.locX, this.locY, this.locZ, this.yaw, this.pitch); + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); + + server.getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle)); + + if (!from.equals(to)) { + VehicleMoveEvent event = new VehicleMoveEvent(vehicle, from, to); + server.getPluginManager().callEvent(event); + } + // CraftBukkit end + if (!this.world.isClientSide) { + List list = this.world.getEntities(this, this.getBoundingBox().grow(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + + if (list != null && !list.isEmpty()) { + for (int k1 = 0; k1 < list.size(); ++k1) { + Entity entity = (Entity) list.get(k1); + + if (entity != this.passenger && entity.ae() && entity instanceof EntityBoat) { + entity.collide(this); + } + } + } + + if (this.passenger != null && this.passenger.dead) { + this.passenger.vehicle = null; // CraftBukkit + this.passenger = null; + } + + } + } + } + + public void al() { + if (this.passenger != null) { + double d0 = Math.cos((double) this.yaw * 3.141592653589793D / 180.0D) * 0.4D; + double d1 = Math.sin((double) this.yaw * 3.141592653589793D / 180.0D) * 0.4D; + + this.passenger.setPosition(this.locX + d0, this.locY + this.an() + this.passenger.am(), this.locZ + d1); + } + } + + protected void b(NBTTagCompound nbttagcompound) {} + + protected void a(NBTTagCompound nbttagcompound) {} + + public boolean e(EntityHuman entityhuman) { + if (this.passenger != null && this.passenger instanceof EntityHuman && this.passenger != entityhuman) { + return true; + } else { + if (!this.world.isClientSide) { + entityhuman.mount(this); + } + + return true; + } + } + + protected void a(double d0, boolean flag, Block block, BlockPosition blockposition) { + if (flag) { + if (this.fallDistance > 3.0F) { + this.e(this.fallDistance, 1.0F); + if (!this.world.isClientSide && !this.dead) { + // CraftBukkit start + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); + VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, null); + this.world.getServer().getPluginManager().callEvent(destroyEvent); + if (!destroyEvent.isCancelled()) { + this.die(); + if (this.world.getGameRules().getBoolean("doEntityDrops")) { + breakNaturally(); // PaperSpigot + } + } // CraftBukkit end + } + + this.fallDistance = 0.0F; + } + } else if (this.world.getType((new BlockPosition(this)).down()).getBlock().getMaterial() != Material.WATER && d0 < 0.0D) { + this.fallDistance = (float) ((double) this.fallDistance - d0); + } + + } + + public void setDamage(float f) { + this.datawatcher.watch(19, Float.valueOf(f)); + } + + public float j() { + return this.datawatcher.getFloat(19); + } + + public void a(int i) { + this.datawatcher.watch(17, Integer.valueOf(i)); + } + + public int l() { + return this.datawatcher.getInt(17); + } + + public void b(int i) { + this.datawatcher.watch(18, Integer.valueOf(i)); + } + + public int m() { + return this.datawatcher.getInt(18); + } + + /** + * PaperSpigot - Handles boat drops depending on the user's config setting + */ + public void breakNaturally() { + if (this.world.paperSpigotConfig.boatsDropBoats) { + this.a(Items.BOAT, 1, 0.0F); + } else { + for (int k = 0; k < 3; ++k) { + this.a(Item.getItemOf(Blocks.PLANKS), 1, 0.0F); + } + + for (int k = 0; k < 2; ++k) { + this.a(Items.STICK, 1, 0.0F); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityChicken.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityChicken.java new file mode 100644 index 0000000..0d27998 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityChicken.java @@ -0,0 +1,159 @@ +package net.minecraft.server; + +public class EntityChicken extends EntityAnimal { + + public float bm; + public float bo; + public float bp; + public float bq; + public float br = 1.0F; + public int bs; + public boolean bt; + + public EntityChicken(World world) { + super(world); + this.setSize(0.4F, 0.7F); + this.bs = this.random.nextInt(6000) + 6000; + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); + this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); + this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, Items.WHEAT_SEEDS, false)); + this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.1D)); + this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); + } + + public float getHeadHeight() { + return this.length; + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(4.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); + } + + public void m() { + // CraftBukkit start + if (this.isChickenJockey()) { + this.persistent = !this.isTypeNotPersistent(); + } + // CraftBukkit end + super.m(); + this.bq = this.bm; + this.bp = this.bo; + this.bo = (float) ((double) this.bo + (double) (this.onGround ? -1 : 4) * 0.3D); + this.bo = MathHelper.a(this.bo, 0.0F, 1.0F); + if (!this.onGround && this.br < 1.0F) { + this.br = 1.0F; + } + + this.br = (float) ((double) this.br * 0.9D); + if (!this.onGround && this.motY < 0.0D) { + this.motY *= 0.6D; + } + + this.bm += this.br * 2.0F; + if (!this.world.isClientSide && !this.isBaby() && !this.isChickenJockey() && --this.bs <= 0) { + this.makeSound("mob.chicken.plop", 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + this.a(Items.EGG, 1); + this.bs = this.random.nextInt(6000) + 6000; + } + + } + + public void e(float f, float f1) {} + + protected String z() { + return "mob.chicken.say"; + } + + protected String bo() { + return "mob.chicken.hurt"; + } + + protected String bp() { + return "mob.chicken.hurt"; + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.chicken.step", 0.15F, 1.0F); + } + + protected Item getLoot() { + return Items.FEATHER; + } + + protected void dropDeathLoot(boolean flag, int i) { + int j = this.random.nextInt(3) + this.random.nextInt(1 + i); + + for (int k = 0; k < j; ++k) { + this.a(Items.FEATHER, 1); + } + + if (this.isBurning()) { + this.a(Items.COOKED_CHICKEN, 1); + } else { + this.a(Items.CHICKEN, 1); + } + + } + + public EntityChicken b(EntityAgeable entityageable) { + return new EntityChicken(this.world); + } + + public boolean d(ItemStack itemstack) { + return itemstack != null && itemstack.getItem() == Items.WHEAT_SEEDS; + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.bt = nbttagcompound.getBoolean("IsChickenJockey"); + if (nbttagcompound.hasKey("EggLayTime")) { + this.bs = nbttagcompound.getInt("EggLayTime"); + } + + } + + protected int getExpValue(EntityHuman entityhuman) { + return this.isChickenJockey() ? 10 : super.getExpValue(entityhuman); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setBoolean("IsChickenJockey", this.bt); + nbttagcompound.setInt("EggLayTime", this.bs); + } + + protected boolean isTypeNotPersistent() { + return this.isChickenJockey() && this.passenger == null; + } + + public void al() { + super.al(); + float f = MathHelper.sin(this.aI * 3.1415927F / 180.0F); + float f1 = MathHelper.cos(this.aI * 3.1415927F / 180.0F); + float f2 = 0.1F; + float f3 = 0.0F; + + this.passenger.setPosition(this.locX + (double) (f2 * f), this.locY + (double) (this.length * 0.5F) + this.passenger.am() + (double) f3, this.locZ - (double) (f2 * f1)); + if (this.passenger instanceof EntityLiving) { + ((EntityLiving) this.passenger).aI = this.aI; + } + + } + + public boolean isChickenJockey() { + return this.bt; + } + + public void l(boolean flag) { + this.bt = flag; + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.b(entityageable); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCow.java new file mode 100644 index 0000000..b5627b7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCow.java @@ -0,0 +1,112 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +// CraftBukkit end + +public class EntityCow extends EntityAnimal { + + public EntityCow(World world) { + super(world); + this.setSize(0.9F, 1.3F); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalPanic(this, 2.0D)); + this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); + this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.25D, Items.WHEAT, false)); + this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.25D)); + this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.20000000298023224D); + } + + protected String z() { + return "mob.cow.say"; + } + + protected String bo() { + return "mob.cow.hurt"; + } + + protected String bp() { + return "mob.cow.hurt"; + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.cow.step", 0.15F, 1.0F); + } + + protected float bB() { + return 0.4F; + } + + protected Item getLoot() { + return Items.LEATHER; + } + + protected void dropDeathLoot(boolean flag, int i) { + int j = this.random.nextInt(3) + this.random.nextInt(1 + i); + + int k; + + for (k = 0; k < j; ++k) { + this.a(Items.LEATHER, 1); + } + + j = this.random.nextInt(3) + 1 + this.random.nextInt(1 + i); + + for (k = 0; k < j; ++k) { + if (this.isBurning()) { + this.a(Items.COOKED_BEEF, 1); + } else { + this.a(Items.BEEF, 1); + } + } + + } + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.BUCKET && !entityhuman.abilities.canInstantlyBuild && !this.isBaby()) { + // CraftBukkit start - Got milk? + org.bukkit.Location loc = this.getBukkitEntity().getLocation(); + org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), null, itemstack, Items.MILK_BUCKET); + + if (event.isCancelled()) { + return false; + } + + ItemStack result = CraftItemStack.asNMSCopy(event.getItemStack()); + if (--itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, result); + } else if (!entityhuman.inventory.pickup(result)) { + entityhuman.drop(result, false); + } + // CraftBukkit end + + return true; + } else { + return super.a(entityhuman); + } + } + + public EntityCow b(EntityAgeable entityageable) { + return new EntityCow(this.world); + } + + public float getHeadHeight() { + return this.length; + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.b(entityageable); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCreature.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCreature.java new file mode 100644 index 0000000..5ea36f7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCreature.java @@ -0,0 +1,124 @@ +package net.minecraft.server; + +import java.util.UUID; + +// CraftBukkit start +import org.bukkit.event.entity.EntityUnleashEvent; +// CraftBukkit end + +public abstract class EntityCreature extends EntityInsentient { + + public static final UUID bk = UUID.fromString("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; + private PathfinderGoal c; + private boolean bm; + + public EntityCreature(World world) { + super(world); + this.a = BlockPosition.ZERO; + this.b = -1.0F; + this.c = new PathfinderGoalMoveTowardsRestriction(this, 1.0D); + } + + public float a(BlockPosition blockposition) { + return 0.0F; + } + + public boolean bR() { + return super.bR() && this.a(new BlockPosition(this.locX, this.getBoundingBox().b, this.locZ)) >= 0.0F; + } + + public boolean cf() { + return !this.navigation.m(); + } + + public boolean cg() { + return this.e(new BlockPosition(this)); + } + + public boolean e(BlockPosition blockposition) { + return this.b == -1.0F ? true : this.a.i(blockposition) < (double) (this.b * this.b); + } + + public void a(BlockPosition blockposition, int i) { + this.a = blockposition; + this.b = (float) i; + } + + public BlockPosition ch() { + return this.a; + } + + public float ci() { + return this.b; + } + + public void cj() { + this.b = -1.0F; + } + + public boolean ck() { + return this.b != -1.0F; + } + + protected void ca() { + super.ca(); + if (this.cc() && this.getLeashHolder() != null && this.getLeashHolder().world == this.world) { + Entity entity = this.getLeashHolder(); + + this.a(new BlockPosition((int) entity.locX, (int) entity.locY, (int) entity.locZ), 5); + float f = this.g(entity); + + if (this instanceof EntityTameableAnimal && ((EntityTameableAnimal) this).isSitting()) { + if (f > 10.0F) { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit + this.unleash(true, true); + } + + return; + } + + if (!this.bm) { + this.goalSelector.a(2, this.c); + if (this.getNavigation() instanceof Navigation) { + ((Navigation) this.getNavigation()).a(false); + } + + this.bm = true; + } + + this.o(f); + if (f > 4.0F) { + this.getNavigation().a(entity, 1.0D); + } + + if (f > 6.0F) { + double d0 = (entity.locX - this.locX) / (double) f; + double d1 = (entity.locY - this.locY) / (double) f; + double d2 = (entity.locZ - this.locZ) / (double) f; + + this.motX += d0 * Math.abs(d0) * 0.4D; + this.motY += d1 * Math.abs(d1) * 0.4D; + this.motZ += d2 * Math.abs(d2) * 0.4D; + } + + if (f > 10.0F) { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit + this.unleash(true, true); + } + } else if (!this.cc() && this.bm) { + this.bm = false; + this.goalSelector.a(this.c); + if (this.getNavigation() instanceof Navigation) { + ((Navigation) this.getNavigation()).a(true); + } + + this.cj(); + } + + } + + protected void o(float f) {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCreeper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCreeper.java new file mode 100644 index 0000000..fecf94d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityCreeper.java @@ -0,0 +1,241 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end + +public class EntityCreeper extends EntityMonster { + + private int a; + private int fuseTicks; + private int maxFuseTicks = 30; + private int explosionRadius = 3; + private int bn = 0; + private int record = -1; // CraftBukkit + + public EntityCreeper(World world) { + super(world); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, new PathfinderGoalSwell(this)); + this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityOcelot.class, 6.0F, 1.0D, 1.2D)); + this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false)); + this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 0.8D)); + this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); + this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true)); + this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); + } + + public int aE() { + return this.getGoalTarget() == null ? 3 : 3 + (int) (this.getHealth() - 1.0F); + } + + public void e(float f, float f1) { + super.e(f, f1); + this.fuseTicks = (int) ((float) this.fuseTicks + f * 1.5F); + if (this.fuseTicks > this.maxFuseTicks - 5) { + this.fuseTicks = this.maxFuseTicks - 5; + } + + } + + protected void h() { + super.h(); + this.datawatcher.a(16, Byte.valueOf((byte) -1)); + this.datawatcher.a(17, Byte.valueOf((byte) 0)); + this.datawatcher.a(18, Byte.valueOf((byte) 0)); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + if (this.datawatcher.getByte(17) == 1) { + nbttagcompound.setBoolean("powered", true); + } + + nbttagcompound.setShort("Fuse", (short) this.maxFuseTicks); + nbttagcompound.setByte("ExplosionRadius", (byte) this.explosionRadius); + nbttagcompound.setBoolean("ignited", this.cn()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.datawatcher.watch(17, Byte.valueOf((byte) (nbttagcompound.getBoolean("powered") ? 1 : 0))); + if (nbttagcompound.hasKeyOfType("Fuse", 99)) { + this.maxFuseTicks = nbttagcompound.getShort("Fuse"); + } + + if (nbttagcompound.hasKeyOfType("ExplosionRadius", 99)) { + this.explosionRadius = nbttagcompound.getByte("ExplosionRadius"); + } + + if (nbttagcompound.getBoolean("ignited")) { + this.co(); + } + + } + + public void t_() { + if (this.isAlive()) { + this.a = this.fuseTicks; + if (this.cn()) { + this.a(1); + } + + int i = this.cm(); + + if (i > 0 && this.fuseTicks == 0) { + this.makeSound("creeper.primed", 1.0F, 0.5F); + } + + this.fuseTicks += i; + if (this.fuseTicks < 0) { + this.fuseTicks = 0; + } + + if (this.fuseTicks >= this.maxFuseTicks) { + this.fuseTicks = this.maxFuseTicks; + this.cr(); + } + } + + super.t_(); + } + + protected String bo() { + return "mob.creeper.say"; + } + + protected String bp() { + return "mob.creeper.death"; + } + + public void die(DamageSource damagesource) { + // super.die(damagesource); // CraftBukkit - Moved to end + if (damagesource.getEntity() instanceof EntitySkeleton) { + int i = Item.getId(Items.RECORD_13); + int j = Item.getId(Items.RECORD_WAIT); + int k = i + this.random.nextInt(j - i + 1); + + // CraftBukkit start - Store record for now, drop in dropDeathLoot + // this.a(Item.getById(k), 1); + this.record = k; + // CraftBukkit end + } else if (damagesource.getEntity() instanceof EntityCreeper && damagesource.getEntity() != this && ((EntityCreeper) damagesource.getEntity()).isPowered() && ((EntityCreeper) damagesource.getEntity()).cp()) { + ((EntityCreeper) damagesource.getEntity()).cq(); + // CraftBukkit start + // this.a(new ItemStack(Items.SKULL, 1, 4), 0.0F); + headDrop = new ItemStack(Items.SKULL, 1, 4); + // CraftBukkit end + } + + super.die(damagesource); // CraftBukkit - Moved from above + } + + // CraftBukkit start - Whole method + @Override + protected void dropDeathLoot(boolean flag, int i) { + super.dropDeathLoot(flag, i); + + // Drop a music disc? + if (this.record != -1) { + this.a(Item.getById(this.record), 1); + this.record = -1; + } + } + // CraftBukkit end + + public boolean r(Entity entity) { + return true; + } + + public boolean isPowered() { + return this.datawatcher.getByte(17) == 1; + } + + protected Item getLoot() { + return Items.GUNPOWDER; + } + + public int cm() { + return this.datawatcher.getByte(16); + } + + public void a(int i) { + this.datawatcher.watch(16, Byte.valueOf((byte) i)); + } + + public void onLightningStrike(EntityLightning entitylightning) { + super.onLightningStrike(entitylightning); + // CraftBukkit start + if (CraftEventFactory.callCreeperPowerEvent(this, entitylightning, org.bukkit.event.entity.CreeperPowerEvent.PowerCause.LIGHTNING).isCancelled()) { + return; + } + + this.setPowered(true); + } + + public void setPowered(boolean powered) { + if (!powered) { + this.datawatcher.watch(17, Byte.valueOf((byte) 0)); + } else { + this.datawatcher.watch(17, Byte.valueOf((byte) 1)); + } + // CraftBukkit end + } + + protected boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.FLINT_AND_STEEL) { + this.world.makeSound(this.locX + 0.5D, this.locY + 0.5D, this.locZ + 0.5D, "fire.ignite", 1.0F, this.random.nextFloat() * 0.4F + 0.8F); + entityhuman.bw(); + if (!this.world.isClientSide) { + this.co(); + itemstack.damage(1, entityhuman); + return true; + } + } + + return super.a(entityhuman); + } + + private void cr() { + if (!this.world.isClientSide) { + boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); + float f = this.isPowered() ? 2.0F : 1.0F; + + ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), this.explosionRadius * f, false); + this.world.getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) { + this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), flag); + this.die(); + } else { + fuseTicks = 0; + } + // CraftBukkit end + } + + } + + public boolean cn() { + return this.datawatcher.getByte(18) != 0; + } + + public void co() { + this.datawatcher.watch(18, Byte.valueOf((byte) 1)); + } + + public boolean cp() { + return this.bn < 1 && this.world.getGameRules().getBoolean("doMobLoot"); + } + + public void cq() { + ++this.bn; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityDamageSourceIndirect.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityDamageSourceIndirect.java new file mode 100644 index 0000000..b72fb3c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityDamageSourceIndirect.java @@ -0,0 +1,34 @@ +package net.minecraft.server; + +public class EntityDamageSourceIndirect extends EntityDamageSource { + + private Entity owner; + + public EntityDamageSourceIndirect(String s, Entity entity, Entity entity1) { + super(s, entity); + this.owner = entity1; + } + + public Entity i() { + return this.q; + } + + public Entity getEntity() { + return this.owner; + } + + public IChatBaseComponent getLocalizedDeathMessage(EntityLiving entityliving) { + IChatBaseComponent ichatbasecomponent = this.owner == null ? this.q.getScoreboardDisplayName() : this.owner.getScoreboardDisplayName(); + ItemStack itemstack = this.owner instanceof EntityLiving ? ((EntityLiving) this.owner).bA() : null; + String s = "death.attack." + this.translationIndex; + String s1 = s + ".item"; + + return itemstack != null && itemstack.hasName() && LocaleI18n.c(s1) ? new ChatMessage(s1, new Object[] { entityliving.getScoreboardDisplayName(), ichatbasecomponent, itemstack.C()}) : new ChatMessage(s, new Object[] { entityliving.getScoreboardDisplayName(), ichatbasecomponent}); + } + + // CraftBukkit start + public Entity getProximateDamageSource() { + return super.getEntity(); + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEgg.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEgg.java new file mode 100644 index 0000000..5d57a11 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEgg.java @@ -0,0 +1,72 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.entity.Ageable; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerEggThrowEvent; +// CraftBukkit end + +public class EntityEgg extends EntityProjectile { + + public EntityEgg(World world) { + super(world); + } + + public EntityEgg(World world, EntityLiving entityliving) { + super(world, entityliving); + } + + public EntityEgg(World world, double d0, double d1, double d2) { + super(world, d0, d1, d2); + } + + protected void a(MovingObjectPosition movingobjectposition) { + if (movingobjectposition.entity != null) { + movingobjectposition.entity.damageEntity(DamageSource.projectile(this, this.getShooter()), 0.0F); + } + + // CraftBukkit start - Fire PlayerEggThrowEvent + boolean hatching = !this.world.isClientSide && this.random.nextInt(8) == 0; + int numHatching = (this.random.nextInt(32) == 0) ? 4 : 1; + if (!hatching) { + numHatching = 0; + } + + EntityType hatchingType = EntityType.CHICKEN; + + Entity shooter = this.getShooter(); + if (shooter instanceof EntityPlayer) { + Player player = (shooter == null) ? null : (Player) shooter.getBukkitEntity(); + + PlayerEggThrowEvent event = new PlayerEggThrowEvent(player, (org.bukkit.entity.Egg) this.getBukkitEntity(), hatching, (byte) numHatching, hatchingType); + this.world.getServer().getPluginManager().callEvent(event); + + hatching = event.isHatching(); + numHatching = event.getNumHatches(); + hatchingType = event.getHatchingType(); + } + + if (hatching) { + for (int k = 0; k < numHatching; k++) { + Entity entity = world.getWorld().createEntity(new org.bukkit.Location(world.getWorld(), this.locX, this.locY, this.locZ, this.yaw, 0.0F), hatchingType.getEntityClass()); + if (entity.getBukkitEntity() instanceof Ageable) { + ((Ageable) entity.getBukkitEntity()).setBaby(); + } + world.getWorld().addEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); + } + } + // CraftBukkit end + + double d0 = 0.08D; + + for (int j = 0; j < 8; ++j) { + this.world.addParticle(EnumParticle.ITEM_CRACK, this.locX, this.locY, this.locZ, ((double) this.random.nextFloat() - 0.5D) * 0.08D, ((double) this.random.nextFloat() - 0.5D) * 0.08D, ((double) this.random.nextFloat() - 0.5D) * 0.08D, new int[] { Item.getId(Items.EGG)}); + } + + if (!this.world.isClientSide) { + this.die(); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderCrystal.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderCrystal.java new file mode 100644 index 0000000..5b9bb93 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderCrystal.java @@ -0,0 +1,87 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end + +public class EntityEnderCrystal extends Entity { + + public int a; + public int b; + + public EntityEnderCrystal(World world) { + super(world); + this.k = true; + this.setSize(2.0F, 2.0F); + this.b = 5; + this.a = this.random.nextInt(100000); + } + + protected boolean s_() { + return false; + } + + protected void h() { + this.datawatcher.a(8, Integer.valueOf(this.b)); + } + + public void t_() { + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + ++this.a; + this.datawatcher.watch(8, Integer.valueOf(this.b)); + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY); + int k = MathHelper.floor(this.locZ); + + if (this.world.worldProvider instanceof WorldProviderTheEnd && this.world.getType(i, j, k).getBlock() != Blocks.FIRE) { + // CraftBukkit start + if (!CraftEventFactory.callBlockIgniteEvent(this.world, i, j, k, this).isCancelled()) { + this.world.setTypeUpdate(new BlockPosition(i, j, k), Blocks.FIRE.getBlockData()); + } + // CraftBukkit end + } + + } + + protected void b(NBTTagCompound nbttagcompound) {} + + protected void a(NBTTagCompound nbttagcompound) {} + + public boolean ad() { + return true; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + if (!this.dead && !this.world.isClientSide) { + // CraftBukkit start - All non-living entities need this + if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { + return false; + } + // CraftBukkit end + this.b = 0; + if (this.b <= 0) { + this.die(); + if (!this.world.isClientSide) { + // CraftBukkit start + ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 6.0F, false); + this.world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + this.dead = false; + return false; + } + this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), true); + // CraftBukkit end + } + } + } + + return true; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderDragon.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderDragon.java new file mode 100644 index 0000000..d246ae7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderDragon.java @@ -0,0 +1,712 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +// CraftBukkit start +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.util.BlockStateListPopulator; +import org.bukkit.event.entity.EntityCreatePortalEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.Bukkit; +// CraftBukkit end + +public class EntityEnderDragon extends EntityInsentient implements IComplex, IMonster { + + public double a; + public double b; + public double c; + public double[][] bk = new double[64][3]; + public int bl = -1; + public EntityComplexPart[] children; + public EntityComplexPart bn; + public EntityComplexPart bo; + public EntityComplexPart bp; + public EntityComplexPart bq; + public EntityComplexPart br; + public EntityComplexPart bs; + public EntityComplexPart bt; + public float bu; + public float bv; + public boolean bw; + public boolean bx; + public Entity target; + public int by; + public EntityEnderCrystal bz; + private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, true); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() + + public EntityEnderDragon(World world) { + super(world); + this.children = new EntityComplexPart[] { this.bn = new EntityComplexPart(this, "head", 6.0F, 6.0F), this.bo = new EntityComplexPart(this, "body", 8.0F, 8.0F), this.bp = new EntityComplexPart(this, "tail", 4.0F, 4.0F), this.bq = new EntityComplexPart(this, "tail", 4.0F, 4.0F), this.br = new EntityComplexPart(this, "tail", 4.0F, 4.0F), this.bs = new EntityComplexPart(this, "wing", 4.0F, 4.0F), this.bt = new EntityComplexPart(this, "wing", 4.0F, 4.0F)}; + this.setHealth(this.getMaxHealth()); + this.setSize(16.0F, 8.0F); + this.noclip = true; + this.fireProof = true; + this.b = 100.0D; + this.ah = true; + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(200.0D); + } + + protected void h() { + super.h(); + } + + public double[] b(int i, float f) { + if (this.getHealth() <= 0.0F) { + f = 0.0F; + } + + f = 1.0F - f; + int j = this.bl - i * 1 & 63; + int k = this.bl - i * 1 - 1 & 63; + double[] adouble = new double[3]; + double d0 = this.bk[j][0]; + double d1 = MathHelper.g(this.bk[k][0] - d0); + + adouble[0] = d0 + d1 * (double) f; + d0 = this.bk[j][1]; + d1 = this.bk[k][1] - d0; + adouble[1] = d0 + d1 * (double) f; + adouble[2] = this.bk[j][2] + (this.bk[k][2] - this.bk[j][2]) * (double) f; + return adouble; + } + + public void m() { + float f; + float f1; + + if (this.world.isClientSide) { + f = MathHelper.cos(this.bv * 3.1415927F * 2.0F); + f1 = MathHelper.cos(this.bu * 3.1415927F * 2.0F); + if (f1 <= -0.3F && f >= -0.3F && !this.R()) { + this.world.a(this.locX, this.locY, this.locZ, "mob.enderdragon.wings", 5.0F, 0.8F + this.random.nextFloat() * 0.3F, false); + } + } + + this.bu = this.bv; + float f2; + + if (this.getHealth() <= 0.0F) { + 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]); + } else { + this.n(); + f = 0.2F / (MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 10.0F + 1.0F); + f *= (float) Math.pow(2.0D, this.motY); + if (this.bx) { + this.bv += f * 0.5F; + } else { + this.bv += f; + } + + this.yaw = MathHelper.g(this.yaw); + if (this.ce()) { + this.bv = 0.5F; + } else { + if (this.bl < 0) { + for (int i = 0; i < this.bk.length; ++i) { + this.bk[i][0] = (double) this.yaw; + this.bk[i][1] = this.locY; + } + } + + if (++this.bl == this.bk.length) { + this.bl = 0; + } + + this.bk[this.bl][0] = (double) this.yaw; + this.bk[this.bl][1] = this.locY; + double d0; + double d1; + double d2; + double d3; + float f3; + + if (this.world.isClientSide) { + if (this.bc > 0) { + d3 = this.locX + (this.bd - this.locX) / (double) this.bc; + d0 = this.locY + (this.be - this.locY) / (double) this.bc; + d1 = this.locZ + (this.bf - this.locZ) / (double) this.bc; + d2 = MathHelper.g(this.bg - (double) this.yaw); + this.yaw = (float) ((double) this.yaw + d2 / (double) this.bc); + this.pitch = (float) ((double) this.pitch + (this.bh - (double) this.pitch) / (double) this.bc); + --this.bc; + this.setPosition(d3, d0, d1); + this.setYawPitch(this.yaw, this.pitch); + } + } else { + d3 = this.a - this.locX; + d0 = this.b - this.locY; + d1 = this.c - this.locZ; + d2 = d3 * d3 + d0 * d0 + d1 * d1; + double d4; + + if (this.target != null) { + this.a = this.target.locX; + this.c = this.target.locZ; + double d5 = this.a - this.locX; + double d6 = this.c - this.locZ; + double d7 = Math.sqrt(d5 * d5 + d6 * d6); + + d4 = 0.4000000059604645D + d7 / 80.0D - 1.0D; + if (d4 > 10.0D) { + d4 = 10.0D; + } + + this.b = this.target.getBoundingBox().b + d4; + } else { + this.a += this.random.nextGaussian() * 2.0D; + this.c += this.random.nextGaussian() * 2.0D; + } + + if (this.bw || d2 < 100.0D || d2 > 22500.0D || this.positionChanged || this.E) { + this.cf(); + } + + d0 /= (double) MathHelper.sqrt(d3 * d3 + d1 * d1); + f3 = 0.6F; + d0 = MathHelper.a(d0, (double) (-f3), (double) f3); + this.motY += d0 * 0.10000000149011612D; + this.yaw = MathHelper.g(this.yaw); + double d8 = 180.0D - MathHelper.b(d3, d1) * 180.0D / 3.1415927410125732D; + double d9 = MathHelper.g(d8 - (double) this.yaw); + + if (d9 > 50.0D) { + d9 = 50.0D; + } + + if (d9 < -50.0D) { + d9 = -50.0D; + } + + Vec3D vec3d = (new Vec3D(this.a - this.locX, this.b - this.locY, this.c - this.locZ)).a(); + + d4 = (double) (-MathHelper.cos(this.yaw * 3.1415927F / 180.0F)); + Vec3D vec3d1 = (new Vec3D((double) MathHelper.sin(this.yaw * 3.1415927F / 180.0F), this.motY, d4)).a(); + float f4 = ((float) vec3d1.b(vec3d) + 0.5F) / 1.5F; + + if (f4 < 0.0F) { + f4 = 0.0F; + } + + this.bb *= 0.8F; + float f5 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 1.0F + 1.0F; + double d10 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 1.0D + 1.0D; + + if (d10 > 40.0D) { + d10 = 40.0D; + } + + this.bb = (float) ((double) this.bb + d9 * (0.699999988079071D / d10 / (double) f5)); + this.yaw += this.bb * 0.1F; + float f6 = (float) (2.0D / (d10 + 1.0D)); + float f7 = 0.06F; + + this.a(0.0F, -1.0F, f7 * (f4 * f6 + (1.0F - f6))); + if (this.bx) { + this.move(this.motX * 0.800000011920929D, this.motY * 0.800000011920929D, this.motZ * 0.800000011920929D); + } else { + this.move(this.motX, this.motY, this.motZ); + } + + Vec3D vec3d2 = (new Vec3D(this.motX, this.motY, this.motZ)).a(); + float f8 = ((float) vec3d2.b(vec3d1) + 1.0F) / 2.0F; + + f8 = 0.8F + 0.15F * f8; + this.motX *= (double) f8; + this.motZ *= (double) f8; + this.motY *= 0.9100000262260437D; + } + + this.aI = this.yaw; + this.bn.width = this.bn.length = 3.0F; + this.bp.width = this.bp.length = 2.0F; + this.bq.width = this.bq.length = 2.0F; + this.br.width = this.br.length = 2.0F; + this.bo.length = 3.0F; + this.bo.width = 5.0F; + this.bs.length = 2.0F; + this.bs.width = 4.0F; + this.bt.length = 3.0F; + this.bt.width = 4.0F; + f1 = (float) (this.b(5, 1.0F)[1] - this.b(10, 1.0F)[1]) * 10.0F / 180.0F * 3.1415927F; + f2 = MathHelper.cos(f1); + float f9 = -MathHelper.sin(f1); + float f10 = this.yaw * 3.1415927F / 180.0F; + float f11 = MathHelper.sin(f10); + float f12 = MathHelper.cos(f10); + + this.bo.t_(); + this.bo.setPositionRotation(this.locX + (double) (f11 * 0.5F), this.locY, this.locZ - (double) (f12 * 0.5F), 0.0F, 0.0F); + this.bs.t_(); + this.bs.setPositionRotation(this.locX + (double) (f12 * 4.5F), this.locY + 2.0D, this.locZ + (double) (f11 * 4.5F), 0.0F, 0.0F); + this.bt.t_(); + this.bt.setPositionRotation(this.locX - (double) (f12 * 4.5F), this.locY + 2.0D, this.locZ - (double) (f11 * 4.5F), 0.0F, 0.0F); + if (!this.world.isClientSide && this.hurtTicks == 0) { + this.a(this.world.getEntities(this, this.bs.getBoundingBox().grow(4.0D, 2.0D, 4.0D).c(0.0D, -2.0D, 0.0D))); + this.a(this.world.getEntities(this, this.bt.getBoundingBox().grow(4.0D, 2.0D, 4.0D).c(0.0D, -2.0D, 0.0D))); + this.b(this.world.getEntities(this, this.bn.getBoundingBox().grow(1.0D, 1.0D, 1.0D))); + } + + double[] adouble = this.b(5, 1.0F); + double[] adouble1 = this.b(0, 1.0F); + + f3 = MathHelper.sin(this.yaw * 3.1415927F / 180.0F - this.bb * 0.01F); + float f13 = MathHelper.cos(this.yaw * 3.1415927F / 180.0F - this.bb * 0.01F); + + this.bn.t_(); + this.bn.setPositionRotation(this.locX + (double) (f3 * 5.5F * f2), this.locY + (adouble1[1] - adouble[1]) * 1.0D + (double) (f9 * 5.5F), this.locZ - (double) (f13 * 5.5F * f2), 0.0F, 0.0F); + + for (int j = 0; j < 3; ++j) { + EntityComplexPart entitycomplexpart = null; + + if (j == 0) { + entitycomplexpart = this.bp; + } + + if (j == 1) { + entitycomplexpart = this.bq; + } + + if (j == 2) { + entitycomplexpart = this.br; + } + + double[] adouble2 = this.b(12 + j * 2, 1.0F); + float f14 = this.yaw * 3.1415927F / 180.0F + this.b(adouble2[0] - adouble[0]) * 3.1415927F / 180.0F * 1.0F; + float f15 = MathHelper.sin(f14); + float f16 = MathHelper.cos(f14); + float f17 = 1.5F; + float f18 = (float) (j + 1) * 2.0F; + + entitycomplexpart.t_(); + entitycomplexpart.setPositionRotation(this.locX - (double) ((f11 * f17 + f15 * f18) * f2), this.locY + (adouble2[1] - adouble[1]) * 1.0D - (double) ((f18 + f17) * f9) + 1.5D, this.locZ + (double) ((f12 * f17 + f16 * f18) * f2), 0.0F, 0.0F); + } + + if (!this.world.isClientSide) { + this.bx = this.b(this.bn.getBoundingBox()) | this.b(this.bo.getBoundingBox()); + } + + } + } + } + + private void n() { + if (this.bz != null) { + if (this.bz.dead) { + if (!this.world.isClientSide) { + CraftEventFactory.entityDamage = this.bz; // CraftBukkit + this.a(this.bn, DamageSource.explosion((Explosion) null), 10.0F); + CraftEventFactory.entityDamage = null; // CraftBukkit + } + + this.bz = null; + } else if (this.ticksLived % 10 == 0 && this.getHealth() < this.getMaxHealth()) { + // CraftBukkit start + EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), 1.0D, EntityRegainHealthEvent.RegainReason.ENDER_CRYSTAL); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + this.setHealth((float) (this.getHealth() + event.getAmount())); + } + // CraftBukkit end + } + } + + if (this.random.nextInt(10) == 0) { + float f = 32.0F; + List list = this.world.a(EntityEnderCrystal.class, this.getBoundingBox().grow((double) f, (double) f, (double) f)); + EntityEnderCrystal entityendercrystal = null; + double d0 = Double.MAX_VALUE; + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityEnderCrystal entityendercrystal1 = (EntityEnderCrystal) iterator.next(); + double d1 = entityendercrystal1.h(this); + + if (d1 < d0) { + d0 = d1; + entityendercrystal = entityendercrystal1; + } + } + + this.bz = entityendercrystal; + } + + } + + private void a(List list) { + double d0 = (this.bo.getBoundingBox().a + this.bo.getBoundingBox().d) / 2.0D; + double d1 = (this.bo.getBoundingBox().c + this.bo.getBoundingBox().f) / 2.0D; + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (entity instanceof EntityLiving) { + double d2 = entity.locX - d0; + double d3 = entity.locZ - d1; + double d4 = d2 * d2 + d3 * d3; + + entity.g(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D); + } + } + + } + + private void b(List list) { + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + + if (entity instanceof EntityLiving) { + entity.damageEntity(DamageSource.mobAttack(this), 10.0F); + this.a((EntityLiving) this, entity); + } + } + + } + + private void cf() { + this.bw = false; + ArrayList arraylist = Lists.newArrayList(this.world.players); + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + if (((EntityHuman) iterator.next()).isSpectator()) { + iterator.remove(); + } + } + + if (this.random.nextInt(2) == 0 && !arraylist.isEmpty()) { + // CraftBukkit start + Entity target = (Entity) this.world.players.get(this.random.nextInt(this.world.players.size())); + EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), target.getBukkitEntity(), EntityTargetEvent.TargetReason.RANDOM_TARGET); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + if (event.getTarget() == null) { + this.target = null; + } else { + this.target = ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); + } + } + // CraftBukkit end + } else { + boolean flag; + + do { + this.a = 0.0D; + this.b = (double) (70.0F + this.random.nextFloat() * 50.0F); + this.c = 0.0D; + this.a += (double) (this.random.nextFloat() * 120.0F - 60.0F); + this.c += (double) (this.random.nextFloat() * 120.0F - 60.0F); + double d0 = this.locX - this.a; + double d1 = this.locY - this.b; + double d2 = this.locZ - this.c; + + flag = d0 * d0 + d1 * d1 + d2 * d2 > 100.0D; + } while (!flag); + + this.target = null; + } + + } + + private float b(double d0) { + return (float) MathHelper.g(d0); + } + + private boolean b(AxisAlignedBB axisalignedbb) { + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.b); + int k = MathHelper.floor(axisalignedbb.c); + int l = MathHelper.floor(axisalignedbb.d); + int i1 = MathHelper.floor(axisalignedbb.e); + int j1 = MathHelper.floor(axisalignedbb.f); + boolean flag = false; + boolean flag1 = false; + + // CraftBukkit start - Create a list to hold all the destroyed blocks + List destroyedBlocks = new java.util.ArrayList(); + org.bukkit.craftbukkit.CraftWorld craftWorld = this.world.getWorld(); + // CraftBukkit end + + for (int k1 = i; k1 <= l; ++k1) { + for (int l1 = j; l1 <= i1; ++l1) { + for (int i2 = k; i2 <= j1; ++i2) { + BlockPosition blockposition = new BlockPosition(k1, l1, i2); + Block block = this.world.getType(blockposition).getBlock(); + + if (block.getMaterial() != Material.AIR) { + if (block != Blocks.BARRIER && block != Blocks.OBSIDIAN && block != Blocks.END_STONE && block != Blocks.BEDROCK && block != Blocks.COMMAND_BLOCK && this.world.getGameRules().getBoolean("mobGriefing")) { + // CraftBukkit start - Add blocks to list rather than destroying them + // flag1 = this.world.setAir(new BlockPosition(blockposition)) || flag1; + flag1 = true; + destroyedBlocks.add(craftWorld.getBlockAt(k1, l1, i2)); + // CraftBukkit end + } else { + flag = true; + } + } + } + } + } + + if (flag1) { + // CraftBukkit start - Set off an EntityExplodeEvent for the dragon exploding all these blocks + org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity(); + EntityExplodeEvent event = new EntityExplodeEvent(bukkitEntity, bukkitEntity.getLocation(), destroyedBlocks, 0F); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + // This flag literally means 'Dragon hit something hard' (Obsidian, White Stone or Bedrock) and will cause the dragon to slow down. + // We should consider adding an event extension for it, or perhaps returning true if the event is cancelled. + return flag; + } else if (event.getYield() == 0F) { + // Yield zero ==> no drops + for (org.bukkit.block.Block block : event.blockList()) { + this.world.setAir(new BlockPosition(block.getX(), block.getY(), block.getZ())); + } + } else { + for (org.bukkit.block.Block block : event.blockList()) { + org.bukkit.Material blockId = block.getType(); + if (blockId == org.bukkit.Material.AIR) { + continue; + } + + int blockX = block.getX(); + int blockY = block.getY(); + int blockZ = block.getZ(); + + Block nmsBlock = org.bukkit.craftbukkit.util.CraftMagicNumbers.getBlock(blockId); + if (nmsBlock.a(explosionSource)) { + nmsBlock.dropNaturally(this.world, new BlockPosition(blockX, blockY, blockZ), nmsBlock.fromLegacyData(block.getData()), event.getYield(), 0); + } + nmsBlock.wasExploded(world, new BlockPosition(blockX, blockY, blockZ), explosionSource); + + this.world.setAir(new BlockPosition(blockX, blockY, blockZ)); + } + } + // CraftBukkit end + double d0 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) this.random.nextFloat(); + 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]); + } + + return flag; + } + + public boolean a(EntityComplexPart entitycomplexpart, DamageSource damagesource, float f) { + if (entitycomplexpart != this.bn) { + f = f / 4.0F + 1.0F; + } + + float f1 = this.yaw * 3.1415927F / 180.0F; + float f2 = MathHelper.sin(f1); + float f3 = MathHelper.cos(f1); + + this.a = this.locX + (double) (f2 * 5.0F) + (double) ((this.random.nextFloat() - 0.5F) * 2.0F); + this.b = this.locY + (double) (this.random.nextFloat() * 3.0F) + 1.0D; + this.c = this.locZ - (double) (f3 * 5.0F) + (double) ((this.random.nextFloat() - 0.5F) * 2.0F); + this.target = null; + if (damagesource.getEntity() instanceof EntityHuman || damagesource.isExplosion()) { + this.dealDamage(damagesource, f); + } + + return true; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (damagesource instanceof EntityDamageSource && ((EntityDamageSource) damagesource).w()) { + this.dealDamage(damagesource, f); + } + + return false; + } + + protected boolean dealDamage(DamageSource damagesource, float f) { + return super.damageEntity(damagesource, f); + } + + public void G() { + this.die(); + } + + protected void aZ() { + if (this.dead) return; // CraftBukkit - can't kill what's already dead + ++this.by; + if (this.by >= 180 && this.by <= 200) { + float f = (this.random.nextFloat() - 0.5F) * 8.0F; + 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]); + } + + boolean flag = this.world.getGameRules().getBoolean("doMobLoot"); + int i; + int j; + + if (!this.world.isClientSide) { + if (this.by > 150 && this.by % 5 == 0 && flag) { + i = this.expToDrop / 12; // CraftBukkit - drop experience as dragon falls from sky. use experience drop from death event. This is now set in getExpReward() + + while (i > 0) { + j = EntityExperienceOrb.getOrbValue(i); + i -= j; + this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j)); + } + } + + if (this.by == 1) { + // CraftBukkit start - Use relative location for far away sounds + // this.world.a(1018, new BlockPosition(this), 0); + int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; + for (EntityPlayer player : (List) MinecraftServer.getServer().getPlayerList().players) { + double deltaX = this.locX - player.locX; + double deltaZ = this.locZ - player.locZ; + double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; + if ( world.spigotConfig.dragonDeathSoundRadius > 0 && distanceSquared > world.spigotConfig.dragonDeathSoundRadius * world.spigotConfig.dragonDeathSoundRadius ) continue; // Spigot + if (distanceSquared > viewDistance * viewDistance) { + double deltaLength = Math.sqrt(distanceSquared); + double relativeX = player.locX + (deltaX / deltaLength) * viewDistance; + double relativeZ = player.locZ + (deltaZ / deltaLength) * viewDistance; + player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1018, new BlockPosition((int) relativeX, (int) this.locY, (int) relativeZ), 0, true)); + } else { + player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1018, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0, true)); + } + } + // CraftBukkit end + } + } + + this.move(0.0D, 0.10000000149011612D, 0.0D); + this.aI = this.yaw += 20.0F; + if (this.by == 200 && !this.world.isClientSide) { + if (flag) { + i = this.expToDrop - (10 * this.expToDrop / 12); // CraftBukkit - drop the remaining experience + + while (i > 0) { + j = EntityExperienceOrb.getOrbValue(i); + i -= j; + this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j)); + } + } + + this.a(new BlockPosition(this.locX, 64.0D, this.locZ)); + this.die(); + } + + } + + private void a(BlockPosition blockposition) { + boolean flag = true; + double d0 = 12.25D; + double d1 = 6.25D; + + // CraftBukkit start - Replace any "this.world" in the following with just "world"! + BlockStateListPopulator world = new BlockStateListPopulator(this.world.getWorld()); + + for (int i = -1; i <= 32; ++i) { + for (int j = -4; j <= 4; ++j) { + for (int k = -4; k <= 4; ++k) { + double d2 = (double) (j * j + k * k); + + if (d2 <= 12.25D) { + BlockPosition blockposition1 = blockposition.a(j, i, k); + + if (i < 0) { + if (d2 <= 6.25D) { + world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData()); + } + } else if (i > 0) { + world.setTypeUpdate(blockposition1, Blocks.AIR.getBlockData()); + } else if (d2 > 6.25D) { + world.setTypeUpdate(blockposition1, Blocks.BEDROCK.getBlockData()); + } else { + world.setTypeUpdate(blockposition1, Blocks.END_PORTAL.getBlockData()); + } + } + } + } + } + + world.setTypeUpdate(blockposition, Blocks.BEDROCK.getBlockData()); + world.setTypeUpdate(blockposition.up(), Blocks.BEDROCK.getBlockData()); + BlockPosition blockposition2 = blockposition.up(2); + + world.setTypeUpdate(blockposition2, Blocks.BEDROCK.getBlockData()); + world.setTypeUpdate(blockposition2.west(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.EAST)); + world.setTypeUpdate(blockposition2.east(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.WEST)); + world.setTypeUpdate(blockposition2.north(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.SOUTH)); + world.setTypeUpdate(blockposition2.south(), Blocks.TORCH.getBlockData().set(BlockTorch.FACING, EnumDirection.NORTH)); + world.setTypeUpdate(blockposition.up(3), Blocks.BEDROCK.getBlockData()); + world.setTypeUpdate(blockposition.up(4), Blocks.DRAGON_EGG.getBlockData()); + + EntityCreatePortalEvent event = new EntityCreatePortalEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), java.util.Collections.unmodifiableList(world.getList()), org.bukkit.PortalType.ENDER); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + for (BlockState state : event.getBlocks()) { + state.update(true); + } + } else { + for (BlockState state : event.getBlocks()) { + PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, new BlockPosition(state.getX(), state.getY(), state.getZ())); + for (Iterator it = this.world.players.iterator(); it.hasNext();) { + EntityHuman entity = (EntityHuman) it.next(); + if (entity instanceof EntityPlayer) { + ((EntityPlayer) entity).playerConnection.sendPacket(packet); + } + } + } + } + // CraftBukkit end + } + + protected void D() {} + + public Entity[] aB() { + return this.children; + } + + public boolean ad() { + return false; + } + + public World a() { + return this.world; + } + + protected String z() { + return "mob.enderdragon.growl"; + } + + protected String bo() { + return "mob.enderdragon.hit"; + } + + protected float bB() { + return 5.0F; + } + + // CraftBukkit start + public int getExpReward() { + // This value is equal to the amount of experience dropped while falling from the sky (10 * 1000) + // plus what is dropped when the dragon hits the ground (2000) + return 12000; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderPearl.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderPearl.java new file mode 100644 index 0000000..1165017 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderPearl.java @@ -0,0 +1,729 @@ +package net.minecraft.server; + +// CraftBukkit start + +import me.levansj01.mythicspigot.MythicConfiguration; +import net.jafama.FastMath; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.entity.CraftEnderPearl; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EnderPearlEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.Gate; +import org.bukkit.material.Stairs; +import org.bukkit.material.Step; +import org.bukkit.material.WoodenStep; +import org.bukkit.util.BlockIterator; +import org.bukkit.util.Vector; + +import java.util.stream.Stream; +// CraftBukkit end + +public class EntityEnderPearl extends EntityProjectile { + + private static final BlockFace[] faces = new BlockFace[]{BlockFace.SOUTH, BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST, BlockFace.SELF}; + + private static final ItemStack enderpearl = new ItemStack(org.bukkit.Material.ENDER_PEARL); + private Location valid; + + public EntityEnderPearl(World world) { + super(world); + this.loadChunks = world.paperSpigotConfig.loadUnloadedEnderPearls; // PaperSpigot + } + + public EntityEnderPearl(World world, EntityLiving entityliving) { + super(world, entityliving); + this.loadChunks = world.paperSpigotConfig.loadUnloadedEnderPearls; // PaperSpigot + } + + + protected void a(MovingObjectPosition movingobjectposition) { + if (movingobjectposition.a() != null) { + Block block = this.world.getType(movingobjectposition.a()).getBlock(); + + if (MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughString && block == Blocks.TRIPWIRE) { + return; + } else if (MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughFenceGates && block == Blocks.FENCE_GATE) { + BlockIterator bi = null; + + try { + Vector l = new Vector(this.locX, this.locY, this.locZ); + Vector l2 = new Vector(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + Vector dir = new Vector(l2.getX() - l.getX(), l2.getY() - l.getY(), l2.getZ() - l.getZ()).normalize(); + bi = new BlockIterator(this.world.getWorld(), l, dir, 0, 1); + } catch (IllegalStateException ex) { + // ignore + } + + if (bi != null) { + boolean open = true; + boolean hasSolidBlock = false; + + while (bi.hasNext()) { + org.bukkit.block.Block b = bi.next(); + + if (b.getType().isSolid() && b.getType().isOccluding()) { + hasSolidBlock = true; + } + + if (b.getState().getData() instanceof Gate && !((Gate) b.getState().getData()).isOpen()) { + open = false; + break; + } + } + + if (open && !hasSolidBlock) { + return; + } + } + } else if (MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughCobweb && block == Blocks.WEB) { + return; + } + } + + if (MythicConfiguration.Options.Enderpearls.Taliban.damagePearls && movingobjectposition.entity != null) { + movingobjectposition.entity.damageEntity(DamageSource.projectile(this, this.getShooter()), 0.0F); + } + + // PaperSpigot start - Remove entities in unloaded chunks + if (inUnloadedChunk && world.paperSpigotConfig.removeUnloadedEnderPearls) { + die(); + } + // PaperSpigot end + + if (MythicConfiguration.Options.Enderpearls.pearlParticles) { + this.world.addParticle(EnumParticle.PORTAL, this.locX, this.locY + this.random.nextDouble() * 2.0D, + this.locZ, this.random.nextGaussian(), 0.0D, this.random.nextGaussian()); + } + + if (!this.world.isClientSide) { + if (this.getShooter() != null && this.getShooter() instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) this.getShooter(); + if (entityplayer.playerConnection.a().g() && entityplayer.world == this.world) { + if (valid != null) { + // CraftBukkit start - Fire PlayerTeleportEvent + CraftPlayer player = entityplayer.getBukkitEntity(); + + + PlayerTeleportEvent teleEvent = null; + + // Ender pearl reason + EnderPearlEvent.Reason reason = movingobjectposition.entity != null + ? EnderPearlEvent.Reason.ENTITY : EnderPearlEvent.Reason.BLOCK; + + // Hit entity with pearl + CraftEntity bukkitHitEntity = movingobjectposition.entity != null + ? movingobjectposition.entity.getBukkitEntity() : null; + + // Create land event and call it + EnderPearlEvent landEvent = new EnderPearlEvent((CraftEnderPearl) getBukkitEntity(), reason, bukkitHitEntity); + Bukkit.getPluginManager().callEvent(landEvent); + + // Creat the location and save it + Location location = getBukkitEntity().getLocation(); + location.setPitch(player.getLocation().getPitch()); + location.setYaw(player.getLocation().getYaw()); + + + if (landEvent.isCancelled()) { + this.die(); + return; + } + + if (!tali(location, player)) { + die(); + refund(player); + return; + } + + + + if (k) { + BlockPosition position = new BlockPosition(this.locX, this.locY, this.locZ); + double dist = gateY - location.getBlockY(); + double distX = this.locX - this.gateX; + double distZ = this.locZ - this.gateZ; + double xzDist = Math.sqrt(distX * distX + distZ * distZ); + if (this.world.getType(position).getBlock() != Blocks.AIR && this.pitch < -10 && dist <= 2 && xzDist <= 2) { + location.setY(gateY); + } + } + + badTeleport(location); + + teleEvent = new PlayerTeleportEvent(player, player.getLocation(), location, + PlayerTeleportEvent.TeleportCause.ENDER_PEARL); + Bukkit.getPluginManager().callEvent(teleEvent); + + if (!teleEvent.isCancelled() && !entityplayer.playerConnection.isDisconnected()) { + if (this.getShooter().au()) { + this.getShooter().mount(null); + } + + Location to = teleEvent.getTo().clone(); + to.setX(FastMath.floor(to.getX()) + 0.5); + to.setY(FastMath.floor(to.getY()) + 0.5); + to.setZ(FastMath.floor(to.getZ()) + 0.5); + + entityplayer.playerConnection.teleport(teleEvent.getTo()); + this.getShooter().fallDistance = 0.0F; + if (MythicConfiguration.Options.Enderpearls.Taliban.damagePearls) { + CraftEventFactory.entityDamage = this; + this.getShooter().damageEntity(DamageSource.FALL, 5.0F); + CraftEventFactory.entityDamage = null; + } + } + // CraftBukkit end + } else { + refund(entityplayer.getBukkitEntity()); + } + } + } + this.die(); + } + } + + + private void refund(Player player) { + String message = "Pearl was refunded"; + + player.sendMessage(message); + + player.getInventory().addItem(enderpearl); + player.updateInventory(); + } + + private Location badTeleport(Location location) { + org.bukkit.block.Block block = location.getBlock(); + if (block.getType() == org.bukkit.Material.AIR) { + org.bukkit.block.Block up = block.getRelative(BlockFace.UP); + org.bukkit.block.Block down = block.getRelative(BlockFace.DOWN); + + if (down.getType() == org.bukkit.Material.AIR) { + if (up.getType() != org.bukkit.Material.AIR) { + location.setY(location.getBlockY() - 1.0); + } else if (up.getRelative(BlockFace.UP).getType() != org.bukkit.Material.AIR) { + if (location.getBlockY() < 5) { + return location; + } + location.setY(location.getBlockY() - 2.0); + } + } else { + if (up.getRelative(BlockFace.UP).getType() != org.bukkit.Material.AIR) { + location.setY(location.getBlockY()); + } + } + } + + boolean check = Stream.of(faces) + .filter(face -> block.getRelative(face).getType() != org.bukkit.Material.AIR) + .findAny() + .orElse(null) != null; + if (check) { + location.setX(location.getBlockX() + 0.5); + location.setZ(location.getBlockZ() + 0.5); + } + + return location; + } + + /*private boolean antiGlitch(Location location, Player player) { + return location.distance(player.getLocation()) <= 1.2; + } + */ + + private boolean tali(Location location, Player player) { + org.bukkit.block.Block current = location.getBlock(), above = current.getRelative(BlockFace.UP), down = current.getRelative(BlockFace.DOWN), + west = current.getRelative(BlockFace.WEST), + east = current.getRelative(BlockFace.EAST), + north = current.getRelative(BlockFace.NORTH), + south = current.getRelative(BlockFace.SOUTH); + org.bukkit.Material + westType = west.getRelative(BlockFace.UP).getType(), + eastType = east.getRelative(BlockFace.UP).getType(), + northType = north.getRelative(BlockFace.UP).getType(), + southType = south.getRelative(BlockFace.UP).getType(); + + if (current.getType() == Material.FENCE_GATE) { + if (!((Gate) current.getState().getData()).isOpen()) { + die(); + return false; + } + } + + boolean stairCurrent = false, stairUp = false, crittable = MythicConfiguration.Options.Enderpearls.Taliban.pearlCriticalBlock; + + org.bukkit.block.Block currentBottom = location.clone().subtract(0, 1, 0).getBlock(); + + if (!(current.getLocation().distance(player.getLocation()) > 4) && + (isSlab(current.getType(), currentBottom.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairCurrent = isStair(current.getType(), currentBottom.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || isSlab(above.getType(), currentBottom.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairUp = isStair(above.getType(), currentBottom.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || (isType(Material.COBBLE_WALL, current.getType(), currentBottom.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlCobbleWall))) { + BlockFace blockFace = null; + + if (stairCurrent || stairUp) { + Stairs stairs = (Stairs) (stairCurrent ? current : above).getState().getData(); + + blockFace = stairs.getFacing(); + } + + //System.out.println("Trying tali with " + getDirectionName(player.getLocation()) + ", face=" + blockFace + ", staircurrent=" + stairCurrent + ", stairup=" + stairUp); + byte isPassable = 0b1111; // ten ben tws bws + + if (getDirectionName(player.getLocation()).contains("E")) { + if ((stairCurrent || stairUp) && (blockFace != null && blockFace != BlockFace.NORTH && blockFace != BlockFace.SOUTH)) { + die(); + //System.out.println("DP1"); + return false; + } + + //System.out.println("Doing first tali"); + + location.setX(location.getX() + 1); + + for(int i = 0; i < MythicConfiguration.Options.Enderpearls.pearlMaxPass - 1; i++) { + if(MythicConfiguration.Options.Enderpearls.pearlPassFine) { + if (isSlab(current.getType()) || isSlab(above.getType())) { + isPassable = procBlocked(BlockFace.EAST, null, (isSlab(current.getType()) ? current : above).getState().getData(), isPassable); + } else if (stairCurrent || stairUp) { + isPassable = procBlocked(BlockFace.EAST, (Stairs) (stairCurrent ? current : above).getState().getData(), null, isPassable); + } + if (isPassable == 0) { + if (MythicConfiguration.Options.Enderpearls.pearlPassFineCancel) { + die(); + //System.out.println("PPFC"); + return false; + } + break; + } + } + // Iterate block + org.bukkit.block.Block nextcurrent = current.getRelative(BlockFace.EAST); + org.bukkit.block.Block nextabove = nextcurrent.getRelative(BlockFace.UP); + + if(isSlab(nextcurrent.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairCurrent = isStair(nextcurrent.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || isSlab(nextabove.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairUp = isStair(nextabove.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || (nextcurrent.getType() == org.bukkit.Material.COBBLE_WALL && MythicConfiguration.Options.Enderpearls.Taliban.pearlCobbleWall)) { + if ((stairCurrent || stairUp) && (blockFace != null && blockFace != BlockFace.NORTH && blockFace != BlockFace.SOUTH)) { + break; + } + + location.setX(location.getX() + 1); + + current = nextcurrent; + above = nextabove; + + //System.out.println("Iterated"); + } + } + + if (current.getRelative(BlockFace.EAST).getType().isSolid()) { + if (!crittable) return false; + location.setY(east.getLocation().getY() - 1); + } + } else if (getDirectionName(player.getLocation()).contains("W")) { + if ((stairCurrent || stairUp) && (blockFace != null && blockFace != BlockFace.NORTH && blockFace != BlockFace.SOUTH)) { + die(); + //System.out.println("DP1"); + return false; + } + + //System.out.println("Doing first tali"); + + location.setX(location.getX() - 1); + + for(int i = 0; i < MythicConfiguration.Options.Enderpearls.pearlMaxPass - 1; i++) { + if(MythicConfiguration.Options.Enderpearls.pearlPassFine) { + if (isSlab(current.getType()) || isSlab(above.getType())) { + isPassable = procBlocked(BlockFace.WEST, null, (isSlab(current.getType()) ? current : above).getState().getData(), isPassable); + } else if (stairCurrent || stairUp) { + isPassable = procBlocked(BlockFace.WEST, (Stairs) (stairCurrent ? current : above).getState().getData(), null, isPassable); + } + if (isPassable == 0) { + if (MythicConfiguration.Options.Enderpearls.pearlPassFineCancel) { + die(); + //System.out.println("PPFC"); + return false; + } + break; + } + } + // Iterate block + org.bukkit.block.Block nextcurrent = current.getRelative(BlockFace.WEST); + org.bukkit.block.Block nextabove = nextcurrent.getRelative(BlockFace.UP); + + if(isSlab(nextcurrent.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairCurrent = isStair(nextcurrent.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || isSlab(nextabove.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairUp = isStair(nextabove.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || (nextcurrent.getType() == org.bukkit.Material.COBBLE_WALL && MythicConfiguration.Options.Enderpearls.Taliban.pearlCobbleWall)) { + if ((stairCurrent || stairUp) && (blockFace != null && blockFace != BlockFace.NORTH && blockFace != BlockFace.SOUTH)) { + break; + } + + location.setX(location.getX() - 1); + + current = nextcurrent; + + //System.out.println("Iterated"); + } + } + + + if (current.getRelative(BlockFace.WEST).getType().isSolid()) { + if (!crittable) return false; + location.setY(west.getLocation().getY() - 1); + } + } else if (getDirectionName(player.getLocation()).contains("N")) { + if ((stairCurrent || stairUp) && (blockFace != null && blockFace != BlockFace.EAST && blockFace != BlockFace.WEST)) { + die(); + //System.out.println("DP1"); + return false; + } + + //System.out.println("Doing first tali"); + + location.setZ(location.getZ() - 1); + + for(int i = 0; i < MythicConfiguration.Options.Enderpearls.pearlMaxPass- 1; i++) { + if(MythicConfiguration.Options.Enderpearls.pearlPassFine) { + if (isSlab(current.getType()) || isSlab(above.getType())) { + isPassable = procBlocked(BlockFace.NORTH, null, (isSlab(current.getType()) ? current : above).getState().getData(), isPassable); + } else if (stairCurrent || stairUp) { + isPassable = procBlocked(BlockFace.NORTH, (Stairs) (stairCurrent ? current : above).getState().getData(), null, isPassable); + } + if (isPassable == 0) { + if (MythicConfiguration.Options.Enderpearls.pearlPassFineCancel) { + die(); + //System.out.println("PPFC"); + return false; + } + break; + } + } + // Iterate block + org.bukkit.block.Block nextcurrent = current.getRelative(BlockFace.NORTH); + org.bukkit.block.Block nextabove = nextcurrent.getRelative(BlockFace.UP); + + if(isSlab(nextcurrent.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairCurrent = isStair(nextcurrent.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || isSlab(nextabove.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairUp = isStair(nextabove.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || (nextcurrent.getType() == org.bukkit.Material.COBBLE_WALL && MythicConfiguration.Options.Enderpearls.Taliban.pearlCobbleWall)) { + if ((stairCurrent || stairUp) && (blockFace != null && blockFace != BlockFace.EAST && blockFace != BlockFace.WEST)) { + break; + } + + location.setZ(location.getZ() - 1); + + current = nextcurrent; + + //System.out.println("Iterated"); + } + } + + if (current.getRelative(BlockFace.NORTH).getType().isSolid()) { + if (!crittable) return false; + location.setY(north.getLocation().getY() - 1); + } + } else if (getDirectionName(player.getLocation()).contains("S")) { + if ((stairCurrent || stairUp) && (blockFace != null && blockFace != BlockFace.EAST && blockFace != BlockFace.WEST)) { + die(); + //System.out.println("DP1"); + return false; + } + + //System.out.println("Doing first tali"); + + location.setZ(location.getZ() + 1); + + for(int i = 0; i < MythicConfiguration.Options.Enderpearls.pearlMaxPass - 1; i++) { + if(MythicConfiguration.Options.Enderpearls.pearlPassFine) { + if (isSlab(current.getType()) || isSlab(above.getType())) { + isPassable = procBlocked(BlockFace.SOUTH, null, (isSlab(current.getType()) ? current : above).getState().getData(), isPassable); + } else if (stairCurrent || stairUp) { + isPassable = procBlocked(BlockFace.SOUTH, (Stairs) (stairCurrent ? current : above).getState().getData(), null, isPassable); + } + if (isPassable == 0) { + if (MythicConfiguration.Options.Enderpearls.pearlPassFineCancel) { + die(); + //System.out.println("PPFC"); + return false; + } + break; + } + } + // Iterate block + org.bukkit.block.Block nextcurrent = current.getRelative(BlockFace.SOUTH); + org.bukkit.block.Block nextabove = nextcurrent.getRelative(BlockFace.UP); + + if(isSlab(nextcurrent.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairCurrent = isStair(nextcurrent.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughStairs + || isSlab(nextabove.getType()) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (stairUp = isStair(nextabove.getType())) && MythicConfiguration.Options.Enderpearls.Taliban.pearlThroughSlab + || (nextcurrent.getType() == org.bukkit.Material.COBBLE_WALL && MythicConfiguration.Options.Enderpearls.Taliban.pearlCobbleWall)) { + if ((stairCurrent || stairUp) && (blockFace != null && blockFace != BlockFace.EAST && blockFace != BlockFace.WEST)) { + break; + } + + location.setZ(location.getZ() + 1); + + current = nextcurrent; + + //System.out.println("Iterated"); + } + } + + if (current.getRelative(BlockFace.SOUTH).getType().isSolid()) { + if (!crittable) return false; + location.setY(south.getLocation().getY() - 1); + } + } + } + + return true; + } + + private boolean isInverted(Object object) { + return object instanceof Step ? ((Step) object).isInverted() : ((WoodenStep) object).isInverted(); + } + + // ten ben tws bws + private byte procBlocked(BlockFace dir, Stairs stairs, Object step, byte curPassable) { + if(stairs == null && step == null) { + return curPassable; + } + + if(curPassable == 0) return 0; + + if((curPassable & 0b0001) != 0) { // BWS is still passable + if(step != null) { + if(!this.isInverted(step)) { + curPassable &= ~0b0001; // BWS is not passable + //System.out.println("Eliminated BWS"); + } + } else { // Stair + if(!stairs.isInverted()) { + curPassable &= ~0b0001; // BWS is not passable + //System.out.println("Eliminated BWS"); + } else { + switch (dir) { + case EAST: + case WEST: + if(stairs.getFacing() == BlockFace.SOUTH) { // On south facing stair, south side is blocked + curPassable &= ~0b0001; // BWS is not passable + //System.out.println("Eliminated BWS"); + } + break; + case NORTH: + case SOUTH: + if(stairs.getFacing() == BlockFace.WEST) { // On west facing stair, west side is blocked + curPassable &= ~0b0001; // BWS is not passable + //System.out.println("Eliminated BWS"); + } + break; + } + } + } + } + + if((curPassable & 0b0010) != 0) { // TWS is still passable + if(step != null) { + if(this.isInverted(step)) { + curPassable &= ~0b0010; // TWS is not passable + //System.out.println("Eliminated TWS"); + } + } else { // Stair + if(stairs.isInverted()) { + curPassable &= ~0b0010; // TWS is not passable + //System.out.println("Eliminated TWS"); + } else { + switch (dir) { + case EAST: + case WEST: + if(stairs.getFacing() == BlockFace.SOUTH) { // On south facing stair, south side is blocked + curPassable &= ~0b0010; // TWS is not passable + //System.out.println("Eliminated TWS"); + } + break; + case NORTH: + case SOUTH: + if(stairs.getFacing() == BlockFace.WEST) { // On west facing stair, west side is blocked + curPassable &= ~0b0010; // TWS is not passable + //System.out.println("Eliminated TWS"); + } + break; + } + } + } + } + + + if((curPassable & 0b0100) != 0) { // BEN is still passable + if(step != null) { + if(!this.isInverted(step)) { + curPassable &= ~0b0100; // BEN is not passable + //System.out.println("Eliminated BEN"); + } + } else { // Stair + if(!stairs.isInverted()) { + curPassable &= ~0b0100; // BEN is not passable + //System.out.println("Eliminated BEN"); + } else { + switch (dir) { + case EAST: + case WEST: + if(stairs.getFacing() == BlockFace.NORTH) { // On north facing stair, north side is blocked + curPassable &= ~0b0100; // BEN is not passable + //System.out.println("Eliminated BEN"); + } + break; + case NORTH: + case SOUTH: + if(stairs.getFacing() == BlockFace.EAST) { // On east facing stair, east side is blocked + curPassable &= ~0b0100; // BEN is not passable + //System.out.println("Eliminated BEN"); + } + break; + } + } + } + } + + if((curPassable & 0b1000) != 0) { // TEN is still passable + if(step != null) { + if(this.isInverted(step)) { + curPassable &= ~0b1000; // TEN is not passable + //System.out.println("Eliminated TEN"); + } + } else { // Stair + if(stairs.isInverted()) { + curPassable &= ~0b1000; // TEN is not passable + //System.out.println("Eliminated TEN"); + } else { + switch (dir) { + case EAST: + case WEST: + if(stairs.getFacing() == BlockFace.NORTH) { // On north facing stair, north side is blocked + curPassable &= ~0b1000; // TEN is not passable + //System.out.println("Eliminated TEN"); + } + break; + case NORTH: + case SOUTH: + if(stairs.getFacing() == BlockFace.EAST) { // On east facing stair, east side is blocked + curPassable &= ~0b1000; // TEN is not passable + //System.out.println("Eliminated TEN"); + } + break; + } + } + } + } + + if(curPassable == 0) { + //System.out.println("No longer passable"); + } + + return curPassable; + } + + private boolean isSlab(org.bukkit.Material material) { + return material.toString().contains("STEP"); + } + + private boolean isType(Material required, Material... currentMaterials) { + for (Material material : currentMaterials) { + if (material.equals(required)) return true; + } + + return false; + } + + private boolean isSlab(org.bukkit.Material... materials) { + for (Material material : materials) { + if (material.toString().contains("STEP")) return true; + } + return false; + } + + private boolean isStair(org.bukkit.Material... materials) { + for (Material material : materials) { + if (material.toString().contains("STAIRS")) return true; + } + return false; + } + + private boolean isStair(org.bukkit.Material material) { + return material.toString().contains("STAIRS"); + } + + private String getDirectionName(Location location) { + double rotation = (location.getYaw() - 90) % 360; + if (rotation < 0) { + rotation += 360.0; + } + if (0 <= rotation && rotation < 22.5) { + return "W"; + } else if (22.5 <= rotation && rotation < 67.5) { + return "NW"; + } else if (67.5 <= rotation && rotation < 112.5) { + return "N"; + } else if (112.5 <= rotation && rotation < 157.5) { + return "NE"; + } else if (157.5 <= rotation && rotation < 202.5) { + return "E"; + } else if (202.5 <= rotation && rotation < 247.5) { + return "SE"; + } else if (247.5 <= rotation && rotation < 292.5) { + return "S"; + } else if (292.5 <= rotation && rotation < 337.5) { + return "SW"; + } else if (337.5 <= rotation && rotation < 360.0) { + return "W"; + } else { + return "invalid"; + } + } + + + @Override + public void t_() { + final EntityLiving shooter = this.shooter; + + if (shooter != null && !shooter.isAlive()) { + die(); + return; + } + + Location location = getBukkitEntity().getLocation(); + org.bukkit.block.Block block = location.getBlock(); + + if (block.isEmpty()) { + this.valid = location; + } + + if (block.getType().toString().contains("STAIRS") || block.getType().toString().contains("STEP")) { + this.valid = location; + } + + if (block.getType() == org.bukkit.Material.FENCE_GATE) { + if (((Gate) block.getState().getData()).isOpen()) { + this.valid = location; + } + } + + super.t_(); + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderman.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderman.java new file mode 100644 index 0000000..f3afbbd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityEnderman.java @@ -0,0 +1,491 @@ +package net.minecraft.server; + +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; +import java.util.UUID; + +// CraftBukkit start +import org.bukkit.Location; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityTeleportEvent; +// CraftBukkit end + +public class EntityEnderman extends EntityMonster { + + private static final UUID a = UUID.fromString("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; + + public EntityEnderman(World world) { + super(world); + this.setSize(0.6F, 2.9F); + this.S = 1.0F; + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); + this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); + this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.goalSelector.a(10, new EntityEnderman.PathfinderGoalEndermanPlaceBlock(this)); + this.goalSelector.a(11, new EntityEnderman.PathfinderGoalEndermanPickupBlock(this)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(2, new EntityEnderman.PathfinderGoalPlayerWhoLookedAtTarget(this)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget(this, EntityEndermite.class, 10, true, false, new Predicate() { + public boolean a(EntityEndermite entityendermite) { + return entityendermite.n(); + } + + public boolean apply(Object object) { + return this.a((EntityEndermite) object); + } + })); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(40.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(7.0D); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(64.0D); + } + + protected void h() { + super.h(); + this.datawatcher.a(16, new Short((short) 0)); + this.datawatcher.a(17, new Byte((byte) 0)); + this.datawatcher.a(18, new Byte((byte) 0)); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + IBlockData iblockdata = this.getCarried(); + + nbttagcompound.setShort("carried", (short) Block.getId(iblockdata.getBlock())); + nbttagcompound.setShort("carriedData", (short) iblockdata.getBlock().toLegacyData(iblockdata)); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + IBlockData iblockdata; + + if (nbttagcompound.hasKeyOfType("carried", 8)) { + iblockdata = Block.getByName(nbttagcompound.getString("carried")).fromLegacyData(nbttagcompound.getShort("carriedData") & '\uffff'); + } else { + iblockdata = Block.getById(nbttagcompound.getShort("carried")).fromLegacyData(nbttagcompound.getShort("carriedData") & '\uffff'); + } + + this.setCarried(iblockdata); + } + + private boolean c(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.armor[3]; + + if (itemstack != null && itemstack.getItem() == Item.getItemOf(Blocks.PUMPKIN)) { + return false; + } else { + Vec3D vec3d = entityhuman.d(1.0F).a(); + Vec3D vec3d1 = new Vec3D(this.locX - entityhuman.locX, this.getBoundingBox().b + (double) (this.length / 2.0F) - (entityhuman.locY + (double) entityhuman.getHeadHeight()), this.locZ - entityhuman.locZ); + double d0 = vec3d1.b(); + + vec3d1 = vec3d1.a(); + double d1 = vec3d.b(vec3d1); + + return d1 > 1.0D - 0.025D / d0 ? entityhuman.hasLineOfSight(this) : false; + } + } + + public float getHeadHeight() { + return 2.55F; + } + + 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.aY = false; + super.m(); + } + + protected void E() { + if (this.U()) { + this.damageEntity(DamageSource.DROWN, 1.0F); + } + + if (this.co() && !this.bm && this.random.nextInt(100) == 0) { + this.a(false); + } + + if (this.world.w()) { + float f = this.c(1.0F); + + if (f > 0.5F && this.world.i(new BlockPosition(this)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) { + this.setGoalTarget((EntityLiving) null); + this.a(false); + this.bm = false; + this.n(); + } + } + + super.E(); + } + + protected boolean n() { + double d0 = this.locX + (this.random.nextDouble() - 0.5D) * 64.0D; + double d1 = this.locY + (double) (this.random.nextInt(64) - 32); + double d2 = this.locZ + (this.random.nextDouble() - 0.5D) * 64.0D; + + return this.k(d0, d1, d2); + } + + protected boolean b(Entity entity) { + Vec3D vec3d = new Vec3D(this.locX - entity.locX, this.getBoundingBox().b + (double) (this.length / 2.0F) - entity.locY + (double) entity.getHeadHeight(), this.locZ - entity.locZ); + + vec3d = vec3d.a(); + double d0 = 16.0D; + double d1 = this.locX + (this.random.nextDouble() - 0.5D) * 8.0D - vec3d.a * d0; + double d2 = this.locY + (double) (this.random.nextInt(16) - 8) - vec3d.b * d0; + double d3 = this.locZ + (this.random.nextDouble() - 0.5D) * 8.0D - vec3d.c * d0; + + return this.k(d1, d2, d3); + } + + protected boolean k(double d0, double d1, double d2) { + double d3 = this.locX; + double d4 = this.locY; + double d5 = this.locZ; + + this.locX = d0; + this.locY = d1; + this.locZ = d2; + boolean flag = false; + BlockPosition blockposition = new BlockPosition(this.locX, this.locY, this.locZ); + + if (this.world.isLoaded(blockposition)) { + boolean flag1 = false; + + while (!flag1 && blockposition.getY() > 0) { + BlockPosition blockposition1 = blockposition.down(); + Block block = this.world.getType(blockposition1).getBlock(); + + if (block.getMaterial().isSolid()) { + flag1 = true; + } else { + --this.locY; + blockposition = blockposition1; + } + } + + if (flag1) { + // CraftBukkit start - Teleport event + // super.enderTeleportTo(this.locX, this.locY, this.locZ); + EntityTeleportEvent teleport = new EntityTeleportEvent(this.getBukkitEntity(), new Location(this.world.getWorld(), d3, d4, d5), new Location(this.world.getWorld(), this.locX, this.locY, this.locZ)); + this.world.getServer().getPluginManager().callEvent(teleport); + if (teleport.isCancelled()) { + return false; + } + + Location to = teleport.getTo(); + this.enderTeleportTo(to.getX(), to.getY(), to.getZ()); + // CraftBukkit end + if (this.world.getCubes(this, this.getBoundingBox()).isEmpty() && !this.world.containsLiquid(this.getBoundingBox())) { + flag = true; + } + } + } + + if (!flag) { + this.setPosition(d3, d4, d5); + return false; + } else { + short short0 = 128; + + for (int i = 0; i < short0; ++i) { + double d6 = (double) i / ((double) short0 - 1.0D); + float f = (this.random.nextFloat() - 0.5F) * 0.2F; + float f1 = (this.random.nextFloat() - 0.5F) * 0.2F; + float f2 = (this.random.nextFloat() - 0.5F) * 0.2F; + double d7 = d3 + (this.locX - d3) * d6 + (this.random.nextDouble() - 0.5D) * (double) this.width * 2.0D; + 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, (double) f, (double) f1, (double) f2, new int[0]); + } + + this.world.makeSound(d3, d4, d5, "mob.endermen.portal", 1.0F, 1.0F); + this.makeSound("mob.endermen.portal", 1.0F, 1.0F); + return true; + } + } + + protected String z() { + return this.co() ? "mob.endermen.scream" : "mob.endermen.idle"; + } + + protected String bo() { + return "mob.endermen.hit"; + } + + protected String bp() { + return "mob.endermen.death"; + } + + protected Item getLoot() { + return Items.ENDER_PEARL; + } + + protected void dropDeathLoot(boolean flag, int i) { + Item item = this.getLoot(); + + if (item != null) { + int j = this.random.nextInt(2 + i); + + for (int k = 0; k < j; ++k) { + this.a(item, 1); + } + } + + // PaperSpigot start - Drop the block the entity is holding when it dies + Item carriedItem = Item.getItemOf(getCarried().getBlock()); + if (carriedItem != null) { + this.a(carriedItem, 1); + } + // PaperSpigot end + + } + + public void setCarried(IBlockData iblockdata) { + this.datawatcher.watch(16, Short.valueOf((short) (Block.getCombinedId(iblockdata) & '\uffff'))); + } + + public IBlockData getCarried() { + return Block.getByCombinedId(this.datawatcher.getShort(16) & '\uffff'); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + if (damagesource.getEntity() == null || !(damagesource.getEntity() instanceof EntityEndermite)) { + if (!this.world.isClientSide) { + this.a(true); + } + + if (damagesource instanceof EntityDamageSource && damagesource.getEntity() instanceof EntityHuman) { + if (damagesource.getEntity() instanceof EntityPlayer && ((EntityPlayer) damagesource.getEntity()).playerInteractManager.isCreative()) { + this.a(false); + } else { + this.bm = true; + } + } + + if (damagesource instanceof EntityDamageSourceIndirect) { + this.bm = false; + + for (int i = 0; i < 64; ++i) { + if (this.n()) { + return true; + } + } + + return false; + } + } + + boolean flag = super.damageEntity(damagesource, f); + + if (damagesource.ignoresArmor() && this.random.nextInt(10) != 0) { + this.n(); + } + + return flag; + } + } + + public boolean co() { + return this.datawatcher.getByte(18) > 0; + } + + public void a(boolean flag) { + this.datawatcher.watch(18, Byte.valueOf((byte) (flag ? 1 : 0))); + } + + static { + EntityEnderman.c.add(Blocks.GRASS); + EntityEnderman.c.add(Blocks.DIRT); + EntityEnderman.c.add(Blocks.SAND); + EntityEnderman.c.add(Blocks.GRAVEL); + EntityEnderman.c.add(Blocks.YELLOW_FLOWER); + EntityEnderman.c.add(Blocks.RED_FLOWER); + EntityEnderman.c.add(Blocks.BROWN_MUSHROOM); + EntityEnderman.c.add(Blocks.RED_MUSHROOM); + EntityEnderman.c.add(Blocks.TNT); + EntityEnderman.c.add(Blocks.CACTUS); + EntityEnderman.c.add(Blocks.CLAY); + EntityEnderman.c.add(Blocks.PUMPKIN); + EntityEnderman.c.add(Blocks.MELON_BLOCK); + EntityEnderman.c.add(Blocks.MYCELIUM); + } + + static class PathfinderGoalEndermanPickupBlock extends PathfinderGoal { + + private EntityEnderman enderman; + + public PathfinderGoalEndermanPickupBlock(EntityEnderman entityenderman) { + this.enderman = entityenderman; + } + + public boolean a() { + return !this.enderman.world.getGameRules().getBoolean("mobGriefing") ? false : (this.enderman.getCarried().getBlock().getMaterial() != Material.AIR ? false : this.enderman.bc().nextInt(20) == 0); + } + + public void e() { + Random random = this.enderman.bc(); + World world = this.enderman.world; + int i = MathHelper.floor(this.enderman.locX - 2.0D + random.nextDouble() * 4.0D); + int j = MathHelper.floor(this.enderman.locY + random.nextDouble() * 3.0D); + int k = MathHelper.floor(this.enderman.locZ - 2.0D + random.nextDouble() * 4.0D); + BlockPosition blockposition = new BlockPosition(i, j, k); + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (EntityEnderman.c.contains(block)) { + // CraftBukkit start - Pickup event + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.enderman, this.enderman.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), org.bukkit.Material.AIR).isCancelled()) { + this.enderman.setCarried(iblockdata); + world.setTypeUpdate(blockposition, Blocks.AIR.getBlockData()); + } + // CraftBukkit end + } + + } + } + + static class PathfinderGoalEndermanPlaceBlock extends PathfinderGoal { + + private EntityEnderman a; + + public PathfinderGoalEndermanPlaceBlock(EntityEnderman entityenderman) { + this.a = entityenderman; + } + + public boolean a() { + return !this.a.world.getGameRules().getBoolean("mobGriefing") ? false : (this.a.getCarried().getBlock().getMaterial() == Material.AIR ? false : this.a.bc().nextInt(2000) == 0); + } + + public void e() { + Random random = this.a.bc(); + World world = this.a.world; + int i = MathHelper.floor(this.a.locX - 1.0D + random.nextDouble() * 2.0D); + int j = MathHelper.floor(this.a.locY + random.nextDouble() * 2.0D); + int k = MathHelper.floor(this.a.locZ - 1.0D + random.nextDouble() * 2.0D); + BlockPosition blockposition = new BlockPosition(i, j, k); + Block block = world.getType(blockposition).getBlock(); + Block block1 = world.getType(blockposition.down()).getBlock(); + + if (this.a(world, blockposition, this.a.getCarried().getBlock(), block, block1)) { + // CraftBukkit start - Place event + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.a, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.a.getCarried().getBlock(), this.a.getCarried().getBlock().toLegacyData(this.a.getCarried())).isCancelled()) { + world.setTypeAndData(blockposition, this.a.getCarried(), 3); + this.a.setCarried(Blocks.AIR.getBlockData()); + } + // CraftBukkit end + } + + } + + private boolean a(World world, BlockPosition blockposition, Block block, Block block1, Block block2) { + return !block.canPlace(world, blockposition) ? false : (block1.getMaterial() != Material.AIR ? false : (block2.getMaterial() == Material.AIR ? false : block2.d())); + } + } + + static class PathfinderGoalPlayerWhoLookedAtTarget extends PathfinderGoalNearestAttackableTarget { + + private EntityHuman g; + private int h; + private int i; + private EntityEnderman j; + + public PathfinderGoalPlayerWhoLookedAtTarget(EntityEnderman entityenderman) { + super(entityenderman, EntityHuman.class, true); + this.j = entityenderman; + } + + public boolean a() { + double d0 = this.f(); + List list = this.e.world.a(EntityHuman.class, this.e.getBoundingBox().grow(d0, 4.0D, d0), this.c); + + Collections.sort(list, this.b); + if (list.isEmpty()) { + return false; + } else { + this.g = (EntityHuman) list.get(0); + return true; + } + } + + public void c() { + this.h = 5; + this.i = 0; + } + + public void d() { + this.g = null; + this.j.a(false); + AttributeInstance attributeinstance = this.j.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); + + attributeinstance.c(EntityEnderman.b); + super.d(); + } + + public boolean b() { + if (this.g != null) { + if (!this.j.c(this.g)) { + return false; + } else { + this.j.bm = true; + this.j.a(this.g, 10.0F, 10.0F); + return true; + } + } else { + return super.b(); + } + } + + public void e() { + if (this.g != null) { + if (--this.h <= 0) { + this.d = this.g; + this.g = null; + super.c(); + this.j.makeSound("mob.endermen.stare", 1.0F, 1.0F); + this.j.a(true); + AttributeInstance attributeinstance = this.j.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); + + attributeinstance.b(EntityEnderman.b); + } + } else { + if (this.d != null) { + if (this.d instanceof EntityHuman && this.j.c((EntityHuman) this.d)) { + if (this.d.h(this.j) < 16.0D) { + this.j.n(); + } + + this.i = 0; + } else if (this.d.h(this.j) > 256.0D && this.i++ >= 30 && this.j.b((Entity) this.d)) { + this.i = 0; + } + } + + super.e(); + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityExperienceOrb.java new file mode 100644 index 0000000..4da3e1e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityExperienceOrb.java @@ -0,0 +1,200 @@ +package net.minecraft.server; + +// CraftBukkit start + +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +// CraftBukkit end + +public class EntityExperienceOrb extends Entity { + + public int a; + public int b; + public int c; + private int d = 5; + public int value; + private EntityHuman targetPlayer; + private int targetTime; + + public EntityExperienceOrb(World world, double d0, double d1, double d2, int i) { + super(world); + this.setSize(0.5F, 0.5F); + this.setPosition(d0, d1, d2); + this.yaw = (float) (Math.random() * 360.0D); + this.motX = (float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F; + this.motY = (float) (Math.random() * 0.2D) * 2.0F; + this.motZ = (float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 2.0F; + this.value = i; + } + + protected boolean s_() { + return false; + } + + public EntityExperienceOrb(World world) { + super(world); + this.setSize(0.25F, 0.25F); + } + + protected void h() {} + + public void t_() { + super.t_(); + EntityHuman prevTarget = this.targetPlayer;// CraftBukkit - store old target + if (this.c > 0) { + --this.c; + } + + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + this.motY -= 0.029999999329447746D; + if (this.world.getType(new BlockPosition(this)).getBlock().getMaterial() == Material.LAVA) { + this.motY = 0.20000000298023224D; + this.motX = (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; + this.motZ = (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; + this.makeSound("random.fizz", 0.4F, 2.0F + this.random.nextFloat() * 0.4F); + } + + this.j(this.locX, (this.getBoundingBox().b + this.getBoundingBox().e) / 2.0D, this.locZ); + double d0 = 8.0D; + + if (this.targetTime < this.a - 20 + this.getId() % 100) { + if (this.targetPlayer == null || this.targetPlayer.h(this) > d0 * d0) { + this.targetPlayer = this.world.findNearbyPlayer(this, d0); + } + + this.targetTime = this.a; + } + + if (this.targetPlayer != null && this.targetPlayer.isSpectator()) { + this.targetPlayer = null; + } + + if (this.targetPlayer != null) { + // CraftBukkit start + boolean cancelled = false; + if (this.targetPlayer != prevTarget) { + EntityTargetLivingEntityEvent event = CraftEventFactory.callEntityTargetLivingEvent(this, targetPlayer, EntityTargetEvent.TargetReason.CLOSEST_PLAYER); + EntityLiving target = event.getTarget() == null ? null : ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); + targetPlayer = target instanceof EntityHuman ? (EntityHuman) target : null; + cancelled = event.isCancelled(); + } + + if (!cancelled && targetPlayer != null) { + double d1 = (this.targetPlayer.locX - this.locX) / d0; + double d2 = (this.targetPlayer.locY + (double) this.targetPlayer.getHeadHeight() - this.locY) / d0; + double d3 = (this.targetPlayer.locZ - this.locZ) / d0; + double d4 = Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3); + double d5 = 1.0D - d4; + + if (d5 > 0.0D) { + d5 *= d5; + this.motX += d1 / d4 * d5 * 0.1D; + this.motY += d2 / d4 * d5 * 0.1D; + this.motZ += d3 / d4 * d5 * 0.1D; + } + } + // CraftBukkit end + } + + this.move(this.motX, this.motY, this.motZ); + float f = 0.98F; + + if (this.onGround) { + f = this.world.getType(MathHelper.floor(this.locX), MathHelper.floor(this.getBoundingBox().b) - 1, MathHelper.floor(this.locZ)).getBlock().frictionFactor * 0.98F; + } + + this.motX *= f; + this.motY *= 0.9800000190734863D; + this.motZ *= f; + if (this.onGround) { + this.motY *= -0.8999999761581421D; + } + + ++this.a; + ++this.b; + if (this.b >= 6000) { + this.die(); + } + + } + + public boolean W() { + return this.world.a(this.getBoundingBox(), Material.WATER, this); + } + + protected void burn(int i) { + this.damageEntity(DamageSource.FIRE, (float) i); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + this.ac(); + this.d = (int) ((float) this.d - f); + if (this.d <= 0) { + this.die(); + } + + return false; + } + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setShort("Health", (byte) this.d); + nbttagcompound.setShort("Age", (short) this.b); + nbttagcompound.setShort("Value", (short) this.value); + } + + public void a(NBTTagCompound nbttagcompound) { + this.d = nbttagcompound.getShort("Health") & 255; + this.b = nbttagcompound.getShort("Age"); + this.value = nbttagcompound.getShort("Value"); + } + + public void d(EntityHuman entityhuman) { + if (!this.world.isClientSide) { + if (this.c == 0 && entityhuman.bp == 0) { + entityhuman.bp = 2; + this.world.makeSound(entityhuman, "random.orb", 0.1F, 0.5F * ((this.random.nextFloat() - this.random.nextFloat()) * 0.7F + 1.8F)); + entityhuman.receive(this, 1); + entityhuman.giveExp(CraftEventFactory.callPlayerExpChangeEvent(entityhuman, this.value).getAmount()); // CraftBukkit - this.value -> event.getAmount() + this.die(); + } + + } + } + + public int j() { + return this.value; + } + + public static int getOrbValue(int i) { + // CraftBukkit start + if (i > 162670129) return i - 100000; + if (i > 81335063) return 81335063; + if (i > 40667527) return 40667527; + if (i > 20333759) return 20333759; + if (i > 10166857) return 10166857; + if (i > 5083423) return 5083423; + if (i > 2541701) return 2541701; + if (i > 1270849) return 1270849; + if (i > 635413) return 635413; + if (i > 317701) return 317701; + if (i > 158849) return 158849; + if (i > 79423) return 79423; + if (i > 39709) return 39709; + if (i > 19853) return 19853; + if (i > 9923) return 9923; + if (i > 4957) return 4957; + // CraftBukkit end + return i >= 2477 ? 2477 : (i >= 1237 ? 1237 : (i >= 617 ? 617 : (i >= 307 ? 307 : (i >= 149 ? 149 : (i >= 73 ? 73 : (i >= 37 ? 37 : (i >= 17 ? 17 : (i >= 7 ? 7 : (i >= 3 ? 3 : 1))))))))); + } + + public boolean aD() { + return false; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFallingBlock.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFallingBlock.java new file mode 100644 index 0000000..e3bfd86 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFallingBlock.java @@ -0,0 +1,303 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Iterator; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class EntityFallingBlock extends Entity { + + private IBlockData block; + public int ticksLived; + public boolean dropItem = true; + private boolean e; + public boolean hurtEntities; // PAIL: private -> public + private int fallHurtMax = 40; + private float fallHurtAmount = 2.0F; + public NBTTagCompound tileEntityData; + public org.bukkit.Location sourceLoc; // PaperSpigot + + // PaperSpigot start - Add FallingBlock source location API + public EntityFallingBlock(World world) { + this(null, world); + } + + public EntityFallingBlock(org.bukkit.Location loc, World world) { + super(world); + sourceLoc = loc; + this.loadChunks = world.paperSpigotConfig.loadUnloadedFallingBlocks; // PaperSpigot + } + + public EntityFallingBlock(World world, double d0, double d1, double d2, IBlockData iblockdata) { + this(null, world, d0, d1, d2, iblockdata); + } + + public EntityFallingBlock(org.bukkit.Location loc, World world, double d0, double d1, double d2, IBlockData iblockdata) { + super(world); + sourceLoc = loc; + // PaperSpigot end + this.block = iblockdata; + this.k = true; + this.setSize(0.98F, 0.98F); + this.setPosition(d0, d1, d2); + this.motX = 0.0D; + this.motY = 0.0D; + this.motZ = 0.0D; + this.lastX = d0; + this.lastY = d1; + this.lastZ = d2; + this.loadChunks = world.paperSpigotConfig.loadUnloadedFallingBlocks; // PaperSpigot + } + + protected boolean s_() { + return false; + } + + protected void h() {} + + public boolean ad() { + return !this.dead; + } + + public void t_() { + Block block = this.block.getBlock(); + + if (block.getMaterial() == Material.AIR) { + this.die(); + } else { + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + BlockPosition blockposition; + + if (this.ticksLived++ == 0) { + blockposition = new BlockPosition(this); + if (this.world.getType(blockposition).getBlock() == block && !CraftEventFactory.callEntityChangeBlockEvent(this, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.AIR, 0).isCancelled()) { + this.world.setAir(blockposition); + world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, blockposition); // Spigot + } else if (!this.world.isClientSide) { + this.die(); + return; + } + } + + this.motY -= 0.03999999910593033D; + this.move(this.motX, this.motY, this.motZ); + + // PaperSpigot start - Remove entities in unloaded chunks + if (this.inUnloadedChunk && world.paperSpigotConfig.removeUnloadedFallingBlocks) { + this.die(); + } + // PaperSpigot end + + // PaperSpigot start - Drop falling blocks above the specified height + if (this.world.paperSpigotConfig.fallingBlockHeightNerf != 0 && this.locY > this.world.paperSpigotConfig.fallingBlockHeightNerf) { + if (this.dropItem) { + this.a(new ItemStack(block, 1, block.getDropData(this.block)), 0.0F); + } + + this.die(); + } + // PaperSpigot end + + this.motX *= 0.9800000190734863D; + this.motY *= 0.9800000190734863D; + this.motZ *= 0.9800000190734863D; + if (!this.world.isClientSide) { + blockposition = new BlockPosition(this); + if (this.onGround) { + this.motX *= 0.699999988079071D; + this.motZ *= 0.699999988079071D; + this.motY *= -0.5D; + if (this.world.getType(blockposition).getBlock() != Blocks.PISTON_EXTENSION) { + this.die(); + if (!this.e) { + if (this.world.a(block, blockposition, true, EnumDirection.UP, (Entity) null, (ItemStack) 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 (CraftEventFactory.callEntityChangeBlockEvent(this, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.block.getBlock(), this.block.getBlock().toLegacyData(this.block)).isCancelled()) { + return; + } + this.world.setTypeAndData(blockposition, this.block, 3); + world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, blockposition); // Spigot + // CraftBukkit end + if (block instanceof BlockFalling) { + ((BlockFalling) block).a_(this.world, blockposition); + } + + if (this.tileEntityData != null && block instanceof IContainer) { + TileEntity tileentity = this.world.getTileEntity(blockposition); + + if (tileentity != null) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + tileentity.b(nbttagcompound); + Iterator iterator = this.tileEntityData.c().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + NBTBase nbtbase = this.tileEntityData.get(s); + + if (!s.equals("x") && !s.equals("y") && !s.equals("z")) { + nbttagcompound.set(s, nbtbase.clone()); + } + } + + tileentity.a(nbttagcompound); + tileentity.update(); + } + } + } else if (this.dropItem && this.world.getGameRules().getBoolean("doEntityDrops")) { + this.a(new ItemStack(block, 1, block.getDropData(this.block)), 0.0F); + } + } + } + } else if (this.ticksLived > 100 && !this.world.isClientSide && (blockposition.getY() < 1 || blockposition.getY() > 256) || this.ticksLived > 600) { + if (this.dropItem && this.world.getGameRules().getBoolean("doEntityDrops")) { + this.a(new ItemStack(block, 1, block.getDropData(this.block)), 0.0F); + } + + this.die(); + } + } + + } + } + + public void e(float f, float f1) { + Block block = this.block.getBlock(); + + if (this.hurtEntities) { + int i = MathHelper.f(f - 1.0F); + + if (i > 0) { + ArrayList arraylist = Lists.newArrayList(this.world.getEntities(this, this.getBoundingBox())); + boolean flag = block == Blocks.ANVIL; + DamageSource damagesource = flag ? DamageSource.ANVIL : DamageSource.FALLING_BLOCK; + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + CraftEventFactory.entityDamage = this; // CraftBukkit + entity.damageEntity(damagesource, (float) Math.min(MathHelper.d((float) i * this.fallHurtAmount), this.fallHurtMax)); + CraftEventFactory.entityDamage = null; // CraftBukkit + } + + if (flag && (double) this.random.nextFloat() < 0.05000000074505806D + (double) i * 0.05D) { + int j = ((Integer) this.block.get(BlockAnvil.DAMAGE)).intValue(); + + ++j; + if (j > 2) { + this.e = true; + } else { + this.block = this.block.set(BlockAnvil.DAMAGE, Integer.valueOf(j)); + } + } + } + } + + } + + protected void b(NBTTagCompound nbttagcompound) { + Block block = this.block != null ? this.block.getBlock() : Blocks.AIR; + MinecraftKey minecraftkey = (MinecraftKey) Block.REGISTRY.c(block); + + nbttagcompound.setString("Block", minecraftkey == null ? "" : minecraftkey.toString()); + nbttagcompound.setByte("Data", (byte) block.toLegacyData(this.block)); + nbttagcompound.setByte("Time", (byte) this.ticksLived); + nbttagcompound.setBoolean("DropItem", this.dropItem); + nbttagcompound.setBoolean("HurtEntities", this.hurtEntities); + nbttagcompound.setFloat("FallHurtAmount", this.fallHurtAmount); + nbttagcompound.setInt("FallHurtMax", this.fallHurtMax); + if (this.tileEntityData != null) { + nbttagcompound.set("TileEntityData", this.tileEntityData); + } + // PaperSpigot start - Add FallingBlock source location API + if (sourceLoc != null) { + nbttagcompound.setInt("SourceLoc_x", sourceLoc.getBlockX()); + nbttagcompound.setInt("SourceLoc_y", sourceLoc.getBlockY()); + nbttagcompound.setInt("SourceLoc_z", sourceLoc.getBlockZ()); + } + // PaperSpigot end + } + + protected void a(NBTTagCompound nbttagcompound) { + int i = nbttagcompound.getByte("Data") & 255; + + if (nbttagcompound.hasKeyOfType("Block", 8)) { + this.block = Block.getByName(nbttagcompound.getString("Block")).fromLegacyData(i); + } else if (nbttagcompound.hasKeyOfType("TileID", 99)) { + this.block = Block.getById(nbttagcompound.getInt("TileID")).fromLegacyData(i); + } else { + this.block = Block.getById(nbttagcompound.getByte("Tile") & 255).fromLegacyData(i); + } + + this.ticksLived = nbttagcompound.getByte("Time") & 255; + Block block = this.block.getBlock(); + + if (nbttagcompound.hasKeyOfType("HurtEntities", 99)) { + this.hurtEntities = nbttagcompound.getBoolean("HurtEntities"); + this.fallHurtAmount = nbttagcompound.getFloat("FallHurtAmount"); + this.fallHurtMax = nbttagcompound.getInt("FallHurtMax"); + } else if (block == Blocks.ANVIL) { + this.hurtEntities = true; + } + + if (nbttagcompound.hasKeyOfType("DropItem", 99)) { + this.dropItem = nbttagcompound.getBoolean("DropItem"); + } + + if (nbttagcompound.hasKeyOfType("TileEntityData", 10)) { + this.tileEntityData = nbttagcompound.getCompound("TileEntityData"); + } + + if (block == null || block.getMaterial() == Material.AIR) { + this.block = Blocks.SAND.getBlockData(); + } + // PaperSpigot start - Add FallingBlock source location API + if (nbttagcompound.hasKey("SourceLoc_x")) { + int srcX = nbttagcompound.getInt("SourceLoc_x"); + int srcY = nbttagcompound.getInt("SourceLoc_y"); + int srcZ = nbttagcompound.getInt("SourceLoc_z"); + sourceLoc = new org.bukkit.Location(world.getWorld(), srcX, srcY, srcZ); + } + // PaperSpigot end + } + + public void a(boolean flag) { + this.hurtEntities = flag; + } + + public void appendEntityCrashDetails(CrashReportSystemDetails crashreportsystemdetails) { + super.appendEntityCrashDetails(crashreportsystemdetails); + if (this.block != null) { + Block block = this.block.getBlock(); + + crashreportsystemdetails.a("Immitating block ID", (Object) Integer.valueOf(Block.getId(block))); + crashreportsystemdetails.a("Immitating block data", (Object) Integer.valueOf(block.toLegacyData(this.block))); + } + + } + + public IBlockData getBlock() { + return this.block; + } + + // PaperSpigot start - Fix cannons + @Override + public double f(double d0, double d1, double d2) { + if (!world.paperSpigotConfig.fixCannons) return super.f(d0, d1, d2); + + double d3 = this.locX - d0; + double d4 = this.locY + this.getHeadHeight() - d1; + double d5 = this.locZ - d2; + + return (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); + } + + @Override + public float getHeadHeight() { + return world.paperSpigotConfig.fixCannons ? this.length / 2 : super.getHeadHeight(); + } + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFireball.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFireball.java new file mode 100644 index 0000000..c55360b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFireball.java @@ -0,0 +1,281 @@ +package net.minecraft.server; + +import org.bukkit.craftbukkit.event.CraftEventFactory; + +import java.util.List; + +public abstract class EntityFireball extends Entity { + + private int e = -1; + private int f = -1; + private int g = -1; + private Block h; + private boolean i; + public EntityLiving shooter; + private int ar; + private int as; + public double dirX; + public double dirY; + public double dirZ; + public float bukkitYield = 1; // CraftBukkit + public boolean isIncendiary = true; // CraftBukkit + + public EntityFireball(World world) { + super(world); + this.setSize(1.0F, 1.0F); + } + + protected void h() {} + + public EntityFireball(World world, double d0, double d1, double d2, double d3, double d4, double d5) { + super(world); + this.setSize(1.0F, 1.0F); + this.setPositionRotation(d0, d1, d2, this.yaw, this.pitch); + this.setPosition(d0, d1, d2); + double d6 = MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); + + this.dirX = d3 / d6 * 0.1D; + this.dirY = d4 / d6 * 0.1D; + this.dirZ = d5 / d6 * 0.1D; + } + + public EntityFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) { + super(world); + this.shooter = entityliving; + this.projectileSource = (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit + this.setSize(1.0F, 1.0F); + this.setPositionRotation(entityliving.locX, entityliving.locY, entityliving.locZ, entityliving.yaw, entityliving.pitch); + this.setPosition(this.locX, this.locY, this.locZ); + this.motX = this.motY = this.motZ = 0.0D; + // CraftBukkit start - Added setDirection method + this.setDirection(d0, d1, d2); + } + + public void setDirection(double d0, double d1, double d2) { + // CraftBukkit end + d0 += this.random.nextGaussian() * 0.4D; + d1 += this.random.nextGaussian() * 0.4D; + d2 += this.random.nextGaussian() * 0.4D; + double d3 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + + this.dirX = d0 / d3 * 0.1D; + this.dirY = d1 / d3 * 0.1D; + this.dirZ = d2 / d3 * 0.1D; + } + + public void t_() { + if (!this.world.isClientSide && (this.shooter != null && this.shooter.dead || !this.world.isLoaded(new BlockPosition(this)))) { + this.die(); + } else { + super.t_(); + this.setOnFire(1); + if (this.i) { + if (this.world.getType(this.e, this.f, this.g).getBlock() == this.h) { + ++this.ar; + if (this.ar == 600) { + this.die(); + } + + return; + } + + this.i = false; + this.motX *= this.random.nextFloat() * 0.2F; + this.motY *= this.random.nextFloat() * 0.2F; + this.motZ *= this.random.nextFloat() * 0.2F; + this.ar = 0; + this.as = 0; + } else { + ++this.as; + } + + Vec3D vec3d = new Vec3D(this.locX, this.locY, this.locZ); + Vec3D vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, vec3d1); + + vec3d = new Vec3D(this.locX, this.locY, this.locZ); + vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + if (movingobjectposition != null) { + vec3d1 = new Vec3D(movingobjectposition.pos.a, movingobjectposition.pos.b, movingobjectposition.pos.c); + } + + Entity entity = null; + List list = this.world.getEntities(this, this.getBoundingBox().a(this.motX, this.motY, this.motZ).grow(1.0D, 1.0D, 1.0D)); + double d0 = 0.0D; + + for (int i = 0; i < list.size(); ++i) { + Entity entity1 = (Entity) list.get(i); + + if (entity1.ad() && (!entity1.k(this.shooter) || this.as >= 25)) { + float f = 0.3F; + AxisAlignedBB axisalignedbb = entity1.getBoundingBox().grow(f, f, f); + MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1); + + if (movingobjectposition1 != null) { + double d1 = vec3d.distanceSquared(movingobjectposition1.pos); + + if (d1 < d0 || d0 == 0.0D) { + entity = entity1; + d0 = d1; + } + } + } + } + + if (entity != null) { + movingobjectposition = new MovingObjectPosition(entity); + } + + if (movingobjectposition != null) { + this.a(movingobjectposition); + + // CraftBukkit start - Fire ProjectileHitEvent + if (this.dead) { + CraftEventFactory.callProjectileHitEvent(this); + } + // CraftBukkit end + } + + this.locX += this.motX; + this.locY += this.motY; + this.locZ += this.motZ; + float f1 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + + this.yaw = (float) (MathHelper.b(this.motZ, this.motX) * 180.0D / 3.1415927410125732D) + 90.0F; + + for (this.pitch = (float) (MathHelper.b(f1, this.motY) * 180.0D / 3.1415927410125732D) - 90.0F; this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + } + + while (this.pitch - this.lastPitch >= 180.0F) { + this.lastPitch += 360.0F; + } + + while (this.yaw - this.lastYaw < -180.0F) { + this.lastYaw -= 360.0F; + } + + while (this.yaw - this.lastYaw >= 180.0F) { + this.lastYaw += 360.0F; + } + + this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; + this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + float f2 = this.j(); + + if (this.V()) { + 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); + } + + f2 = 0.8F; + } + + this.motX += this.dirX; + this.motY += this.dirY; + this.motZ += this.dirZ; + 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); + this.setPosition(this.locX, this.locY, this.locZ); + } + } + + protected float j() { + return 0.95F; + } + + protected abstract void a(MovingObjectPosition movingobjectposition); + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setShort("xTile", (short) this.e); + nbttagcompound.setShort("yTile", (short) this.f); + nbttagcompound.setShort("zTile", (short) this.g); + MinecraftKey minecraftkey = Block.REGISTRY.c(this.h); + + nbttagcompound.setString("inTile", minecraftkey == null ? "" : minecraftkey.toString()); + nbttagcompound.setByte("inGround", (byte) (this.i ? 1 : 0)); + // CraftBukkit - Fix direction being mismapped to invalid variables + nbttagcompound.set("power", this.a(this.dirX, this.dirY, this.dirZ)); + nbttagcompound.set("direction", this.a(this.motX, this.motY, this.motZ)); + } + + public void a(NBTTagCompound nbttagcompound) { + this.e = nbttagcompound.getShort("xTile"); + this.f = nbttagcompound.getShort("yTile"); + this.g = nbttagcompound.getShort("zTile"); + if (nbttagcompound.hasKeyOfType("inTile", 8)) { + this.h = Block.getByName(nbttagcompound.getString("inTile")); + } else { + this.h = Block.getById(nbttagcompound.getByte("inTile") & 255); + } + + this.i = nbttagcompound.getByte("inGround") == 1; + // CraftBukkit start - direction -> power + if (nbttagcompound.hasKeyOfType("power", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("power", 6); + + this.dirX = nbttaglist.d(0); + this.dirY = nbttaglist.d(1); + this.dirZ = nbttaglist.d(2); + } else if (nbttagcompound.hasKeyOfType("direction", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("direction", 6); + + this.motX = nbttaglist.d(0); + this.motY = nbttaglist.d(1); + this.motZ = nbttaglist.d(2); + // CraftBukkit end + } else { + this.die(); + } + + } + + public boolean ad() { + return true; + } + + public float ao() { + return 1.0F; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + this.ac(); + if (damagesource.getEntity() != null) { + // CraftBukkit start + if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { + return false; + } + // CraftBukkit end + Vec3D vec3d = damagesource.getEntity().ap(); + + if (vec3d != null) { + this.motX = vec3d.a; + this.motY = vec3d.b; + this.motZ = vec3d.c; + this.dirX = this.motX * 0.1D; + this.dirY = this.motY * 0.1D; + this.dirZ = this.motZ * 0.1D; + } + + if (damagesource.getEntity() instanceof EntityLiving) { + this.shooter = (EntityLiving) damagesource.getEntity(); + this.projectileSource = (org.bukkit.projectiles.ProjectileSource) this.shooter.getBukkitEntity(); + } + + return true; + } else { + return false; + } + } + } + + public float c(float f) { + return 1.0F; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFireworks.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFireworks.java new file mode 100644 index 0000000..d7be6c2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFireworks.java @@ -0,0 +1,132 @@ +package net.minecraft.server; + +public class EntityFireworks extends Entity { + + private int ticksFlown; + public int expectedLifespan; + + // Spigot Start + @Override + public void inactiveTick() + { + this.ticksFlown += 1; + super.inactiveTick(); + } + // Spigot End + + public EntityFireworks(World world) { + super(world); + this.setSize(0.25F, 0.25F); + } + + protected void h() { + this.datawatcher.add(8, 5); + } + + public EntityFireworks(World world, double d0, double d1, double d2, ItemStack itemstack) { + super(world); + this.ticksFlown = 0; + this.setSize(0.25F, 0.25F); + this.setPosition(d0, d1, d2); + int i = 1; + + if (itemstack != null && itemstack.hasTag()) { + this.datawatcher.watch(8, itemstack); + NBTTagCompound nbttagcompound = itemstack.getTag(); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Fireworks"); + + if (nbttagcompound1 != null) { + i += nbttagcompound1.getByte("Flight"); + } + } + + this.motX = this.random.nextGaussian() * 0.001D; + this.motZ = this.random.nextGaussian() * 0.001D; + this.motY = 0.05D; + this.expectedLifespan = 10 * i + this.random.nextInt(6) + this.random.nextInt(7); + } + + public void t_() { + this.P = this.locX; + this.Q = this.locY; + this.R = this.locZ; + super.t_(); + this.motX *= 1.15D; + this.motZ *= 1.15D; + this.motY += 0.04D; + this.move(this.motX, this.motY, this.motZ); + float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + + this.yaw = (float) (MathHelper.b(this.motX, this.motZ) * 180.0D / 3.1415927410125732D); + + for (this.pitch = (float) (MathHelper.b(this.motY, (double) f) * 180.0D / 3.1415927410125732D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + ; + } + + while (this.pitch - this.lastPitch >= 180.0F) { + this.lastPitch += 360.0F; + } + + while (this.yaw - this.lastYaw < -180.0F) { + this.lastYaw -= 360.0F; + } + + while (this.yaw - this.lastYaw >= 180.0F) { + this.lastYaw += 360.0F; + } + + this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; + this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + if (this.ticksFlown == 0 && !this.R()) { + this.world.makeSound(this, "fireworks.launch", 3.0F, 1.0F); + } + + ++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]); + } + + if (!this.world.isClientSide && this.ticksFlown > this.expectedLifespan) { + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callFireworkExplodeEvent(this).isCancelled()) this.world.broadcastEntityEffect(this, (byte) 17); + this.die(); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setInt("Life", this.ticksFlown); + nbttagcompound.setInt("LifeTime", this.expectedLifespan); + ItemStack itemstack = this.datawatcher.getItemStack(8); + + if (itemstack != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + itemstack.save(nbttagcompound1); + nbttagcompound.set("FireworksItem", nbttagcompound1); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + this.ticksFlown = nbttagcompound.getInt("Life"); + this.expectedLifespan = nbttagcompound.getInt("LifeTime"); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("FireworksItem"); + + if (nbttagcompound1 != null) { + ItemStack itemstack = ItemStack.createStack(nbttagcompound1); + + if (itemstack != null) { + this.datawatcher.watch(8, itemstack); + } + } + + } + + public float c(float f) { + return super.c(f); + } + + public boolean aD() { + return false; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFishingHook.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFishingHook.java new file mode 100644 index 0000000..fa91d89 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityFishingHook.java @@ -0,0 +1,507 @@ +package net.minecraft.server; + +import org.bukkit.entity.Fish; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerFishEvent; + +import java.util.Arrays; +import java.util.List; + +// CraftBukkit start +// CraftBukkit end + +public class EntityFishingHook extends Entity { + + private static final List d = Arrays.asList((new PossibleFishingResult(new ItemStack(Items.LEATHER_BOOTS), 10)).a(0.9F), new PossibleFishingResult(new ItemStack(Items.LEATHER), 10), new PossibleFishingResult(new ItemStack(Items.BONE), 10), new PossibleFishingResult(new ItemStack(Items.POTION), 10), new PossibleFishingResult(new ItemStack(Items.STRING), 5), (new PossibleFishingResult(new ItemStack(Items.FISHING_ROD), 2)).a(0.9F), new PossibleFishingResult(new ItemStack(Items.BOWL), 10), new PossibleFishingResult(new ItemStack(Items.STICK), 5), new PossibleFishingResult(new ItemStack(Items.DYE, 10, EnumColor.BLACK.getInvColorIndex()), 1), new PossibleFishingResult(new ItemStack(Blocks.TRIPWIRE_HOOK), 10), new PossibleFishingResult(new ItemStack(Items.ROTTEN_FLESH), 10)); + private static final List e = Arrays.asList(new PossibleFishingResult(new ItemStack(Blocks.WATERLILY), 1), new PossibleFishingResult(new ItemStack(Items.NAME_TAG), 1), new PossibleFishingResult(new ItemStack(Items.SADDLE), 1), (new PossibleFishingResult(new ItemStack(Items.BOW), 1)).a(0.25F).a(), (new PossibleFishingResult(new ItemStack(Items.FISHING_ROD), 1)).a(0.25F).a(), (new PossibleFishingResult(new ItemStack(Items.BOOK), 1)).a()); + private static final List f = Arrays.asList(new PossibleFishingResult(new ItemStack(Items.FISH, 1, ItemFish.EnumFish.COD.a()), 60), new PossibleFishingResult(new ItemStack(Items.FISH, 1, ItemFish.EnumFish.SALMON.a()), 25), new PossibleFishingResult(new ItemStack(Items.FISH, 1, ItemFish.EnumFish.CLOWNFISH.a()), 2), new PossibleFishingResult(new ItemStack(Items.FISH, 1, ItemFish.EnumFish.PUFFERFISH.a()), 13)); + private int g = -1; + private int h = -1; + private int i = -1; + private Block ar; + private boolean as; + public int a; + public EntityHuman owner; + private int at; + private int au; + private int av; + private int aw; + private int ax; + private float ay; + public Entity hooked; + private int az; + private double aA; + private double aB; + private double aC; + private double aD; + private double aE; + + public static List j() { + return EntityFishingHook.f; + } + + public EntityFishingHook(World world) { + super(world); + this.setSize(0.25F, 0.25F); + this.ah = true; + } + + public EntityFishingHook(World world, EntityHuman entityhuman) { + super(world); + this.ah = true; + this.owner = entityhuman; + this.owner.hookedFish = this; + this.setSize(0.25F, 0.25F); + this.setPositionRotation(entityhuman.locX, entityhuman.locY + (double) entityhuman.getHeadHeight(), entityhuman.locZ, entityhuman.yaw, entityhuman.pitch); + this.locX -= MathHelper.cos(this.yaw / 180.0F * 3.1415927F) * 0.16F; + this.locY -= 0.10000000149011612D; + this.locZ -= MathHelper.sin(this.yaw / 180.0F * 3.1415927F) * 0.16F; + this.setPosition(this.locX, this.locY, this.locZ); + float f = 0.4F; + + this.motX = -MathHelper.sin(this.yaw / 180.0F * 3.1415927F) * MathHelper.cos(this.pitch / 180.0F * 3.1415927F) * f; + this.motZ = MathHelper.cos(this.yaw / 180.0F * 3.1415927F) * MathHelper.cos(this.pitch / 180.0F * 3.1415927F) * f; + this.motY = -MathHelper.sin(this.pitch / 180.0F * 3.1415927F) * f; + this.c(this.motX, this.motY, this.motZ, 1.5F, 1.0F); + } + + protected void h() {} + + public void c(double d0, double d1, double d2, float f, float f1) { + float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + + d0 /= f2; + d1 /= f2; + d2 /= f2; + d0 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d1 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d2 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d0 *= f; + d1 *= f; + d2 *= f; + this.motX = d0; + this.motY = d1; + this.motZ = d2; + float f3 = MathHelper.sqrt(d0 * d0 + d2 * d2); + + this.lastYaw = this.yaw = (float) (MathHelper.b(d0, d2) * 180.0D / 3.1415927410125732D); + this.lastPitch = this.pitch = (float) (MathHelper.b(d1, f3) * 180.0D / 3.1415927410125732D); + this.at = 0; + } + + public void t_() { + super.t_(); + if (this.az > 0) { + double d0 = this.locX + (this.aA - this.locX) / (double) this.az; + double d1 = this.locY + (this.aB - this.locY) / (double) this.az; + double d2 = this.locZ + (this.aC - this.locZ) / (double) this.az; + double d3 = MathHelper.g(this.aD - (double) this.yaw); + + this.yaw = (float) ((double) this.yaw + d3 / (double) this.az); + this.pitch = (float) ((double) this.pitch + (this.aE - (double) this.pitch) / (double) this.az); + --this.az; + this.setPosition(d0, d1, d2); + this.setYawPitch(this.yaw, this.pitch); + } else { + if (!this.world.isClientSide) { + ItemStack itemstack = this.owner.bZ(); + + if (this.owner.dead || !this.owner.isAlive() || itemstack == null || itemstack.getItem() != Items.FISHING_ROD || this.h(this.owner) > 1024.0D) { + this.die(); + this.owner.hookedFish = null; + return; + } + + if (this.hooked != null) { + if (!this.hooked.dead) { + this.locX = this.hooked.locX; + double d4 = this.hooked.length; + + this.locY = this.hooked.getBoundingBox().b + d4 * 0.8D; + this.locZ = this.hooked.locZ; + return; + } + + this.hooked = null; + } + } + + if (this.a > 0) { + --this.a; + } + + if (this.as) { + if (this.world.getType(this.g, this.h, this.i).getBlock() == this.ar) { + ++this.at; + if (this.at == 1200) { + this.die(); + } + + return; + } + + this.as = false; + this.motX *= this.random.nextFloat() * 0.2F; + this.motY *= this.random.nextFloat() * 0.2F; + this.motZ *= this.random.nextFloat() * 0.2F; + this.at = 0; + this.au = 0; + } else { + ++this.au; + } + + Vec3D vec3d = new Vec3D(this.locX, this.locY, this.locZ); + Vec3D vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, vec3d1); + + vec3d = new Vec3D(this.locX, this.locY, this.locZ); + vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + if (movingobjectposition != null) { + vec3d1 = new Vec3D(movingobjectposition.pos.a, movingobjectposition.pos.b, movingobjectposition.pos.c); + } + + Entity entity = null; + List list = this.world.getEntities(this, this.getBoundingBox().a(this.motX, this.motY, this.motZ).grow(1.0D, 1.0D, 1.0D)); + double d5 = 0.0D; + + double d6; + + for (int i = 0; i < list.size(); ++i) { + Entity entity1 = (Entity) list.get(i); + + if (entity1.ad() && (entity1 != this.owner || this.au >= 5)) { + float f = 0.3F; + AxisAlignedBB axisalignedbb = entity1.getBoundingBox().grow(f, f, f); + MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1); + + if (movingobjectposition1 != null) { + d6 = vec3d.distanceSquared(movingobjectposition1.pos); + if (d6 < d5 || d5 == 0.0D) { + entity = entity1; + d5 = d6; + } + } + } + } + + if (entity != null) { + movingobjectposition = new MovingObjectPosition(entity); + } + + // PaperSpigot start - Allow fishing hooks to fly through vanished players the shooter can't see + if (movingobjectposition != null && movingobjectposition.entity instanceof EntityPlayer && owner != null && owner instanceof EntityPlayer) { + if (!((EntityPlayer) owner).getBukkitEntity().canSee(((EntityPlayer) movingobjectposition.entity).getBukkitEntity())) { + movingobjectposition = null; + } + } + // PaperSpigot end + + if (movingobjectposition != null) { + org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); // Craftbukkit - Call event + if (movingobjectposition.entity != null) { + if (movingobjectposition.entity.damageEntity(DamageSource.projectile(this, this.owner), 0.0F)) { + this.hooked = movingobjectposition.entity; + } + } else { + this.as = true; + } + } + + if (!this.as) { + this.move(this.motX, this.motY, this.motZ); + float f1 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + + this.yaw = (float) (MathHelper.b(this.motX, this.motZ) * 180.0D / 3.1415927410125732D); + + for (this.pitch = (float) (MathHelper.b(this.motY, f1) * 180.0D / 3.1415927410125732D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + } + + while (this.pitch - this.lastPitch >= 180.0F) { + this.lastPitch += 360.0F; + } + + while (this.yaw - this.lastYaw < -180.0F) { + this.lastYaw -= 360.0F; + } + + while (this.yaw - this.lastYaw >= 180.0F) { + this.lastYaw += 360.0F; + } + + this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; + this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + float f2 = 0.92F; + + if (this.onGround || this.positionChanged) { + f2 = 0.5F; + } + + byte b0 = 5; + double d7 = 0.0D; + + double d8; + + for (int j = 0; j < b0; ++j) { + AxisAlignedBB axisalignedbb1 = this.getBoundingBox(); + double d9 = axisalignedbb1.e - axisalignedbb1.b; + double d10 = axisalignedbb1.b + d9 * (double) j / (double) b0; + + d8 = axisalignedbb1.b + d9 * (double) (j + 1) / (double) b0; + AxisAlignedBB axisalignedbb2 = new AxisAlignedBB(axisalignedbb1.a, d10, axisalignedbb1.c, axisalignedbb1.d, d8, axisalignedbb1.f); + + if (this.world.b(axisalignedbb2, Material.WATER)) { + d7 += 1.0D / (double) b0; + } + } + + if (!this.world.isClientSide && d7 > 0.0D) { + WorldServer worldserver = (WorldServer) this.world; + int k = 1; + BlockPosition blockposition = (new BlockPosition(this)).up(); + + if (this.random.nextFloat() < 0.25F && this.world.isRainingAt(blockposition)) { + k = 2; + } + + if (this.random.nextFloat() < 0.5F && !this.world.i(blockposition)) { + --k; + } + + if (this.av > 0) { + --this.av; + if (this.av <= 0) { + this.aw = 0; + this.ax = 0; + } + } else { + float f3; + float f4; + double d11; + Block block; + float f5; + double d12; + + if (this.ax > 0) { + this.ax -= k; + if (this.ax <= 0) { + 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); + 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); + this.av = MathHelper.nextInt(this.random, 10, 30); + } else { + this.ay = (float) ((double) this.ay + this.random.nextGaussian() * 4.0D); + f3 = this.ay * 0.017453292F; + f5 = MathHelper.sin(f3); + f4 = MathHelper.cos(f3); + d8 = this.locX + (double) (f5 * (float) this.ax * 0.1F); + d12 = (float) MathHelper.floor(this.getBoundingBox().b) + 1.0F; + d11 = this.locZ + (double) (f4 * (float) this.ax * 0.1F); + block = worldserver.getType((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); + } + + 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); + worldserver.a(EnumParticle.WATER_WAKE, d8, d12, d11, 0, -f7, 0.01D, f6, 1.0D); + } + } + } else if (this.aw > 0) { + this.aw -= k; + f3 = 0.15F; + if (this.aw < 20) { + f3 = (float) ((double) f3 + (double) (20 - this.aw) * 0.05D); + } else if (this.aw < 40) { + f3 = (float) ((double) f3 + (double) (40 - this.aw) * 0.02D); + } else if (this.aw < 60) { + f3 = (float) ((double) f3 + (double) (60 - this.aw) * 0.01D); + } + + if (this.random.nextFloat() < f3) { + f5 = MathHelper.a(this.random, 0.0F, 360.0F) * 0.017453292F; + f4 = MathHelper.a(this.random, 25.0F, 60.0F); + d8 = this.locX + (double) (MathHelper.sin(f5) * f4 * 0.1F); + d12 = (float) MathHelper.floor(this.getBoundingBox().b) + 1.0F; + d11 = this.locZ + (double) (MathHelper.cos(f5) * f4 * 0.1F); + block = worldserver.getType((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); + } + } + + if (this.aw <= 0) { + this.ay = MathHelper.a(this.random, 0.0F, 360.0F); + this.ax = MathHelper.nextInt(this.random, 20, 80); + } + } else { + this.aw = MathHelper.nextInt(this.random, this.world.paperSpigotConfig.fishingMinTicks, this.world.paperSpigotConfig.fishingMaxTicks); // PaperSpigot - Configurable fishing tick range + this.aw -= EnchantmentManager.h(this.owner) * 20 * 5; + } + } + + if (this.av > 0) { + this.motY -= (double) (this.random.nextFloat() * this.random.nextFloat() * this.random.nextFloat()) * 0.2D; + } + } + + d6 = d7 * 2.0D - 1.0D; + this.motY += 0.03999999910593033D * d6; + if (d7 > 0.0D) { + f2 = (float) ((double) f2 * 0.9D); + this.motY *= 0.8D; + } + + this.motX *= f2; + this.motY *= f2; + this.motZ *= f2; + this.setPosition(this.locX, this.locY, this.locZ); + } + } + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setShort("xTile", (short) this.g); + nbttagcompound.setShort("yTile", (short) this.h); + nbttagcompound.setShort("zTile", (short) this.i); + MinecraftKey minecraftkey = Block.REGISTRY.c(this.ar); + + nbttagcompound.setString("inTile", minecraftkey == null ? "" : minecraftkey.toString()); + nbttagcompound.setByte("shake", (byte) this.a); + nbttagcompound.setByte("inGround", (byte) (this.as ? 1 : 0)); + } + + public void a(NBTTagCompound nbttagcompound) { + this.g = nbttagcompound.getShort("xTile"); + this.h = nbttagcompound.getShort("yTile"); + this.i = nbttagcompound.getShort("zTile"); + if (nbttagcompound.hasKeyOfType("inTile", 8)) { + this.ar = Block.getByName(nbttagcompound.getString("inTile")); + } else { + this.ar = Block.getById(nbttagcompound.getByte("inTile") & 255); + } + + this.a = nbttagcompound.getByte("shake") & 255; + this.as = nbttagcompound.getByte("inGround") == 1; + } + + public int l() { + if (this.world.isClientSide) { + return 0; + } else { + byte b0 = 0; + + if (this.hooked != null) { + // CraftBukkit start + PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), this.hooked.getBukkitEntity(), (Fish) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_ENTITY); + this.world.getServer().getPluginManager().callEvent(playerFishEvent); + + if (playerFishEvent.isCancelled()) { + return 0; + } + // CraftBukkit end + + double d0 = this.owner.locX - this.locX; + double d1 = this.owner.locY - this.locY; + double d2 = this.owner.locZ - this.locZ; + double d3 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + double d4 = 0.1D; + + this.hooked.motX += d0 * d4; + this.hooked.motY += d1 * d4 + (double) MathHelper.sqrt(d3) * 0.08D; + this.hooked.motZ += d2 * d4; + b0 = 3; + } else if (this.av > 0) { + EntityItem entityitem = new EntityItem(this.world, this.locX, this.locY, this.locZ, this.m()); + // CraftBukkit start + PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), entityitem.getBukkitEntity(), (Fish) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); + playerFishEvent.setExpToDrop(this.random.nextInt(6) + 1); + this.world.getServer().getPluginManager().callEvent(playerFishEvent); + + if (playerFishEvent.isCancelled()) { + return 0; + } + // CraftBukkit end + double d5 = this.owner.locX - this.locX; + double d6 = this.owner.locY - this.locY; + double d7 = this.owner.locZ - this.locZ; + double d8 = MathHelper.sqrt(d5 * d5 + d6 * d6 + d7 * d7); + double d9 = 0.1D; + + entityitem.motX = d5 * d9; + entityitem.motY = d6 * d9 + (double) MathHelper.sqrt(d8) * 0.08D; + entityitem.motZ = d7 * d9; + this.world.addEntity(entityitem); + // CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop() + if (playerFishEvent.getExpToDrop() > 0) { + this.owner.world.addEntity(new EntityExperienceOrb(this.owner.world, this.owner.locX, this.owner.locY + 0.5D, this.owner.locZ + 0.5D, playerFishEvent.getExpToDrop())); + } // CraftBukkit end + b0 = 1; + } + + if (this.as) { + // CraftBukkit start + PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), null, (Fish) this.getBukkitEntity(), PlayerFishEvent.State.IN_GROUND); + this.world.getServer().getPluginManager().callEvent(playerFishEvent); + + if (playerFishEvent.isCancelled()) { + return 0; + } + // CraftBukkit end + b0 = 2; + } + + // CraftBukkit start + if (b0 == 0) { + PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.owner.getBukkitEntity(), null, (Fish) this.getBukkitEntity(), PlayerFishEvent.State.FAILED_ATTEMPT); + this.world.getServer().getPluginManager().callEvent(playerFishEvent); + if (playerFishEvent.isCancelled()) { + return 0; + } + } + // CraftBukkit end + + this.die(); + this.owner.hookedFish = null; + return b0; + } + } + + private ItemStack m() { + float f = this.world.random.nextFloat(); + int i = EnchantmentManager.g(this.owner); + int j = EnchantmentManager.h(this.owner); + float f1 = 0.1F - (float) i * 0.025F - (float) j * 0.01F; + float f2 = 0.05F + (float) i * 0.01F - (float) j * 0.01F; + + f1 = MathHelper.a(f1, 0.0F, 1.0F); + f2 = MathHelper.a(f2, 0.0F, 1.0F); + if (f < f1) { + this.owner.b(StatisticList.D); + return WeightedRandom.a(this.random, EntityFishingHook.d).a(this.random); + } else { + f -= f1; + if (f < f2) { + this.owner.b(StatisticList.E); + return WeightedRandom.a(this.random, EntityFishingHook.e).a(this.random); + } else { + float f3 = f - f2; + + this.owner.b(StatisticList.C); + return WeightedRandom.a(this.random, EntityFishingHook.f).a(this.random); + } + } + } + + public void die() { + super.die(); + if (this.owner != null) { + this.owner.hookedFish = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityGhast.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityGhast.java new file mode 100644 index 0000000..51608e9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityGhast.java @@ -0,0 +1,299 @@ +package net.minecraft.server; + +import java.util.Random; + +public class EntityGhast extends EntityFlying implements IMonster { + + private int a = 1; + + public EntityGhast(World world) { + super(world); + this.setSize(4.0F, 4.0F); + this.fireProof = true; + this.b_ = 5; + this.moveController = new EntityGhast.ControllerGhast(this); + this.goalSelector.a(5, new EntityGhast.PathfinderGoalGhastIdleMove(this)); + this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastMoveTowardsTarget(this)); + this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastAttackTarget(this)); + this.targetSelector.a(1, new PathfinderGoalTargetNearestPlayer(this)); + } + + public void a(boolean flag) { + this.datawatcher.watch(16, Byte.valueOf((byte) (flag ? 1 : 0))); + } + + public int cf() { + return this.a; + } + + public void t_() { + super.t_(); + if (!this.world.isClientSide && this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { + this.die(); + } + + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else if ("fireball".equals(damagesource.p()) && damagesource.getEntity() instanceof EntityHuman) { + super.damageEntity(damagesource, 1000.0F); + ((EntityHuman) damagesource.getEntity()).b((Statistic) AchievementList.z); + return true; + } else { + return super.damageEntity(damagesource, f); + } + } + + protected void h() { + super.h(); + this.datawatcher.a(16, Byte.valueOf((byte) 0)); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D); + } + + protected String z() { + return "mob.ghast.moan"; + } + + protected String bo() { + return "mob.ghast.scream"; + } + + protected String bp() { + return "mob.ghast.death"; + } + + protected Item getLoot() { + return Items.GUNPOWDER; + } + + protected void dropDeathLoot(boolean flag, int i) { + int j = this.random.nextInt(2) + this.random.nextInt(1 + i); + + int k; + + for (k = 0; k < j; ++k) { + this.a(Items.GHAST_TEAR, 1); + } + + j = this.random.nextInt(3) + this.random.nextInt(1 + i); + + for (k = 0; k < j; ++k) { + this.a(Items.GUNPOWDER, 1); + } + + } + + protected float bB() { + return 10.0F; + } + + public boolean bR() { + return this.random.nextInt(20) == 0 && super.bR() && this.world.getDifficulty() != EnumDifficulty.PEACEFUL; + } + + public int bV() { + return 1; + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("ExplosionPower", this.a); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("ExplosionPower", 99)) { + this.a = nbttagcompound.getInt("ExplosionPower"); + } + + } + + public float getHeadHeight() { + return 2.6F; + } + + static class PathfinderGoalGhastAttackTarget extends PathfinderGoal { + + private EntityGhast b; + public int a; + + public PathfinderGoalGhastAttackTarget(EntityGhast entityghast) { + this.b = entityghast; + } + + public boolean a() { + return this.b.getGoalTarget() != null; + } + + public void c() { + this.a = 0; + } + + public void d() { + this.b.a(false); + } + + public void e() { + EntityLiving entityliving = this.b.getGoalTarget(); + double d0 = 64.0D; + + if (entityliving.h(this.b) < d0 * d0 && this.b.hasLineOfSight(entityliving)) { + World world = this.b.world; + + ++this.a; + if (this.a == 10) { + world.a((EntityHuman) null, 1007, new BlockPosition(this.b), 0); + } + + if (this.a == 20) { + double d1 = 4.0D; + Vec3D vec3d = this.b.d(1.0F); + double d2 = entityliving.locX - (this.b.locX + vec3d.a * d1); + double d3 = entityliving.getBoundingBox().b + (double) (entityliving.length / 2.0F) - (0.5D + this.b.locY + (double) (this.b.length / 2.0F)); + double d4 = entityliving.locZ - (this.b.locZ + vec3d.c * d1); + + world.a((EntityHuman) null, 1008, new BlockPosition(this.b), 0); + EntityLargeFireball entitylargefireball = new EntityLargeFireball(world, this.b, d2, d3, d4); + + + // CraftBukkit - set bukkitYield when setting explosionpower + entitylargefireball.bukkitYield = entitylargefireball.yield = this.b.cf(); + entitylargefireball.locX = this.b.locX + vec3d.a * d1; + entitylargefireball.locY = this.b.locY + (double) (this.b.length / 2.0F) + 0.5D; + entitylargefireball.locZ = this.b.locZ + vec3d.c * d1; + world.addEntity(entitylargefireball); + this.a = -40; + } + } else if (this.a > 0) { + --this.a; + } + + this.b.a(this.a > 10); + } + } + + static class PathfinderGoalGhastMoveTowardsTarget extends PathfinderGoal { + + private EntityGhast a; + + public PathfinderGoalGhastMoveTowardsTarget(EntityGhast entityghast) { + this.a = entityghast; + this.a(2); + } + + public boolean a() { + return true; + } + + public void e() { + if (this.a.getGoalTarget() == null) { + this.a.aI = this.a.yaw = -((float) MathHelper.b(this.a.motX, this.a.motZ)) * 180.0F / 3.1415927F; + } else { + EntityLiving entityliving = this.a.getGoalTarget(); + double d0 = 64.0D; + + if (entityliving.h(this.a) < d0 * d0) { + double d1 = entityliving.locX - this.a.locX; + double d2 = entityliving.locZ - this.a.locZ; + + this.a.aI = this.a.yaw = -((float) MathHelper.b(d1, d2)) * 180.0F / 3.1415927F; + } + } + + } + } + + static class PathfinderGoalGhastIdleMove extends PathfinderGoal { + + private EntityGhast a; + + public PathfinderGoalGhastIdleMove(EntityGhast entityghast) { + this.a = entityghast; + this.a(1); + } + + public boolean a() { + ControllerMove controllermove = this.a.getControllerMove(); + + if (!controllermove.a()) { + return true; + } else { + double d0 = controllermove.d() - this.a.locX; + double d1 = controllermove.e() - this.a.locY; + double d2 = controllermove.f() - this.a.locZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + return d3 < 1.0D || d3 > 3600.0D; + } + } + + public boolean b() { + return false; + } + + public void c() { + Random random = this.a.bc(); + double d0 = this.a.locX + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + double d1 = this.a.locY + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + double d2 = this.a.locZ + (double) ((random.nextFloat() * 2.0F - 1.0F) * 16.0F); + + this.a.getControllerMove().a(d0, d1, d2, 1.0D); + } + } + + static class ControllerGhast extends ControllerMove { + + private EntityGhast g; + private int h; + + public ControllerGhast(EntityGhast entityghast) { + super(entityghast); + this.g = entityghast; + } + + public void c() { + if (this.f) { + double d0 = this.b - this.g.locX; + double d1 = this.c - this.g.locY; + double d2 = this.d - this.g.locZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + if (this.h-- <= 0) { + this.h += this.g.bc().nextInt(5) + 2; + d3 = (double) MathHelper.sqrt(d3); + if (this.b(this.b, this.c, this.d, d3)) { + this.g.motX += d0 / d3 * 0.1D; + this.g.motY += d1 / d3 * 0.1D; + this.g.motZ += d2 / d3 * 0.1D; + } else { + this.f = false; + } + } + + } + } + + private boolean b(double d0, double d1, double d2, double d3) { + double d4 = (d0 - this.g.locX) / d3; + double d5 = (d1 - this.g.locY) / d3; + double d6 = (d2 - this.g.locZ) / d3; + AxisAlignedBB axisalignedbb = this.g.getBoundingBox(); + + for (int i = 1; (double) i < d3; ++i) { + axisalignedbb = axisalignedbb.c(d4, d5, d6); + if (!this.g.world.getCubes(this.g, axisalignedbb).isEmpty()) { + return false; + } + } + + return true; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHanging.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHanging.java new file mode 100644 index 0000000..1820936 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHanging.java @@ -0,0 +1,304 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +import net.jafama.FastMath; +import org.apache.commons.lang3.Validate; + +// CraftBukkit start +import org.bukkit.entity.Hanging; +import org.bukkit.entity.Painting; +import org.bukkit.event.hanging.HangingBreakEvent; +import org.bukkit.event.painting.PaintingBreakEvent; +// CraftBukkit end + +public abstract class EntityHanging extends Entity { + + private int c; + public BlockPosition blockPosition; + public EnumDirection direction; + + public EntityHanging(World world) { + super(world); + this.setSize(0.5F, 0.5F); + } + + public EntityHanging(World world, BlockPosition blockposition) { + this(world); + this.blockPosition = blockposition; + } + + protected void h() {} + + public void setDirection(EnumDirection enumdirection) { + Validate.notNull(enumdirection); + Validate.isTrue(enumdirection.k().c()); + this.direction = enumdirection; + this.lastYaw = this.yaw = (float) (this.direction.b() * 90); + this.updateBoundingBox(); + } + + /* CraftBukkit start - bounding box calculation made static (for spawn usage) + + l is from function l() + m is from function m() + + Placing here as it's more likely to be noticed as something which needs to be updated + then something in a CraftBukkit file. + */ + public static AxisAlignedBB calculateBoundingBox(BlockPosition blockPosition, EnumDirection direction, int width, int height) { + double d0 = (double) blockPosition.getX() + 0.5D; + double d1 = (double) blockPosition.getY() + 0.5D; + double d2 = (double) blockPosition.getZ() + 0.5D; + double d3 = 0.46875D; + double d4 = width % 32 == 0 ? 0.5D : 0.0D; + double d5 = height % 32 == 0 ? 0.5D : 0.0D; + + d0 -= (double) direction.getAdjacentX() * 0.46875D; + d2 -= (double) direction.getAdjacentZ() * 0.46875D; + d1 += d5; + EnumDirection enumdirection = direction.f(); + + d0 += d4 * (double) enumdirection.getAdjacentX(); + d2 += d4 * (double) enumdirection.getAdjacentZ(); + double d6 = (double) width; + double d7 = (double) height; + double d8 = (double) width; + + if (direction.k() == EnumDirection.EnumAxis.Z) { + d8 = 1.0D; + } else { + d6 = 1.0D; + } + + d6 /= 32.0D; + d7 /= 32.0D; + d8 /= 32.0D; + return new AxisAlignedBB(d0 - d6, d1 - d7, d2 - d8, d0 + d6, d1 + d7, d2 + d8); + } + + private void updateBoundingBox() { + if (this.direction != null) { + // CraftBukkit start code moved in to calculateBoundingBox + AxisAlignedBB bb = calculateBoundingBox(this.blockPosition, this.direction, this.l(), this.m()); + this.locX = (bb.a + bb.d) / 2.0D; + this.locY = (bb.b + bb.e) / 2.0D; + this.locZ = (bb.c + bb.f) / 2.0D; + this.a(bb); + // CraftBukkit end + } + } + + private double a(int i) { + return i % 32 == 0 ? 0.5D : 0.0D; + } + + public void t_() { + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + if (this.c++ == this.world.spigotConfig.hangingTickFrequency && !this.world.isClientSide) { + this.c = 0; + if (!this.dead && !this.survives()) { + // CraftBukkit start - fire break events + Material material = this.world.getType(new BlockPosition(this)).getBlock().getMaterial(); + HangingBreakEvent.RemoveCause cause; + + if (!material.equals(Material.AIR)) { + // TODO: This feels insufficient to catch 100% of suffocation cases + cause = HangingBreakEvent.RemoveCause.OBSTRUCTION; + } else { + cause = HangingBreakEvent.RemoveCause.PHYSICS; + } + + HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), cause); + this.world.getServer().getPluginManager().callEvent(event); + + PaintingBreakEvent paintingEvent = null; + if (this instanceof EntityPainting) { + // Fire old painting event until it can be removed + paintingEvent = new PaintingBreakEvent((Painting) this.getBukkitEntity(), PaintingBreakEvent.RemoveCause.valueOf(cause.name())); + paintingEvent.setCancelled(event.isCancelled()); + this.world.getServer().getPluginManager().callEvent(paintingEvent); + } + + if (dead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { + return; + } + // CraftBukkit end + this.die(); + this.b((Entity) null); + } + } + + } + + public boolean survives() { + if (!this.world.getCubes(this, this.getBoundingBox()).isEmpty()) { + return false; + } else { + int i = FastMath.max(1, this.l() / 16); + int j = FastMath.max(1, this.m() / 16); + BlockPosition blockposition = this.blockPosition.shift(this.direction.opposite()); + EnumDirection enumdirection = this.direction.f(); + + for (int k = 0; k < i; ++k) { + for (int l = 0; l < j; ++l) { + BlockPosition blockposition1 = blockposition.shift(enumdirection, k).up(l); + Block block = this.world.getType(blockposition1).getBlock(); + + if (!block.getMaterial().isBuildable() && !BlockDiodeAbstract.d(block)) { + return false; + } + } + } + + List list = this.world.getEntities(this, this.getBoundingBox()); + Iterator iterator = list.iterator(); + + Entity entity; + + do { + if (!iterator.hasNext()) { + return true; + } + + entity = (Entity) iterator.next(); + } while (!(entity instanceof EntityHanging)); + + return false; + } + } + + public boolean ad() { + return true; + } + + public boolean l(Entity entity) { + return entity instanceof EntityHuman ? this.damageEntity(DamageSource.playerAttack((EntityHuman) entity), 0.0F) : false; + } + + public EnumDirection getDirection() { + return this.direction; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + if (!this.dead && !this.world.isClientSide) { + // CraftBukkit start - fire break events + HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.DEFAULT); + PaintingBreakEvent paintingEvent = null; + if (damagesource.getEntity() != null) { + event = new org.bukkit.event.hanging.HangingBreakByEntityEvent((Hanging) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity()); + + if (this instanceof EntityPainting) { + // Fire old painting event until it can be removed + paintingEvent = new org.bukkit.event.painting.PaintingBreakByEntityEvent((Painting) this.getBukkitEntity(), damagesource.getEntity() == null ? null : damagesource.getEntity().getBukkitEntity()); + } + } else if (damagesource.isExplosion()) { + event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.EXPLOSION); + } + + this.world.getServer().getPluginManager().callEvent(event); + + if (paintingEvent != null) { + paintingEvent.setCancelled(event.isCancelled()); + this.world.getServer().getPluginManager().callEvent(paintingEvent); + } + + if (this.dead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { + return true; + } + // CraftBukkit end + + this.die(); + this.ac(); + this.b(damagesource.getEntity()); + } + + return true; + } + } + + public void move(double d0, double d1, double d2) { + if (!this.world.isClientSide && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { + if (this.dead) return; // CraftBukkit + + // CraftBukkit start - fire break events + // TODO - Does this need its own cause? Seems to only be triggered by pistons + HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.PHYSICS); + this.world.getServer().getPluginManager().callEvent(event); + + if (this.dead || event.isCancelled()) { + return; + } + // CraftBukkit end + + this.die(); + this.b((Entity) null); + } + + } + + public void g(double d0, double d1, double d2) { + if (false && !this.world.isClientSide && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { // CraftBukkit - not needed + this.die(); + this.b((Entity) null); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setByte("Facing", (byte) this.direction.b()); + nbttagcompound.setInt("TileX", this.getBlockPosition().getX()); + nbttagcompound.setInt("TileY", this.getBlockPosition().getY()); + nbttagcompound.setInt("TileZ", this.getBlockPosition().getZ()); + } + + public void a(NBTTagCompound nbttagcompound) { + this.blockPosition = new BlockPosition(nbttagcompound.getInt("TileX"), nbttagcompound.getInt("TileY"), nbttagcompound.getInt("TileZ")); + EnumDirection enumdirection; + + if (nbttagcompound.hasKeyOfType("Direction", 99)) { + enumdirection = EnumDirection.fromType2(nbttagcompound.getByte("Direction")); + this.blockPosition = this.blockPosition.shift(enumdirection); + } else if (nbttagcompound.hasKeyOfType("Facing", 99)) { + enumdirection = EnumDirection.fromType2(nbttagcompound.getByte("Facing")); + } else { + enumdirection = EnumDirection.fromType2(nbttagcompound.getByte("Dir")); + } + + this.setDirection(enumdirection); + } + + public abstract int l(); + + public abstract int m(); + + public abstract void b(Entity entity); + + protected boolean af() { + return false; + } + + public void setPosition(double d0, double d1, double d2) { + this.locX = d0; + this.locY = d1; + this.locZ = d2; + BlockPosition blockposition = this.blockPosition; + + this.blockPosition = new BlockPosition(d0, d1, d2); + if (!this.blockPosition.equals(blockposition)) { + this.updateBoundingBox(); + this.ai = true; + } + + } + + public BlockPosition getBlockPosition() { + return this.blockPosition; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHorse.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHorse.java new file mode 100644 index 0000000..53aaa65 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHorse.java @@ -0,0 +1,1326 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.Iterator; +import java.util.List; + +import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; // CraftBukkit + +public class EntityHorse extends EntityAnimal implements IInventoryListener { + + private static final Predicate bs = new Predicate() { + public boolean a(Entity entity) { + return entity instanceof EntityHorse && ((EntityHorse) entity).cA(); + } + + public boolean apply(Object object) { + return this.a((Entity) object); + } + }; + public static final IAttribute attributeJumpStrength = (new AttributeRanged((IAttribute) null, "horse.jumpStrength", 0.7D, 0.0D, 2.0D)).a("Jump Strength").a(true); + private static final String[] bu = new String[] { null, "textures/entity/horse/armor/horse_armor_iron.png", "textures/entity/horse/armor/horse_armor_gold.png", "textures/entity/horse/armor/horse_armor_diamond.png"}; + private static final String[] bv = new String[] { "", "meo", "goo", "dio"}; + private static final int[] bw = new int[] { 0, 5, 7, 11}; + private static final String[] bx = new String[] { "textures/entity/horse/horse_white.png", "textures/entity/horse/horse_creamy.png", "textures/entity/horse/horse_chestnut.png", "textures/entity/horse/horse_brown.png", "textures/entity/horse/horse_black.png", "textures/entity/horse/horse_gray.png", "textures/entity/horse/horse_darkbrown.png"}; + private static final String[] by = new String[] { "hwh", "hcr", "hch", "hbr", "hbl", "hgr", "hdb"}; + private static final String[] bz = new String[] { null, "textures/entity/horse/horse_markings_white.png", "textures/entity/horse/horse_markings_whitefield.png", "textures/entity/horse/horse_markings_whitedots.png", "textures/entity/horse/horse_markings_blackdots.png"}; + private static final String[] bA = new String[] { "", "wo_", "wmo", "wdo", "bdo"}; + private int bB; + private int bC; + private int bD; + public int bm; + public int bo; + protected boolean bp; + public InventoryHorseChest inventoryChest; + private boolean bF; + protected int bq; + protected float br; + private boolean bG; + private float bH; + private float bI; + private float bJ; + private float bK; + private float bL; + private float bM; + private int bN; + private String bO; + private String[] bP = new String[3]; + private boolean bQ = false; + public int maxDomestication = 100; // CraftBukkit - store max domestication value + + public EntityHorse(World world) { + super(world); + this.setSize(1.4F, 1.6F); + this.fireProof = false; + this.setHasChest(false); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.2D)); + this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D)); + this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); + this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.0D)); + this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, 0.7D)); + this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.loadChest(); + } + + protected void h() { + super.h(); + this.datawatcher.a(16, Integer.valueOf(0)); + this.datawatcher.a(19, Byte.valueOf((byte) 0)); + this.datawatcher.a(20, Integer.valueOf(0)); + this.datawatcher.a(21, String.valueOf("")); + this.datawatcher.a(22, Integer.valueOf(0)); + } + + public void setType(int i) { + this.datawatcher.watch(19, Byte.valueOf((byte) i)); + this.dc(); + } + + public int getType() { + return this.datawatcher.getByte(19); + } + + public void setVariant(int i) { + this.datawatcher.watch(20, Integer.valueOf(i)); + this.dc(); + } + + public int getVariant() { + return this.datawatcher.getInt(20); + } + + public String getName() { + if (this.hasCustomName()) { + return this.getCustomName(); + } else { + int i = this.getType(); + + switch (i) { + case 0: + default: + return LocaleI18n.get("entity.horse.name"); + + case 1: + return LocaleI18n.get("entity.donkey.name"); + + case 2: + return LocaleI18n.get("entity.mule.name"); + + case 3: + return LocaleI18n.get("entity.zombiehorse.name"); + + case 4: + return LocaleI18n.get("entity.skeletonhorse.name"); + } + } + } + + private boolean w(int i) { + return (this.datawatcher.getInt(16) & i) != 0; + } + + private void c(int i, boolean flag) { + int j = this.datawatcher.getInt(16); + + if (flag) { + this.datawatcher.watch(16, Integer.valueOf(j | i)); + } else { + this.datawatcher.watch(16, Integer.valueOf(j & ~i)); + } + + } + + public boolean cn() { + return !this.isBaby(); + } + + public boolean isTame() { + return this.w(2); + } + + public boolean cp() { + return this.cn(); + } + + public String getOwnerUUID() { + return this.datawatcher.getString(21); + } + + public void setOwnerUUID(String s) { + this.datawatcher.watch(21, s); + } + + public float cu() { + return 0.5F; + } + + public void a(boolean flag) { + if (flag) { + this.a(this.cu()); + } else { + this.a(1.0F); + } + + } + + public boolean cv() { + return this.bp; + } + + public void setTame(boolean flag) { + this.c(2, flag); + } + + public void m(boolean flag) { + this.bp = flag; + } + + public boolean cb() { + // PaperSpigot start - Configurable undead horse leashing + if (this.world.paperSpigotConfig.allowUndeadHorseLeashing) { + return super.cb(); + } + // PaperSpigot end + return !this.cR() && super.cb(); + } + + protected void o(float f) { + if (f > 6.0F && this.cy()) { + this.r(false); + } + + } + + public boolean hasChest() { + return this.w(8); + } + + public int cx() { + return this.datawatcher.getInt(22); + } + + private int f(ItemStack itemstack) { + if (itemstack == null) { + return 0; + } else { + Item item = itemstack.getItem(); + + return item == Items.IRON_HORSE_ARMOR ? 1 : (item == Items.GOLDEN_HORSE_ARMOR ? 2 : (item == Items.DIAMOND_HORSE_ARMOR ? 3 : 0)); + } + } + + public boolean cy() { + return this.w(32); + } + + public boolean cz() { + return this.w(64); + } + + public boolean cA() { + return this.w(16); + } + + public boolean cB() { + return this.bF; + } + + public void e(ItemStack itemstack) { + this.datawatcher.watch(22, Integer.valueOf(this.f(itemstack))); + this.dc(); + } + + public void n(boolean flag) { + this.c(16, flag); + } + + public void setHasChest(boolean flag) { + this.c(8, flag); + } + + public void p(boolean flag) { + this.bF = flag; + } + + public void q(boolean flag) { + this.c(4, flag); + } + + public int getTemper() { + return this.bq; + } + + public void setTemper(int i) { + this.bq = i; + } + + public int u(int i) { + int j = MathHelper.clamp(this.getTemper() + i, 0, this.getMaxDomestication()); + + this.setTemper(j); + return j; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + Entity entity = damagesource.getEntity(); + + return this.passenger != null && this.passenger.equals(entity) ? false : super.damageEntity(damagesource, f); + } + + public int br() { + return EntityHorse.bw[this.cx()]; + } + + public boolean ae() { + return this.passenger == null; + } + + public boolean cD() { + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locZ); + + this.world.getBiome(new BlockPosition(i, 0, j)); + return true; + } + + public void cE() { + if (!this.world.isClientSide && this.hasChest()) { + this.a(Item.getItemOf(Blocks.CHEST), 1); + this.setHasChest(false); + } + } + + private void cY() { + this.df(); + if (!this.R()) { + this.world.makeSound(this, "eating", 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); + } + + } + + public void e(float f, float f1) { + if (f > 1.0F) { + this.makeSound("mob.horse.land", 0.4F, 1.0F); + } + + int i = MathHelper.f((f * 0.5F - 3.0F) * f1); + + if (i > 0) { + this.damageEntity(DamageSource.FALL, (float) i); + if (this.passenger != null) { + this.passenger.damageEntity(DamageSource.FALL, (float) i); + } + + Block block = this.world.getType(new BlockPosition(this.locX, this.locY - 0.2D - (double) this.lastYaw, this.locZ)).getBlock(); + + if (block.getMaterial() != Material.AIR && !this.R()) { + Block.StepSound block_stepsound = block.stepSound; + + this.world.makeSound(this, block_stepsound.getStepSound(), block_stepsound.getVolume1() * 0.5F, block_stepsound.getVolume2() * 0.75F); + } + + } + } + + private int cZ() { + int i = this.getType(); + + return this.hasChest() /* && (i == 1 || i == 2) */ ? 17 : 2; // CraftBukkit - Remove type check + } + + public void loadChest() { + InventoryHorseChest inventoryhorsechest = this.inventoryChest; + + this.inventoryChest = new InventoryHorseChest("HorseChest", this.cZ(), this); // CraftBukkit - add this horse + this.inventoryChest.a(this.getName()); + if (inventoryhorsechest != null) { + inventoryhorsechest.b(this); + int i = Math.min(inventoryhorsechest.getSize(), this.inventoryChest.getSize()); + + for (int j = 0; j < i; ++j) { + ItemStack itemstack = inventoryhorsechest.getItem(j); + + if (itemstack != null) { + this.inventoryChest.setItem(j, itemstack.cloneItemStack()); + } + } + } + + this.inventoryChest.a((IInventoryListener) this); + this.db(); + } + + private void db() { + if (!this.world.isClientSide) { + this.q(this.inventoryChest.getItem(0) != null); + if (this.cO()) { + this.e(this.inventoryChest.getItem(1)); + } + } + + } + + public void a(InventorySubcontainer inventorysubcontainer) { + int i = this.cx(); + boolean flag = this.cG(); + + this.db(); + if (this.ticksLived > 20) { + if (i == 0 && i != this.cx()) { + this.makeSound("mob.horse.armor", 0.5F, 1.0F); + } else if (i != this.cx()) { + this.makeSound("mob.horse.armor", 0.5F, 1.0F); + } + + if (!flag && this.cG()) { + this.makeSound("mob.horse.leather", 0.5F, 1.0F); + } + } + + } + + public boolean bR() { + this.cD(); + return super.bR(); + } + + protected EntityHorse a(Entity entity, double d0) { + double d1 = Double.MAX_VALUE; + Entity entity1 = null; + List list = this.world.a(entity, entity.getBoundingBox().a(d0, d0, d0), EntityHorse.bs); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Entity entity2 = (Entity) iterator.next(); + double d2 = entity2.e(entity.locX, entity.locY, entity.locZ); + + if (d2 < d1) { + entity1 = entity2; + d1 = d2; + } + } + + return (EntityHorse) entity1; + } + + public double getJumpStrength() { + return this.getAttributeInstance(EntityHorse.attributeJumpStrength).getValue(); + } + + protected String bp() { + this.df(); + int i = this.getType(); + + return i == 3 ? "mob.horse.zombie.death" : (i == 4 ? "mob.horse.skeleton.death" : (i != 1 && i != 2 ? "mob.horse.death" : "mob.horse.donkey.death")); + } + + protected Item getLoot() { + boolean flag = this.random.nextInt(4) == 0; + int i = this.getType(); + + return i == 4 ? Items.BONE : (i == 3 ? (flag ? null : Items.ROTTEN_FLESH) : Items.LEATHER); + } + + protected String bo() { + this.df(); + if (this.random.nextInt(3) == 0) { + this.dh(); + } + + int i = this.getType(); + + return i == 3 ? "mob.horse.zombie.hit" : (i == 4 ? "mob.horse.skeleton.hit" : (i != 1 && i != 2 ? "mob.horse.hit" : "mob.horse.donkey.hit")); + } + + public boolean cG() { + return this.w(4); + } + + protected String z() { + this.df(); + if (this.random.nextInt(10) == 0 && !this.bD()) { + this.dh(); + } + + int i = this.getType(); + + return i == 3 ? "mob.horse.zombie.idle" : (i == 4 ? "mob.horse.skeleton.idle" : (i != 1 && i != 2 ? "mob.horse.idle" : "mob.horse.donkey.idle")); + } + + protected String cH() { + this.df(); + this.dh(); + int i = this.getType(); + + return i != 3 && i != 4 ? (i != 1 && i != 2 ? "mob.horse.angry" : "mob.horse.donkey.angry") : null; + } + + protected void a(BlockPosition blockposition, Block block) { + Block.StepSound block_stepsound = block.stepSound; + + if (this.world.getType(blockposition.up()).getBlock() == Blocks.SNOW_LAYER) { + block_stepsound = Blocks.SNOW_LAYER.stepSound; + } + + if (!block.getMaterial().isLiquid()) { + int i = this.getType(); + + if (this.passenger != null && i != 1 && i != 2) { + ++this.bN; + if (this.bN > 5 && this.bN % 3 == 0) { + this.makeSound("mob.horse.gallop", block_stepsound.getVolume1() * 0.15F, block_stepsound.getVolume2()); + if (i == 0 && this.random.nextInt(10) == 0) { + this.makeSound("mob.horse.breathe", block_stepsound.getVolume1() * 0.6F, block_stepsound.getVolume2()); + } + } else if (this.bN <= 5) { + this.makeSound("mob.horse.wood", block_stepsound.getVolume1() * 0.15F, block_stepsound.getVolume2()); + } + } else if (block_stepsound == Block.f) { + this.makeSound("mob.horse.wood", block_stepsound.getVolume1() * 0.15F, block_stepsound.getVolume2()); + } else { + this.makeSound("mob.horse.soft", block_stepsound.getVolume1() * 0.15F, block_stepsound.getVolume2()); + } + } + + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeMap().b(EntityHorse.attributeJumpStrength); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(53.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.22499999403953552D); + } + + public int bV() { + return 6; + } + + public int getMaxDomestication() { + return this.maxDomestication; // CraftBukkit - return stored max domestication instead of 100 + } + + protected float bB() { + return 0.8F; + } + + public int w() { + return 400; + } + + private void dc() { + this.bO = null; + } + + public void g(EntityHuman entityhuman) { + if (!this.world.isClientSide && (this.passenger == null || this.passenger == entityhuman) && this.isTame()) { + this.inventoryChest.a(this.getName()); + entityhuman.openHorseInventory(this, this.inventoryChest); + } + + } + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.SPAWN_EGG) { + return super.a(entityhuman); + } else if (!this.isTame() && this.cR()) { + return false; + } else if (this.isTame() && this.cn() && entityhuman.isSneaking()) { + this.g(entityhuman); + return true; + } else if (this.cp() && this.passenger != null) { + return super.a(entityhuman); + } else { + if (itemstack != null) { + boolean flag = false; + + if (this.cO()) { + byte b0 = -1; + + if (itemstack.getItem() == Items.IRON_HORSE_ARMOR) { + b0 = 1; + } else if (itemstack.getItem() == Items.GOLDEN_HORSE_ARMOR) { + b0 = 2; + } else if (itemstack.getItem() == Items.DIAMOND_HORSE_ARMOR) { + b0 = 3; + } + + if (b0 >= 0) { + if (!this.isTame()) { + this.cW(); + return true; + } + + this.g(entityhuman); + return true; + } + } + + if (!flag && !this.cR()) { + float f = 0.0F; + short short0 = 0; + byte b1 = 0; + + if (itemstack.getItem() == Items.WHEAT) { + f = 2.0F; + short0 = 20; + b1 = 3; + } else if (itemstack.getItem() == Items.SUGAR) { + f = 1.0F; + short0 = 30; + b1 = 3; + } else if (Block.asBlock(itemstack.getItem()) == Blocks.HAY_BLOCK) { + f = 20.0F; + short0 = 180; + } else if (itemstack.getItem() == Items.APPLE) { + f = 3.0F; + short0 = 60; + b1 = 3; + } else if (itemstack.getItem() == Items.GOLDEN_CARROT) { + f = 4.0F; + short0 = 60; + b1 = 5; + if (this.isTame() && this.getAge() == 0) { + flag = true; + this.c(entityhuman); + } + } else if (itemstack.getItem() == Items.GOLDEN_APPLE) { + f = 10.0F; + short0 = 240; + b1 = 10; + if (this.isTame() && this.getAge() == 0) { + flag = true; + this.c(entityhuman); + } + } + + if (this.getHealth() < this.getMaxHealth() && f > 0.0F) { + this.heal(f, RegainReason.EATING); // CraftBukkit + flag = true; + } + + if (!this.cn() && short0 > 0) { + this.setAge(short0); + flag = true; + } + + if (b1 > 0 && (flag || !this.isTame()) && b1 < this.getMaxDomestication()) { + flag = true; + this.u(b1); + } + + if (flag) { + this.cY(); + } + } + + if (!this.isTame() && !flag) { + if (itemstack != null && itemstack.a(entityhuman, (EntityLiving) this)) { + return true; + } + + this.cW(); + return true; + } + + if (!flag && this.cP() && !this.hasChest() && itemstack.getItem() == Item.getItemOf(Blocks.CHEST)) { + this.setHasChest(true); + this.makeSound("mob.chickenplop", 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + flag = true; + this.loadChest(); + } + + if (!flag && this.cp() && !this.cG() && itemstack.getItem() == Items.SADDLE) { + this.g(entityhuman); + return true; + } + + if (flag) { + if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count == 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + + return true; + } + } + + if (this.cp() && this.passenger == null) { + if (itemstack != null && itemstack.a(entityhuman, (EntityLiving) this)) { + return true; + } else { + this.i(entityhuman); + return true; + } + } else { + return super.a(entityhuman); + } + } + } + + private void i(EntityHuman entityhuman) { + entityhuman.yaw = this.yaw; + entityhuman.pitch = this.pitch; + this.r(false); + this.s(false); + if (!this.world.isClientSide) { + entityhuman.mount(this); + } + + } + + public boolean cO() { + return this.getType() == 0; + } + + public boolean cP() { + int i = this.getType(); + + return i == 2 || i == 1; + } + + protected boolean bD() { + return this.passenger != null && this.cG() ? true : this.cy() || this.cz(); + } + + public boolean cR() { + int i = this.getType(); + + return i == 3 || i == 4; + } + + public boolean cS() { + return this.cR() || this.getType() == 2; + } + + public boolean d(ItemStack itemstack) { + return false; + } + + private void de() { + this.bm = 1; + } + + public void die(DamageSource damagesource) { + super.die(damagesource); + /* CraftBukkit start - Handle chest dropping in dropDeathLoot below + if (!this.world.isClientSide) { + this.dropChest(); + } + // CraftBukkit end */ + } + + // CraftBukkit start - Add method + @Override + protected void dropDeathLoot(boolean flag, int i) { + super.dropDeathLoot(flag, i); + + // Moved from die method above + if (!this.world.isClientSide) { + this.dropChest(); + } + } + // CraftBukkit end + + public void m() { + if (this.random.nextInt(200) == 0) { + this.de(); + } + + super.m(); + if (!this.world.isClientSide) { + if (this.random.nextInt(900) == 0 && this.deathTicks == 0) { + this.heal(1.0F, RegainReason.REGEN); // CraftBukkit + } + + if (!this.cy() && this.passenger == null && this.random.nextInt(300) == 0 && this.world.getType(new BlockPosition(MathHelper.floor(this.locX), MathHelper.floor(this.locY) - 1, MathHelper.floor(this.locZ))).getBlock() == Blocks.GRASS) { + this.r(true); + } + + if (this.cy() && ++this.bB > 50) { + this.bB = 0; + this.r(false); + } + + if (this.cA() && !this.cn() && !this.cy()) { + EntityHorse entityhorse = this.a(this, 16.0D); + + if (entityhorse != null && this.h((Entity) entityhorse) > 4.0D) { + this.navigation.a((Entity) entityhorse); + } + } + } + + } + + public void t_() { + super.t_(); + if (this.world.isClientSide && this.datawatcher.a()) { + this.datawatcher.e(); + this.dc(); + } + + if (this.bC > 0 && ++this.bC > 30) { + this.bC = 0; + this.c(128, false); + } + + if (!this.world.isClientSide && this.bD > 0 && ++this.bD > 20) { + this.bD = 0; + this.s(false); + } + + if (this.bm > 0 && ++this.bm > 8) { + this.bm = 0; + } + + if (this.bo > 0) { + ++this.bo; + if (this.bo > 300) { + this.bo = 0; + } + } + + this.bI = this.bH; + if (this.cy()) { + this.bH += (1.0F - this.bH) * 0.4F + 0.05F; + if (this.bH > 1.0F) { + this.bH = 1.0F; + } + } else { + this.bH += (0.0F - this.bH) * 0.4F - 0.05F; + if (this.bH < 0.0F) { + this.bH = 0.0F; + } + } + + this.bK = this.bJ; + if (this.cz()) { + this.bI = this.bH = 0.0F; + this.bJ += (1.0F - this.bJ) * 0.4F + 0.05F; + if (this.bJ > 1.0F) { + this.bJ = 1.0F; + } + } else { + this.bG = false; + this.bJ += (0.8F * this.bJ * this.bJ * this.bJ - this.bJ) * 0.6F - 0.05F; + if (this.bJ < 0.0F) { + this.bJ = 0.0F; + } + } + + this.bM = this.bL; + if (this.w(128)) { + this.bL += (1.0F - this.bL) * 0.7F + 0.05F; + if (this.bL > 1.0F) { + this.bL = 1.0F; + } + } else { + this.bL += (0.0F - this.bL) * 0.7F - 0.05F; + if (this.bL < 0.0F) { + this.bL = 0.0F; + } + } + + } + + private void df() { + if (!this.world.isClientSide) { + this.bC = 1; + this.c(128, true); + } + + } + + private boolean dg() { + return this.passenger == null && this.vehicle == null && this.isTame() && this.cn() && !this.cS() && this.getHealth() >= this.getMaxHealth() && this.isInLove(); + } + + public void f(boolean flag) { + this.c(32, flag); + } + + public void r(boolean flag) { + this.f(flag); + } + + public void s(boolean flag) { + if (flag) { + this.r(false); + } + + this.c(64, flag); + } + + private void dh() { + if (!this.world.isClientSide) { + this.bD = 1; + this.s(true); + } + + } + + public void cW() { + this.dh(); + String s = this.cH(); + + if (s != null) { + this.makeSound(s, this.bB(), this.bC()); + } + + } + + public void dropChest() { + this.a((Entity) this, this.inventoryChest); + this.cE(); + } + + private void a(Entity entity, InventoryHorseChest inventoryhorsechest) { + if (inventoryhorsechest != null && !this.world.isClientSide) { + for (int i = 0; i < inventoryhorsechest.getSize(); ++i) { + ItemStack itemstack = inventoryhorsechest.getItem(i); + + if (itemstack != null) { + this.a(itemstack, 0.0F); + } + } + + } + } + + public boolean h(EntityHuman entityhuman) { + this.setOwnerUUID(entityhuman.getUniqueID().toString()); + this.setTame(true); + return true; + } + + public void g(float f, float f1) { + if (this.passenger != null && this.passenger instanceof EntityLiving && this.cG()) { + this.lastYaw = this.yaw = this.passenger.yaw; + this.pitch = this.passenger.pitch * 0.5F; + this.setYawPitch(this.yaw, this.pitch); + this.aK = this.aI = this.yaw; + f = ((EntityLiving) this.passenger).aZ * 0.5F; + f1 = ((EntityLiving) this.passenger).ba; + if (f1 <= 0.0F) { + f1 *= 0.25F; + this.bN = 0; + } + + if (this.onGround && this.br == 0.0F && this.cz() && !this.bG) { + f = 0.0F; + f1 = 0.0F; + } + + if (this.br > 0.0F && !this.cv() && this.onGround) { + this.motY = this.getJumpStrength() * (double) this.br; + if (this.hasEffect(MobEffectList.JUMP)) { + this.motY += (double) ((float) (this.getEffect(MobEffectList.JUMP).getAmplifier() + 1) * 0.1F); + } + + this.m(true); + this.ai = true; + if (f1 > 0.0F) { + float f2 = MathHelper.sin(this.yaw * 3.1415927F / 180.0F); + float f3 = MathHelper.cos(this.yaw * 3.1415927F / 180.0F); + + this.motX += (double) (-0.4F * f2 * this.br); + this.motZ += (double) (0.4F * f3 * this.br); + this.makeSound("mob.horse.jump", 0.4F, 1.0F); + } + + this.br = 0.0F; + } + + this.S = 1.0F; + this.aM = this.bI() * 0.1F; + if (!this.world.isClientSide) { + this.k((float) this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); + super.g(f, f1); + } + + if (this.onGround) { + this.br = 0.0F; + this.m(false); + } + + this.aA = this.aB; + double d0 = this.locX - this.lastX; + double d1 = this.locZ - this.lastZ; + float f4 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F; + + if (f4 > 1.0F) { + f4 = 1.0F; + } + + this.aB += (f4 - this.aB) * 0.4F; + this.aC += this.aB; + } else { + this.S = 0.5F; + this.aM = 0.02F; + super.g(f, f1); + } + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setBoolean("EatingHaystack", this.cy()); + nbttagcompound.setBoolean("ChestedHorse", this.hasChest()); + nbttagcompound.setBoolean("HasReproduced", this.cB()); + nbttagcompound.setBoolean("Bred", this.cA()); + nbttagcompound.setInt("Type", this.getType()); + nbttagcompound.setInt("Variant", this.getVariant()); + nbttagcompound.setInt("Temper", this.getTemper()); + nbttagcompound.setBoolean("Tame", this.isTame()); + nbttagcompound.setString("OwnerUUID", this.getOwnerUUID()); + nbttagcompound.setInt("Bukkit.MaxDomestication", this.maxDomestication); // CraftBukkit + if (this.hasChest()) { + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 2; i < this.inventoryChest.getSize(); ++i) { + ItemStack itemstack = this.inventoryChest.getItem(i); + + if (itemstack != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setByte("Slot", (byte) i); + itemstack.save(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Items", nbttaglist); + } + + if (this.inventoryChest.getItem(1) != null) { + nbttagcompound.set("ArmorItem", this.inventoryChest.getItem(1).save(new NBTTagCompound())); + } + + if (this.inventoryChest.getItem(0) != null) { + nbttagcompound.set("SaddleItem", this.inventoryChest.getItem(0).save(new NBTTagCompound())); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.r(nbttagcompound.getBoolean("EatingHaystack")); + this.n(nbttagcompound.getBoolean("Bred")); + this.setHasChest(nbttagcompound.getBoolean("ChestedHorse")); + this.p(nbttagcompound.getBoolean("HasReproduced")); + this.setType(nbttagcompound.getInt("Type")); + this.setVariant(nbttagcompound.getInt("Variant")); + this.setTemper(nbttagcompound.getInt("Temper")); + this.setTame(nbttagcompound.getBoolean("Tame")); + String s = ""; + + if (nbttagcompound.hasKeyOfType("OwnerUUID", 8)) { + s = nbttagcompound.getString("OwnerUUID"); + } else { + String s1 = nbttagcompound.getString("Owner"); + // Spigot start + if ( s1 == null || s1.isEmpty() ) + { + if (nbttagcompound.hasKey("OwnerName")) { + String owner = nbttagcompound.getString("OwnerName"); + if (owner != null && !owner.isEmpty()) { + s1 = owner; + } + } + } + // Spigot end + + s = NameReferencingFileConverter.a(s1); + } + + if (s.length() > 0) { + this.setOwnerUUID(s); + } + + // CraftBukkit start + if (nbttagcompound.hasKey("Bukkit.MaxDomestication")) { + this.maxDomestication = nbttagcompound.getInt("Bukkit.MaxDomestication"); + } + // CraftBukkit end + + AttributeInstance attributeinstance = this.getAttributeMap().a("Speed"); + + if (attributeinstance != null) { + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(attributeinstance.b() * 0.25D); + } + + if (this.hasChest()) { + NBTTagList nbttaglist = nbttagcompound.getList("Items", 10); + + this.loadChest(); + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + int j = nbttagcompound1.getByte("Slot") & 255; + + if (j >= 2 && j < this.inventoryChest.getSize()) { + this.inventoryChest.setItem(j, ItemStack.createStack(nbttagcompound1)); + } + } + } + + ItemStack itemstack; + + if (nbttagcompound.hasKeyOfType("ArmorItem", 10)) { + itemstack = ItemStack.createStack(nbttagcompound.getCompound("ArmorItem")); + if (itemstack != null && a(itemstack.getItem())) { + this.inventoryChest.setItem(1, itemstack); + } + } + + if (nbttagcompound.hasKeyOfType("SaddleItem", 10)) { + itemstack = ItemStack.createStack(nbttagcompound.getCompound("SaddleItem")); + if (itemstack != null && itemstack.getItem() == Items.SADDLE) { + this.inventoryChest.setItem(0, itemstack); + } + } else if (nbttagcompound.getBoolean("Saddle")) { + this.inventoryChest.setItem(0, new ItemStack(Items.SADDLE)); + } + + this.db(); + } + + public boolean mate(EntityAnimal entityanimal) { + if (entityanimal == this) { + return false; + } else if (entityanimal.getClass() != this.getClass()) { + return false; + } else { + EntityHorse entityhorse = (EntityHorse) entityanimal; + + if (this.dg() && entityhorse.dg()) { + int i = this.getType(); + int j = entityhorse.getType(); + + return i == j || i == 0 && j == 1 || i == 1 && j == 0; + } else { + return false; + } + } + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + EntityHorse entityhorse = (EntityHorse) entityageable; + EntityHorse entityhorse1 = new EntityHorse(this.world); + int i = this.getType(); + int j = entityhorse.getType(); + int k = 0; + + if (i == j) { + k = i; + } else if (i == 0 && j == 1 || i == 1 && j == 0) { + k = 2; + } + + if (k == 0) { + int l = this.random.nextInt(9); + int i1; + + if (l < 4) { + i1 = this.getVariant() & 255; + } else if (l < 8) { + i1 = entityhorse.getVariant() & 255; + } else { + i1 = this.random.nextInt(7); + } + + int j1 = this.random.nextInt(5); + + if (j1 < 2) { + i1 |= this.getVariant() & '\uff00'; + } else if (j1 < 4) { + i1 |= entityhorse.getVariant() & '\uff00'; + } else { + i1 |= this.random.nextInt(5) << 8 & '\uff00'; + } + + entityhorse1.setVariant(i1); + } + + entityhorse1.setType(k); + double d0 = this.getAttributeInstance(GenericAttributes.maxHealth).b() + entityageable.getAttributeInstance(GenericAttributes.maxHealth).b() + (double) this.di(); + + entityhorse1.getAttributeInstance(GenericAttributes.maxHealth).setValue(d0 / 3.0D); + double d1 = this.getAttributeInstance(EntityHorse.attributeJumpStrength).b() + entityageable.getAttributeInstance(EntityHorse.attributeJumpStrength).b() + this.dj(); + + entityhorse1.getAttributeInstance(EntityHorse.attributeJumpStrength).setValue(d1 / 3.0D); + double d2 = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).b() + entityageable.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).b() + this.dk(); + + entityhorse1.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(d2 / 3.0D); + return entityhorse1; + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + Object object = super.prepare(difficultydamagescaler, groupdataentity); + boolean flag = false; + int i = 0; + int j; + + if (object instanceof EntityHorse.GroupDataHorse) { + j = ((EntityHorse.GroupDataHorse) object).a; + i = ((EntityHorse.GroupDataHorse) object).b & 255 | this.random.nextInt(5) << 8; + } else { + if (this.random.nextInt(10) == 0) { + j = 1; + } else { + int k = this.random.nextInt(7); + int l = this.random.nextInt(5); + + j = 0; + i = k | l << 8; + } + + object = new EntityHorse.GroupDataHorse(j, i); + } + + this.setType(j); + this.setVariant(i); + if (this.random.nextInt(5) == 0) { + this.setAgeRaw(-24000); + } + + if (j != 4 && j != 3) { + this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) this.di()); + if (j == 0) { + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(this.dk()); + } else { + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.17499999701976776D); + } + } else { + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(15.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.20000000298023224D); + } + + if (j != 2 && j != 1) { + this.getAttributeInstance(EntityHorse.attributeJumpStrength).setValue(this.dj()); + } else { + this.getAttributeInstance(EntityHorse.attributeJumpStrength).setValue(0.5D); + } + + this.setHealth(this.getMaxHealth()); + return (GroupDataEntity) object; + } + + public void v(int i) { + if (this.cG()) { + // CraftBukkit start - fire HorseJumpEvent, use event power + if (i < 0) { + i = 0; + } + + float power; + if (i >= 90) { + power = 1.0F; + } else { + power = 0.4F + 0.4F * (float) i / 90.0F; + } + + org.bukkit.event.entity.HorseJumpEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callHorseJumpEvent(this, power); + if (!event.isCancelled()) { + this.bG = true; + this.dh(); + this.br = power; + } + // CraftBukkit end + } + + } + + public void al() { + super.al(); + if (this.bK > 0.0F) { + float f = MathHelper.sin(this.aI * 3.1415927F / 180.0F); + float f1 = MathHelper.cos(this.aI * 3.1415927F / 180.0F); + float f2 = 0.7F * this.bK; + float f3 = 0.15F * this.bK; + + this.passenger.setPosition(this.locX + (double) (f2 * f), this.locY + this.an() + this.passenger.am() + (double) f3, this.locZ - (double) (f2 * f1)); + if (this.passenger instanceof EntityLiving) { + ((EntityLiving) this.passenger).aI = this.aI; + } + } + + } + + private float di() { + return 15.0F + (float) this.random.nextInt(8) + (float) this.random.nextInt(9); + } + + private double dj() { + return 0.4000000059604645D + this.random.nextDouble() * 0.2D + this.random.nextDouble() * 0.2D + this.random.nextDouble() * 0.2D; + } + + private double dk() { + return (0.44999998807907104D + this.random.nextDouble() * 0.3D + this.random.nextDouble() * 0.3D + this.random.nextDouble() * 0.3D) * 0.25D; + } + + public static boolean a(Item item) { + return item == Items.IRON_HORSE_ARMOR || item == Items.GOLDEN_HORSE_ARMOR || item == Items.DIAMOND_HORSE_ARMOR; + } + + public boolean k_() { + return false; + } + + public float getHeadHeight() { + return this.length; + } + + public boolean d(int i, ItemStack itemstack) { + if (i == 499 && this.cP()) { + if (itemstack == null && this.hasChest()) { + this.setHasChest(false); + this.loadChest(); + return true; + } + + if (itemstack != null && itemstack.getItem() == Item.getItemOf(Blocks.CHEST) && !this.hasChest()) { + this.setHasChest(true); + this.loadChest(); + return true; + } + } + + int j = i - 400; + + if (j >= 0 && j < 2 && j < this.inventoryChest.getSize()) { + if (j == 0 && itemstack != null && itemstack.getItem() != Items.SADDLE) { + return false; + } else if (j == 1 && (itemstack != null && !a(itemstack.getItem()) || !this.cO())) { + return false; + } else { + this.inventoryChest.setItem(j, itemstack); + this.db(); + return true; + } + } else { + int k = i - 500 + 2; + + if (k >= 2 && k < this.inventoryChest.getSize()) { + this.inventoryChest.setItem(k, itemstack); + return true; + } else { + return false; + } + } + } + + public static class GroupDataHorse implements GroupDataEntity { + + public int a; + public int b; + + public GroupDataHorse(int i, int j) { + this.a = i; + this.b = j; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHuman.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHuman.java new file mode 100644 index 0000000..cd8c105 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityHuman.java @@ -0,0 +1,1869 @@ +package net.minecraft.server; + +import com.google.common.base.Charsets; +import com.google.common.base.Objects; +import com.google.common.collect.Lists; +import com.mojang.authlib.GameProfile; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.kb.KBOption; +import me.levansj01.mythicspigot.kb.KBProfile; +import net.jafama.FastMath; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.entity.CraftItem; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityCombustByEntityEvent; +import org.bukkit.event.inventory.EquipmentSetEvent; +import org.bukkit.event.player.*; +import org.bukkit.util.Vector; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; + +// CraftBukkit start +// CraftBukkit end + +public abstract class EntityHuman extends EntityLiving { + + public PlayerInventory inventory = new PlayerInventory(this); + private InventoryEnderChest enderChest = new InventoryEnderChest(); + public Container defaultContainer; + public Container activeContainer; + protected FoodMetaData foodData = new FoodMetaData(this); // CraftBukkit - add "this" to constructor + protected int bm; + public float bn; + public float bo; + public int bp; + public double bq; + public double br; + public double bs; + public double bt; + public double bu; + public double bv; + public boolean sleeping; + public BlockPosition bx; + public int sleepTicks; + public float by; + public float bz; + private BlockPosition c; + private boolean d; + private BlockPosition e; + public PlayerAbilities abilities = new PlayerAbilities(); + public int expLevel; + public int expTotal; + public float exp; + private int f; + private ItemStack g; + private int h; + protected float bE = 0.1F; + protected float bF = 0.02F; + private int i; + private final GameProfile bH; + private boolean bI = false; + public EntityFishingHook hookedFish; + public boolean affectsSpawning = true; // PaperSpigot + + // CraftBukkit start + public boolean fauxSleeping; + public String spawnWorld = ""; + public int oldLevel = -1; + + @Override + public CraftHumanEntity getBukkitEntity() { + return (CraftHumanEntity) super.getBukkitEntity(); + } + // CraftBukkit end + + public EntityHuman(World world, GameProfile gameprofile) { + super(world); + this.uniqueID = a(gameprofile); + this.bH = gameprofile; + this.defaultContainer = new ContainerPlayer(this.inventory, !world.isClientSide, this); + this.activeContainer = this.defaultContainer; + BlockPosition blockposition = world.getSpawn(); + + this.setPositionRotation((double) blockposition.getX() + 0.5D, blockposition.getY() + 1, (double) blockposition.getZ() + 0.5D, 0.0F, 0.0F); + this.aV = 180.0F; + this.maxFireTicks = 20; + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE).setValue(1.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.10000000149011612D); + } + + protected void h() { + super.h(); + this.datawatcher.a(16, Byte.valueOf((byte) 0)); + this.datawatcher.a(17, Float.valueOf(0.0F)); + this.datawatcher.a(18, Integer.valueOf(0)); + this.datawatcher.a(10, Byte.valueOf((byte) 0)); + } + + public boolean bS() { + return this.g != null; + } + + public void bU() { + if (this.g != null) { + this.g.b(this.world, this, this.h); + } + + this.bV(); + } + + public void bV() { + this.g = null; + this.h = 0; + if (!this.world.isClientSide) { + this.f(false); + } + + } + + public boolean isBlocking() { + return this.bS() && this.g.getItem().e(this.g) == EnumAnimation.BLOCK; + } + + public void t_() { + this.noclip = this.isSpectator(); + if (this.isSpectator()) { + this.onGround = false; + } + + if (this.g != null) { + ItemStack itemstack = this.inventory.getItemInHand(); + + if (itemstack == this.g) { + if (this.h <= 25 && this.h % 4 == 0) { + this.b(itemstack, 5); + } + + if (--this.h == 0 && !this.world.isClientSide) { + this.s(); + } + } else { + this.bV(); + } + } + + if (this.bp > 0) { + --this.bp; + } + + if (this.isSleeping()) { + ++this.sleepTicks; + if (this.sleepTicks > 100) { + this.sleepTicks = 100; + } + + if (!this.world.isClientSide) { + if (!this.p()) { + this.a(true, true, false); + } else if (this.world.w()) { + this.a(false, true, true); + } + } + } else if (this.sleepTicks > 0) { + ++this.sleepTicks; + if (this.sleepTicks >= 110) { + this.sleepTicks = 0; + } + } + + super.t_(); + if (!this.world.isClientSide && this.activeContainer != null && !this.activeContainer.a(this)) { + this.closeInventory(); + this.activeContainer = this.defaultContainer; + } + + if (this.isBurning() && this.abilities.isInvulnerable) { + this.extinguish(); + } + + this.bq = this.bt; + this.br = this.bu; + this.bs = this.bv; + double d0 = this.locX - this.bt; + double d1 = this.locY - this.bu; + double d2 = this.locZ - this.bv; + double d3 = 10.0D; + + if (d0 > d3) { + this.bq = this.bt = this.locX; + } + + if (d2 > d3) { + this.bs = this.bv = this.locZ; + } + + if (d1 > d3) { + this.br = this.bu = this.locY; + } + + if (d0 < -d3) { + this.bq = this.bt = this.locX; + } + + if (d2 < -d3) { + this.bs = this.bv = this.locZ; + } + + if (d1 < -d3) { + this.br = this.bu = this.locY; + } + + this.bt += d0 * 0.25D; + this.bv += d2 * 0.25D; + this.bu += d1 * 0.25D; + if (this.vehicle == null) { + this.e = null; + } + + if (!this.world.isClientSide) { + this.foodData.a(this); + this.b(StatisticList.g); + if (this.isAlive()) { + this.b(StatisticList.h); + } + } + + int i = 29999999; + double d4 = MathHelper.a(this.locX, -2.9999999E7D, 2.9999999E7D); + double d5 = MathHelper.a(this.locZ, -2.9999999E7D, 2.9999999E7D); + + if (d4 != this.locX || d5 != this.locZ) { + this.setPosition(d4, this.locY, d5); + } + + } + + public int L() { + return this.abilities.isInvulnerable ? 0 : 80; + } + + protected String P() { + return "game.player.swim"; + } + + protected String aa() { + return "game.player.swim.splash"; + } + + public int aq() { + return 10; + } + + public void makeSound(String s, float f, float f1) { + this.world.a(this, s, f, f1); + } + + protected void b(ItemStack itemstack, int i) { + if (itemstack.m() == EnumAnimation.DRINK) { + this.makeSound("random.drink", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + } + + if (itemstack.m() == EnumAnimation.EAT) { + for (int j = 0; j < i; ++j) { + Vec3D vec3d = new Vec3D(((double) this.random.nextFloat() - 0.5D) * 0.1D, FastMath.random() * 0.1D + 0.1D, 0.0D); + + vec3d = vec3d.a(-this.pitch * 3.1415927F / 180.0F); + vec3d = vec3d.b(-this.yaw * 3.1415927F / 180.0F); + double d0 = (double) (-this.random.nextFloat()) * 0.6D - 0.3D; + Vec3D vec3d1 = new Vec3D(((double) this.random.nextFloat() - 0.5D) * 0.3D, d0, 0.6D); + + vec3d1 = vec3d1.a(-this.pitch * 3.1415927F / 180.0F); + vec3d1 = vec3d1.b(-this.yaw * 3.1415927F / 180.0F); + vec3d1 = vec3d1.add(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ); + if (itemstack.usesData()) { + this.world.addParticle(EnumParticle.ITEM_CRACK, vec3d1.a, vec3d1.b, vec3d1.c, vec3d.a, vec3d.b + 0.05D, vec3d.c, Item.getId(itemstack.getItem()), itemstack.getData()); + } else { + this.world.addParticle(EnumParticle.ITEM_CRACK, vec3d1.a, vec3d1.b, vec3d1.c, vec3d.a, vec3d.b + 0.05D, vec3d.c, Item.getId(itemstack.getItem())); + } + } + + this.makeSound("random.eat", 0.5F + 0.5F * (float) this.random.nextInt(2), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + } + + } + + protected void s() { + if (this.g != null) { + this.b(this.g, 16); + int i = this.g.count; + + // CraftBukkit start - fire PlayerItemConsumeEvent + org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(this.g); + PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + // Update client + if (this instanceof EntityPlayer) { + ((EntityPlayer) this).playerConnection.sendPacket(new PacketPlayOutSetSlot((byte) 0, activeContainer.getSlot(this.inventory, this.inventory.itemInHandIndex).index, this.g)); + // Spigot Start + ((EntityPlayer) this).getBukkitEntity().updateInventory(); + ((EntityPlayer) this).getBukkitEntity().updateScaledHealth(); + // Spigot End + } + return; + } + + // Plugin modified the item, process it but don't remove it + if (!craftItem.equals(event.getItem())) { + CraftItemStack.asNMSCopy(event.getItem()).b(this.world, this); + + // Update client + if (this instanceof EntityPlayer) { + ((EntityPlayer) this).playerConnection.sendPacket(new PacketPlayOutSetSlot((byte) 0, activeContainer.getSlot(this.inventory, this.inventory.itemInHandIndex).index, this.g)); + } + return; + } + // CraftBukkit end + + ItemStack itemstack = this.g.b(this.world, this); + + if (itemstack != this.g || itemstack != null && itemstack.count != i) { + this.inventory.items[this.inventory.itemInHandIndex] = itemstack; + if (itemstack.count == 0) { + this.inventory.items[this.inventory.itemInHandIndex] = null; + } + } + + this.bV(); + } + + } + + protected boolean bD() { + return this.getHealth() <= 0.0F || this.isSleeping(); + } + + public void closeInventory() { + this.activeContainer = this.defaultContainer; + } + + public void ak() { + if (!this.world.isClientSide && this.isSneaking()) { + this.mount(null); + this.setSneaking(false); + } else { + double d0 = this.locX; + double d1 = this.locY; + double d2 = this.locZ; + float f = this.yaw; + float f1 = this.pitch; + + super.ak(); + this.bn = this.bo; + this.bo = 0.0F; + this.l(this.locX - d0, this.locY - d1, this.locZ - d2); + if (this.vehicle instanceof EntityPig) { + this.pitch = f1; + this.yaw = f; + this.aI = ((EntityPig) this.vehicle).aI; + } + + } + } + + protected void doTick() { + super.doTick(); + this.bx(); + this.aK = this.yaw; + } + + public void m() { + if (this.bm > 0) { + --this.bm; + } + + if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.world.getGameRules().getBoolean("naturalRegeneration")) { + if (this.getHealth() < this.getMaxHealth() && this.ticksLived % 20 == 0) { + // CraftBukkit - added regain reason of "REGEN" for filtering purposes. + this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); + } + + if (this.foodData.c() && this.ticksLived % 10 == 0) { + this.foodData.a(this.foodData.getFoodLevel() + 1); + } + } + + this.inventory.k(); + this.bn = this.bo; + super.m(); + AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); + + if (!this.world.isClientSide) { + attributeinstance.setValue(this.abilities.b()); + } + + this.aM = this.bF; + if (this.isSprinting()) { + this.aM = (float) ((double) this.aM + (double) this.bF * 0.3D); + } + + this.k((float) attributeinstance.getValue()); + float f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + float f1 = (float) ( org.bukkit.craftbukkit.TrigMath.atan(-this.motY * 0.20000000298023224D) * 15.0D); // CraftBukkit + + if (f > 0.1F) { + f = 0.1F; + } + + if (!this.onGround || this.getHealth() <= 0.0F) { + f = 0.0F; + } + + if (this.onGround || this.getHealth() <= 0.0F) { + f1 = 0.0F; + } + + this.bo += (f - this.bo) * 0.4F; + this.aF += (f1 - this.aF) * 0.8F; + if (this.getHealth() > 0.0F && !this.isSpectator()) { + AxisAlignedBB axisalignedbb = null; + + if (this.vehicle != null && !this.vehicle.dead) { + axisalignedbb = this.getBoundingBox().a(this.vehicle.getBoundingBox()).grow(1.0D, 0.0D, 1.0D); + } else { + axisalignedbb = this.getBoundingBox().grow(1.0D, 0.5D, 1.0D); + } + + List list = this.world.getEntities(this, axisalignedbb); + + if (this.ae()) { // Spigot: Add this.ae() condition (second !this.isDead near bottom of EntityLiving) + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + + if (!entity.dead) { + this.d(entity); + } + } + } // Spigot + } + + } + + private void d(Entity entity) { + entity.d(this); + } + + public int getScore() { + return this.datawatcher.getInt(18); + } + + public void setScore(int i) { + this.datawatcher.watch(18, Integer.valueOf(i)); + } + + public void addScore(int i) { + int j = this.getScore(); + + this.datawatcher.watch(18, Integer.valueOf(j + i)); + } + + public void die(DamageSource damagesource) { + super.die(damagesource); + this.setSize(0.2F, 0.2F); + this.setPosition(this.locX, this.locY, this.locZ); + this.motY = 0.10000000149011612D; + if (this.getName().equals("Notch")) { + this.a(new ItemStack(Items.APPLE, 1), true, false); + } + + if (!this.world.getGameRules().getBoolean("keepInventory")) { + this.inventory.n(); + } + + if (damagesource != null) { + this.motX = -MathHelper.cos((this.aw + this.yaw) * 3.1415927F / 180.0F) * 0.1F; + this.motZ = -MathHelper.sin((this.aw + this.yaw) * 3.1415927F / 180.0F) * 0.1F; + } else { + this.motX = this.motZ = 0.0D; + } + + this.b(StatisticList.y); + this.a(StatisticList.h); + } + + protected String bo() { + return "game.player.hurt"; + } + + protected String bp() { + return "game.player.die"; + } + + public void b(Entity entity, int i) { + this.addScore(i); + // CraftBukkit - Get our scores instead + Collection collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.f, this.getName(), new java.util.ArrayList()); + + if (entity instanceof EntityHuman) { + this.b(StatisticList.B); + // CraftBukkit - Get our scores instead + this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.e, this.getName(), collection); + collection.addAll(this.e(entity)); + } else { + this.b(StatisticList.z); + } + + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); // CraftBukkit - Use our scores instead + + scoreboardscore.incrementScore(); + } + + } + + private Collection e(Entity entity) { // CraftBukkit - TODO: Check me? + ScoreboardTeam scoreboardteam = this.getScoreboard().getPlayerTeam(this.getName()); + + if (scoreboardteam != null) { + int i = scoreboardteam.l().b(); + + if (i >= 0 && i < IScoreboardCriteria.i.length) { + Iterator iterator = this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.i[i]).iterator(); + + while (iterator.hasNext()) { + ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); + ScoreboardScore scoreboardscore = this.getScoreboard().getPlayerScoreForObjective(entity.getName(), scoreboardobjective); + + scoreboardscore.incrementScore(); + } + } + } + + ScoreboardTeam scoreboardteam1 = this.getScoreboard().getPlayerTeam(entity.getName()); + + if (scoreboardteam1 != null) { + int j = scoreboardteam1.l().b(); + + if (j >= 0 && j < IScoreboardCriteria.h.length) { + return this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.h[j]); + } + } + + return Lists.newArrayList(); + } + + public EntityItem a(boolean flag) { + // Called only when dropped by Q or CTRL-Q + return this.a(this.inventory.splitStack(this.inventory.itemInHandIndex, flag && this.inventory.getItemInHand() != null ? this.inventory.getItemInHand().count : 1), false, true); + } + + public EntityItem drop(ItemStack itemstack, boolean flag) { + return this.a(itemstack, false, false); + } + + public EntityItem a(ItemStack itemstack, boolean flag, boolean flag1) { + if (itemstack == null) { + return null; + } else if (itemstack.count == 0) { + return null; + } else { + double d0 = this.locY - 0.30000001192092896D + (double) this.getHeadHeight(); + EntityItem entityitem = new EntityItem(this.world, this.locX, d0, this.locZ, itemstack, this); + + // Mythic - Hide items for practice + if(MythicConfiguration.Options.Tracking.Hide.items) entityitem.dropper = this; + + entityitem.a(40); + if (flag1) { + entityitem.c(this.getName()); + } + + float f; + float f1; + + if (flag) { + f = this.random.nextFloat() * 0.5F; + f1 = this.random.nextFloat() * 3.1415927F * 2.0F; + entityitem.motX = -MathHelper.sin(f1) * f; + entityitem.motZ = MathHelper.cos(f1) * f; + entityitem.motY = 0.20000000298023224D; + } else { + f = 0.3F; + entityitem.motX = -MathHelper.sin(this.yaw / 180.0F * 3.1415927F) * MathHelper.cos(this.pitch / 180.0F * 3.1415927F) * f; + entityitem.motZ = MathHelper.cos(this.yaw / 180.0F * 3.1415927F) * MathHelper.cos(this.pitch / 180.0F * 3.1415927F) * f; + entityitem.motY = -MathHelper.sin(this.pitch / 180.0F * 3.1415927F) * f + 0.1F; + f1 = this.random.nextFloat() * 3.1415927F * 2.0F; + f = 0.02F * this.random.nextFloat(); + entityitem.motX += FastMath.cos(f1) * (double) f; + entityitem.motY += (this.random.nextFloat() - this.random.nextFloat()) * 0.1F; + entityitem.motZ += FastMath.sin(f1) * (double) f; + } + + // CraftBukkit start - fire PlayerDropItemEvent + Player player = (Player) this.getBukkitEntity(); + CraftItem drop = new CraftItem(this.world.getServer(), entityitem); + + PlayerDropItemEvent event = new PlayerDropItemEvent(player, drop); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + org.bukkit.inventory.ItemStack cur = player.getInventory().getItemInHand(); + if (flag1 && (cur == null || cur.getAmount() == 0)) { + // The complete stack was dropped + player.getInventory().setItemInHand(drop.getItemStack()); + } else if (flag1 && cur.isSimilar(drop.getItemStack()) && drop.getItemStack().getAmount() == 1) { + // Only one item is dropped + cur.setAmount(cur.getAmount() + 1); + player.getInventory().setItemInHand(cur); + } else { + // Fallback + player.getInventory().addItem(drop.getItemStack()); + } + return null; + } + // CraftBukkit end + + this.a(entityitem); + if (flag1) { + this.b(StatisticList.v); + } + + return entityitem; + } + } + + protected void a(EntityItem entityitem) { + this.world.addEntity(entityitem); + } + + public float a(Block block) { + float f = this.inventory.a(block); + + if (f > 1.0F) { + int i = EnchantmentManager.getDigSpeedEnchantmentLevel(this); + ItemStack itemstack = this.inventory.getItemInHand(); + + if (i > 0 && itemstack != null) { + f += (float) (i * i + 1); + } + } + + if (this.hasEffect(MobEffectList.FASTER_DIG)) { + f *= 1.0F + (float) (this.getEffect(MobEffectList.FASTER_DIG).getAmplifier() + 1) * 0.2F; + } + + if (this.hasEffect(MobEffectList.SLOWER_DIG)) { + float f1 = 1.0F; + + switch (this.getEffect(MobEffectList.SLOWER_DIG).getAmplifier()) { + case 0: + f1 = 0.3F; + break; + + case 1: + f1 = 0.09F; + break; + + case 2: + f1 = 0.0027F; + break; + + case 3: + default: + f1 = 8.1E-4F; + } + + f *= f1; + } + + if (this.a(Material.WATER) && !EnchantmentManager.j(this)) { + f /= 5.0F; + } + + if (!this.onGround) { + f /= 5.0F; + } + + return f; + } + + public boolean b(Block block) { + return this.inventory.b(block); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.uniqueID = a(this.bH); + NBTTagList nbttaglist = nbttagcompound.getList("Inventory", 10); + + this.inventory.b(nbttaglist); + this.inventory.itemInHandIndex = nbttagcompound.getInt("SelectedItemSlot"); + this.sleeping = nbttagcompound.getBoolean("Sleeping"); + this.sleepTicks = nbttagcompound.getShort("SleepTimer"); + this.exp = nbttagcompound.getFloat("XpP"); + this.expLevel = nbttagcompound.getInt("XpLevel"); + this.expTotal = nbttagcompound.getInt("XpTotal"); + this.f = nbttagcompound.getInt("XpSeed"); + if (this.f == 0) { + this.f = this.random.nextInt(); + } + + this.setScore(nbttagcompound.getInt("Score")); + if (this.sleeping) { + this.bx = new BlockPosition(this); + this.a(true, true, false); + } + + // CraftBukkit start + this.spawnWorld = nbttagcompound.getString("SpawnWorld"); + if ("".equals(spawnWorld)) { + this.spawnWorld = this.world.getServer().getWorlds().get(0).getName(); + } + // CraftBukkit end + + if (nbttagcompound.hasKeyOfType("SpawnX", 99) && nbttagcompound.hasKeyOfType("SpawnY", 99) && nbttagcompound.hasKeyOfType("SpawnZ", 99)) { + this.c = new BlockPosition(nbttagcompound.getInt("SpawnX"), nbttagcompound.getInt("SpawnY"), nbttagcompound.getInt("SpawnZ")); + this.d = nbttagcompound.getBoolean("SpawnForced"); + } + + this.foodData.a(nbttagcompound); + this.abilities.b(nbttagcompound); + if (nbttagcompound.hasKeyOfType("EnderItems", 9)) { + NBTTagList nbttaglist1 = nbttagcompound.getList("EnderItems", 10); + + this.enderChest.a(nbttaglist1); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.set("Inventory", this.inventory.a(new NBTTagList())); + nbttagcompound.setInt("SelectedItemSlot", this.inventory.itemInHandIndex); + nbttagcompound.setBoolean("Sleeping", this.sleeping); + nbttagcompound.setShort("SleepTimer", (short) this.sleepTicks); + nbttagcompound.setFloat("XpP", this.exp); + nbttagcompound.setInt("XpLevel", this.expLevel); + nbttagcompound.setInt("XpTotal", this.expTotal); + nbttagcompound.setInt("XpSeed", this.f); + nbttagcompound.setInt("Score", this.getScore()); + if (this.c != null) { + nbttagcompound.setInt("SpawnX", this.c.getX()); + nbttagcompound.setInt("SpawnY", this.c.getY()); + nbttagcompound.setInt("SpawnZ", this.c.getZ()); + nbttagcompound.setBoolean("SpawnForced", this.d); + } + + this.foodData.b(nbttagcompound); + this.abilities.a(nbttagcompound); + nbttagcompound.set("EnderItems", this.enderChest.h()); + ItemStack itemstack = this.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() != null) { + nbttagcompound.set("SelectedItem", itemstack.save(new NBTTagCompound())); + } + nbttagcompound.setString("SpawnWorld", spawnWorld); // CraftBukkit - fixes bed spawns for multiworld worlds + + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else if (this.abilities.isInvulnerable && !damagesource.ignoresInvulnerability()) { + return false; + } else { + this.ticksFarFromPlayer = 0; + if (this.getHealth() <= 0.0F) { + return false; + } else { + if (this.isSleeping() && !this.world.isClientSide) { + this.a(true, true, false); + } + + if (damagesource.r()) { + if (this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { + return false; // CraftBukkit - f = 0.0f -> return false + } + + if (this.world.getDifficulty() == EnumDifficulty.EASY) { + f = f / 2.0F + 1.0F; + } + + if (this.world.getDifficulty() == EnumDifficulty.HARD) { + f = f * 3.0F / 2.0F; + } + } + + if (false && f == 0.0F) { // CraftBukkit - Don't filter out 0 damage + return false; + } else { + Entity entity = damagesource.getEntity(); + + if (entity instanceof EntityArrow && ((EntityArrow) entity).shooter != null) { + entity = ((EntityArrow) entity).shooter; + } + + return super.damageEntity(damagesource, f); + } + } + } + } + + public boolean a(EntityHuman entityhuman) { + // CraftBukkit start - Change to check OTHER player's scoreboard team according to API + // To summarize this method's logic, it's "Can parameter hurt this" + org.bukkit.scoreboard.Team team; + if (entityhuman instanceof EntityPlayer) { + EntityPlayer thatPlayer = (EntityPlayer) entityhuman; + team = thatPlayer.getBukkitEntity().getScoreboard().getPlayerTeam(thatPlayer.getBukkitEntity()); + if (team == null || team.allowFriendlyFire()) { + return true; + } + } else { + // This should never be called, but is implemented anyway + org.bukkit.OfflinePlayer thisPlayer = entityhuman.world.getServer().getOfflinePlayer(entityhuman.getName()); + team = entityhuman.world.getServer().getScoreboardManager().getMainScoreboard().getPlayerTeam(thisPlayer); + if (team == null || team.allowFriendlyFire()) { + return true; + } + } + + if (this instanceof EntityPlayer) { + return !team.hasPlayer(((EntityPlayer) this).getBukkitEntity()); + } + return !team.hasPlayer(this.world.getServer().getOfflinePlayer(this.getName())); + // CraftBukkit end + } + + protected void damageArmor(float f) { + this.inventory.a(f); + } + + public int br() { + return this.inventory.m(); + } + + public float bY() { + int i = 0; + ItemStack[] aitemstack = this.inventory.armor; + int j = aitemstack.length; + + for (int k = 0; k < j; ++k) { + ItemStack itemstack = aitemstack[k]; + + if (itemstack != null) { + ++i; + } + } + + return (float) i / (float) this.inventory.armor.length; + } + + // CraftBukkit start + protected boolean d(DamageSource damagesource, float f) { // void -> boolean + if (true) { + return super.d(damagesource, f); + } + // CraftBukkit end + if (!this.isInvulnerable(damagesource)) { + if (!damagesource.ignoresArmor() && this.isBlocking() && f > 0.0F) { + f = (1.0F + f) * this.world.paperSpigotConfig.playerBlockingDamageMultiplier; // PaperSpigot - Configurable damage multiplier for blocking; + } + + f = this.applyArmorModifier(damagesource, f); + f = this.applyMagicModifier(damagesource, f); + float f1 = f; + + f = FastMath.max(f - this.getAbsorptionHearts(), 0.0F); + this.setAbsorptionHearts(this.getAbsorptionHearts() - (f1 - f)); + if (f != 0.0F) { + this.applyExhaustion(damagesource.getExhaustionCost()); + float f2 = this.getHealth(); + + this.setHealth(this.getHealth() - f); + this.bs().a(damagesource, f2, f); + if (f < 3.4028235E37F) { + this.a(StatisticList.x, FastMath.round(f * 10.0F)); + } + + } + } + return false; // CraftBukkit + } + + public void openSign(TileEntitySign tileentitysign) {} + + public void a(CommandBlockListenerAbstract commandblocklistenerabstract) {} + + public void openTrade(IMerchant imerchant) {} + + public void openContainer(IInventory iinventory) {} + + public void openHorseInventory(EntityHorse entityhorse, IInventory iinventory) {} + + public void openTileEntity(ITileEntityContainer itileentitycontainer) {} + + public void openBook(ItemStack itemstack) {} + + public boolean u(Entity entity) { + if (this.isSpectator()) { + if (entity instanceof IInventory) { + this.openContainer((IInventory) entity); + } + + return false; + } else { + ItemStack itemstack = this.bZ(); + ItemStack itemstack1 = itemstack != null ? itemstack.cloneItemStack() : null; + + if (!entity.e(this)) { + if (itemstack != null && entity instanceof EntityLiving) { + if (this.abilities.canInstantlyBuild) { + itemstack = itemstack1; + } + + if (itemstack.a(this, (EntityLiving) entity)) { + // CraftBukkit - bypass infinite items; <= 0 -> == 0 + if (itemstack.count == 0 && !this.abilities.canInstantlyBuild) { + this.ca(); + } + + return true; + } + } + + return false; + } else { + if (itemstack != null && itemstack == this.bZ()) { + if (itemstack.count <= 0 && !this.abilities.canInstantlyBuild) { + this.ca(); + } else if (itemstack.count < itemstack1.count && this.abilities.canInstantlyBuild) { + itemstack.count = itemstack1.count; + } + } + + return true; + } + } + } + + public ItemStack bZ() { + return this.inventory.getItemInHand(); + } + + public void ca() { + this.inventory.setItem(this.inventory.itemInHandIndex, null); + } + + public double am() { + return -0.35D; + } + + public void attack(Entity entity) { + if (entity.aD()) { + if (!entity.l(this)) { + float f = (float) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue(); + byte b0 = 0; + float f1 = 0.0F; + + if (entity instanceof EntityLiving) { + f1 = EnchantmentManager.a(this.bA(), ((EntityLiving) entity).getMonsterType()); + } else { + f1 = EnchantmentManager.a(this.bA(), EnumMonsterType.UNDEFINED); + } + + int i = b0 + EnchantmentManager.a(this); + + if (this.isSprinting()) { + ++i; + } + + if (f > 0.0F || f1 > 0.0F) { + // flag = is crit + boolean flag = !world.paperSpigotConfig.disablePlayerCrits && this.fallDistance > 0.0F && !this.onGround && !this.k_() && !this.V() && !this.hasEffect(MobEffectList.BLINDNESS) && this.vehicle == null && entity instanceof EntityLiving; // PaperSpigot + + if (flag && f > 0.0F) { + f *= 1.5F; + } + + f += f1; + boolean flag1 = false; + int j = EnchantmentManager.getFireAspectEnchantmentLevel(this); + + if (entity instanceof EntityLiving && j > 0 && !entity.isBurning()) { + // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item + EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 1); + org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); + + if (!combustEvent.isCancelled()) { + flag1 = true; + entity.setOnFire(combustEvent.getDuration()); + } + // CraftBukkit end + } + + KBProfile kb = entity.getKBProfile(); + double d0 = entity.motX; + double d1 = entity.motY; + double d2 = entity.motZ; + boolean flag2 = entity.damageEntity(DamageSource.playerAttack(this), f); + + if (flag2) { + if (i > 0) { + KBOption wTap = kb.getWTap(); //i * 0.5F was the OG KB enchant check + entity.g((double) (-MathHelper.sin(this.yaw * 3.1415927F / 180.0F) * (float) i * 0.5F) * wTap.getHorizontal(), + wTap.getVertical(), + (double) (MathHelper.cos(this.yaw * 3.1415927F / 180.0F) * (float) i * 0.5F) * wTap.getHorizontal()); + this.motX *= kb.getSlow(); + this.motZ *= kb.getSlow(); + this.setSprinting(false); + } + + if (flag) { + KBOption crit = kb.getCrit(); + entity.motX += crit.getHorizontal(); + entity.motY += crit.getVertical(); + entity.motZ += crit.getHorizontal(); + } + + if (entity instanceof EntityPlayer && entity.velocityChanged) { + // CraftBukkit start - Add Velocity Event + boolean cancelled = false; + Player player = (Player) entity.getBukkitEntity(); + org.bukkit.util.Vector velocity = new Vector( d0, d1, d2 ); + + PlayerVelocityEvent event = new PlayerVelocityEvent(player, velocity.clone()); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + cancelled = true; + } else if (!velocity.equals(event.getVelocity())) { + player.setVelocity(event.getVelocity()); + } + + if (!cancelled) { + ( (EntityPlayer) entity ).playerConnection.sendPacket( new PacketPlayOutEntityVelocity( entity ) ); + entity.velocityChanged = false; + entity.motX = d0; + entity.motY = d1; + entity.motZ = d2; + } + // CraftBukkit end + } + + if (flag) { + this.b(entity); + } + + if (f1 > 0.0F) { + this.c(entity); + } + + if (f >= 18.0F) { + this.b(AchievementList.F); + } + + this.p(entity); + if (entity instanceof EntityLiving) { + EnchantmentManager.a((EntityLiving) entity, this); + } + + EnchantmentManager.b(this, entity); + ItemStack itemstack = this.bZ(); + Object object = entity; + + if (entity instanceof EntityComplexPart) { + IComplex icomplex = ((EntityComplexPart) entity).owner; + + if (icomplex instanceof EntityLiving) { + object = icomplex; + } + } + + if (itemstack != null && object instanceof EntityLiving) { + itemstack.a((EntityLiving) object, this); + // CraftBukkit - bypass infinite items; <= 0 -> == 0 + if (itemstack.count == 0) { + this.ca(); + } + } + + if (entity instanceof EntityLiving) { + this.a(StatisticList.w, Math.round(f * 10.0F)); + if (j > 0) { + // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item + EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), j * 4); + org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); + + if (!combustEvent.isCancelled()) { + entity.setOnFire(combustEvent.getDuration()); + } + // CraftBukkit end + } + } + + this.applyExhaustion(world.spigotConfig.combatExhaustion); // Spigot - Change to use configurable value + } else if (flag1) { + entity.extinguish(); + } + } + + } + } + } + + public void b(Entity entity) {} + + public void c(Entity entity) {} + + public void die() { + super.die(); + this.defaultContainer.b(this); + if (this.activeContainer != null) { + this.activeContainer.b(this); + } + + } + + public boolean inBlock() { + return !this.sleeping && super.inBlock(); + } + + public GameProfile getProfile() { + return this.bH; + } + + public EntityHuman.EnumBedResult a(BlockPosition blockposition) { + if (!this.world.isClientSide) { + if (this.isSleeping() || !this.isAlive()) { + return EntityHuman.EnumBedResult.OTHER_PROBLEM; + } + + if (!this.world.worldProvider.d()) { + return EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE; + } + + if (this.world.w()) { + return EntityHuman.EnumBedResult.NOT_POSSIBLE_NOW; + } + + if (FastMath.abs(this.locX - (double) blockposition.getX()) > 3.0D || FastMath.abs(this.locY - (double) blockposition.getY()) > 2.0D || FastMath.abs(this.locZ - (double) blockposition.getZ()) > 3.0D) { + return EntityHuman.EnumBedResult.TOO_FAR_AWAY; + } + + double d0 = 8.0D; + double d1 = 5.0D; + List list = this.world.a(EntityMonster.class, new AxisAlignedBB((double) blockposition.getX() - d0, (double) blockposition.getY() - d1, (double) blockposition.getZ() - d0, (double) blockposition.getX() + d0, (double) blockposition.getY() + d1, (double) blockposition.getZ() + d0)); + + if (!list.isEmpty()) { + return EntityHuman.EnumBedResult.NOT_SAFE; + } + } + + if (this.au()) { + this.mount(null); + } + + // CraftBukkit start - fire PlayerBedEnterEvent + if (this.getBukkitEntity() instanceof Player) { + Player player = (Player) this.getBukkitEntity(); + org.bukkit.block.Block bed = this.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + PlayerBedEnterEvent event = new PlayerBedEnterEvent(player, bed); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return EnumBedResult.OTHER_PROBLEM; + } + } + // CraftBukkit end + + this.setSize(0.2F, 0.2F); + if (this.world.isLoaded(blockposition)) { + EnumDirection enumdirection = this.world.getType(blockposition).get(BlockDirectional.FACING); + float f = 0.5F; + float f1 = 0.5F; + + switch (EntityHuman.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + f1 = 0.9F; + break; + + case 2: + f1 = 0.1F; + break; + + case 3: + f = 0.1F; + break; + + case 4: + f = 0.9F; + } + + this.a(enumdirection); + this.setPosition((float) blockposition.getX() + f, (float) blockposition.getY() + 0.6875F, (float) blockposition.getZ() + f1); + } else { + this.setPosition((float) blockposition.getX() + 0.5F, (float) blockposition.getY() + 0.6875F, (float) blockposition.getZ() + 0.5F); + } + + this.sleeping = true; + this.sleepTicks = 0; + this.bx = blockposition; + this.motX = this.motZ = this.motY = 0.0D; + if (!this.world.isClientSide) { + this.world.everyoneSleeping(); + } + + return EntityHuman.EnumBedResult.OK; + } + + private void a(EnumDirection enumdirection) { + this.by = 0.0F; + this.bz = 0.0F; + switch (EntityHuman.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + this.bz = -1.8F; + break; + + case 2: + this.bz = 1.8F; + break; + + case 3: + this.by = 1.8F; + break; + + case 4: + this.by = -1.8F; + } + + } + + public void a(boolean flag, boolean flag1, boolean flag2) { + this.setSize(0.6F, 1.8F); + IBlockData iblockdata = this.world.getType(this.bx); + + if (this.bx != null && iblockdata.getBlock() == Blocks.BED) { + this.world.setTypeAndData(this.bx, iblockdata.set(BlockBed.OCCUPIED, Boolean.valueOf(false)), 4); + BlockPosition blockposition = BlockBed.a(this.world, this.bx, 0); + + if (blockposition == null) { + blockposition = this.bx.up(); + } + + this.setPosition((float) blockposition.getX() + 0.5F, (float) blockposition.getY() + 0.1F, (float) blockposition.getZ() + 0.5F); + } + + this.sleeping = false; + if (!this.world.isClientSide && flag1) { + this.world.everyoneSleeping(); + } + + // CraftBukkit start - fire PlayerBedLeaveEvent + if (this.getBukkitEntity() instanceof Player) { + Player player = (Player) this.getBukkitEntity(); + + org.bukkit.block.Block bed; + BlockPosition blockposition = this.bx; + if (blockposition != null) { + bed = this.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } else { + bed = this.world.getWorld().getBlockAt(player.getLocation()); + } + + PlayerBedLeaveEvent event = new PlayerBedLeaveEvent(player, bed); + this.world.getServer().getPluginManager().callEvent(event); + } + // CraftBukkit end + + this.sleepTicks = flag ? 0 : 100; + if (flag2) { + this.setRespawnPosition(this.bx, false); + } + + } + + private boolean p() { + return this.world.getType(this.bx).getBlock() == Blocks.BED; + } + + // PaperSpigot start - SPIGOT-1387: Resolve bed issues on unloaded chunks + public static BlockPosition getBed(World world, BlockPosition blockposition, boolean flag) { + boolean before = ((WorldServer) world).chunkProviderServer.forceChunkLoad; + ((WorldServer) world).chunkProviderServer.forceChunkLoad = true; + final BlockPosition result = getBed0(world, blockposition, flag); + ((WorldServer) world).chunkProviderServer.forceChunkLoad = before; + return result; + } + + private static BlockPosition getBed0(World world, BlockPosition blockposition, boolean flag) { + // PaperSpigot end + ((ChunkProviderServer) world.chunkProvider).getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); // CraftBukkit + Block block = world.getType(blockposition).getBlock(); + + if (block != Blocks.BED) { + if (!flag) { + return null; + } else { + boolean flag1 = block.g(); + boolean flag2 = world.getType(blockposition.up()).getBlock().g(); + + return flag1 && flag2 ? blockposition : null; + } + } else { + return BlockBed.a(world, blockposition, 0); + } + } + + public boolean isSleeping() { + return this.sleeping; + } + + public boolean isDeeplySleeping() { + return this.sleeping && this.sleepTicks >= 100; + } + + public void b(IChatBaseComponent ichatbasecomponent) {} + + public BlockPosition getBed() { + return this.c; + } + + public boolean isRespawnForced() { + return this.d; + } + + public void setRespawnPosition(BlockPosition blockposition, boolean flag) { + if (blockposition != null) { + this.c = blockposition; + this.d = flag; + this.spawnWorld = this.world.worldData.getName(); // CraftBukkit + } else { + this.c = null; + this.d = false; + this.spawnWorld = ""; // CraftBukkit + } + + } + + public void b(Statistic statistic) { + this.a(statistic, 1); + } + + public void a(Statistic statistic, int i) {} + + public void a(Statistic statistic) {} + + public void bF() { + super.bF(); + this.b(StatisticList.u); + if (this.isSprinting()) { + this.applyExhaustion(world.spigotConfig.sprintExhaustion); // Spigot - Change to use configurable value + } else { + this.applyExhaustion(world.spigotConfig.walkExhaustion); // Spigot - Change to use configurable value + } + + } + + public void g(float f, float f1) { + double d0 = this.locX; + double d1 = this.locY; + double d2 = this.locZ; + + if (this.abilities.isFlying && this.vehicle == null) { + double d3 = this.motY; + float f2 = this.aM; + + this.aM = this.abilities.a() * (float) (this.isSprinting() ? 2 : 1); + super.g(f, f1); + this.motY = d3 * 0.6D; + this.aM = f2; + } else { + super.g(f, f1); + } + + this.checkMovement(this.locX - d0, this.locY - d1, this.locZ - d2); + } + + public float bI() { + return (float) this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue(); + } + + public void checkMovement(double d0, double d1, double d2) { + if (this.vehicle == null) { + int i; + + if (this.a(Material.WATER)) { + i = FastMath.round(MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 100.0F); + if (i > 0) { + this.a(StatisticList.p, i); + this.applyExhaustion(world.paperSpigotConfig.playerSwimmingExhaustion * (float) i * 0.01F); // PaperSpigot - Configurable swimming exhaustion + } + } else if (this.V()) { + i = FastMath.round(MathHelper.sqrt(d0 * d0 + d2 * d2) * 100.0F); + if (i > 0) { + this.a(StatisticList.l, i); + this.applyExhaustion(world.paperSpigotConfig.playerSwimmingExhaustion * (float) i * 0.01F); // PaperSpigot - Configurable swimming (diving) exhaustion + } + } else if (this.k_()) { + if (d1 > 0.0D) { + this.a(StatisticList.n, (int) FastMath.round(d1 * 100.0D)); + } + } else if (this.onGround) { + i = FastMath.round(MathHelper.sqrt(d0 * d0 + d2 * d2) * 100.0F); + if (i > 0) { + this.a(StatisticList.i, i); + if (this.isSprinting()) { + this.a(StatisticList.k, i); + this.applyExhaustion(0.099999994F * (float) i * 0.01F); + } else { + if (this.isSneaking()) { + this.a(StatisticList.j, i); + } + + this.applyExhaustion(0.01F * (float) i * 0.01F); + } + } + } else { + i = FastMath.round(MathHelper.sqrt(d0 * d0 + d2 * d2) * 100.0F); + if (i > 25) { + this.a(StatisticList.o, i); + } + } + + } + } + + private void l(double d0, double d1, double d2) { + if (this.vehicle != null) { + int i = FastMath.round(MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2) * 100.0F); + + if (i > 0) { + if (this.vehicle instanceof EntityMinecartAbstract) { + this.a(StatisticList.q, i); + if (this.e == null) { + this.e = new BlockPosition(this); + } else if (this.e.c(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)) >= 1000000.0D) { + this.b(AchievementList.q); + } + } else if (this.vehicle instanceof EntityBoat) { + this.a(StatisticList.r, i); + } else if (this.vehicle instanceof EntityPig) { + this.a(StatisticList.s, i); + } else if (this.vehicle instanceof EntityHorse) { + this.a(StatisticList.t, i); + } + } + } + + } + + public void e(float f, float f1) { + if (!this.abilities.canFly) { + if (f >= 2.0F) { + this.a(StatisticList.m, (int) FastMath.round((double) f * 100.0D)); + } + + super.e(f, f1); + } + } + + protected void X() { + if (!this.isSpectator()) { + super.X(); + } + + } + + protected String n(int i) { + return i > 4 ? "game.player.hurt.fall.big" : "game.player.hurt.fall.small"; + } + + public void a(EntityLiving entityliving) { + if (entityliving instanceof IMonster) { + this.b(AchievementList.s); + } + + EntityTypes.MonsterEggInfo entitytypes_monsteregginfo = EntityTypes.eggInfo.get(Integer.valueOf(EntityTypes.a(entityliving))); + + if (entitytypes_monsteregginfo != null) { + this.b(entitytypes_monsteregginfo.killEntityStatistic); + } + + } + + public void aA() { + if (!this.abilities.isFlying) { + super.aA(); + } + + } + + public ItemStack q(int i) { + return this.inventory.e(i); + } + + public void giveExp(int i) { + this.addScore(i); + int j = Integer.MAX_VALUE - this.expTotal; + + if (i > j) { + i = j; + } + + this.exp += (float) i / (float) this.getExpToLevel(); + + for (this.expTotal += i; this.exp >= 1.0F; this.exp /= (float) this.getExpToLevel()) { + this.exp = (this.exp - 1.0F) * (float) this.getExpToLevel(); + this.levelDown(1); + } + + } + + public int cj() { + return this.f; + } + + public void enchantDone(int i) { + this.expLevel -= i; + if (this.expLevel < 0) { + this.expLevel = 0; + this.exp = 0.0F; + this.expTotal = 0; + } + + this.f = this.random.nextInt(); + } + + public void levelDown(int i) { + this.expLevel += i; + if (this.expLevel < 0) { + this.expLevel = 0; + this.exp = 0.0F; + this.expTotal = 0; + } + + if (i > 0 && this.expLevel % 5 == 0 && (float) this.i < (float) this.ticksLived - 100.0F) { + float f = this.expLevel > 30 ? 1.0F : (float) this.expLevel / 30.0F; + + this.world.makeSound(this, "random.levelup", f * 0.75F, 1.0F); + this.i = this.ticksLived; + } + + } + + public int getExpToLevel() { + return this.expLevel >= 30 ? 112 + (this.expLevel - 30) * 9 : (this.expLevel >= 15 ? 37 + (this.expLevel - 15) * 5 : 7 + this.expLevel * 2); + } + + public void applyExhaustion(float f) { + if (!this.abilities.isInvulnerable) { + if (!this.world.isClientSide) { + this.foodData.a(f); + } + + } + } + + public FoodMetaData getFoodData() { + return this.foodData; + } + + public boolean j(boolean flag) { + return (flag || this.foodData.c()) && !this.abilities.isInvulnerable; + } + + public boolean cm() { + return this.getHealth() > 0.0F && this.getHealth() < this.getMaxHealth(); + } + + public void a(ItemStack itemstack, int i) { + if (itemstack != this.g) { + this.g = itemstack; + this.h = i; + if (!this.world.isClientSide) { + this.f(true); + } + + } + } + + public boolean cn() { + return this.abilities.mayBuild; + } + + public boolean a(BlockPosition blockposition, EnumDirection enumdirection, ItemStack itemstack) { + if (this.abilities.mayBuild) { + return true; + } else if (itemstack == null) { + return false; + } else { + BlockPosition blockposition1 = blockposition.shift(enumdirection.opposite()); + Block block = this.world.getType(blockposition1).getBlock(); + + return itemstack.d(block) || itemstack.x(); + } + } + + protected int getExpValue(EntityHuman entityhuman) { + if (this.world.getGameRules().getBoolean("keepInventory")) { + return 0; + } else { + int i = this.expLevel * 7; + + return i > 100 ? 100 : i; + } + } + + protected boolean alwaysGivesExp() { + return true; + } + + public void copyTo(EntityHuman entityhuman, boolean flag) { + if (flag) { + this.inventory.b(entityhuman.inventory); + this.setHealth(entityhuman.getHealth()); + this.foodData = entityhuman.foodData; + this.expLevel = entityhuman.expLevel; + this.expTotal = entityhuman.expTotal; + this.exp = entityhuman.exp; + this.setScore(entityhuman.getScore()); + this.an = entityhuman.an; + this.ao = entityhuman.ao; + this.ap = entityhuman.ap; + } else if (this.world.getGameRules().getBoolean("keepInventory")) { + this.inventory.b(entityhuman.inventory); + this.expLevel = entityhuman.expLevel; + this.expTotal = entityhuman.expTotal; + this.exp = entityhuman.exp; + this.setScore(entityhuman.getScore()); + } + + this.f = entityhuman.f; + this.enderChest = entityhuman.enderChest; + this.getDataWatcher().watch(10, Byte.valueOf(entityhuman.getDataWatcher().getByte(10))); + } + + protected boolean s_() { + return !this.abilities.isFlying; + } + + public void updateAbilities() {} + + public void a(WorldSettings.EnumGamemode worldsettings_enumgamemode) {} + + public String getName() { + return this.bH.getName(); + } + + public InventoryEnderChest getEnderChest() { + return this.enderChest; + } + + public ItemStack getEquipment(int i) { + return i == 0 ? this.inventory.getItemInHand() : this.inventory.armor[i - 1]; + } + + public ItemStack bA() { + return this.inventory.getItemInHand(); + } + + public void setEquipment(int i, ItemStack itemstack) { + ItemStack previous = this.inventory.armor[i]; + if (!Objects.equal(itemstack, previous)) { + if (previous != null && EquipmentSetEvent.getHandlerList().getRegisteredListeners().length > 0) { + previous = previous.cloneItemStack(); + } + this.inventory.armor[i] = itemstack; + Bukkit.getPluginManager().callEvent(new EquipmentSetEvent(getBukkitEntity(), i, CraftItemStack.asBukkitCopy(itemstack), CraftItemStack.asBukkitCopy(previous))); + } + } + + public abstract boolean isSpectator(); + + public ItemStack[] getEquipment() { + return this.inventory.armor; + } + + public boolean aL() { + return !this.abilities.isFlying; + } + + public Scoreboard getScoreboard() { + return this.world.getScoreboard(); + } + + public ScoreboardTeamBase getScoreboardTeam() { + return this.getScoreboard().getPlayerTeam(this.getName()); + } + + public IChatBaseComponent getScoreboardDisplayName() { + // CraftBukkit - todo: fun + ChatComponentText chatcomponenttext = new ChatComponentText(ScoreboardTeam.getPlayerDisplayName(this.getScoreboardTeam(), this.getName())); + + chatcomponenttext.getChatModifier().setChatClickable(new ChatClickable(ChatClickable.EnumClickAction.SUGGEST_COMMAND, "/msg " + this.getName() + " ")); + chatcomponenttext.getChatModifier().setChatHoverable(this.aQ()); + chatcomponenttext.getChatModifier().setInsertion(this.getName()); + return chatcomponenttext; + } + + public float getHeadHeight() { + float f = 1.62F; + + if (this.isSleeping()) { + f = 0.2F; + } + + if (this.isSneaking()) { + f -= 0.08F; + } + + return f; + } + + public void setAbsorptionHearts(float f) { + if (f < 0.0F) { + f = 0.0F; + } + + this.getDataWatcher().watch(17, Float.valueOf(f)); + } + + public float getAbsorptionHearts() { + return this.getDataWatcher().getFloat(17); + } + + public static UUID a(GameProfile gameprofile) { + UUID uuid = gameprofile.getId(); + + if (uuid == null) { + uuid = b(gameprofile.getName()); + } + + return uuid; + } + + public static UUID b(String s) { + return UUID.nameUUIDFromBytes(("OfflinePlayer:" + s).getBytes(Charsets.UTF_8)); + } + + public boolean a(ChestLock chestlock) { + if (chestlock.a()) { + return true; + } else { + ItemStack itemstack = this.bZ(); + + return (itemstack != null && itemstack.hasName()) && itemstack.getName().equals(chestlock.b()); + } + } + + public boolean getSendCommandFeedback() { + return MinecraftServer.getServer().worldServer[0].getGameRules().getBoolean("sendCommandFeedback"); + } + + public boolean d(int i, ItemStack itemstack) { + if (i >= 0 && i < this.inventory.items.length) { + this.inventory.setItem(i, itemstack); + return true; + } else { + int j = i - 100; + int k; + + if (j >= 0 && j < this.inventory.armor.length) { + k = j + 1; + if (itemstack != null && itemstack.getItem() != null) { + if (itemstack.getItem() instanceof ItemArmor) { + if (EntityInsentient.c(itemstack) != k) { + return false; + } + } else if (k != 4 || itemstack.getItem() != Items.SKULL && !(itemstack.getItem() instanceof ItemBlock)) { + return false; + } + } + + this.inventory.setItem(j + this.inventory.items.length, itemstack); + return true; + } else { + k = i - 200; + if (k >= 0 && k < this.enderChest.getSize()) { + this.enderChest.setItem(k, itemstack); + return true; + } else { + return false; + } + } + } + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + EntityHuman.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + } + + try { + EntityHuman.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + } + + try { + EntityHuman.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + } + + try { + EntityHuman.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + } + + } + } + + public enum EnumBedResult { + + OK, NOT_POSSIBLE_HERE, NOT_POSSIBLE_NOW, TOO_FAR_AWAY, OTHER_PROBLEM, NOT_SAFE; + + EnumBedResult() {} + } + + public enum EnumChatVisibility { + + FULL(0, "options.chat.visibility.full"), SYSTEM(1, "options.chat.visibility.system"), HIDDEN(2, "options.chat.visibility.hidden"); + + private static final EntityHuman.EnumChatVisibility[] d = new EntityHuman.EnumChatVisibility[values().length]; + private final int e; + private final String f; + + EnumChatVisibility(int i, String s) { + this.e = i; + this.f = s; + } + + public int a() { + return this.e; + } + + public static EntityHuman.EnumChatVisibility a(int i) { + return EntityHuman.EnumChatVisibility.d[i % EntityHuman.EnumChatVisibility.d.length]; + } + + static { + EntityHuman.EnumChatVisibility[] aentityhuman_enumchatvisibility = values(); + int i = aentityhuman_enumchatvisibility.length; + + for (int j = 0; j < i; ++j) { + EntityHuman.EnumChatVisibility entityhuman_enumchatvisibility = aentityhuman_enumchatvisibility[j]; + + EntityHuman.EnumChatVisibility.d[entityhuman_enumchatvisibility.e] = entityhuman_enumchatvisibility; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityInsentient.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityInsentient.java new file mode 100644 index 0000000..b82b984 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityInsentient.java @@ -0,0 +1,951 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; +import java.util.UUID; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.EntityUnleashEvent; +import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason; +// CraftBukkit end + +public abstract class EntityInsentient extends EntityLiving { + + public int a_; + protected int b_; + private ControllerLook lookController; + protected ControllerMove moveController; + protected ControllerJump g; + private EntityAIBodyControl b; + protected NavigationAbstract navigation; + public PathfinderGoalSelector goalSelector; + public PathfinderGoalSelector targetSelector; + private EntityLiving goalTarget; + private EntitySenses bk; + private ItemStack[] equipment = new ItemStack[5]; + public float[] dropChances = new float[5]; + public boolean canPickUpLoot; + public boolean persistent; + private boolean bo; + private Entity bp; + private NBTTagCompound bq; + public PathfinderGoalFloat goalFloat; // PaperSpigot + + public EntityInsentient(World world) { + super(world); + this.goalSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); + this.targetSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); + this.lookController = new ControllerLook(this); + this.moveController = new ControllerMove(this); + this.g = new ControllerJump(this); + this.b = new EntityAIBodyControl(this); + this.navigation = this.b(world); + this.bk = new EntitySenses(this); + + for (int i = 0; i < this.dropChances.length; ++i) { + this.dropChances[i] = 0.085F; + } + + // CraftBukkit start - default persistance to type's persistance value + this.persistent = !isTypeNotPersistent(); + // CraftBukkit end + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeMap().b(GenericAttributes.FOLLOW_RANGE).setValue(16.0D); + } + + protected NavigationAbstract b(World world) { + return new Navigation(this, world); + } + + public ControllerLook getControllerLook() { + return this.lookController; + } + + public ControllerMove getControllerMove() { + return this.moveController; + } + + public ControllerJump getControllerJump() { + return this.g; + } + + public NavigationAbstract getNavigation() { + return this.navigation; + } + + public EntitySenses getEntitySenses() { + return this.bk; + } + + public EntityLiving getGoalTarget() { + return this.goalTarget; + } + + public void setGoalTarget(EntityLiving entityliving) { + // CraftBukkit start - fire event + setGoalTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true); + } + + public void setGoalTarget(EntityLiving entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) { + if (getGoalTarget() == entityliving) return; + if (fireEvent) { + if (reason == EntityTargetEvent.TargetReason.UNKNOWN && getGoalTarget() != null && entityliving == null) { + reason = getGoalTarget().isAlive() ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED; + } + if (reason == EntityTargetEvent.TargetReason.UNKNOWN) { + world.getServer().getLogger().log(java.util.logging.Level.WARNING, "Unknown target reason, please report on the issue tracker", new Exception()); + } + CraftLivingEntity ctarget = null; + if (entityliving != null) { + ctarget = (CraftLivingEntity) entityliving.getBukkitEntity(); + } + EntityTargetLivingEntityEvent event = new EntityTargetLivingEntityEvent(this.getBukkitEntity(), ctarget, reason); + world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + + if (event.getTarget() != null) { + entityliving = ((CraftLivingEntity) event.getTarget()).getHandle(); + } else { + entityliving = null; + } + } + this.goalTarget = entityliving; + // CraftBukkit end + } + + public boolean a(Class oclass) { + return oclass != EntityGhast.class; + } + + public void v() {} + + protected void h() { + super.h(); + this.datawatcher.a(15, Byte.valueOf((byte) 0)); + } + + public int w() { + return 80; + } + + public void x() { + String s = this.z(); + + if (s != null) { + this.makeSound(s, this.bB(), this.bC()); + } + + } + + public void K() { + super.K(); + this.world.methodProfiler.a("mobBaseTick"); + if (this.isAlive() && this.random.nextInt(1000) < this.a_++) { + this.a_ = -this.w(); + this.x(); + } + + this.world.methodProfiler.b(); + } + + protected int getExpValue(EntityHuman entityhuman) { + if (this.b_ > 0) { + int i = this.b_; + ItemStack[] aitemstack = this.getEquipment(); + + for (int j = 0; j < aitemstack.length; ++j) { + if (aitemstack[j] != null && this.dropChances[j] <= 1.0F) { + i += 1 + this.random.nextInt(3); + } + } + + return i; + } else { + return this.b_; + } + } + + public void y() { + if (this.world.isClientSide) { + for (int i = 0; i < 20; ++i) { + double d0 = this.random.nextGaussian() * 0.02D; + double d1 = this.random.nextGaussian() * 0.02D; + 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]); + } + } else { + this.world.broadcastEntityEffect(this, (byte) 20); + } + + } + + public void t_() { + super.t_(); + if (!this.world.isClientSide) { + this.ca(); + } + + } + + protected float h(float f, float f1) { + this.b.a(); + return f1; + } + + protected String z() { + return null; + } + + protected Item getLoot() { + return null; + } + + protected ItemStack headDrop = null; // CraftBukkit + protected void dropDeathLoot(boolean flag, int i) { + Item item = this.getLoot(); + + if (item != null) { + int j = this.random.nextInt(3); + + if (i > 0) { + j += this.random.nextInt(i + 1); + } + + for (int k = 0; k < j; ++k) { + this.a(item, 1); + } + } + + // CraftBukkit start + if (headDrop != null) { + this.a(headDrop, 0.0F); + headDrop = null; + } + // CraftBukkit end + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setBoolean("CanPickUpLoot", this.bY()); + nbttagcompound.setBoolean("PersistenceRequired", this.persistent); + NBTTagList nbttaglist = new NBTTagList(); + + NBTTagCompound nbttagcompound1; + + for (int i = 0; i < this.equipment.length; ++i) { + nbttagcompound1 = new NBTTagCompound(); + if (this.equipment[i] != null) { + this.equipment[i].save(nbttagcompound1); + } + + nbttaglist.add(nbttagcompound1); + } + + nbttagcompound.set("Equipment", nbttaglist); + NBTTagList nbttaglist1 = new NBTTagList(); + + for (int j = 0; j < this.dropChances.length; ++j) { + nbttaglist1.add(new NBTTagFloat(this.dropChances[j])); + } + + nbttagcompound.set("DropChances", nbttaglist1); + nbttagcompound.setBoolean("Leashed", this.bo); + if (this.bp != null) { + nbttagcompound1 = new NBTTagCompound(); + if (this.bp instanceof EntityLiving) { + nbttagcompound1.setLong("UUIDMost", this.bp.getUniqueID().getMostSignificantBits()); + nbttagcompound1.setLong("UUIDLeast", this.bp.getUniqueID().getLeastSignificantBits()); + } else if (this.bp instanceof EntityHanging) { + BlockPosition blockposition = ((EntityHanging) this.bp).getBlockPosition(); + + nbttagcompound1.setInt("X", blockposition.getX()); + nbttagcompound1.setInt("Y", blockposition.getY()); + nbttagcompound1.setInt("Z", blockposition.getZ()); + } + + nbttagcompound.set("Leash", nbttagcompound1); + } + + if (this.ce()) { + nbttagcompound.setBoolean("NoAI", this.ce()); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + + // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it + if (nbttagcompound.hasKeyOfType("CanPickUpLoot", 1)) { + boolean data = nbttagcompound.getBoolean("CanPickUpLoot"); + if (isLevelAtLeast(nbttagcompound, 1) || data) { + this.j(data); + } + } + + boolean data = nbttagcompound.getBoolean("PersistenceRequired"); + if (isLevelAtLeast(nbttagcompound, 1) || data) { + this.persistent = data; + } + // CraftBukkit end + NBTTagList nbttaglist; + int i; + + if (nbttagcompound.hasKeyOfType("Equipment", 9)) { + nbttaglist = nbttagcompound.getList("Equipment", 10); + + for (i = 0; i < this.equipment.length; ++i) { + this.equipment[i] = ItemStack.createStack(nbttaglist.get(i)); + } + } + + if (nbttagcompound.hasKeyOfType("DropChances", 9)) { + nbttaglist = nbttagcompound.getList("DropChances", 5); + + for (i = 0; i < nbttaglist.size(); ++i) { + this.dropChances[i] = nbttaglist.e(i); + } + } + + this.bo = nbttagcompound.getBoolean("Leashed"); + if (this.bo && nbttagcompound.hasKeyOfType("Leash", 10)) { + this.bq = nbttagcompound.getCompound("Leash"); + } + + this.k(nbttagcompound.getBoolean("NoAI")); + } + + public void n(float f) { + this.ba = f; + } + + public void k(float f) { + super.k(f); + this.n(f); + } + + public void m() { + super.m(); + this.world.methodProfiler.a("looting"); + if (!this.world.isClientSide && this.bY() && !this.aP && this.world.getGameRules().getBoolean("mobGriefing")) { + List list = this.world.a(EntityItem.class, this.getBoundingBox().grow(1.0D, 0.0D, 1.0D)); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityItem entityitem = (EntityItem) iterator.next(); + + if (!entityitem.dead && entityitem.getItemStack() != null && !entityitem.s()) { + this.a(entityitem); + } + } + } + + this.world.methodProfiler.b(); + } + + protected void a(EntityItem entityitem) { + ItemStack itemstack = entityitem.getItemStack(); + int i = c(itemstack); + + if (i > -1) { + boolean flag = true; + ItemStack itemstack1 = this.getEquipment(i); + + if (itemstack1 != null) { + if (i == 0) { + if (itemstack.getItem() instanceof ItemSword && !(itemstack1.getItem() instanceof ItemSword)) { + flag = true; + } else if (itemstack.getItem() instanceof ItemSword && itemstack1.getItem() instanceof ItemSword) { + ItemSword itemsword = (ItemSword) itemstack.getItem(); + ItemSword itemsword1 = (ItemSword) itemstack1.getItem(); + + if (itemsword.g() == itemsword1.g()) { + flag = itemstack.getData() > itemstack1.getData() || itemstack.hasTag() && !itemstack1.hasTag(); + } else { + flag = itemsword.g() > itemsword1.g(); + } + } else if (itemstack.getItem() instanceof ItemBow && itemstack1.getItem() instanceof ItemBow) { + flag = itemstack.hasTag() && !itemstack1.hasTag(); + } else { + flag = false; + } + } else if (itemstack.getItem() instanceof ItemArmor && !(itemstack1.getItem() instanceof ItemArmor)) { + flag = true; + } else if (itemstack.getItem() instanceof ItemArmor && itemstack1.getItem() instanceof ItemArmor) { + ItemArmor itemarmor = (ItemArmor) itemstack.getItem(); + ItemArmor itemarmor1 = (ItemArmor) itemstack1.getItem(); + + if (itemarmor.c == itemarmor1.c) { + flag = itemstack.getData() > itemstack1.getData() || itemstack.hasTag() && !itemstack1.hasTag(); + } else { + flag = itemarmor.c > itemarmor1.c; + } + } else { + flag = false; + } + } + + if (flag && this.a(itemstack)) { + if (itemstack1 != null && this.random.nextFloat() - 0.1F < this.dropChances[i]) { + this.a(itemstack1, 0.0F); + } + + if (itemstack.getItem() == Items.DIAMOND && entityitem.n() != null) { + EntityHuman entityhuman = this.world.a(entityitem.n()); + + if (entityhuman != null) { + entityhuman.b((Statistic) AchievementList.x); + } + } + + this.setEquipment(i, itemstack); + this.dropChances[i] = 2.0F; + this.persistent = true; + this.receive(entityitem, 1); + entityitem.die(); + } + } + + } + + protected boolean a(ItemStack itemstack) { + return true; + } + + protected boolean isTypeNotPersistent() { + return true; + } + + protected void D() { + if (this.persistent) { + this.ticksFarFromPlayer = 0; + } else { + EntityHuman entityhuman = this.world.findNearbyPlayerWhoAffectsSpawning(this, -1.0D); // PaperSpigot - Affects Spawning API + + if (entityhuman != null) { + double d0 = entityhuman.locX - this.locX; + double d1 = entityhuman.locY - this.locY; + double d2 = entityhuman.locZ - this.locZ; + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + if (d3 > this.world.paperSpigotConfig.hardDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // PaperSpigot - custom despawn distances + this.die(); + } + + if (this.ticksFarFromPlayer > 600 && this.random.nextInt(800) == 0 && d3 > this.world.paperSpigotConfig.softDespawnDistance) { // CraftBukkit - remove isTypeNotPersistent() check // PaperSpigot - custom despawn distance + this.die(); + } else if (d3 < this.world.paperSpigotConfig.softDespawnDistance) { // PaperSpigot - custom despawn distances + this.ticksFarFromPlayer = 0; + } + } + + } + } + + protected final void doTick() { + ++this.ticksFarFromPlayer; + this.world.methodProfiler.a("checkDespawn"); + this.D(); + this.world.methodProfiler.b(); + // Spigot Start + if ( this.fromMobSpawner ) + { + // PaperSpigot start - Allow nerfed mobs to jump + if (goalFloat != null) { + if (goalFloat.a()) goalFloat.e(); + this.g.b(); + } + // PaperSpigot end + return; + } + // Spigot End + this.world.methodProfiler.a("sensing"); + this.bk.a(); + this.world.methodProfiler.b(); + this.world.methodProfiler.a("targetSelector"); + this.targetSelector.a(); + this.world.methodProfiler.b(); + this.world.methodProfiler.a("goalSelector"); + this.goalSelector.a(); + this.world.methodProfiler.b(); + this.world.methodProfiler.a("navigation"); + this.navigation.k(); + this.world.methodProfiler.b(); + this.world.methodProfiler.a("mob tick"); + this.E(); + this.world.methodProfiler.b(); + this.world.methodProfiler.a("controls"); + this.world.methodProfiler.a("move"); + this.moveController.c(); + this.world.methodProfiler.c("look"); + this.lookController.a(); + this.world.methodProfiler.c("jump"); + this.g.b(); + this.world.methodProfiler.b(); + this.world.methodProfiler.b(); + } + + protected void E() {} + + public int bQ() { + return 40; + } + + public void a(Entity entity, float f, float f1) { + double d0 = entity.locX - this.locX; + double d1 = entity.locZ - this.locZ; + double d2; + + if (entity instanceof EntityLiving) { + EntityLiving entityliving = (EntityLiving) entity; + + d2 = entityliving.locY + (double) entityliving.getHeadHeight() - (this.locY + (double) this.getHeadHeight()); + } else { + d2 = (entity.getBoundingBox().b + entity.getBoundingBox().e) / 2.0D - (this.locY + (double) this.getHeadHeight()); + } + + double d3 = (double) MathHelper.sqrt(d0 * d0 + d1 * d1); + float f2 = (float) (MathHelper.b(d1, d0) * 180.0D / 3.1415927410125732D) - 90.0F; + float f3 = (float) (-(MathHelper.b(d2, d3) * 180.0D / 3.1415927410125732D)); + + this.pitch = this.b(this.pitch, f3, f1); + this.yaw = this.b(this.yaw, f2, f); + } + + private float b(float f, float f1, float f2) { + float f3 = MathHelper.g(f1 - f); + + if (f3 > f2) { + f3 = f2; + } + + if (f3 < -f2) { + f3 = -f2; + } + + return f + f3; + } + + public boolean bR() { + return true; + } + + public boolean canSpawn() { + return this.world.a(this.getBoundingBox(), (Entity) this) && this.world.getCubes(this, this.getBoundingBox()).isEmpty() && !this.world.containsLiquid(this.getBoundingBox()); + } + + public int bV() { + return 4; + } + + public int aE() { + if (this.getGoalTarget() == null) { + return 3; + } else { + int i = (int) (this.getHealth() - this.getMaxHealth() * 0.33F); + + i -= (3 - this.world.getDifficulty().a()) * 4; + if (i < 0) { + i = 0; + } + + return i + 3; + } + } + + public ItemStack bA() { + return this.equipment[0]; + } + + public ItemStack getEquipment(int i) { + return this.equipment[i]; + } + + public ItemStack q(int i) { + return this.equipment[i + 1]; + } + + public void setEquipment(int i, ItemStack itemstack) { + this.equipment[i] = itemstack; + } + + public ItemStack[] getEquipment() { + return this.equipment; + } + + protected void dropEquipment(boolean flag, int i) { + for (int j = 0; j < this.getEquipment().length; ++j) { + ItemStack itemstack = this.getEquipment(j); + boolean flag1 = this.dropChances[j] > 1.0F; + + if (itemstack != null && (flag || flag1) && this.random.nextFloat() - (float) i * 0.01F < this.dropChances[j]) { + if (!flag1 && itemstack.e()) { + int k = Math.max(itemstack.j() - 25, 1); + int l = itemstack.j() - this.random.nextInt(this.random.nextInt(k) + 1); + + if (l > k) { + l = k; + } + + if (l < 1) { + l = 1; + } + + itemstack.setData(l); + } + + this.a(itemstack, 0.0F); + } + } + + } + + protected void a(DifficultyDamageScaler difficultydamagescaler) { + if (this.random.nextFloat() < 0.15F * difficultydamagescaler.c()) { + int i = this.random.nextInt(2); + float f = this.world.getDifficulty() == EnumDifficulty.HARD ? 0.1F : 0.25F; + + if (this.random.nextFloat() < 0.095F) { + ++i; + } + + if (this.random.nextFloat() < 0.095F) { + ++i; + } + + if (this.random.nextFloat() < 0.095F) { + ++i; + } + + for (int j = 3; j >= 0; --j) { + ItemStack itemstack = this.q(j); + + if (j < 3 && this.random.nextFloat() < f) { + break; + } + + if (itemstack == null) { + Item item = a(j + 1, i); + + if (item != null) { + this.setEquipment(j + 1, new ItemStack(item)); + } + } + } + } + + } + + public static int c(ItemStack itemstack) { + if (itemstack.getItem() != Item.getItemOf(Blocks.PUMPKIN) && itemstack.getItem() != Items.SKULL) { + if (itemstack.getItem() instanceof ItemArmor) { + switch (((ItemArmor) itemstack.getItem()).b) { + case 0: + return 4; + + case 1: + return 3; + + case 2: + return 2; + + case 3: + return 1; + } + } + + return 0; + } else { + return 4; + } + } + + public static Item a(int i, int j) { + switch (i) { + case 4: + if (j == 0) { + return Items.LEATHER_HELMET; + } else if (j == 1) { + return Items.GOLDEN_HELMET; + } else if (j == 2) { + return Items.CHAINMAIL_HELMET; + } else if (j == 3) { + return Items.IRON_HELMET; + } else if (j == 4) { + return Items.DIAMOND_HELMET; + } + + case 3: + if (j == 0) { + return Items.LEATHER_CHESTPLATE; + } else if (j == 1) { + return Items.GOLDEN_CHESTPLATE; + } else if (j == 2) { + return Items.CHAINMAIL_CHESTPLATE; + } else if (j == 3) { + return Items.IRON_CHESTPLATE; + } else if (j == 4) { + return Items.DIAMOND_CHESTPLATE; + } + + case 2: + if (j == 0) { + return Items.LEATHER_LEGGINGS; + } else if (j == 1) { + return Items.GOLDEN_LEGGINGS; + } else if (j == 2) { + return Items.CHAINMAIL_LEGGINGS; + } else if (j == 3) { + return Items.IRON_LEGGINGS; + } else if (j == 4) { + return Items.DIAMOND_LEGGINGS; + } + + case 1: + if (j == 0) { + return Items.LEATHER_BOOTS; + } else if (j == 1) { + return Items.GOLDEN_BOOTS; + } else if (j == 2) { + return Items.CHAINMAIL_BOOTS; + } else if (j == 3) { + return Items.IRON_BOOTS; + } else if (j == 4) { + return Items.DIAMOND_BOOTS; + } + + default: + return null; + } + } + + protected void b(DifficultyDamageScaler difficultydamagescaler) { + float f = difficultydamagescaler.c(); + + if (this.bA() != null && this.random.nextFloat() < 0.25F * f) { + EnchantmentManager.a(this.random, this.bA(), (int) (5.0F + f * (float) this.random.nextInt(18))); + } + + for (int i = 0; i < 4; ++i) { + ItemStack itemstack = this.q(i); + + if (itemstack != null && this.random.nextFloat() < 0.5F * f) { + EnchantmentManager.a(this.random, itemstack, (int) (5.0F + f * (float) this.random.nextInt(18))); + } + } + + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).b(new AttributeModifier("Random spawn bonus", this.random.nextGaussian() * 0.05D, 1)); + return groupdataentity; + } + + public boolean bW() { + return false; + } + + public void bX() { + this.persistent = true; + } + + public void a(int i, float f) { + this.dropChances[i] = f; + } + + public boolean bY() { + return this.canPickUpLoot; + } + + public void j(boolean flag) { + this.canPickUpLoot = flag; + } + + public boolean isPersistent() { + return this.persistent; + } + + public final boolean e(EntityHuman entityhuman) { + if (this.cc() && this.getLeashHolder() == entityhuman) { + // CraftBukkit start - fire PlayerUnleashEntityEvent + if (CraftEventFactory.callPlayerUnleashEntityEvent(this, entityhuman).isCancelled()) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder())); + return false; + } + // CraftBukkit end + this.unleash(true, !entityhuman.abilities.canInstantlyBuild); + return true; + } else { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.LEAD && this.cb()) { + if (!(this instanceof EntityTameableAnimal) || !((EntityTameableAnimal) this).isTamed()) { + // CraftBukkit start - fire PlayerLeashEntityEvent + if (CraftEventFactory.callPlayerLeashEntityEvent(this, entityhuman, entityhuman).isCancelled()) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder())); + return false; + } + // CraftBukkit end + this.setLeashHolder(entityhuman, true); + --itemstack.count; + return true; + } + + if (((EntityTameableAnimal) this).e((EntityLiving) entityhuman)) { + // CraftBukkit start - fire PlayerLeashEntityEvent + if (CraftEventFactory.callPlayerLeashEntityEvent(this, entityhuman, entityhuman).isCancelled()) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this, this.getLeashHolder())); + return false; + } + // CraftBukkit end + this.setLeashHolder(entityhuman, true); + --itemstack.count; + return true; + } + } + + return this.a(entityhuman) ? true : super.e(entityhuman); + } + } + + protected boolean a(EntityHuman entityhuman) { + return false; + } + + protected void ca() { + if (this.bq != null) { + this.n(); + } + + if (this.bo) { + if (!this.isAlive()) { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.PLAYER_UNLEASH)); // CraftBukkit + this.unleash(true, true); + } + + if (this.bp == null || this.bp.dead) { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.HOLDER_GONE)); // CraftBukkit + this.unleash(true, true); + } + } + } + + public void unleash(boolean flag, boolean flag1) { + if (this.bo) { + this.bo = false; + this.bp = null; + if (!this.world.isClientSide && flag1) { + this.a(Items.LEAD, 1); + } + + if (!this.world.isClientSide && flag && this.world instanceof WorldServer) { + ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAttachEntity(1, this, (Entity) null))); + } + } + + } + + public boolean cb() { + return !this.cc() && !(this instanceof IMonster); + } + + public boolean cc() { + return this.bo; + } + + public Entity getLeashHolder() { + return this.bp; + } + + public void setLeashHolder(Entity entity, boolean flag) { + this.bo = true; + this.bp = entity; + if (!this.world.isClientSide && flag && this.world instanceof WorldServer) { + ((WorldServer) this.world).getTracker().a((Entity) this, (Packet) (new PacketPlayOutAttachEntity(1, this, this.bp))); + } + + } + + private void n() { + if (this.bo && this.bq != null) { + if (this.bq.hasKeyOfType("UUIDMost", 4) && this.bq.hasKeyOfType("UUIDLeast", 4)) { + UUID uuid = new UUID(this.bq.getLong("UUIDMost"), this.bq.getLong("UUIDLeast")); + List list = this.world.a(EntityLiving.class, this.getBoundingBox().grow(10.0D, 10.0D, 10.0D)); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityLiving entityliving = (EntityLiving) iterator.next(); + + if (entityliving.getUniqueID().equals(uuid)) { + this.bp = entityliving; + break; + } + } + } else if (this.bq.hasKeyOfType("X", 99) && this.bq.hasKeyOfType("Y", 99) && this.bq.hasKeyOfType("Z", 99)) { + BlockPosition blockposition = new BlockPosition(this.bq.getInt("X"), this.bq.getInt("Y"), this.bq.getInt("Z")); + EntityLeash entityleash = EntityLeash.b(this.world, blockposition); + + if (entityleash == null) { + entityleash = EntityLeash.a(this.world, blockposition); + } + + this.bp = entityleash; + } else { + this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit + this.unleash(false, true); + } + } + + this.bq = null; + } + + public boolean d(int i, ItemStack itemstack) { + int j; + + if (i == 99) { + j = 0; + } else { + j = i - 100 + 1; + if (j < 0 || j >= this.equipment.length) { + return false; + } + } + + if (itemstack != null && c(itemstack) != j && (j != 4 || !(itemstack.getItem() instanceof ItemBlock))) { + return false; + } else { + this.setEquipment(j, itemstack); + return true; + } + } + + public boolean bM() { + return super.bM() && !this.ce(); + } + + public void k(boolean flag) { + this.datawatcher.watch(15, Byte.valueOf((byte) (flag ? 1 : 0))); + } + + public boolean ce() { + return this.datawatcher.getByte(15) != 0; + } + + public static enum EnumEntityPositionType { + + ON_GROUND, IN_AIR, IN_WATER; + + private EnumEntityPositionType() {} + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityIronGolem.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityIronGolem.java new file mode 100644 index 0000000..eeea090 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityIronGolem.java @@ -0,0 +1,228 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; + +public class EntityIronGolem extends EntityGolem { + + private int b; + Village a; + private int c; + private int bm; + + public EntityIronGolem(World world) { + super(world); + this.setSize(1.4F, 2.9F); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, true)); + this.goalSelector.a(2, new PathfinderGoalMoveTowardsTarget(this, 0.9D, 32.0F)); + this.goalSelector.a(3, new PathfinderGoalMoveThroughVillage(this, 0.6D, true)); + this.goalSelector.a(4, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); + this.goalSelector.a(5, new PathfinderGoalOfferFlower(this)); + this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, 0.6D)); + this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(1, new PathfinderGoalDefendVillage(this)); + this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, false)); + this.targetSelector.a(3, new EntityIronGolem.PathfinderGoalNearestGolemTarget(this, EntityInsentient.class, 10, false, true, IMonster.e)); + } + + protected void h() { + super.h(); + this.datawatcher.a(16, Byte.valueOf((byte) 0)); + } + + protected void E() { + if (--this.b <= 0) { + this.b = 70 + this.random.nextInt(50); + this.a = this.world.ae().getClosestVillage(new BlockPosition(this), 32); + if (this.a == null) { + this.cj(); + } else { + BlockPosition blockposition = this.a.a(); + + this.a(blockposition, (int) ((float) this.a.b() * 0.6F)); + } + } + + super.E(); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(100.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); + } + + protected int j(int i) { + return i; + } + + protected void s(Entity entity) { + if (entity instanceof IMonster && !(entity instanceof EntityCreeper) && this.bc().nextInt(20) == 0) { + this.setGoalTarget((EntityLiving) entity, org.bukkit.event.entity.EntityTargetLivingEntityEvent.TargetReason.COLLISION, true); // CraftBukkit - set reason + } + + super.s(entity); + } + + public void m() { + super.m(); + if (this.c > 0) { + --this.c; + } + + if (this.bm > 0) { + --this.bm; + } + + if (this.motX * this.motX + this.motZ * this.motZ > 2.500000277905201E-7D && this.random.nextInt(5) == 0) { + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY - 0.20000000298023224D); + int k = MathHelper.floor(this.locZ); + IBlockData iblockdata = this.world.getType(i, j, k); + Block block = iblockdata.getBlock(); + + if (block.getMaterial() != Material.AIR) { + this.world.addParticle(EnumParticle.BLOCK_CRACK, this.locX + ((double) this.random.nextFloat() - 0.5D) * (double) this.width, this.getBoundingBox().b + 0.1D, this.locZ + ((double) this.random.nextFloat() - 0.5D) * (double) this.width, 4.0D * ((double) this.random.nextFloat() - 0.5D), 0.5D, ((double) this.random.nextFloat() - 0.5D) * 4.0D, Block.getCombinedId(iblockdata)); + } + } + + } + + public boolean a(Class oclass) { + return (!this.isPlayerCreated() || !EntityHuman.class.isAssignableFrom(oclass)) && (oclass != EntityCreeper.class && super.a(oclass)); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setBoolean("PlayerCreated", this.isPlayerCreated()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setPlayerCreated(nbttagcompound.getBoolean("PlayerCreated")); + } + + public boolean r(Entity entity) { + this.c = 10; + this.world.broadcastEntityEffect(this, (byte) 4); + boolean flag = entity.damageEntity(DamageSource.mobAttack(this), (float) (7 + this.random.nextInt(15))); + + if (flag) { + entity.motY += 0.4000000059604645D; + this.a(this, entity); + } + + this.makeSound("mob.irongolem.throw", 1.0F, 1.0F); + return flag; + } + + public Village n() { + return this.a; + } + + public void a(boolean flag) { + this.bm = flag ? 400 : 0; + this.world.broadcastEntityEffect(this, (byte) 11); + } + + protected String bo() { + return "mob.irongolem.hit"; + } + + protected String bp() { + return "mob.irongolem.death"; + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.irongolem.walk", 1.0F, 1.0F); + } + + protected void dropDeathLoot(boolean flag, int i) { + int j = this.random.nextInt(3); + + int k; + + for (k = 0; k < j; ++k) { + this.a(Item.getItemOf(Blocks.RED_FLOWER), 1, (float) BlockFlowers.EnumFlowerVarient.POPPY.b()); + } + + k = 3 + this.random.nextInt(3); + + for (int l = 0; l < k; ++l) { + this.a(Items.IRON_INGOT, 1); + } + + } + + public int cm() { + return this.bm; + } + + public boolean isPlayerCreated() { + return (this.datawatcher.getByte(16) & 1) != 0; + } + + public void setPlayerCreated(boolean flag) { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1))); + } else { + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2))); + } + + } + + public void die(DamageSource damagesource) { + if (!this.isPlayerCreated() && this.killer != null && this.a != null) { + this.a.a(this.killer.getName(), -5); + } + + super.die(damagesource); + } + + static class PathfinderGoalNearestGolemTarget extends PathfinderGoalNearestAttackableTarget { + + public PathfinderGoalNearestGolemTarget(final EntityCreature entitycreature, Class oclass, int i, boolean flag, boolean flag1, final Predicate predicate) { + super(entitycreature, oclass, i, flag, flag1, predicate); + this.c = new Predicate() { + public boolean a(T t0) { + if (predicate != null && !predicate.apply(t0)) { + return false; + } else if (t0 instanceof EntityCreeper) { + return false; + } else { + if (t0 instanceof EntityHuman) { + double d0 = PathfinderGoalNearestGolemTarget.this.f(); + + if (t0.isSneaking()) { + d0 *= 0.800000011920929D; + } + + if (t0.isInvisible()) { + float f = ((EntityHuman) t0).bY(); + + if (f < 0.1F) { + f = 0.1F; + } + + d0 *= 0.7F * f; + } + + if ((double) t0.g(entitycreature) > d0) { + return false; + } + } + + return PathfinderGoalNearestGolemTarget.this.a(t0, false); + } + } + + public boolean apply(Object object) { + return this.a((T) object); // CraftBukkit - fix decompiler error + } + }; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityItem.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityItem.java new file mode 100644 index 0000000..217e432 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityItem.java @@ -0,0 +1,506 @@ +package net.minecraft.server; + +import me.levansj01.mythicspigot.MythicConfiguration; +import net.techcable.tacospigot.HopperPusher; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.event.player.PlayerPickupItemEvent; + +import java.util.Iterator; + +// TacoSpigot start - implement HopperPusher +public class EntityItem extends Entity implements HopperPusher { + @Override + public boolean acceptItem(TileEntityHopper hopper) { + return TileEntityHopper.a(hopper, this); + } + // TacoSpigot end + + private static final Logger b = LogManager.getLogger(); + private int age; + public int pickupDelay; + private int e; + private String f; + private String g; + public float a; + private int lastTick = MinecraftServer.currentTick; // CraftBukkit + public Entity dropper; // Mythic - Hide items for practice + + public EntityItem(World world, double d0, double d1, double d2) { + super(world); + this.e = 5; + this.a = (float) (Math.random() * 3.141592653589793D * 2.0D); + this.setSize(0.25F, 0.25F); + this.setPosition(d0, d1, d2); + this.yaw = (float) (Math.random() * 360.0D); + this.motX = (float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D); + this.motY = 0.20000000298023224D; + this.motZ = (float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D); + } + + public EntityItem(World world, double d0, double d1, double d2, ItemStack itemstack) { + this(world, d0, d1, d2); + // CraftBukkit start - Can't set null items in the datawatcher + if (itemstack == null || itemstack.getItem() == null) { + return; + } + // CraftBukkit end + this.setItemStack(itemstack); + } + + public EntityItem(World world, double d0, double d1, double d2, ItemStack itemStack, Entity owner) { + this(world, d0, d1, d2, itemStack); + this.dropper = owner; + } + + protected boolean s_() { + return false; + } + + public EntityItem(World world) { + super(world); + this.e = 5; + this.a = (float) (Math.random() * 3.141592653589793D * 2.0D); + this.setSize(0.25F, 0.25F); + this.setItemStack(new ItemStack(Blocks.AIR, 0)); + } + + protected void h() { + this.getDataWatcher().add(10, 5); + } + + public void t_() { + if (this.getItemStack() == null) { + this.die(); + } else { + super.t_(); + if (tryPutInHopper()) return; // TacoSpigot + // CraftBukkit start - Use wall time for pickup and despawn timers + int elapsedTicks = MinecraftServer.currentTick - this.lastTick; + if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; + if (this.age != -32768) this.age += elapsedTicks; + this.lastTick = MinecraftServer.currentTick; + // CraftBukkit end + + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + this.motY -= 0.03999999910593033D; + this.noclip = this.j(this.locX, (this.getBoundingBox().b + this.getBoundingBox().e) / 2.0D, this.locZ); + this.move(this.motX, this.motY, this.motZ); + boolean flag = (int) this.lastX != (int) this.locX || (int) this.lastY != (int) this.locY || (int) this.lastZ != (int) this.locZ; + + if (flag || this.ticksLived % 25 == 0) { + if (this.world.getType(new BlockPosition(this)).getBlock().getMaterial() == Material.LAVA) { + this.motY = 0.20000000298023224D; + this.motX = (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; + this.motZ = (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; + this.makeSound("random.fizz", 0.4F, 2.0F + this.random.nextFloat() * 0.4F); + } + + if (!this.world.isClientSide) { + this.w(); + } + } + + float f = 0.98F; + + if (this.onGround) { + f = this.world.getType(MathHelper.floor(this.locX), MathHelper.floor(this.getBoundingBox().b) - 1, MathHelper.floor(this.locZ)).getBlock().frictionFactor * 0.98F; + } + + this.motX *= f; + this.motY *= 0.9800000190734863D; + this.motZ *= f; + if (this.onGround) { + this.motY *= -0.5D; + } + + /* Craftbukkit start - moved up + if (this.age != -32768) { + ++this.age; + } + // Craftbukkit end */ + + + this.W(); + if (!this.world.isClientSide && this.age >= world.spigotConfig.itemDespawnRate) { // Spigot + // CraftBukkit start - fire ItemDespawnEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { + this.age = 0; + return; + } + // CraftBukkit end + this.die(); + } + + } + } + + // Spigot start - copied from above + @Override + public void inactiveTick() { + if (tryPutInHopper()) return; // TacoSpigot + // CraftBukkit end + // CraftBukkit start - Use wall time for pickup and despawn timers + int elapsedTicks = MinecraftServer.currentTick - this.lastTick; + if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks; + if (this.age != -32768) this.age += elapsedTicks; + this.lastTick = MinecraftServer.currentTick; + // CraftBukkit end + + if (!this.world.isClientSide && this.age >= world.spigotConfig.itemDespawnRate) { // Spigot + // CraftBukkit start - fire ItemDespawnEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) { + this.age = 0; + return; + } + // CraftBukkit end + this.die(); + } + } + // Spigot end + + private void w() { + // Spigot start + double radius = world.spigotConfig.itemMerge; + Iterator iterator = this.world.a(EntityItem.class, this.getBoundingBox().grow(radius, radius, radius)).iterator(); + // Spigot end + + while (iterator.hasNext()) { + EntityItem entityitem = (EntityItem) iterator.next(); + + this.a(entityitem); + } + + } + + private boolean a(EntityItem entityitem) { + if (entityitem == this) { + return false; + } else if (entityitem.isAlive() && this.isAlive()) { + // Mythic - Hide items for practice + if(MythicConfiguration.Options.Tracking.Hide.items && entityitem.dropper != dropper) return false; + + ItemStack itemstack = this.getItemStack(); + ItemStack itemstack1 = entityitem.getItemStack(); + + if (this.pickupDelay != 32767 && entityitem.pickupDelay != 32767) { + if (this.age != -32768 && entityitem.age != -32768) { + if (itemstack1.getItem() != itemstack.getItem()) { + return false; + } else if (itemstack1.hasTag() ^ itemstack.hasTag()) { + return false; + } else if (itemstack1.hasTag() && !itemstack1.getTag().equals(itemstack.getTag())) { + return false; + } else if (itemstack1.getItem() == null) { + return false; + } else if (itemstack1.getItem().k() && itemstack1.getData() != itemstack.getData()) { + return false; + } else if (itemstack1.count < itemstack.count) { + return entityitem.a(this); + } else if (itemstack1.count + itemstack.count > itemstack1.getMaxStackSize()) { + return false; + } else { + // Spigot start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemMergeEvent(entityitem, this).isCancelled()) return false; // CraftBukkit + itemstack.count += itemstack1.count; + this.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay); + this.age = Math.min(entityitem.age, this.age); + this.setItemStack(itemstack); + entityitem.die(); + // Spigot end + return true; + } + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } + + public void j() { + this.age = 4800; + } + + public boolean W() { + if (this.world.a(this.getBoundingBox(), Material.WATER, this)) { + if (!this.inWater && !this.justCreated) { + this.X(); + } + + this.inWater = true; + } else { + this.inWater = false; + } + + return this.inWater; + } + + protected void burn(int i) { + this.damageEntity(DamageSource.FIRE, (float) i); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else if (this.getItemStack() != null && this.getItemStack().getItem() == Items.NETHER_STAR && damagesource.isExplosion()) { + return false; + } else { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) { + return false; + } + // CraftBukkit end + this.ac(); + this.e = (int) ((float) this.e - f); + if (this.e <= 0) { + this.die(); + } + + return false; + } + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setShort("Health", (byte) this.e); + nbttagcompound.setShort("Age", (short) this.age); + nbttagcompound.setShort("PickupDelay", (short) this.pickupDelay); + if (this.n() != null) { + nbttagcompound.setString("Thrower", this.f); + } + + if (this.m() != null) { + nbttagcompound.setString("Owner", this.g); + } + + if (this.getItemStack() != null) { + nbttagcompound.set("Item", this.getItemStack().save(new NBTTagCompound())); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + this.e = nbttagcompound.getShort("Health") & 255; + this.age = nbttagcompound.getShort("Age"); + if (nbttagcompound.hasKey("PickupDelay")) { + this.pickupDelay = nbttagcompound.getShort("PickupDelay"); + } + + if (nbttagcompound.hasKey("Owner")) { + this.g = nbttagcompound.getString("Owner"); + } + + if (nbttagcompound.hasKey("Thrower")) { + this.f = nbttagcompound.getString("Thrower"); + } + + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Item"); + + // CraftBukkit start - Handle missing "Item" compounds + if (nbttagcompound1 != null) { + ItemStack itemstack = ItemStack.createStack(nbttagcompound1); + if (itemstack != null) { + this.setItemStack(itemstack); + } else { + this.die(); + } + } else { + this.die(); + } + // CraftBukkit end + if (this.getItemStack() == null) { + this.die(); + } + + } + + public void d(EntityHuman entityhuman) { + if (!this.world.isClientSide) { + ItemStack itemstack = this.getItemStack(); + int i = itemstack.count; + + // Mythic - Hide items for practice +// if(dropper instanceof EntityPlayer && entityhuman instanceof EntityPlayer && MythicConfiguration.Options.Tracking.Hide.items) { +// EntityPlayer droppedPlayer = (EntityPlayer) dropper, pickupPlayer = (EntityPlayer) entityhuman; +// if(!droppedPlayer.getBukkitEntity().canSee(pickupPlayer.getBukkitEntity())) { +// return; +// } +// } + + // CraftBukkit start - fire PlayerPickupItemEvent + int canHold = entityhuman.inventory.canHold(itemstack); + int remaining = itemstack.count - canHold; + + // Mythic - Hide items for practice v2 + if (this.dropper != null) { + if (entityhuman instanceof EntityPlayer && this.dropper instanceof EntityPlayer) { + EntityPlayer player = (EntityPlayer) entityhuman; + EntityPlayer own = (EntityPlayer) this.dropper; + if (!player.getBukkitEntity().canSeeEntity(own.getBukkitEntity()) || !own.getBukkitEntity().canSeeEntity(player.getBukkitEntity())) { + return; + } + } + } + + if (this.pickupDelay <= 0 && canHold > 0) { + itemstack.count = canHold; + PlayerPickupItemEvent event = new PlayerPickupItemEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); + // event.setCancelled(!entityhuman.canPickUpLoot); TODO + this.world.getServer().getPluginManager().callEvent(event); + itemstack.count = canHold + remaining; + + if (event.isCancelled()) { + return; + } + + // Possibly < 0; fix here so we do not have to modify code below + this.pickupDelay = 0; + } + // CraftBukkit end + + if (this.pickupDelay == 0 && (this.g == null || 6000 - this.age <= 200 || this.g.equals(entityhuman.getName())) && entityhuman.inventory.pickup(itemstack)) { + if (itemstack.getItem() == Item.getItemOf(Blocks.LOG)) { + entityhuman.b(AchievementList.g); + } + + if (itemstack.getItem() == Item.getItemOf(Blocks.LOG2)) { + entityhuman.b(AchievementList.g); + } + + if (itemstack.getItem() == Items.LEATHER) { + entityhuman.b(AchievementList.t); + } + + if (itemstack.getItem() == Items.DIAMOND) { + entityhuman.b(AchievementList.w); + } + + if (itemstack.getItem() == Items.BLAZE_ROD) { + entityhuman.b(AchievementList.A); + } + + if (itemstack.getItem() == Items.DIAMOND && this.n() != null) { + EntityHuman entityhuman1 = this.world.a(this.n()); + + if (entityhuman1 != null && entityhuman1 != entityhuman) { + entityhuman1.b(AchievementList.x); + } + } + + if (!this.R()) { + this.world.makeSound(entityhuman, "random.pop", 0.2F, ((this.random.nextFloat() - this.random.nextFloat()) * 0.7F + 1.0F) * 2.0F); + } + + entityhuman.receive(this, i); + if (itemstack.count <= 0) { + this.die(); + } + } + + } + } + + public String getName() { + return this.hasCustomName() ? this.getCustomName() : LocaleI18n.get("item." + this.getItemStack().a()); + } + + public boolean aD() { + return false; + } + + public void c(int i) { + super.c(i); + if (!this.world.isClientSide) { + this.w(); + } + + } + + public ItemStack getItemStack() { + ItemStack itemstack = this.getDataWatcher().getItemStack(10); + + if (itemstack == null) { + if (this.world != null) { + EntityItem.b.error("Item entity " + this.getId() + " has no item?!"); + } + + return new ItemStack(Blocks.STONE); + } else { + return itemstack; + } + } + + public void setItemStack(ItemStack itemstack) { + this.getDataWatcher().watch(10, itemstack); + this.getDataWatcher().update(10); + } + + public String m() { + return this.g; + } + + public void b(String s) { + this.g = s; + } + + public String n() { + return this.f; + } + + public void c(String s) { + this.f = s; + } + + public void p() { + this.pickupDelay = 10; + } + + public void q() { + this.pickupDelay = 0; + } + + public void r() { + this.pickupDelay = 32767; + } + + public void a(int i) { + this.pickupDelay = i; + } + + public boolean s() { + return this.pickupDelay > 0; + } + + public void u() { + this.age = -6000; + } + + public void v() { + this.r(); + this.age = 5999; + } + + // Mythic - Hide items for practice + public void die() { + super.die(); + dropper = null; + } + + // Mythic - Hide items for practice + public boolean a(EntityPlayer entityplayer) { + if(!super.a(entityplayer)) return false; + + if(MythicConfiguration.Options.Tracking.Hide.items) { + if (dropper instanceof EntityPlayer) { + EntityPlayer otherPlayer = (EntityPlayer) dropper; + return entityplayer.getBukkitEntity().canSee(otherPlayer.getBukkitEntity()); + } + } + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityItemFrame.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityItemFrame.java new file mode 100644 index 0000000..1008567 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityItemFrame.java @@ -0,0 +1,185 @@ +package net.minecraft.server; + +import java.util.UUID; +import org.apache.commons.codec.Charsets; + +public class EntityItemFrame extends EntityHanging { + + private float c = 1.0F; + + public EntityItemFrame(World world) { + super(world); + } + + public EntityItemFrame(World world, BlockPosition blockposition, EnumDirection enumdirection) { + super(world, blockposition); + this.setDirection(enumdirection); + } + + protected void h() { + this.getDataWatcher().add(8, 5); + this.getDataWatcher().a(9, Byte.valueOf((byte) 0)); + } + + public float ao() { + return 0.0F; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else if (!damagesource.isExplosion() && this.getItem() != null) { + if (!this.world.isClientSide) { + // CraftBukkit start - fire EntityDamageEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f, false) || this.dead) { + return true; + } + // CraftBukkit end + this.a(damagesource.getEntity(), false); + this.setItem((ItemStack) null); + } + + return true; + } else { + return super.damageEntity(damagesource, f); + } + } + + public int l() { + return 12; + } + + public int m() { + return 12; + } + + public void b(Entity entity) { + this.a(entity, true); + } + + public void a(Entity entity, boolean flag) { + if (this.world.getGameRules().getBoolean("doEntityDrops")) { + ItemStack itemstack = this.getItem(); + + if (entity instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) entity; + + if (entityhuman.abilities.canInstantlyBuild) { + this.b(itemstack); + return; + } + } + + if (flag) { + this.a(new ItemStack(Items.ITEM_FRAME), 0.0F); + } + + if (itemstack != null && this.random.nextFloat() < this.c) { + itemstack = itemstack.cloneItemStack(); + this.b(itemstack); + this.a(itemstack, 0.0F); + } + + } + } + + private void b(ItemStack itemstack) { + if (itemstack != null) { + if (itemstack.getItem() == Items.FILLED_MAP) { + WorldMap worldmap = ((ItemWorldMap) itemstack.getItem()).getSavedMap(itemstack, this.world); + + worldmap.decorations.remove(UUID.nameUUIDFromBytes(("frame-" + this.getId()).getBytes(Charsets.US_ASCII))); // Spigot + } + + itemstack.a((EntityItemFrame) null); + } + } + + public ItemStack getItem() { + return this.getDataWatcher().getItemStack(8); + } + + public void setItem(ItemStack itemstack) { + this.setItem(itemstack, true); + } + + private void setItem(ItemStack itemstack, boolean flag) { + if (itemstack != null) { + itemstack = itemstack.cloneItemStack(); + itemstack.count = 1; + itemstack.a(this); + } + + this.getDataWatcher().watch(8, itemstack); + this.getDataWatcher().update(8); + if (flag && this.blockPosition != null) { + this.world.updateAdjacentComparators(this.blockPosition, Blocks.AIR); + } + + } + + public int getRotation() { + return this.getDataWatcher().getByte(9); + } + + public void setRotation(int i) { + this.setRotation(i, true); + } + + private void setRotation(int i, boolean flag) { + this.getDataWatcher().watch(9, Byte.valueOf((byte) (i % 8))); + if (flag && this.blockPosition != null) { + this.world.updateAdjacentComparators(this.blockPosition, Blocks.AIR); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + if (this.getItem() != null) { + nbttagcompound.set("Item", this.getItem().save(new NBTTagCompound())); + nbttagcompound.setByte("ItemRotation", (byte) this.getRotation()); + nbttagcompound.setFloat("ItemDropChance", this.c); + } + + super.b(nbttagcompound); + } + + public void a(NBTTagCompound nbttagcompound) { + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Item"); + + if (nbttagcompound1 != null && !nbttagcompound1.isEmpty()) { + this.setItem(ItemStack.createStack(nbttagcompound1), false); + this.setRotation(nbttagcompound.getByte("ItemRotation"), false); + if (nbttagcompound.hasKeyOfType("ItemDropChance", 99)) { + this.c = nbttagcompound.getFloat("ItemDropChance"); + } + + if (nbttagcompound.hasKey("Direction")) { + this.setRotation(this.getRotation() * 2, false); + } + } + + super.a(nbttagcompound); + } + + public boolean e(EntityHuman entityhuman) { + if (this.getItem() == null) { + ItemStack itemstack = entityhuman.bA(); + + if (itemstack != null && !this.world.isClientSide) { + this.setItem(itemstack); + if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + } + } else if (!this.world.isClientSide) { + this.setRotation(this.getRotation() + 1); + } + + return true; + } + + public int q() { + return this.getItem() == null ? 0 : this.getRotation() % 8 + 1; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLargeFireball.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLargeFireball.java new file mode 100644 index 0000000..b62c037 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLargeFireball.java @@ -0,0 +1,53 @@ +package net.minecraft.server; + +import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit + +public class EntityLargeFireball extends EntityFireball { + + public int yield = 1; + + public EntityLargeFireball(World world) { + super(world); + } + + public EntityLargeFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) { + super(world, entityliving, d0, d1, d2); + } + + protected void a(MovingObjectPosition movingobjectposition) { + if (!this.world.isClientSide) { + if (movingobjectposition.entity != null) { + movingobjectposition.entity.damageEntity(DamageSource.fireball(this, this.shooter), 6.0F); + this.a(this.shooter, movingobjectposition.entity); + } + + boolean flag = this.world.getGameRules().getBoolean("mobGriefing"); + + // CraftBukkit start - fire ExplosionPrimeEvent + ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) org.bukkit.craftbukkit.entity.CraftEntity.getEntity(this.world.getServer(), this)); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + // give 'this' instead of (Entity) null so we know what causes the damage + this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), flag); + } + // CraftBukkit end + this.die(); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("ExplosionPower", this.yield); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("ExplosionPower", 99)) { + // CraftBukkit - set bukkitYield when setting explosionpower + bukkitYield = this.yield = nbttagcompound.getInt("ExplosionPower"); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLeash.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLeash.java new file mode 100644 index 0000000..492cd86 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLeash.java @@ -0,0 +1,144 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class EntityLeash extends EntityHanging { + + public EntityLeash(World world) { + super(world); + } + + public EntityLeash(World world, BlockPosition blockposition) { + super(world, blockposition); + this.setPosition((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D); + float f = 0.125F; + float f1 = 0.1875F; + float f2 = 0.25F; + + this.a(new AxisAlignedBB(this.locX - 0.1875D, this.locY - 0.25D + 0.125D, this.locZ - 0.1875D, this.locX + 0.1875D, this.locY + 0.25D + 0.125D, this.locZ + 0.1875D)); + } + + protected void h() { + super.h(); + } + + public void setDirection(EnumDirection enumdirection) {} + + public int l() { + return 9; + } + + public int m() { + return 9; + } + + public float getHeadHeight() { + return -0.0625F; + } + + public void b(Entity entity) {} + + public boolean d(NBTTagCompound nbttagcompound) { + return false; + } + + public void b(NBTTagCompound nbttagcompound) {} + + public void a(NBTTagCompound nbttagcompound) {} + + public boolean e(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.bA(); + boolean flag = false; + double d0; + List list; + Iterator iterator; + EntityInsentient entityinsentient; + + if (itemstack != null && itemstack.getItem() == Items.LEAD && !this.world.isClientSide) { + d0 = 7.0D; + list = this.world.a(EntityInsentient.class, new AxisAlignedBB(this.locX - d0, this.locY - d0, this.locZ - d0, this.locX + d0, this.locY + d0, this.locZ + d0)); + iterator = list.iterator(); + + while (iterator.hasNext()) { + entityinsentient = (EntityInsentient) iterator.next(); + if (entityinsentient.cc() && entityinsentient.getLeashHolder() == entityhuman) { + // CraftBukkit start + if (CraftEventFactory.callPlayerLeashEntityEvent(entityinsentient, this, entityhuman).isCancelled()) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, entityinsentient, entityinsentient.getLeashHolder())); + continue; + } + // CraftBukkit end + entityinsentient.setLeashHolder(this, true); + flag = true; + } + } + } + + if (!this.world.isClientSide && !flag) { + // CraftBukkit start - Move below + // this.die(); + boolean die = true; + // CraftBukkit end + if (true || entityhuman.abilities.canInstantlyBuild) { // CraftBukkit - Process for non-creative as well + d0 = 7.0D; + list = this.world.a(EntityInsentient.class, new AxisAlignedBB(this.locX - d0, this.locY - d0, this.locZ - d0, this.locX + d0, this.locY + d0, this.locZ + d0)); + iterator = list.iterator(); + + while (iterator.hasNext()) { + entityinsentient = (EntityInsentient) iterator.next(); + if (entityinsentient.cc() && entityinsentient.getLeashHolder() == this) { + // CraftBukkit start + if (CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, entityhuman).isCancelled()) { + die = false; + continue; + } + entityinsentient.unleash(true, !entityhuman.abilities.canInstantlyBuild); // false -> survival mode boolean + // CraftBukkit end + } + } + } + // CraftBukkit start + if (die) { + this.die(); + } + // CraftBukkit end + } + + return true; + } + + public boolean survives() { + return this.world.getType(this.blockPosition).getBlock() instanceof BlockFence; + } + + public static EntityLeash a(World world, BlockPosition blockposition) { + EntityLeash entityleash = new EntityLeash(world, blockposition); + + entityleash.attachedToPlayer = true; + world.addEntity(entityleash); + return entityleash; + } + + public static EntityLeash b(World world, BlockPosition blockposition) { + int i = blockposition.getX(); + int j = blockposition.getY(); + int k = blockposition.getZ(); + List list = world.a(EntityLeash.class, new AxisAlignedBB((double) i - 1.0D, (double) j - 1.0D, (double) k - 1.0D, (double) i + 1.0D, (double) j + 1.0D, (double) k + 1.0D)); + Iterator iterator = list.iterator(); + + EntityLeash entityleash; + + do { + if (!iterator.hasNext()) { + return null; + } + + entityleash = (EntityLeash) iterator.next(); + } while (!entityleash.getBlockPosition().equals(blockposition)); + + return entityleash; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLightning.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLightning.java new file mode 100644 index 0000000..286fdef --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLightning.java @@ -0,0 +1,134 @@ +package net.minecraft.server; + +import java.util.List; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class EntityLightning extends EntityWeather { + + private int lifeTicks; + public long a; + private int c; + + // CraftBukkit start + public boolean isEffect = false; + + public boolean isSilent = false; // Spigot + + public EntityLightning(World world, double d0, double d1, double d2) { + this(world, d0, d1, d2, false); + } + + public EntityLightning(World world, double d0, double d1, double d2, boolean isEffect) { + // CraftBukkit end + super(world); + + // CraftBukkit - Set isEffect + this.isEffect = isEffect; + + this.setPositionRotation(d0, d1, d2, 0.0F, 0.0F); + this.lifeTicks = 2; + this.a = this.random.nextLong(); + this.c = this.random.nextInt(3) + 1; + BlockPosition blockposition = new BlockPosition(this); + + // CraftBukkit - add "!isEffect" + if (!isEffect && !world.isClientSide && world.getGameRules().getBoolean("doFireTick") && (world.getDifficulty() == EnumDifficulty.NORMAL || world.getDifficulty() == EnumDifficulty.HARD) && world.areChunksLoaded(blockposition, 10)) { + if (world.getType(blockposition).getBlock().getMaterial() == Material.AIR && Blocks.FIRE.canPlace(world, blockposition)) { + // CraftBukkit start + if (!CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + } + // CraftBukkit end + } + + for (int i = 0; i < 4; ++i) { + BlockPosition blockposition1 = blockposition.a(this.random.nextInt(3) - 1, this.random.nextInt(3) - 1, this.random.nextInt(3) - 1); + + if (world.getType(blockposition1).getBlock().getMaterial() == Material.AIR && Blocks.FIRE.canPlace(world, blockposition1)) { + // CraftBukkit start + if (!CraftEventFactory.callBlockIgniteEvent(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), this).isCancelled()) { + world.setTypeUpdate(blockposition1, Blocks.FIRE.getBlockData()); + } + // CraftBukkit end + } + } + } + } + + // Spigot start + public EntityLightning(World world, double d0, double d1, double d2, boolean isEffect, boolean isSilent) + { + this( world, d0, d1, d2, isEffect ); + this.isSilent = isSilent; + } + // Spigot end + + public void t_() { + super.t_(); + if (!isSilent && this.lifeTicks == 2) { // Spigot + // CraftBukkit start - Use relative location for far away sounds + //this.world.makeSound(this.locX, this.locY, this.locZ, "ambient.weather.thunder", 10000.0F, 0.8F + this.random.nextFloat() * 0.2F); + float pitch = 0.8F + this.random.nextFloat() * 0.2F; + int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; + for (EntityPlayer player : (List) (List) this.world.players) { + double deltaX = this.locX - player.locX; + double deltaZ = this.locZ - player.locZ; + double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; + if (distanceSquared > viewDistance * viewDistance) { + double deltaLength = Math.sqrt(distanceSquared); + double relativeX = player.locX + (deltaX / deltaLength) * viewDistance; + double relativeZ = player.locZ + (deltaZ / deltaLength) * viewDistance; + player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("ambient.weather.thunder", relativeX, this.locY, relativeZ, 10000.0F, pitch)); + } else { + player.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("ambient.weather.thunder", this.locX, this.locY, this.locZ, 10000.0F, pitch)); + } + } + // CraftBukkit end + this.world.makeSound(this.locX, this.locY, this.locZ, "random.explode", 2.0F, 0.5F + this.random.nextFloat() * 0.2F); + } + + --this.lifeTicks; + if (this.lifeTicks < 0) { + if (this.c == 0) { + this.die(); + } else if (this.lifeTicks < -this.random.nextInt(10)) { + --this.c; + this.lifeTicks = 1; + this.a = this.random.nextLong(); + BlockPosition blockposition = new BlockPosition(this); + + // CraftBukkit - add "!isEffect" + if (!this.world.isClientSide && this.world.getGameRules().getBoolean("doFireTick") && this.world.areChunksLoaded(blockposition, 10) && this.world.getType(blockposition).getBlock().getMaterial() == Material.AIR && Blocks.FIRE.canPlace(this.world, blockposition)) { + // CraftBukkit start + if (!isEffect && !CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { + this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + } + // CraftBukkit end + } + } + } + + if (this.lifeTicks >= 0 && !this.isEffect) { // CraftBukkit - add !this.isEffect + if (this.world.isClientSide) { + this.world.d(2); + } else { + double d0 = 3.0D; + List list = this.world.getEntities(this, new AxisAlignedBB(this.locX - d0, this.locY - d0, this.locZ - d0, this.locX + d0, this.locY + 6.0D + d0, this.locZ + d0)); + + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + + entity.onLightningStrike(this); + } + } + } + + } + + protected void h() {} + + protected void a(NBTTagCompound nbttagcompound) {} + + protected void b(NBTTagCompound nbttagcompound) {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java new file mode 100644 index 0000000..2ad5adf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityLiving.java @@ -0,0 +1,1906 @@ +package net.minecraft.server; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.kb.KBOption; +import me.levansj01.mythicspigot.kb.KBProfile; +import me.levansj01.mythicspigot.kb.KBSet; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.PotionEffectExpireEvent; +import org.bukkit.event.entity.PotionEffectRemoveEvent; +import org.bukkit.event.vehicle.VehicleExitEvent; +import org.spigotmc.event.entity.EntityDismountEvent; + +import java.util.*; + +// CraftBukkit start +// CraftBukkit end +// PaperSpigot start +// PaperSpigot end + +public abstract class EntityLiving extends Entity { + + private static final UUID a = UUID.fromString("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); + public final Map effects = Maps.newHashMap(); + private final ItemStack[] h = new ItemStack[5]; + public boolean ar; + public int as; + public int at; + public int hurtTicks; + public int av; + public float aw; + public int deathTicks; + public float ay; + public float az; + public float aA; + public float aB; + public float aC; + public int maxNoDamageTicks = 20; + public float aE; + public float aF; + public float aG; + public float aH; + public float aI; + public float aJ; + public float aK; + public float aL; + public float aM = 0.02F; + public EntityHuman killer; + protected int lastDamageByPlayerTime; + protected boolean aP; + protected int ticksFarFromPlayer; + protected float aR; + protected float aS; + protected float aT; + protected float aU; + protected float aV; + protected int aW; + public float lastDamage; + protected boolean aY; + public float aZ; + public float ba; + protected float bb; + protected int bc; + protected double bd; + protected double be; + protected double bf; + protected double bg; + protected double bh; + public boolean updateEffects = true; + public EntityLiving lastDamager; + public int hurtTimestamp; + private EntityLiving bk; + private int bl; + private float bm; + private int bn; + private float bo; + // CraftBukkit start + public int expToDrop; + public int maxAirTicks = 300; + ArrayList drops = null; + // CraftBukkit end + // Spigot start + public void inactiveTick() + { + super.inactiveTick(); + ++this.ticksFarFromPlayer; // Above all the floats + } + // Spigot end + + public void G() { + this.damageEntity(DamageSource.OUT_OF_WORLD, Float.MAX_VALUE); + } + + public EntityLiving(World world) { + super(world); + this.initAttributes(); + // CraftBukkit - setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor + this.datawatcher.watch(6, (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue()); + this.k = true; + this.aH = (float) ((Math.random() + 1.0D) * 0.009999999776482582D); + this.setPosition(this.locX, this.locY, this.locZ); + this.aG = (float) Math.random() * 12398.0F; + this.yaw = (float) (Math.random() * 3.1415927410125732D * 2.0D); + this.aK = this.yaw; + this.S = 0.6F; + } + + protected void h() { + this.datawatcher.a(7, Integer.valueOf(0)); + this.datawatcher.a(8, Byte.valueOf((byte) 0)); + this.datawatcher.a(9, Byte.valueOf((byte) 0)); + this.datawatcher.a(6, Float.valueOf(1.0F)); + } + + protected void initAttributes() { + this.getAttributeMap().b(GenericAttributes.maxHealth); + this.getAttributeMap().b(GenericAttributes.c); + this.getAttributeMap().b(GenericAttributes.MOVEMENT_SPEED); + } + + protected void a(double d0, boolean flag, Block block, BlockPosition blockposition) { + if (!this.V()) { + this.W(); + } + + if (!this.world.isClientSide && this.fallDistance > 3.0F && flag) { + IBlockData iblockdata = this.world.getType(blockposition); + Block block1 = iblockdata.getBlock(); + float f = (float) MathHelper.f(this.fallDistance - 3.0F); + + if (block1.getMaterial() != Material.AIR) { + double d1 = Math.min(0.2F + f / 15.0F, 10.0F); + + if (d1 > 2.5D) { + d1 = 2.5D; + } + + int i = (int) (150.0D * d1); + + // CraftBukkit start - visiblity api + if (this instanceof EntityPlayer) { + ((WorldServer) this.world).sendParticles((EntityPlayer) this, EnumParticle.BLOCK_DUST, false, this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, Block.getCombinedId(iblockdata)); + } else { + ((WorldServer) this.world).a(EnumParticle.BLOCK_DUST, this.locX, this.locY, this.locZ, i, 0.0D, 0.0D, 0.0D, 0.15000000596046448D, Block.getCombinedId(iblockdata)); + } + // CraftBukkit end + } + } + + super.a(d0, flag, block, blockposition); + } + + public boolean aY() { + return false; + } + + public void K() { + this.ay = this.az; + super.K(); + this.world.methodProfiler.a("livingEntityBaseTick"); + boolean flag = this instanceof EntityHuman; + + if (this.isAlive()) { + if (this.inBlock()) { + this.damageEntity(DamageSource.STUCK, 1.0F); + } else if (flag && !this.world.getWorldBorder().a(this.getBoundingBox())) { + double d0 = this.world.getWorldBorder().a(this) + this.world.getWorldBorder().getDamageBuffer(); + + if (d0 < 0.0D) { + this.damageEntity(DamageSource.STUCK, (float) Math.max(1, MathHelper.floor(-d0 * this.world.getWorldBorder().getDamageAmount()))); + } + } + } + + if (this.isFireProof() || this.world.isClientSide) { + this.extinguish(); + } + + boolean flag1 = flag && ((EntityHuman) this).abilities.isInvulnerable; + + if (this.isAlive()) { + if (this.a(Material.WATER)) { + if (!this.aY() && !this.hasEffect(MobEffectList.WATER_BREATHING.id) && !flag1) { + this.setAirTicks(this.j(this.getAirTicks())); + if (this.getAirTicks() == -20) { + this.setAirTicks(0); + + for (int i = 0; i < 8; ++i) { + float f = this.random.nextFloat() - this.random.nextFloat(); + 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); + } + + this.damageEntity(DamageSource.DROWN, 2.0F); + } + } + + if (!this.world.isClientSide && this.au() && this.vehicle instanceof EntityLiving) { + this.mount(null); + } + } else { + // CraftBukkit start - Only set if needed to work around a DataWatcher inefficiency + if (this.getAirTicks() != 300) { + this.setAirTicks(maxAirTicks); + } + // CraftBukkit end + } + } + + if (this.isAlive() && this.U()) { + this.extinguish(); + } + + this.aE = this.aF; + if (this.hurtTicks > 0) { + --this.hurtTicks; + } + + if (this.noDamageTicks > 0 && !(this instanceof EntityPlayer)) { + --this.noDamageTicks; + } + + if (this.getHealth() <= 0.0F) { + this.aZ(); + } + + if (this.lastDamageByPlayerTime > 0) { + --this.lastDamageByPlayerTime; + } else { + this.killer = null; + } + + if (this.bk != null && !this.bk.isAlive()) { + this.bk = null; + } + + if (this.lastDamager != null) { + if (!this.lastDamager.isAlive()) { + this.b((EntityLiving) null); + } else if (this.ticksLived - this.hurtTimestamp > 100) { + this.b((EntityLiving) null); + } + } + + this.bi(); + this.aU = this.aT; + this.aJ = this.aI; + this.aL = this.aK; + this.lastYaw = this.yaw; + this.lastPitch = this.pitch; + this.world.methodProfiler.b(); + } + + // CraftBukkit start + public int getExpReward() { + int exp = this.getExpValue(this.killer); + + if (!this.world.isClientSide && (this.lastDamageByPlayerTime > 0 || this.alwaysGivesExp()) && this.ba() && this.world.getGameRules().getBoolean("doMobLoot")) { + return exp; + } else { + return 0; + } + } + // CraftBukkit end + + public boolean isBaby() { + return false; + } + + protected void aZ() { + ++this.deathTicks; + if (this.deathTicks >= 20 && !this.dead) { // CraftBukkit - (this.deathTicks == 20) -> (this.deathTicks >= 20 && !this.dead) + int i; + + // CraftBukkit start - Update getExpReward() above if the removed if() changes! + i = this.expToDrop; + while (i > 0) { + int j = EntityExperienceOrb.getOrbValue(i); + i -= j; + this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j)); + } + this.expToDrop = 0; + // CraftBukkit end + + this.die(); + + for (i = 0; i < 20; ++i) { + double d0 = this.random.nextGaussian() * 0.02D; + 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); + } + } + + } + + protected boolean ba() { + return !this.isBaby(); + } + + protected int j(int i) { + int j = EnchantmentManager.getOxygenEnchantmentLevel(this); + + return j > 0 && this.random.nextInt(j + 1) > 0 ? i : i - 1; + } + + protected int getExpValue(EntityHuman entityhuman) { + return 0; + } + + protected boolean alwaysGivesExp() { + return false; + } + + public Random bc() { + return this.random; + } + + public EntityLiving getLastDamager() { + return this.lastDamager; + } + + public int be() { + return this.hurtTimestamp; + } + + public void b(EntityLiving entityliving) { + this.lastDamager = entityliving; + this.hurtTimestamp = this.ticksLived; + } + + public EntityLiving bf() { + return this.bk; + } + + public int bg() { + return this.bl; + } + + public void p(Entity entity) { + if (entity instanceof EntityLiving) { + this.bk = (EntityLiving) entity; + } else { + this.bk = null; + } + + this.bl = this.ticksLived; + } + + public int bh() { + return this.ticksFarFromPlayer; + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setFloat("HealF", this.getHealth()); + nbttagcompound.setShort("Health", (short) ((int) Math.ceil(this.getHealth()))); + nbttagcompound.setShort("HurtTime", (short) this.hurtTicks); + nbttagcompound.setInt("HurtByTimestamp", this.hurtTimestamp); + nbttagcompound.setShort("DeathTime", (short) this.deathTicks); + nbttagcompound.setFloat("AbsorptionAmount", this.getAbsorptionHearts()); + ItemStack[] aitemstack = this.getEquipment(); + int i = aitemstack.length; + + int j; + ItemStack itemstack; + + for (j = 0; j < i; ++j) { + itemstack = aitemstack[j]; + if (itemstack != null) { + this.c.a(itemstack.B()); + } + } + + nbttagcompound.set("Attributes", GenericAttributes.a(this.getAttributeMap())); + aitemstack = this.getEquipment(); + i = aitemstack.length; + + for (j = 0; j < i; ++j) { + itemstack = aitemstack[j]; + if (itemstack != null) { + this.c.b(itemstack.B()); + } + } + + if (!this.effects.isEmpty()) { + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = this.effects.values().iterator(); + + while (iterator.hasNext()) { + MobEffect mobeffect = (MobEffect) iterator.next(); + + nbttaglist.add(mobeffect.a(new NBTTagCompound())); + } + + nbttagcompound.set("ActiveEffects", nbttaglist); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + this.setAbsorptionHearts(nbttagcompound.getFloat("AbsorptionAmount")); + if (nbttagcompound.hasKeyOfType("Attributes", 9) && this.world != null && !this.world.isClientSide) { + GenericAttributes.a(this.getAttributeMap(), nbttagcompound.getList("Attributes", 10)); + } + + if (nbttagcompound.hasKeyOfType("ActiveEffects", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("ActiveEffects", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + MobEffect mobeffect = MobEffect.b(nbttagcompound1); + + if (mobeffect != null) { + this.effects.put(Integer.valueOf(mobeffect.getEffectId()), mobeffect); + } + } + } + + // CraftBukkit start + if (nbttagcompound.hasKey("Bukkit.MaxHealth")) { + NBTBase nbtbase = nbttagcompound.get("Bukkit.MaxHealth"); + if (nbtbase.getTypeId() == 5) { + this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) ((NBTTagFloat) nbtbase).c()); + } else if (nbtbase.getTypeId() == 3) { + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(((NBTTagInt) nbtbase).d()); + } + } + // CraftBukkit end + + if (nbttagcompound.hasKeyOfType("HealF", 99)) { + this.setHealth(nbttagcompound.getFloat("HealF")); + } else { + NBTBase nbtbase = nbttagcompound.get("Health"); + + if (nbtbase == null) { + this.setHealth(this.getMaxHealth()); + } else if (nbtbase.getTypeId() == 5) { + this.setHealth(((NBTTagFloat) nbtbase).h()); + } else if (nbtbase.getTypeId() == 2) { + this.setHealth(((NBTTagShort) nbtbase).e()); + } + } + + this.hurtTicks = nbttagcompound.getShort("HurtTime"); + this.deathTicks = nbttagcompound.getShort("DeathTime"); + this.hurtTimestamp = nbttagcompound.getInt("HurtByTimestamp"); + } + + // CraftBukkit start + private boolean isTickingEffects = false; + private final List effectsToProcess = Lists.newArrayList(); + // CraftBukkit end + + protected void bi() { + Iterator iterator = this.effects.keySet().iterator(); + + isTickingEffects = true; // CraftBukkit + while (iterator.hasNext()) { + Integer integer = (Integer) iterator.next(); + MobEffect mobeffect = this.effects.get(integer); + + if (!mobeffect.tick(this)) { + if (!this.world.isClientSide) { + PotionEffectExpireEvent event = new PotionEffectExpireEvent((LivingEntity) getBukkitEntity(), mobeffect.toBukkit()); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) { + mobeffect.setDuration(event.getDuration()); + } else { + iterator.remove(); + this.b(mobeffect); + } + } + } else if (mobeffect.getDuration() % 600 == 0) { + this.a(mobeffect, false); + } + } + // CraftBukkit start + isTickingEffects = false; + for (Object e : effectsToProcess) { + if (e instanceof MobEffect) { + addEffect((MobEffect) e); + } else { + removeEffect((Integer) e); + } + } + // CraftBukkit end + + if (this.updateEffects) { + if (!this.world.isClientSide) { + this.B(); + } + + this.updateEffects = false; + } + + int i = this.datawatcher.getInt(7); + boolean flag = this.datawatcher.getByte(8) > 0; + + if (i > 0) { + boolean flag1 = false; + + if (!this.isInvisible()) { + flag1 = this.random.nextBoolean(); + } else { + flag1 = this.random.nextInt(15) == 0; + } + + if (flag) { + flag1 &= this.random.nextInt(5) == 0; + } + + if (flag1 && i > 0) { + double d0 = (double) (i >> 16 & 255) / 255.0D; + double d1 = (double) (i >> 8 & 255) / 255.0D; + double d2 = (double) (i >> 0 & 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); + } + } + + } + + protected void B() { + if (this.effects.isEmpty()) { + this.bj(); + this.setInvisible(false); + } else { + int i = PotionBrewer.a(this.effects.values()); + + this.datawatcher.watch(8, Byte.valueOf((byte) (PotionBrewer.b(this.effects.values()) ? 1 : 0))); + this.datawatcher.watch(7, Integer.valueOf(i)); + this.setInvisible(this.hasEffect(MobEffectList.INVISIBILITY.id)); + } + + } + + protected void bj() { + this.datawatcher.watch(8, Byte.valueOf((byte) 0)); + this.datawatcher.watch(7, Integer.valueOf(0)); + } + + public void removeAllEffects() { + Iterator iterator = this.effects.keySet().iterator(); + + while (iterator.hasNext()) { + Integer integer = (Integer) iterator.next(); + MobEffect mobeffect = this.effects.get(integer); + + if (!this.world.isClientSide) { + PotionEffectRemoveEvent event = new PotionEffectRemoveEvent((LivingEntity) getBukkitEntity(), mobeffect.toBukkit()); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) continue; + + iterator.remove(); + this.b(mobeffect); + } + } + + } + + public Collection getEffects() { + return this.effects.values(); + } + + public boolean hasEffect(int i) { + // CraftBukkit - Add size check for efficiency + return this.effects.size() != 0 && this.effects.containsKey(Integer.valueOf(i)); + } + + public boolean hasEffect(MobEffectList mobeffectlist) { + return this.effects.containsKey(Integer.valueOf(mobeffectlist.id)); + } + + public MobEffect getEffect(MobEffectList mobeffectlist) { + return this.effects.get(Integer.valueOf(mobeffectlist.id)); + } + + public void addEffect(MobEffect mobeffect) { + org.spigotmc.AsyncCatcher.catchOp( "effect add"); // Spigot + // CraftBukkit start + if (isTickingEffects) { + effectsToProcess.add(mobeffect); + return; + } + // CraftBukkit end + if (this.d(mobeffect)) { + if (this.effects.containsKey(Integer.valueOf(mobeffect.getEffectId()))) { + this.effects.get(Integer.valueOf(mobeffect.getEffectId())).a(mobeffect); + this.a(this.effects.get(Integer.valueOf(mobeffect.getEffectId())), true); + } else { + this.effects.put(Integer.valueOf(mobeffect.getEffectId()), mobeffect); + this.a(mobeffect); + } + + } + } + + public boolean d(MobEffect mobeffect) { + if (this.getMonsterType() == EnumMonsterType.UNDEAD) { + int i = mobeffect.getEffectId(); + + return i != MobEffectList.REGENERATION.id && i != MobEffectList.POISON.id; + } + + return true; + } + + public boolean bm() { + return this.getMonsterType() == EnumMonsterType.UNDEAD; + } + + public void removeEffect(int i) { + // CraftBukkit start + if (isTickingEffects) { + effectsToProcess.add(i); + return; + } + // CraftBukkit end + MobEffect mobeffect = this.effects.remove(Integer.valueOf(i)); + + if (mobeffect != null) { + this.b(mobeffect); + } + + } + + protected void a(MobEffect mobeffect) { + this.updateEffects = true; + if (!this.world.isClientSide) { + MobEffectList.byId[mobeffect.getEffectId()].b(this, this.getAttributeMap(), mobeffect.getAmplifier()); + } + + } + + protected void a(MobEffect mobeffect, boolean flag) { + this.updateEffects = true; + if (flag && !this.world.isClientSide) { + MobEffectList.byId[mobeffect.getEffectId()].a(this, this.getAttributeMap(), mobeffect.getAmplifier()); + MobEffectList.byId[mobeffect.getEffectId()].b(this, this.getAttributeMap(), mobeffect.getAmplifier()); + } + + } + + protected void b(MobEffect mobeffect) { + this.updateEffects = true; + if (!this.world.isClientSide) { + MobEffectList.byId[mobeffect.getEffectId()].a(this, this.getAttributeMap(), mobeffect.getAmplifier()); + } + + } + + // CraftBukkit start - Delegate so we can handle providing a reason for health being regained + public void heal(float f) { + heal(f, EntityRegainHealthEvent.RegainReason.CUSTOM); + } + + public void heal(float f, EntityRegainHealthEvent.RegainReason regainReason) { + float f1 = this.getHealth(); + + if (f1 > 0.0F) { + EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), f, regainReason); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + this.setHealth((float) (this.getHealth() + event.getAmount())); + } + // CraftBukkit end + } + + } + + public final float getHealth() { + // CraftBukkit start - Use unscaled health + if (this instanceof EntityPlayer) { + return (float) ((EntityPlayer) this).getBukkitEntity().getHealth(); + } + // CraftBukkit end + return this.datawatcher.getFloat(6); + } + + public void setHealth(float f) { + // CraftBukkit start - Handle scaled health + if (this instanceof EntityPlayer) { + org.bukkit.craftbukkit.entity.CraftPlayer player = ((EntityPlayer) this).getBukkitEntity(); + // Squeeze + if (f < 0.0F) { + player.setRealHealth(0.0D); + } else if (f > player.getMaxHealth()) { + player.setRealHealth(player.getMaxHealth()); + } else { + player.setRealHealth(f); + } + + this.datawatcher.watch(6, Float.valueOf(player.getScaledHealth())); + return; + } + // CraftBukkit end + this.datawatcher.watch(6, Float.valueOf(MathHelper.a(f, 0.0F, this.getMaxHealth()))); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else if (this.world.isClientSide) { + return false; + } else { + this.ticksFarFromPlayer = 0; + if (this.getHealth() <= 0.0F) { + return false; + } else if (damagesource.o() && this.hasEffect(MobEffectList.FIRE_RESISTANCE)) { + return false; + } else { + // CraftBukkit - Moved into d(DamageSource, float) + if (false && (damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { + this.getEquipment(4).damage((int) (f * 4.0F + this.random.nextFloat() * f * 2.0F), this); + f *= 0.75F; + } + + this.aB = 1.5F; + boolean flag = true; + + if ((float) this.noDamageTicks > (float) this.maxNoDamageTicks / 2.0F) { + // Mythic - Projectiled patch + org.bukkit.entity.Entity bukkitSource = damagesource.i() == null ? null : damagesource.i().getBukkitEntity(); + if(MythicConfiguration.Options.Combat.DamageTicks.ProjectilesBypass.enabled && bukkitSource instanceof Projectile) { + if(MythicConfiguration.Options.Combat.DamageTicks.ProjectilesBypass.limitDamage) { + if (!this.d(damagesource, Math.max(f - this.lastDamage, 0))) { + return false; + } + + lastDamage = Math.max(lastDamage, f); + } else { + if (!this.d(damagesource, f)) { + return false; + } + + lastDamage = f; + } + + if(MythicConfiguration.Options.Combat.DamageTicks.ProjectilesBypass.resetTicks) { + this.noDamageTicks = this.maxNoDamageTicks; + this.hurtTicks = this.av = 10; + } + if(!MythicConfiguration.Options.Combat.DamageTicks.ProjectilesBypass.velocity) flag = false; + } else { + if (f <= this.lastDamage) { + this.forceExplosionKnockback = true; // CraftBukkit - SPIGOT-949 - for vanilla consistency, cooldown does not prevent explosion knockback + return false; + } + + // CraftBukkit start + if (!this.d(damagesource, f - this.lastDamage)) { + return false; + } + // CraftBukkit end + this.lastDamage = f; + flag = false; + } + } else { + // CraftBukkit start + float previousHealth = this.getHealth(); + if (!this.d(damagesource, f)) { + return false; + } + this.lastDamage = f; + this.noDamageTicks = this.maxNoDamageTicks; + // CraftBukkit end + this.hurtTicks = this.av = 10; + } + + // CraftBukkit start + if(this instanceof EntityAnimal){ + ((EntityAnimal)this).cq(); + if(this instanceof EntityTameableAnimal){ + ((EntityTameableAnimal)this).getGoalSit().setSitting(false); + } + } + // CraftBukkit end + + this.aw = 0.0F; + Entity entity = damagesource.getEntity(); + + if (entity != null) { + if (entity instanceof EntityLiving) { + this.b((EntityLiving) entity); + } + + if (entity instanceof EntityHuman) { + this.lastDamageByPlayerTime = 100; + this.killer = (EntityHuman) entity; + } else if (entity instanceof EntityWolf) { + EntityWolf entitywolf = (EntityWolf) entity; + + if (entitywolf.isTamed()) { + this.lastDamageByPlayerTime = 100; + this.killer = null; + } + } + } + + // PaperSpigot start - Disable explosion knockback + boolean knockbackCancelled = false; + if (flag && !(knockbackCancelled = world.paperSpigotConfig.disableExplosionKnockback && damagesource.isExplosion() && this instanceof EntityHuman)) { + // PaperSpigot end + this.world.broadcastEntityEffect(this, (byte) 2); + if (damagesource != DamageSource.DROWN) { + this.ac(); + } + + if (entity != null) { + double d0 = entity.locX - this.locX; + + double d1; + + for (d1 = entity.locZ - this.locZ; d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) { + d0 = (Math.random() - Math.random()) * 0.01D; + } + + this.aw = (float) (MathHelper.b(d1, d0) * 180.0D / 3.1415927410125732D - (double) this.yaw); + this.a(damagesource.i(), f, d0, d1); + } else { + this.aw = (float) ((int) (Math.random() * 2.0D) * 180); + } + } + + if (knockbackCancelled) this.world.broadcastEntityEffect(this, (byte) 2); // PaperSpigot + + String s; + + if (this.getHealth() <= 0.0F) { + s = this.bp(); + if (flag && s != null) { + this.makeSound(s, this.bB(), this.bC()); + } + + this.die(damagesource); + } else { + s = this.bo(); + if (flag && s != null) { + this.makeSound(s, this.bB(), this.bC()); + } + } + + return true; + } + } + } + + public void b(ItemStack itemstack) { + this.makeSound("random.break", 0.8F, 0.8F + this.world.random.nextFloat() * 0.4F); + + for (int i = 0; i < 5; ++i) { + Vec3D vec3d = new Vec3D(((double) this.random.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); + + vec3d = vec3d.a(-this.pitch * 3.1415927F / 180.0F); + vec3d = vec3d.b(-this.yaw * 3.1415927F / 180.0F); + double d0 = (double) (-this.random.nextFloat()) * 0.6D - 0.3D; + Vec3D vec3d1 = new Vec3D(((double) this.random.nextFloat() - 0.5D) * 0.3D, d0, 0.6D); + + vec3d1 = vec3d1.a(-this.pitch * 3.1415927F / 180.0F); + vec3d1 = vec3d1.b(-this.yaw * 3.1415927F / 180.0F); + vec3d1 = vec3d1.add(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ); + this.world.addParticle(EnumParticle.ITEM_CRACK, vec3d1.a, vec3d1.b, vec3d1.c, vec3d.a, vec3d.b + 0.05D, vec3d.c, Item.getId(itemstack.getItem())); + } + + } + + public void die(DamageSource damagesource) { + Entity entity = damagesource.getEntity(); + EntityLiving entityliving = this.bt(); + + if (this.aW >= 0 && entityliving != null) { + entityliving.b(this, this.aW); + } + + if (entity != null) { + entity.a(this); + } + + this.aP = true; + this.bs().g(); + if (!this.world.isClientSide) { + int i = 0; + + if (entity instanceof EntityHuman) { + i = EnchantmentManager.getBonusMonsterLootEnchantmentLevel((EntityLiving) entity); + } + + if (this.ba() && this.world.getGameRules().getBoolean("doMobLoot")) { + this.drops = new ArrayList(); // CraftBukkit - Setup drop capture + + this.dropDeathLoot(this.lastDamageByPlayerTime > 0, i); + this.dropEquipment(this.lastDamageByPlayerTime > 0, i); + if (this.lastDamageByPlayerTime > 0 && this.random.nextFloat() < 0.025F + (float) i * 0.01F) { + this.getRareDrop(); + } + // CraftBukkit start - Call death event + CraftEventFactory.callEntityDeathEvent(this, this.drops); + this.drops = null; + } else { + CraftEventFactory.callEntityDeathEvent(this); + // CraftBukkit end + } + } + + this.world.broadcastEntityEffect(this, (byte) 3); + } + + protected void dropEquipment(boolean flag, int i) {} + + public void a(Entity entity, float f, double d0, double d1) { + if (this.random.nextDouble() >= this.getAttributeInstance(GenericAttributes.c).getValue()) { + this.ai = true; + float f1 = MathHelper.sqrt(d0 * d0 + d1 * d1); + + KBProfile kb = getKBProfile(); + KBSet set = kb.get(entity == null ? null : entity.getBukkitEntity()); + KBOption friction = set.getFriction(); + + this.motX *= friction.getHorizontal(); + this.motY *= friction.getVertical(); + this.motZ *= friction.getHorizontal(); + + KBOption base = set.getBase(); + + if (entity != null && this.getDirection() == entity.getDirection()) { + KBOption backStab = kb.getBackStab(); + this.motX -= d0 / (double) f1 * (base.getHorizontal() - backStab.getHorizontal()); + this.motY += (base.getVertical() - backStab.getVertical()); + this.motZ -= d1 / (double) f1 * (base.getHorizontal() - backStab.getHorizontal()); + } else { + this.motX -= d0 / (double) f1 * base.getHorizontal(); + this.motY += base.getVertical(); + this.motZ -= d1 / (double) f1 * base.getHorizontal(); + } + + if (this.motY > kb.getMaxY()) { + this.motY = kb.getMaxY(); + } + + } + } + + protected String bo() { + return "game.neutral.hurt"; + } + + protected String bp() { + return "game.neutral.die"; + } + + protected void getRareDrop() {} + + protected void dropDeathLoot(boolean flag, int i) {} + + public boolean k_() { + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.getBoundingBox().b); + int k = MathHelper.floor(this.locZ); + Block block = this.world.getType(i, j, k).getBlock(); + + return (block == Blocks.LADDER || block == Blocks.VINE) && (!(this instanceof EntityHuman) || !((EntityHuman) this).isSpectator()); + } + + public boolean isAlive() { + return !this.dead && this.getHealth() > 0.0F; + } + + public void e(float f, float f1) { + super.e(f, f1); + MobEffect mobeffect = this.getEffect(MobEffectList.JUMP); + float f2 = mobeffect != null ? (float) (mobeffect.getAmplifier() + 1) : 0.0F; + int i = MathHelper.f((f - 3.0F - f2) * f1); + + if (i > 0) { + // CraftBukkit start + if (!this.damageEntity(DamageSource.FALL, (float) i)) { + return; + } + // CraftBukkit end + this.makeSound(this.n(i), 1.0F, 1.0F); + // this.damageEntity(DamageSource.FALL, (float) i); // CraftBukkit - moved up + int j = MathHelper.floor(this.locX); + int k = MathHelper.floor(this.locY - 0.20000000298023224D); + int l = MathHelper.floor(this.locZ); + Block block = this.world.getType(j, k, l).getBlock(); + + if (block.getMaterial() != Material.AIR) { + Block.StepSound block_stepsound = block.stepSound; + + this.makeSound(block_stepsound.getStepSound(), block_stepsound.getVolume1() * 0.5F, block_stepsound.getVolume2() * 0.75F); + } + } + + } + + protected String n(int i) { + return i > 4 ? "game.neutral.hurt.fall.big" : "game.neutral.hurt.fall.small"; + } + + public int br() { + int i = 0; + ItemStack[] aitemstack = this.getEquipment(); + int j = aitemstack.length; + + for (int k = 0; k < j; ++k) { + ItemStack itemstack = aitemstack[k]; + + if (itemstack != null && itemstack.getItem() instanceof ItemArmor) { + int l = ((ItemArmor) itemstack.getItem()).c; + + i += l; + } + } + + return i; + } + + protected void damageArmor(float f) {} + + protected float applyArmorModifier(DamageSource damagesource, float f) { + if (!damagesource.ignoresArmor()) { + int i = 25 - this.br(); + float f1 = f * (float) i; + + // this.damageArmor(f); // CraftBukkit - Moved into d(DamageSource, float) + f = f1 / 25.0F; + } + + return f; + } + + protected float applyMagicModifier(DamageSource damagesource, float f) { + if (damagesource.isStarvation()) { + return f; + } else { + int i; + int j; + float f1; + + // CraftBukkit - Moved to d(DamageSource, float) + if (false && this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { + i = (this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5; + j = 25 - i; + f1 = f * (float) j; + f = f1 / 25.0F; + } + + if (f <= 0.0F) { + return 0.0F; + } else { + i = EnchantmentManager.a(this.getEquipment(), damagesource); + if (i > 20) { + i = 20; + } + + if (i > 0 && i <= 20) { + j = 25 - i; + f1 = f * (float) j; + f = f1 / 25.0F; + } + + return f; + } + } + } + + // CraftBukkit start + protected boolean d(final DamageSource damagesource, float f) { // void -> boolean, add final + if (!this.isInvulnerable(damagesource)) { + final boolean human = this instanceof EntityHuman; + float originalDamage = f; + Function hardHat = new Function() { + @Override + public Double apply(Double f) { + if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && EntityLiving.this.getEquipment(4) != null) { + return -(f - (f * 0.75F)); + } + return -0.0; + } + }; + float hardHatModifier = hardHat.apply((double) f).floatValue(); + f += hardHatModifier; + + Function blocking = new Function() { + @Override + public Double apply(Double f) { + if (human) { + if (!damagesource.ignoresArmor() && ((EntityHuman) EntityLiving.this).isBlocking() && f > 0.0F) { + return -(f - ((1.0F + f) * 0.5F)); + } + } + return -0.0; + } + }; + float blockingModifier = blocking.apply((double) f).floatValue(); + f += blockingModifier; + + Function armor = new Function() { + @Override + public Double apply(Double f) { + return -(f - EntityLiving.this.applyArmorModifier(damagesource, f.floatValue())); + } + }; + float armorModifier = armor.apply((double) f).floatValue(); + f += armorModifier; + + Function resistance = new Function() { + @Override + public Double apply(Double f) { + if (!damagesource.isStarvation() && EntityLiving.this.hasEffect(MobEffectList.RESISTANCE) && damagesource != DamageSource.OUT_OF_WORLD) { + int i = (EntityLiving.this.getEffect(MobEffectList.RESISTANCE).getAmplifier() + 1) * 5; + int j = 25 - i; + float f1 = f.floatValue() * (float) j; + return -(f - (f1 / 25.0F)); + } + return -0.0; + } + }; + float resistanceModifier = resistance.apply((double) f).floatValue(); + f += resistanceModifier; + + Function magic = new Function() { + @Override + public Double apply(Double f) { + return -(f - EntityLiving.this.applyMagicModifier(damagesource, f.floatValue())); + } + }; + float magicModifier = magic.apply((double) f).floatValue(); + f += magicModifier; + + Function absorption = new Function() { + @Override + public Double apply(Double f) { + return -(Math.max(f - Math.max(f - EntityLiving.this.getAbsorptionHearts(), 0.0F), 0.0F)); + } + }; + float absorptionModifier = absorption.apply((double) f).floatValue(); + + EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption); + if (event.isCancelled()) { + return false; + } + + f = (float) event.getFinalDamage(); + + // Apply damage to helmet + if ((damagesource == DamageSource.ANVIL || damagesource == DamageSource.FALLING_BLOCK) && this.getEquipment(4) != null) { + this.getEquipment(4).damage((int) (event.getDamage() * 4.0F + this.random.nextFloat() * event.getDamage() * 2.0F), this); + } + + // Apply damage to armor + if (!damagesource.ignoresArmor()) { + float armorDamage = (float) (event.getDamage() + event.getDamage(DamageModifier.BLOCKING) + event.getDamage(DamageModifier.HARD_HAT)); + this.damageArmor(MythicConfiguration.Options.Combat.DamageTicks.durabilityFix ? 1.0F : armorDamage); + } + + absorptionModifier = (float) -event.getDamage(DamageModifier.ABSORPTION); + this.setAbsorptionHearts(Math.max(this.getAbsorptionHearts() - absorptionModifier, 0.0F)); + if (f != 0.0F) { + if (human) { + // PAIL: Be sure to drag all this code from the EntityHuman subclass each update. + ((EntityHuman) this).applyExhaustion(damagesource.getExhaustionCost()); + if (f < 3.4028235E37F) { + ((EntityHuman) this).a(StatisticList.x, Math.round(f * 10.0F)); + } + } + // CraftBukkit end + float f2 = this.getHealth(); + + this.setHealth(f2 - f); + this.bs().a(damagesource, f2, f); + // CraftBukkit start + if (human) { + return true; + } + // CraftBukkit end + this.setAbsorptionHearts(this.getAbsorptionHearts() - f); + } + return true; // CraftBukkit + } + return false; // CraftBukkit + } + + public CombatTracker bs() { + return this.combatTracker; + } + + public EntityLiving bt() { + return this.combatTracker.c() != null ? this.combatTracker.c() : (this.killer != null ? this.killer : (this.lastDamager)); + } + + public final float getMaxHealth() { + return (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue(); + } + + // TacoSpigot start - deobfuscation helper + public int getArrowsStuck() { + return this.bv(); + } + // TacoSpigot end + public final int bv() { + return this.datawatcher.getByte(9); + } + + + // TacoSpigot start - deobfuscation helper + public void setArrowsStuck(int i) { + this.o(i); + } + // TacoSpigot end + public final void o(int i) { + this.datawatcher.watch(9, Byte.valueOf((byte) i)); + } + + private int n() { + return this.hasEffect(MobEffectList.FASTER_DIG) ? 6 - (1 + this.getEffect(MobEffectList.FASTER_DIG).getAmplifier()) * 1 : (this.hasEffect(MobEffectList.SLOWER_DIG) ? 6 + (1 + this.getEffect(MobEffectList.SLOWER_DIG).getAmplifier()) * 2 : 6); + } + + public void bw() { + if (!this.ar || this.as >= this.n() / 2 || this.as < 0) { + this.as = -1; + this.ar = true; + if (this.world instanceof WorldServer) { + ((WorldServer) this.world).getTracker().a(this, new PacketPlayOutAnimation(this, 0)); + } + } + + } + + protected void O() { + this.damageEntity(DamageSource.OUT_OF_WORLD, 4.0F); + } + + protected void bx() { + int i = this.n(); + + if (this.ar) { + ++this.as; + if (this.as >= i) { + this.as = 0; + this.ar = false; + } + } else { + this.as = 0; + } + + this.az = (float) this.as / (float) i; + } + + public AttributeInstance getAttributeInstance(IAttribute iattribute) { + return this.getAttributeMap().a(iattribute); + } + + public AttributeMapBase getAttributeMap() { + if (this.c == null) { + this.c = new AttributeMapServer(); + } + + return this.c; + } + + public EnumMonsterType getMonsterType() { + return EnumMonsterType.UNDEFINED; + } + + public abstract ItemStack bA(); + + public abstract ItemStack getEquipment(int i); + + public abstract void setEquipment(int i, ItemStack itemstack); + + public void setSprinting(boolean flag) { + super.setSprinting(flag); + AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); + + if (attributeinstance.a(EntityLiving.a) != null) { + attributeinstance.c(EntityLiving.b); + } + + if (flag) { + attributeinstance.b(EntityLiving.b); + } + + } + + public abstract ItemStack[] getEquipment(); + + protected float bB() { + return 1.0F; + } + + protected float bC() { + return this.isBaby() ? (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.5F : (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F; + } + + protected boolean bD() { + return this.getHealth() <= 0.0F; + } + + public void q(Entity entity) { + double d0 = entity.locX; + double d1 = entity.getBoundingBox().b + (double) entity.length; + double d2 = entity.locZ; + byte b0 = 1; + + for (int i = -b0; i <= b0; ++i) { + for (int j = -b0; j < b0; ++j) { + if (i != 0 || j != 0) { + int k = (int) (this.locX + (double) i); + int l = (int) (this.locZ + (double) j); + AxisAlignedBB axisalignedbb = this.getBoundingBox().c(i, 1.0D, j); + + if (this.world.a(axisalignedbb).isEmpty()) { + if (World.a(this.world, k, (int) this.locY, l)) { + this.enderTeleportTo(this.locX + (double) i, this.locY + 1.0D, this.locZ + (double) j); + return; + } + + if (World.a(this.world, k, (int) this.locY - 1, l) || this.world.getType(k, (int) this.locY - 1, l).getBlock().getMaterial() == Material.WATER) { + d0 = this.locX + (double) i; + d1 = this.locY + 1.0D; + d2 = this.locZ + (double) j; + } + } + } + } + } + + this.enderTeleportTo(d0, d1, d2); + } + + protected float bE() { + return 0.42F; + } + + protected void bF() { + this.motY = this.bE(); + if (this.hasEffect(MobEffectList.JUMP)) { + this.motY += (float) (this.getEffect(MobEffectList.JUMP).getAmplifier() + 1) * 0.1F; + } + + if (this.isSprinting()) { + float f = this.yaw * 0.017453292F; + + this.motX -= MathHelper.sin(f) * 0.2F; + this.motZ += MathHelper.cos(f) * 0.2F; + } + + this.ai = true; + } + + protected void bG() { + this.motY += 0.03999999910593033D; + } + + protected void bH() { + this.motY += 0.03999999910593033D; + } + + public void g(float f, float f1) { + double d0; + float f2; + + if (this.bM()) { + float f3; + float f4; + + if (this.V() && (!(this instanceof EntityHuman) || !((EntityHuman) this).abilities.isFlying)) { + d0 = this.locY; + f3 = 0.8F; + f4 = 0.02F; + f2 = (float) EnchantmentManager.b(this); + if (f2 > 3.0F) { + f2 = 3.0F; + } + + if (!this.onGround) { + f2 *= 0.5F; + } + + if (f2 > 0.0F) { + f3 += (0.54600006F - f3) * f2 / 3.0F; + f4 += (this.bI() * 1.0F - f4) * f2 / 3.0F; + } + + this.a(f, f1, f4); + this.move(this.motX, this.motY, this.motZ); + this.motX *= f3; + this.motY *= 0.800000011920929D; + this.motZ *= f3; + this.motY -= 0.02D; + if (this.positionChanged && this.c(this.motX, this.motY + 0.6000000238418579D - this.locY + d0, this.motZ)) { + this.motY = 0.30000001192092896D; + } + } else if (this.ab() && (!(this instanceof EntityHuman) || !((EntityHuman) this).abilities.isFlying)) { + d0 = this.locY; + this.a(f, f1, 0.02F); + this.move(this.motX, this.motY, this.motZ); + this.motX *= 0.5D; + this.motY *= 0.5D; + this.motZ *= 0.5D; + this.motY -= 0.02D; + if (this.positionChanged && this.c(this.motX, this.motY + 0.6000000238418579D - this.locY + d0, this.motZ)) { + this.motY = 0.30000001192092896D; + } + } else { + float f5 = 0.91F; + + if (this.onGround) { + f5 = this.world.getType(MathHelper.floor(this.locX), MathHelper.floor(this.getBoundingBox().b) - 1, MathHelper.floor(this.locZ)).getBlock().frictionFactor * 0.91F; + } + + float f6 = 0.16277136F / (f5 * f5 * f5); + + if (this.onGround) { + f3 = this.bI() * f6; + } else { + f3 = this.aM; + } + + this.a(f, f1, f3); + f5 = 0.91F; + if (this.onGround) { + f5 = this.world.getType(MathHelper.floor(this.locX), MathHelper.floor(this.getBoundingBox().b) - 1, MathHelper.floor(this.locZ)).getBlock().frictionFactor * 0.91F; + } + + if (this.k_()) { + f4 = 0.15F; + this.motX = MathHelper.a(this.motX, -f4, f4); + this.motZ = MathHelper.a(this.motZ, -f4, f4); + this.fallDistance = 0.0F; + if (this.motY < -0.15D) { + this.motY = -0.15D; + } + + boolean flag = this.isSneaking() && this instanceof EntityHuman; + + if (flag && this.motY < 0.0D) { + this.motY = 0.0D; + } + } + + this.move(this.motX, this.motY, this.motZ); + if (this.positionChanged && this.k_()) { + this.motY = 0.2D; + } + + if (this.world.isClientSide && (!this.world.isLoaded((int) this.locX, 0, (int) this.locZ) || !this.world.getChunkAtWorldCoords((int) this.locX, (int) this.locZ).o())) { + if (this.locY > 0.0D) { + this.motY = -0.1D; + } else { + this.motY = 0.0D; + } + } else { + this.motY -= 0.08D; + } + + this.motY *= 0.9800000190734863D; + this.motX *= f5; + this.motZ *= f5; + } + } + + this.aA = this.aB; + d0 = this.locX - this.lastX; + double d1 = this.locZ - this.lastZ; + + f2 = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F; + if (f2 > 1.0F) { + f2 = 1.0F; + } + + this.aB += (f2 - this.aB) * 0.4F; + this.aC += this.aB; + } + + public float bI() { + return this.bm; + } + + public void k(float f) { + this.bm = f; + } + + public boolean r(Entity entity) { + this.p(entity); + return false; + } + + public boolean isSleeping() { + return false; + } + + public void t_() { + super.t_(); + if (!this.world.isClientSide) { + int i = this.bv(); + + if (i > 0) { + if (this.at <= 0) { + this.at = 20 * (30 - i); + } + + --this.at; + if (this.at <= 0) { + this.o(i - 1); + } + } + + for (int j = 0; j < 5; ++j) { + ItemStack itemstack = this.h[j]; + ItemStack itemstack1 = this.getEquipment(j); + + if (!ItemStack.matches(itemstack1, itemstack)) { + ((WorldServer) this.world).getTracker().a(this, new PacketPlayOutEntityEquipment(this.getId(), j, itemstack1)); + if (itemstack != null) { + this.c.a(itemstack.B()); + } + + if (itemstack1 != null) { + this.c.b(itemstack1.B()); + } + + this.h[j] = itemstack1 == null ? null : itemstack1.cloneItemStack(); + } + } + + if (this.ticksLived % 20 == 0) { + this.bs().g(); + } + } + + this.m(); + double d0 = this.locX - this.lastX; + double d1 = this.locZ - this.lastZ; + float f = (float) (d0 * d0 + d1 * d1); + float f1 = this.aI; + float f2 = 0.0F; + + this.aR = this.aS; + float f3 = 0.0F; + + if (f > 0.0025000002F) { + f3 = 1.0F; + f2 = (float) Math.sqrt(f) * 3.0F; + // CraftBukkit - Math -> TrigMath + f1 = (float) org.bukkit.craftbukkit.TrigMath.atan2(d1, d0) * 180.0F / 3.1415927F - 90.0F; + } + + if (this.az > 0.0F) { + f1 = this.yaw; + } + + if (!this.onGround) { + f3 = 0.0F; + } + + this.aS += (f3 - this.aS) * 0.3F; + this.world.methodProfiler.a("headTurn"); + f2 = this.h(f1, f2); + this.world.methodProfiler.b(); + this.world.methodProfiler.a("rangeChecks"); + + while (this.yaw - this.lastYaw < -180.0F) { + this.lastYaw -= 360.0F; + } + + while (this.yaw - this.lastYaw >= 180.0F) { + this.lastYaw += 360.0F; + } + + while (this.aI - this.aJ < -180.0F) { + this.aJ -= 360.0F; + } + + while (this.aI - this.aJ >= 180.0F) { + this.aJ += 360.0F; + } + + while (this.pitch - this.lastPitch < -180.0F) { + this.lastPitch -= 360.0F; + } + + while (this.pitch - this.lastPitch >= 180.0F) { + this.lastPitch += 360.0F; + } + + while (this.aK - this.aL < -180.0F) { + this.aL -= 360.0F; + } + + while (this.aK - this.aL >= 180.0F) { + this.aL += 360.0F; + } + + this.world.methodProfiler.b(); + this.aT += f2; + } + + protected float h(float f, float f1) { + float f2 = MathHelper.g(f - this.aI); + + this.aI += f2 * 0.3F; + float f3 = MathHelper.g(this.yaw - this.aI); + boolean flag = f3 < -90.0F || f3 >= 90.0F; + + if (f3 < -75.0F) { + f3 = -75.0F; + } + + if (f3 >= 75.0F) { + f3 = 75.0F; + } + + this.aI = this.yaw - f3; + if (f3 * f3 > 2500.0F) { + this.aI += f3 * 0.2F; + } + + if (flag) { + f1 *= -1.0F; + } + + return f1; + } + + public void m() { + if (this.bn > 0) { + --this.bn; + } + + if (this.bc > 0) { + double d0 = this.locX + (this.bd - this.locX) / (double) this.bc; + double d1 = this.locY + (this.be - this.locY) / (double) this.bc; + double d2 = this.locZ + (this.bf - this.locZ) / (double) this.bc; + double d3 = MathHelper.g(this.bg - (double) this.yaw); + + this.yaw = (float) ((double) this.yaw + d3 / (double) this.bc); + this.pitch = (float) ((double) this.pitch + (this.bh - (double) this.pitch) / (double) this.bc); + --this.bc; + this.setPosition(d0, d1, d2); + this.setYawPitch(this.yaw, this.pitch); + } else if (!this.bM()) { + this.motX *= 0.98D; + this.motY *= 0.98D; + this.motZ *= 0.98D; + } + + if (Math.abs(this.motX) < 0.005D) { + this.motX = 0.0D; + } + + if (Math.abs(this.motY) < 0.005D) { + this.motY = 0.0D; + } + + if (Math.abs(this.motZ) < 0.005D) { + this.motZ = 0.0D; + } + + this.world.methodProfiler.a("ai"); + if (this.bD()) { + this.aY = false; + this.aZ = 0.0F; + this.ba = 0.0F; + this.bb = 0.0F; + } else if (this.bM()) { + this.world.methodProfiler.a("newAi"); + this.doTick(); + this.world.methodProfiler.b(); + } + + this.world.methodProfiler.b(); + this.world.methodProfiler.a("jump"); + if (this.aY) { + if (this.V()) { + this.bG(); + } else if (this.ab()) { + this.bH(); + } else if (this.onGround && this.bn == 0) { + this.bF(); + this.bn = 10; + } + } else { + this.bn = 0; + } + + this.world.methodProfiler.b(); + this.world.methodProfiler.a("travel"); + this.aZ *= 0.98F; + this.ba *= 0.98F; + this.bb *= 0.9F; + this.g(this.aZ, this.ba); + this.world.methodProfiler.b(); + this.world.methodProfiler.a("push"); + if (!this.world.isClientSide) { + this.bL(); + } + + this.world.methodProfiler.b(); + } + + protected void doTick() {} + + protected void bL() { + if (MythicConfiguration.Options.Server.entityCollisions) { + return; + } + + List list = this.world.a(this, this.getBoundingBox().grow(0.20000000298023224D, 0.0D, 0.20000000298023224D), Predicates.and(IEntitySelector.d, new Predicate() { + public boolean a(Entity entity) { + return entity.ae(); + } + + public boolean apply(Object object) { + return this.a((Entity) object); + } + })); + + if (this.ad() && !list.isEmpty()) { // Spigot: Add this.ad() condition + numCollisions -= world.spigotConfig.maxCollisionsPerEntity; // Spigot + for (int i = 0; i < list.size(); ++i) { + if (numCollisions > world.spigotConfig.maxCollisionsPerEntity) { break; } // Spigot + Entity entity = (Entity) list.get(i); + + // TODO better check now? + // CraftBukkit start - Only handle mob (non-player) collisions every other tick + if (entity instanceof EntityLiving && !(this instanceof EntityPlayer) && this.ticksLived % 2 == 0) { + continue; + } + // CraftBukkit end + + entity.numCollisions++; // Spigot + numCollisions++; // Spigot + this.s(entity); + } + numCollisions = 0; // Spigot + } + + } + + protected void s(Entity entity) { + entity.collide(this); + } + + public void mount(Entity entity) { + if (this.vehicle != null && entity == null) { + // CraftBukkit start + Entity originalVehicle = this.vehicle; + if ((this.bukkitEntity instanceof LivingEntity) && (this.vehicle.getBukkitEntity() instanceof Vehicle)) { + VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.bukkitEntity); + getBukkitEntity().getServer().getPluginManager().callEvent(event); + + if (event.isCancelled() || vehicle != originalVehicle) { + return; + } + } + // CraftBukkit end + // PaperSpigot start - make dismountEvent cancellable + EntityDismountEvent dismountEvent = new EntityDismountEvent(this.getBukkitEntity(), this.vehicle.getBukkitEntity()); // Spigot + Bukkit.getPluginManager().callEvent(dismountEvent); + if (dismountEvent.isCancelled()) return; + // PaperSpigot end + + if (!this.world.isClientSide) { + this.q(this.vehicle); + } + + if (this.vehicle != null) { + this.vehicle.passenger = null; + } + + this.vehicle = null; + } else { + super.mount(entity); + } + } + + public void ak() { + super.ak(); + this.aR = this.aS; + this.aS = 0.0F; + this.fallDistance = 0.0F; + } + + public void i(boolean flag) { + this.aY = flag; + } + + public void receive(Entity entity, int i) { + if (!entity.dead && !this.world.isClientSide) { + EntityTracker entitytracker = ((WorldServer) this.world).getTracker(); + + if (entity instanceof EntityItem) { + entitytracker.a(entity, new PacketPlayOutCollect(entity.getId(), this.getId())); + } + + if (entity instanceof EntityArrow) { + entitytracker.a(entity, new PacketPlayOutCollect(entity.getId(), this.getId())); + } + + if (entity instanceof EntityExperienceOrb) { + entitytracker.a(entity, new PacketPlayOutCollect(entity.getId(), this.getId())); + } + } + + } + + public boolean hasLineOfSight(Entity entity) { + return this.world.rayTrace(new Vec3D(this.locX, this.locY + (double) this.getHeadHeight(), this.locZ), new Vec3D(entity.locX, entity.locY + (double) entity.getHeadHeight(), entity.locZ)) == null; + } + + public Vec3D ap() { + return this.d(1.0F); + } + + public Vec3D d(float f) { + if (f == 1.0F) { + return this.f(this.pitch, this.aK); + } else { + float f1 = this.lastPitch + (this.pitch - this.lastPitch) * f; + float f2 = this.aL + (this.aK - this.aL) * f; + + return this.f(f1, f2); + } + } + + public boolean bM() { + return !this.world.isClientSide; + } + + public boolean ad() { + return !this.dead; + } + + public boolean ae() { + return !this.dead; + } + + protected void ac() { + this.velocityChanged = this.random.nextDouble() >= this.getAttributeInstance(GenericAttributes.c).getValue(); + } + + public float getHeadRotation() { + return this.aK; + } + + public void f(float f) { + this.aK = f; + } + + public void g(float f) { + this.aI = f; + } + + public float getAbsorptionHearts() { + return this.bo; + } + + public void setAbsorptionHearts(float f) { + if (f < 0.0F) { + f = 0.0F; + } + + this.bo = f; + } + + public ScoreboardTeamBase getScoreboardTeam() { + if (!this.world.tacoSpigotConfig.nonPlayerEntitiesOnScoreboards && !(this instanceof EntityHuman)) return null; // TacoSpigot + return this.world.getScoreboard().getPlayerTeam(this.getUniqueID().toString()); + } + + public boolean c(EntityLiving entityliving) { + return this.a(entityliving.getScoreboardTeam()); + } + + public boolean a(ScoreboardTeamBase scoreboardteambase) { + return this.getScoreboardTeam() != null && this.getScoreboardTeam().isAlly(scoreboardteambase); + } + + public void enterCombat() {} + + public void exitCombat() {} + + protected void bP() { + this.updateEffects = true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartAbstract.java new file mode 100644 index 0000000..8682503 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartAbstract.java @@ -0,0 +1,989 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import org.bukkit.Location; +import org.bukkit.entity.Vehicle; +import org.bukkit.event.vehicle.VehicleDamageEvent; +import org.bukkit.event.vehicle.VehicleDestroyEvent; +import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; +import org.bukkit.util.Vector; + +import java.util.Iterator; +import java.util.Map; + +// CraftBukkit start +// CraftBukkit end + +public abstract class EntityMinecartAbstract extends Entity implements INamableTileEntity { + + private boolean a; + private String b; + private static final int[][][] matrix = new int[][][] { { { 0, 0, -1}, { 0, 0, 1}}, { { -1, 0, 0}, { 1, 0, 0}}, { { -1, -1, 0}, { 1, 0, 0}}, { { -1, 0, 0}, { 1, -1, 0}}, { { 0, 0, -1}, { 0, -1, 1}}, { { 0, -1, -1}, { 0, 0, 1}}, { { 0, 0, 1}, { 1, 0, 0}}, { { 0, 0, 1}, { -1, 0, 0}}, { { 0, 0, -1}, { -1, 0, 0}}, { { 0, 0, -1}, { 1, 0, 0}}}; + private int d; + private double e; + private double f; + private double g; + private double h; + private double i; + + // CraftBukkit start + public boolean slowWhenEmpty = true; + private double derailedX = 0.5; + private double derailedY = 0.5; + private double derailedZ = 0.5; + private double flyingX = 0.95; + private double flyingY = 0.95; + private double flyingZ = 0.95; + public double maxSpeed = 0.4D; + // CraftBukkit end + + public EntityMinecartAbstract(World world) { + super(world); + this.k = true; + this.setSize(0.98F, 0.7F); + } + + public static EntityMinecartAbstract a(World world, double d0, double d1, double d2, EntityMinecartAbstract.EnumMinecartType entityminecartabstract_enumminecarttype) { + switch (EntityMinecartAbstract.SyntheticClass_1.a[entityminecartabstract_enumminecarttype.ordinal()]) { + case 1: + return new EntityMinecartChest(world, d0, d1, d2); + + case 2: + return new EntityMinecartFurnace(world, d0, d1, d2); + + case 3: + return new EntityMinecartTNT(world, d0, d1, d2); + + case 4: + return new EntityMinecartMobSpawner(world, d0, d1, d2); + + case 5: + return new EntityMinecartHopper(world, d0, d1, d2); + + case 6: + return new EntityMinecartCommandBlock(world, d0, d1, d2); + + default: + return new EntityMinecartRideable(world, d0, d1, d2); + } + } + + protected boolean s_() { + return false; + } + + protected void h() { + this.datawatcher.a(17, new Integer(0)); + this.datawatcher.a(18, new Integer(1)); + this.datawatcher.a(19, new Float(0.0F)); + this.datawatcher.a(20, new Integer(0)); + this.datawatcher.a(21, new Integer(6)); + this.datawatcher.a(22, Byte.valueOf((byte) 0)); + } + + public AxisAlignedBB j(Entity entity) { + return entity.ae() ? entity.getBoundingBox() : null; + } + + public AxisAlignedBB S() { + return null; + } + + public boolean ae() { + return true; + } + + public EntityMinecartAbstract(World world, double d0, double d1, double d2) { + this(world); + this.setPosition(d0, d1, d2); + this.motX = 0.0D; + this.motY = 0.0D; + this.motZ = 0.0D; + this.lastX = d0; + this.lastY = d1; + this.lastZ = d2; + + this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleCreateEvent((Vehicle) this.getBukkitEntity())); // CraftBukkit + } + + public double an() { + return 0.0D; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (!this.world.isClientSide && !this.dead) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + // CraftBukkit start - fire VehicleDamageEvent + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); + org.bukkit.entity.Entity passenger = (damagesource.getEntity() == null) ? null : damagesource.getEntity().getBukkitEntity(); + + VehicleDamageEvent event = new VehicleDamageEvent(vehicle, passenger, f); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return true; + } + + f = (float) event.getDamage(); + // CraftBukkit end + this.k(-this.r()); + this.j(10); + this.ac(); + this.setDamage(this.getDamage() + f * 10.0F); + boolean flag = damagesource.getEntity() instanceof EntityHuman && ((EntityHuman) damagesource.getEntity()).abilities.canInstantlyBuild; + + if (flag || this.getDamage() > 40.0F) { + // CraftBukkit start + VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, passenger); + this.world.getServer().getPluginManager().callEvent(destroyEvent); + + if (destroyEvent.isCancelled()) { + this.setDamage(40); // Maximize damage so this doesn't get triggered again right away + return true; + } + // CraftBukkit end + if (this.passenger != null) { + this.passenger.mount(null); + } + + if (flag && !this.hasCustomName()) { + this.die(); + } else { + this.a(damagesource); + } + } + + return true; + } + } else { + return true; + } + } + + public void a(DamageSource damagesource) { + this.die(); + if (this.world.getGameRules().getBoolean("doEntityDrops")) { + ItemStack itemstack = new ItemStack(Items.MINECART, 1); + + if (this.b != null) { + itemstack.c(this.b); + } + + this.a(itemstack, 0.0F); + } + + } + + public boolean ad() { + return !this.dead; + } + + public void die() { + super.die(); + } + + public void t_() { + // CraftBukkit start + double prevX = this.locX; + double prevY = this.locY; + double prevZ = this.locZ; + float prevYaw = this.yaw; + float prevPitch = this.pitch; + // CraftBukkit end + + if (this.getType() > 0) { + this.j(this.getType() - 1); + } + + if (this.getDamage() > 0.0F) { + this.setDamage(this.getDamage() - 1.0F); + } + + if (this.locY < -64.0D) { + this.O(); + } + + int i; + + if (!this.world.isClientSide && this.world instanceof WorldServer) { + this.world.methodProfiler.a("portal"); + MinecraftServer minecraftserver = ((WorldServer) this.world).getMinecraftServer(); + + i = this.L(); + if (this.ak) { + if (true || minecraftserver.getAllowNether()) { // CraftBukkit - multi-world should still allow teleport even if default vanilla nether disabled + if (this.vehicle == null && this.al++ >= i) { + this.al = i; + this.portalCooldown = this.aq(); + byte b0; + + if (this.world.worldProvider.getDimension() == -1) { + b0 = 0; + } else { + b0 = -1; + } + + this.c(b0); + } + + this.ak = false; + } + } else { + if (this.al > 0) { + this.al -= 4; + } + + if (this.al < 0) { + this.al = 0; + } + } + + if (this.portalCooldown > 0) { + --this.portalCooldown; + } + + this.world.methodProfiler.b(); + } + + if (this.world.isClientSide) { + if (this.d > 0) { + double d0 = this.locX + (this.e - this.locX) / (double) this.d; + double d1 = this.locY + (this.f - this.locY) / (double) this.d; + double d2 = this.locZ + (this.g - this.locZ) / (double) this.d; + double d3 = MathHelper.g(this.h - (double) this.yaw); + + this.yaw = (float) ((double) this.yaw + d3 / (double) this.d); + this.pitch = (float) ((double) this.pitch + (this.i - (double) this.pitch) / (double) this.d); + --this.d; + this.setPosition(d0, d1, d2); + this.setYawPitch(this.yaw, this.pitch); + } else { + this.setPosition(this.locX, this.locY, this.locZ); + this.setYawPitch(this.yaw, this.pitch); + } + + } else { + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + this.motY -= 0.03999999910593033D; + int j = MathHelper.floor(this.locX); + + i = MathHelper.floor(this.locY); + int k = MathHelper.floor(this.locZ); + + if (BlockMinecartTrackAbstract.e(this.world, new BlockPosition(j, i - 1, k))) { + --i; + } + + BlockPosition blockposition = new BlockPosition(j, i, k); + IBlockData iblockdata = this.world.getType(blockposition); + + if (BlockMinecartTrackAbstract.d(iblockdata)) { + this.a(blockposition, iblockdata); + if (iblockdata.getBlock() == Blocks.ACTIVATOR_RAIL) { + this.a(j, i, k, iblockdata.get(BlockPoweredRail.POWERED).booleanValue()); + } + } else { + this.n(); + } + + this.checkBlockCollisions(); + this.pitch = 0.0F; + double d4 = this.lastX - this.locX; + double d5 = this.lastZ - this.locZ; + + if (d4 * d4 + d5 * d5 > 0.001D) { + this.yaw = (float) (MathHelper.b(d5, d4) * 180.0D / 3.141592653589793D); + if (this.a) { + this.yaw += 180.0F; + } + } + + double d6 = MathHelper.g(this.yaw - this.lastYaw); + + if (d6 < -170.0D || d6 >= 170.0D) { + this.yaw += 180.0F; + this.a = !this.a; + } + + this.setYawPitch(this.yaw, this.pitch); + + // CraftBukkit start + org.bukkit.World bworld = this.world.getWorld(); + Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); + Location to = new Location(bworld, this.locX, this.locY, this.locZ, this.yaw, this.pitch); + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); + + this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle)); + + if (!from.equals(to)) { + this.world.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to)); + } + // CraftBukkit end + + Iterator iterator = this.world.getEntities(this, this.getBoundingBox().grow(0.20000000298023224D, 0.0D, 0.20000000298023224D)).iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (entity != this.passenger && entity.ae() && entity instanceof EntityMinecartAbstract) { + entity.collide(this); + } + } + + if (this.passenger != null && this.passenger.dead) { + if (this.passenger.vehicle == this) { + this.passenger.vehicle = null; + } + + this.passenger = null; + } + + this.W(); + } + } + + protected double m() { + return this.maxSpeed; // CraftBukkit + } + + public void a(int i, int j, int k, boolean flag) {} + + protected void n() { + double d0 = this.m(); + + this.motX = MathHelper.a(this.motX, -d0, d0); + this.motZ = MathHelper.a(this.motZ, -d0, d0); + if (this.onGround) { + // CraftBukkit start - replace magic numbers with our variables + this.motX *= this.derailedX; + this.motY *= this.derailedY; + this.motZ *= this.derailedZ; + // CraftBukkit end + } + + this.move(this.motX, this.motY, this.motZ); + if (!this.onGround) { + // CraftBukkit start - replace magic numbers with our variables + this.motX *= this.flyingX; + this.motY *= this.flyingY; + this.motZ *= this.flyingZ; + // CraftBukkit end + } + + } + + protected void a(BlockPosition blockposition, IBlockData iblockdata) { + this.fallDistance = 0.0F; + Vec3D vec3d = this.k(this.locX, this.locY, this.locZ); + + this.locY = blockposition.getY(); + boolean flag = false; + boolean flag1 = false; + BlockMinecartTrackAbstract blockminecarttrackabstract = (BlockMinecartTrackAbstract) iblockdata.getBlock(); + + if (blockminecarttrackabstract == Blocks.GOLDEN_RAIL) { + flag = iblockdata.get(BlockPoweredRail.POWERED).booleanValue(); + flag1 = !flag; + } + + double d0 = 0.0078125D; + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = iblockdata.get(blockminecarttrackabstract.n()); + + switch (EntityMinecartAbstract.SyntheticClass_1.b[blockminecarttrackabstract_enumtrackposition.ordinal()]) { + case 1: + this.motX -= 0.0078125D; + ++this.locY; + break; + + case 2: + this.motX += 0.0078125D; + ++this.locY; + break; + + case 3: + this.motZ += 0.0078125D; + ++this.locY; + break; + + case 4: + this.motZ -= 0.0078125D; + ++this.locY; + } + + int[][] aint = EntityMinecartAbstract.matrix[blockminecarttrackabstract_enumtrackposition.a()]; + double d1 = aint[1][0] - aint[0][0]; + double d2 = aint[1][2] - aint[0][2]; + double d3 = Math.sqrt(d1 * d1 + d2 * d2); + double d4 = this.motX * d1 + this.motZ * d2; + + if (d4 < 0.0D) { + d1 = -d1; + d2 = -d2; + } + + double d5 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + + if (d5 > 2.0D) { + d5 = 2.0D; + } + + this.motX = d5 * d1 / d3; + this.motZ = d5 * d2 / d3; + double d6; + double d7; + double d8; + double d9; + + if (this.passenger instanceof EntityLiving) { + d6 = ((EntityLiving) this.passenger).ba; + if (d6 > 0.0D) { + d7 = -Math.sin(this.passenger.yaw * 3.1415927F / 180.0F); + d8 = Math.cos(this.passenger.yaw * 3.1415927F / 180.0F); + d9 = this.motX * this.motX + this.motZ * this.motZ; + if (d9 < 0.01D) { + this.motX += d7 * 0.1D; + this.motZ += d8 * 0.1D; + flag1 = false; + } + } + } + + if (flag1) { + d6 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + if (d6 < 0.03D) { + this.motX *= 0.0D; + this.motY *= 0.0D; + this.motZ *= 0.0D; + } else { + this.motX *= 0.5D; + this.motY *= 0.0D; + this.motZ *= 0.5D; + } + } + + d6 = 0.0D; + d7 = (double) blockposition.getX() + 0.5D + (double) aint[0][0] * 0.5D; + d8 = (double) blockposition.getZ() + 0.5D + (double) aint[0][2] * 0.5D; + d9 = (double) blockposition.getX() + 0.5D + (double) aint[1][0] * 0.5D; + double d10 = (double) blockposition.getZ() + 0.5D + (double) aint[1][2] * 0.5D; + + d1 = d9 - d7; + d2 = d10 - d8; + double d11; + double d12; + + if (d1 == 0.0D) { + this.locX = (double) blockposition.getX() + 0.5D; + d6 = this.locZ - (double) blockposition.getZ(); + } else if (d2 == 0.0D) { + this.locZ = (double) blockposition.getZ() + 0.5D; + d6 = this.locX - (double) blockposition.getX(); + } else { + d11 = this.locX - d7; + d12 = this.locZ - d8; + d6 = (d11 * d1 + d12 * d2) * 2.0D; + } + + this.locX = d7 + d1 * d6; + this.locZ = d8 + d2 * d6; + this.setPosition(this.locX, this.locY, this.locZ); + d11 = this.motX; + d12 = this.motZ; + if (this.passenger != null) { + d11 *= 0.75D; + d12 *= 0.75D; + } + + double d13 = this.m(); + + d11 = MathHelper.a(d11, -d13, d13); + d12 = MathHelper.a(d12, -d13, d13); + this.move(d11, 0.0D, d12); + if (aint[0][1] != 0 && MathHelper.floor(this.locX) - blockposition.getX() == aint[0][0] && MathHelper.floor(this.locZ) - blockposition.getZ() == aint[0][2]) { + this.setPosition(this.locX, this.locY + (double) aint[0][1], this.locZ); + } else if (aint[1][1] != 0 && MathHelper.floor(this.locX) - blockposition.getX() == aint[1][0] && MathHelper.floor(this.locZ) - blockposition.getZ() == aint[1][2]) { + this.setPosition(this.locX, this.locY + (double) aint[1][1], this.locZ); + } + + this.o(); + Vec3D vec3d1 = this.k(this.locX, this.locY, this.locZ); + + if (vec3d1 != null && vec3d != null) { + double d14 = (vec3d.b - vec3d1.b) * 0.05D; + + d5 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + if (d5 > 0.0D) { + this.motX = this.motX / d5 * (d5 + d14); + this.motZ = this.motZ / d5 * (d5 + d14); + } + + this.setPosition(this.locX, vec3d1.b, this.locZ); + } + + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locZ); + + if (i != blockposition.getX() || j != blockposition.getZ()) { + d5 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + this.motX = d5 * (double) (i - blockposition.getX()); + this.motZ = d5 * (double) (j - blockposition.getZ()); + } + + if (flag) { + double d15 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ); + + if (d15 > 0.01D) { + double d16 = 0.06D; + + this.motX += this.motX / d15 * d16; + this.motZ += this.motZ / d15 * d16; + } else if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.EAST_WEST) { + if (this.world.getType(blockposition.west()).getBlock().isOccluding()) { + this.motX = 0.02D; + } else if (this.world.getType(blockposition.east()).getBlock().isOccluding()) { + this.motX = -0.02D; + } + } else if (blockminecarttrackabstract_enumtrackposition == BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH) { + if (this.world.getType(blockposition.north()).getBlock().isOccluding()) { + this.motZ = 0.02D; + } else if (this.world.getType(blockposition.south()).getBlock().isOccluding()) { + this.motZ = -0.02D; + } + } + } + + } + + protected void o() { + if (this.passenger != null || !this.slowWhenEmpty) { // CraftBukkit - add !this.slowWhenEmpty + this.motX *= 0.996999979019165D; + this.motY *= 0.0D; + this.motZ *= 0.996999979019165D; + } else { + this.motX *= 0.9599999785423279D; + this.motY *= 0.0D; + this.motZ *= 0.9599999785423279D; + } + + } + + public void setPosition(double d0, double d1, double d2) { + this.locX = d0; + this.locY = d1; + this.locZ = d2; + float f = this.width / 2.0F; + float f1 = this.length; + + this.a(new AxisAlignedBB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f)); + } + + public Vec3D k(double d0, double d1, double d2) { + int i = MathHelper.floor(d0); + int j = MathHelper.floor(d1); + int k = MathHelper.floor(d2); + + if (BlockMinecartTrackAbstract.e(this.world, new BlockPosition(i, j - 1, k))) { + --j; + } + + IBlockData iblockdata = this.world.getType(i, j, k); + + if (BlockMinecartTrackAbstract.d(iblockdata)) { + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = iblockdata.get(((BlockMinecartTrackAbstract) iblockdata.getBlock()).n()); + int[][] aint = EntityMinecartAbstract.matrix[blockminecarttrackabstract_enumtrackposition.a()]; + double d3 = 0.0D; + double d4 = (double) i + 0.5D + (double) aint[0][0] * 0.5D; + double d5 = (double) j + 0.0625D + (double) aint[0][1] * 0.5D; + double d6 = (double) k + 0.5D + (double) aint[0][2] * 0.5D; + double d7 = (double) i + 0.5D + (double) aint[1][0] * 0.5D; + double d8 = (double) j + 0.0625D + (double) aint[1][1] * 0.5D; + double d9 = (double) k + 0.5D + (double) aint[1][2] * 0.5D; + double d10 = d7 - d4; + double d11 = (d8 - d5) * 2.0D; + double d12 = d9 - d6; + + if (d10 == 0.0D) { + d0 = (double) i + 0.5D; + d3 = d2 - (double) k; + } else if (d12 == 0.0D) { + d2 = (double) k + 0.5D; + d3 = d0 - (double) i; + } else { + double d13 = d0 - d4; + double d14 = d2 - d6; + + d3 = (d13 * d10 + d14 * d12) * 2.0D; + } + + d0 = d4 + d10 * d3; + d1 = d5 + d11 * d3; + d2 = d6 + d12 * d3; + if (d11 < 0.0D) { + ++d1; + } + + if (d11 > 0.0D) { + d1 += 0.5D; + } + + return new Vec3D(d0, d1, d2); + } else { + return null; + } + } + + protected void a(NBTTagCompound nbttagcompound) { + if (nbttagcompound.getBoolean("CustomDisplayTile")) { + int i = nbttagcompound.getInt("DisplayData"); + Block block; + + if (nbttagcompound.hasKeyOfType("DisplayTile", 8)) { + block = Block.getByName(nbttagcompound.getString("DisplayTile")); + if (block == null) { + this.setDisplayBlock(Blocks.AIR.getBlockData()); + } else { + this.setDisplayBlock(block.fromLegacyData(i)); + } + } else { + block = Block.getById(nbttagcompound.getInt("DisplayTile")); + if (block == null) { + this.setDisplayBlock(Blocks.AIR.getBlockData()); + } else { + this.setDisplayBlock(block.fromLegacyData(i)); + } + } + + this.SetDisplayBlockOffset(nbttagcompound.getInt("DisplayOffset")); + } + + if (nbttagcompound.hasKeyOfType("CustomName", 8) && nbttagcompound.getString("CustomName").length() > 0) { + this.b = nbttagcompound.getString("CustomName"); + } + + } + + protected void b(NBTTagCompound nbttagcompound) { + if (this.x()) { + nbttagcompound.setBoolean("CustomDisplayTile", true); + IBlockData iblockdata = this.getDisplayBlock(); + MinecraftKey minecraftkey = Block.REGISTRY.c(iblockdata.getBlock()); + + nbttagcompound.setString("DisplayTile", minecraftkey == null ? "" : minecraftkey.toString()); + nbttagcompound.setInt("DisplayData", iblockdata.getBlock().toLegacyData(iblockdata)); + nbttagcompound.setInt("DisplayOffset", this.getDisplayBlockOffset()); + } + + if (this.b != null && this.b.length() > 0) { + nbttagcompound.setString("CustomName", this.b); + } + + } + + public void collide(Entity entity) { + if (!this.world.isClientSide) { + if (!entity.noclip && !this.noclip) { + if (entity != this.passenger) { + // CraftBukkit start + Vehicle vehicle = (Vehicle) this.getBukkitEntity(); + org.bukkit.entity.Entity hitEntity = (entity == null) ? null : entity.getBukkitEntity(); + + VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent(vehicle, hitEntity); + this.world.getServer().getPluginManager().callEvent(collisionEvent); + + if (collisionEvent.isCancelled()) { + return; + } + // CraftBukkit end + if (entity instanceof EntityLiving && !(entity instanceof EntityHuman) && !(entity instanceof EntityIronGolem) && this.s() == EntityMinecartAbstract.EnumMinecartType.RIDEABLE && this.motX * this.motX + this.motZ * this.motZ > 0.01D && this.passenger == null && entity.vehicle == null) { + entity.mount(this); + } + + double d0 = entity.locX - this.locX; + double d1 = entity.locZ - this.locZ; + double d2 = d0 * d0 + d1 * d1; + + // CraftBukkit - collision + if (d2 >= 9.999999747378752E-5D && !collisionEvent.isCollisionCancelled()) { + d2 = MathHelper.sqrt(d2); + d0 /= d2; + d1 /= d2; + double d3 = 1.0D / d2; + + if (d3 > 1.0D) { + d3 = 1.0D; + } + + d0 *= d3; + d1 *= d3; + d0 *= 0.10000000149011612D; + d1 *= 0.10000000149011612D; + d0 *= 1.0F - this.U; + d1 *= 1.0F - this.U; + d0 *= 0.5D; + d1 *= 0.5D; + if (entity instanceof EntityMinecartAbstract) { + double d4 = entity.locX - this.locX; + double d5 = entity.locZ - this.locZ; + Vec3D vec3d = (new Vec3D(d4, 0.0D, d5)).a(); + Vec3D vec3d1 = (new Vec3D(MathHelper.cos(this.yaw * 3.1415927F / 180.0F), 0.0D, MathHelper.sin(this.yaw * 3.1415927F / 180.0F))).a(); + double d6 = Math.abs(vec3d.b(vec3d1)); + + if (d6 < 0.800000011920929D) { + return; + } + + double d7 = entity.motX + this.motX; + double d8 = entity.motZ + this.motZ; + + if (((EntityMinecartAbstract) entity).s() == EntityMinecartAbstract.EnumMinecartType.FURNACE && this.s() != EntityMinecartAbstract.EnumMinecartType.FURNACE) { + this.motX *= 0.20000000298023224D; + this.motZ *= 0.20000000298023224D; + this.g(entity.motX - d0, 0.0D, entity.motZ - d1); + entity.motX *= 0.949999988079071D; + entity.motZ *= 0.949999988079071D; + } else if (((EntityMinecartAbstract) entity).s() != EntityMinecartAbstract.EnumMinecartType.FURNACE && this.s() == EntityMinecartAbstract.EnumMinecartType.FURNACE) { + entity.motX *= 0.20000000298023224D; + entity.motZ *= 0.20000000298023224D; + entity.g(this.motX + d0, 0.0D, this.motZ + d1); + this.motX *= 0.949999988079071D; + this.motZ *= 0.949999988079071D; + } else { + d7 /= 2.0D; + d8 /= 2.0D; + this.motX *= 0.20000000298023224D; + this.motZ *= 0.20000000298023224D; + this.g(d7 - d0, 0.0D, d8 - d1); + entity.motX *= 0.20000000298023224D; + entity.motZ *= 0.20000000298023224D; + entity.g(d7 + d0, 0.0D, d8 + d1); + } + } else { + this.g(-d0, 0.0D, -d1); + entity.g(d0 / 4.0D, 0.0D, d1 / 4.0D); + } + } + + } + } + } + } + + public void setDamage(float f) { + this.datawatcher.watch(19, Float.valueOf(f)); + } + + public float getDamage() { + return this.datawatcher.getFloat(19); + } + + public void j(int i) { + this.datawatcher.watch(17, Integer.valueOf(i)); + } + + public int getType() { + return this.datawatcher.getInt(17); + } + + public void k(int i) { + this.datawatcher.watch(18, Integer.valueOf(i)); + } + + public int r() { + return this.datawatcher.getInt(18); + } + + public abstract EntityMinecartAbstract.EnumMinecartType s(); + + public IBlockData getDisplayBlock() { + return !this.x() ? this.u() : Block.getByCombinedId(this.getDataWatcher().getInt(20)); + } + + public IBlockData u() { + return Blocks.AIR.getBlockData(); + } + + public int getDisplayBlockOffset() { + return !this.x() ? this.w() : this.getDataWatcher().getInt(21); + } + + public int w() { + return 6; + } + + public void setDisplayBlock(IBlockData iblockdata) { + this.getDataWatcher().watch(20, Integer.valueOf(Block.getCombinedId(iblockdata))); + this.a(true); + } + + public void SetDisplayBlockOffset(int i) { + this.getDataWatcher().watch(21, Integer.valueOf(i)); + this.a(true); + } + + public boolean x() { + return this.getDataWatcher().getByte(22) == 1; + } + + public void a(boolean flag) { + this.getDataWatcher().watch(22, Byte.valueOf((byte) (flag ? 1 : 0))); + } + + public void setCustomName(String s) { + this.b = s; + } + + public String getName() { + return this.b != null ? this.b : super.getName(); + } + + public boolean hasCustomName() { + return this.b != null; + } + + public String getCustomName() { + return this.b; + } + + public IChatBaseComponent getScoreboardDisplayName() { + if (this.hasCustomName()) { + ChatComponentText chatcomponenttext = new ChatComponentText(this.b); + + chatcomponenttext.getChatModifier().setChatHoverable(this.aQ()); + chatcomponenttext.getChatModifier().setInsertion(this.getUniqueID().toString()); + return chatcomponenttext; + } else { + ChatMessage chatmessage = new ChatMessage(this.getName()); + + chatmessage.getChatModifier().setChatHoverable(this.aQ()); + chatmessage.getChatModifier().setInsertion(this.getUniqueID().toString()); + return chatmessage; + } + } + + static class SyntheticClass_1 { + + static final int[] a; + static final int[] b = new int[BlockMinecartTrackAbstract.EnumTrackPosition.values().length]; + + static { + try { + EntityMinecartAbstract.SyntheticClass_1.b[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_EAST.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + } + + try { + EntityMinecartAbstract.SyntheticClass_1.b[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_WEST.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + } + + try { + EntityMinecartAbstract.SyntheticClass_1.b[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_NORTH.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + } + + try { + EntityMinecartAbstract.SyntheticClass_1.b[BlockMinecartTrackAbstract.EnumTrackPosition.ASCENDING_SOUTH.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + } + + a = new int[EntityMinecartAbstract.EnumMinecartType.values().length]; + + try { + EntityMinecartAbstract.SyntheticClass_1.a[EntityMinecartAbstract.EnumMinecartType.CHEST.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror4) { + } + + try { + EntityMinecartAbstract.SyntheticClass_1.a[EntityMinecartAbstract.EnumMinecartType.FURNACE.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror5) { + } + + try { + EntityMinecartAbstract.SyntheticClass_1.a[EntityMinecartAbstract.EnumMinecartType.TNT.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror6) { + } + + try { + EntityMinecartAbstract.SyntheticClass_1.a[EntityMinecartAbstract.EnumMinecartType.SPAWNER.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror7) { + } + + try { + EntityMinecartAbstract.SyntheticClass_1.a[EntityMinecartAbstract.EnumMinecartType.HOPPER.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror8) { + } + + try { + EntityMinecartAbstract.SyntheticClass_1.a[EntityMinecartAbstract.EnumMinecartType.COMMAND_BLOCK.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror9) { + } + + } + } + + public enum EnumMinecartType { + + RIDEABLE(0, "MinecartRideable"), CHEST(1, "MinecartChest"), FURNACE(2, "MinecartFurnace"), TNT(3, "MinecartTNT"), SPAWNER(4, "MinecartSpawner"), HOPPER(5, "MinecartHopper"), COMMAND_BLOCK(6, "MinecartCommandBlock"); + + private static final Map h = Maps.newHashMap(); + private final int i; + private final String j; + + EnumMinecartType(int i, String s) { + this.i = i; + this.j = s; + } + + public int a() { + return this.i; + } + + public String b() { + return this.j; + } + + public static EntityMinecartAbstract.EnumMinecartType a(int i) { + EntityMinecartAbstract.EnumMinecartType entityminecartabstract_enumminecarttype = EnumMinecartType.h.get(Integer.valueOf(i)); + + return entityminecartabstract_enumminecarttype == null ? EntityMinecartAbstract.EnumMinecartType.RIDEABLE : entityminecartabstract_enumminecarttype; + } + + static { + EntityMinecartAbstract.EnumMinecartType[] aentityminecartabstract_enumminecarttype = values(); + int i = aentityminecartabstract_enumminecarttype.length; + + for (int j = 0; j < i; ++j) { + EntityMinecartAbstract.EnumMinecartType entityminecartabstract_enumminecarttype = aentityminecartabstract_enumminecarttype[j]; + + EntityMinecartAbstract.EnumMinecartType.h.put(Integer.valueOf(entityminecartabstract_enumminecarttype.a()), entityminecartabstract_enumminecarttype); + } + + } + } + + // CraftBukkit start - Methods for getting and setting flying and derailed velocity modifiers + public Vector getFlyingVelocityMod() { + return new Vector(flyingX, flyingY, flyingZ); + } + + public void setFlyingVelocityMod(Vector flying) { + flyingX = flying.getX(); + flyingY = flying.getY(); + flyingZ = flying.getZ(); + } + + public Vector getDerailedVelocityMod() { + return new Vector(derailedX, derailedY, derailedZ); + } + + public void setDerailedVelocityMod(Vector derailed) { + derailedX = derailed.getX(); + derailedY = derailed.getY(); + derailedZ = derailed.getZ(); + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java new file mode 100644 index 0000000..44ae155 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java @@ -0,0 +1,96 @@ +package net.minecraft.server; + +public class EntityMinecartCommandBlock extends EntityMinecartAbstract { + + private final CommandBlockListenerAbstract a = new CommandBlockListenerAbstract() { + { + this.sender = (org.bukkit.craftbukkit.entity.CraftMinecartCommand) EntityMinecartCommandBlock.this.getBukkitEntity(); // CraftBukkit - Set the sender + } + public void h() { + EntityMinecartCommandBlock.this.getDataWatcher().watch(23, this.getCommand()); + EntityMinecartCommandBlock.this.getDataWatcher().watch(24, IChatBaseComponent.ChatSerializer.a(this.k())); + } + + public BlockPosition getChunkCoordinates() { + return new BlockPosition(EntityMinecartCommandBlock.this.locX, EntityMinecartCommandBlock.this.locY + 0.5D, EntityMinecartCommandBlock.this.locZ); + } + + public Vec3D d() { + return new Vec3D(EntityMinecartCommandBlock.this.locX, EntityMinecartCommandBlock.this.locY, EntityMinecartCommandBlock.this.locZ); + } + + public World getWorld() { + return EntityMinecartCommandBlock.this.world; + } + + public Entity f() { + return EntityMinecartCommandBlock.this; + } + }; + private int b = 0; + + public EntityMinecartCommandBlock(World world) { + super(world); + } + + public EntityMinecartCommandBlock(World world, double d0, double d1, double d2) { + super(world, d0, d1, d2); + } + + protected void h() { + super.h(); + this.getDataWatcher().a(23, ""); + this.getDataWatcher().a(24, ""); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.a.b(nbttagcompound); + this.getDataWatcher().watch(23, this.getCommandBlock().getCommand()); + this.getDataWatcher().watch(24, IChatBaseComponent.ChatSerializer.a(this.getCommandBlock().k())); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.a.a(nbttagcompound); + } + + public EntityMinecartAbstract.EnumMinecartType s() { + return EntityMinecartAbstract.EnumMinecartType.COMMAND_BLOCK; + } + + public IBlockData u() { + return Blocks.COMMAND_BLOCK.getBlockData(); + } + + public CommandBlockListenerAbstract getCommandBlock() { + return this.a; + } + + public void a(int i, int j, int k, boolean flag) { + if (flag && this.ticksLived - this.b >= 4) { + this.getCommandBlock().a(this.world); + this.b = this.ticksLived; + } + + } + + public boolean e(EntityHuman entityhuman) { + this.a.a(entityhuman); + return false; + } + + public void i(int i) { + super.i(i); + if (i == 24) { + try { + this.a.b(IChatBaseComponent.ChatSerializer.a(this.getDataWatcher().getString(24))); + } catch (Throwable throwable) { + ; + } + } else if (i == 23) { + this.a.setCommand(this.getDataWatcher().getString(23)); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartContainer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartContainer.java new file mode 100644 index 0000000..7368f16 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartContainer.java @@ -0,0 +1,247 @@ +package net.minecraft.server; + +// CraftBukkit start +import java.util.List; + +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.InventoryHolder; +// CraftBukkit end +import net.techcable.tacospigot.HopperPusher; // TacoSpigot + +// TacoSpigot start - HopperPusher +public abstract class EntityMinecartContainer extends EntityMinecartAbstract implements ITileInventory, HopperPusher { + + @Override + public boolean acceptItem(TileEntityHopper hopper) { + return TileEntityHopper.acceptItem(hopper, this); + } + // TacoSpigot end + + private ItemStack[] items = new ItemStack[27]; // CraftBukkit - 36 -> 27 + private boolean b = true; + + // CraftBukkit start + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public InventoryHolder getOwner() { + org.bukkit.entity.Entity cart = getBukkitEntity(); + if(cart instanceof InventoryHolder) return (InventoryHolder) cart; + return null; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public EntityMinecartContainer(World world) { + super(world); + } + + public EntityMinecartContainer(World world, double d0, double d1, double d2) { + super(world, d0, d1, d2); + } + + public void a(DamageSource damagesource) { + super.a(damagesource); + if (this.world.getGameRules().getBoolean("doEntityDrops")) { + InventoryUtils.dropEntity(this.world, this, this); + } + + } + + // TacoSpigot start + @Override + public void t_() { + super.t_(); + tryPutInHopper(); + } + + @Override + public void inactiveTick() { + super.inactiveTick(); + tryPutInHopper(); + } + // TacoSpigot end + + public ItemStack getItem(int i) { + return this.items[i]; + } + + public ItemStack splitStack(int i, int j) { + if (this.items[i] != null) { + ItemStack itemstack; + + if (this.items[i].count <= j) { + itemstack = this.items[i]; + this.items[i] = null; + return itemstack; + } else { + itemstack = this.items[i].cloneAndSubtract(j); + if (this.items[i].count == 0) { + this.items[i] = null; + } + + return itemstack; + } + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.items[i] != null) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + this.items[i] = itemstack; + if (itemstack != null && itemstack.count > this.getMaxStackSize()) { + itemstack.count = this.getMaxStackSize(); + } + + } + + public void update() {} + + public boolean a(EntityHuman entityhuman) { + return this.dead ? false : entityhuman.h(this) <= 64.0D; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public String getName() { + return this.hasCustomName() ? this.getCustomName() : "container.minecart"; + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public void c(int i) { + // Spigot Start + for ( HumanEntity human : new java.util.ArrayList( transaction ) ) + { + human.closeInventory(); + } + // Spigot End + this.b = false; + super.c(i); + } + + public void die() { + if (this.b) { + InventoryUtils.dropEntity(this.world, this, this); + } + + super.die(); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setByte("Slot", (byte) i); + this.items[i].save(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Items", nbttaglist); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getList("Items", 10); + + this.items = new ItemStack[this.getSize()]; + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + int j = nbttagcompound1.getByte("Slot") & 255; + + if (j >= 0 && j < this.items.length) { + this.items[j] = ItemStack.createStack(nbttagcompound1); + } + } + + } + + public boolean e(EntityHuman entityhuman) { + if (!this.world.isClientSide) { + entityhuman.openContainer(this); + } + + return true; + } + + protected void o() { + int i = 15 - Container.b((IInventory) this); + float f = 0.98F + (float) i * 0.001F; + + this.motX *= (double) f; + this.motY *= 0.0D; + this.motZ *= (double) f; + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public boolean r_() { + return false; + } + + public void a(ChestLock chestlock) {} + + public ChestLock i() { + return ChestLock.a; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartFurnace.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartFurnace.java new file mode 100644 index 0000000..908620d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMinecartFurnace.java @@ -0,0 +1,140 @@ +package net.minecraft.server; + +public class EntityMinecartFurnace extends EntityMinecartAbstract { + + private int c; + public double a; + public double b; + + public EntityMinecartFurnace(World world) { + super(world); + } + + public EntityMinecartFurnace(World world, double d0, double d1, double d2) { + super(world, d0, d1, d2); + } + + public EnumMinecartType s() { + return EnumMinecartType.FURNACE; + } + + protected void h() { + super.h(); + this.datawatcher.a(16, new Byte((byte) 0)); + } + + public void t_() { + super.t_(); + if (this.c > 0) { + --this.c; + } + + if (this.c <= 0) { + this.a = this.b = 0.0D; + } + + 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]); + } + + } + + protected double m() { + return 0.2D; + } + + public void a(DamageSource damagesource) { + super.a(damagesource); + if (!damagesource.isExplosion() && this.world.getGameRules().getBoolean("doEntityDrops")) { + this.a(new ItemStack(Blocks.FURNACE, 1), 0.0F); + } + + } + + protected void a(BlockPosition blockposition, IBlockData iblockdata) { + super.a(blockposition, iblockdata); + double d0 = this.a * this.a + this.b * this.b; + + if (d0 > 1.0E-4D && this.motX * this.motX + this.motZ * this.motZ > 0.001D) { + d0 = (double) MathHelper.sqrt(d0); + // PaperSpigot - Don't lose all your velocity on corners + // https://bugs.mojang.com/browse/MC-51053?focusedCommentId=223854 + double d1 = (double) MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + this.a = (motX / d1) * d0; + this.b = (motZ / d1) * d0; + // PaperSpigot end + } + + } + + protected void o() { + double d0 = this.a * this.a + this.b * this.b; + + if (d0 > 1.0E-4D) { + d0 = (double) MathHelper.sqrt(d0); + this.a /= d0; + this.b /= d0; + double d1 = 1.0D; + + this.motX *= 0.800000011920929D; + this.motY *= 0.0D; + this.motZ *= 0.800000011920929D; + this.motX += this.a * d1; + this.motZ += this.b * d1; + } else { + this.motX *= 0.9800000190734863D; + this.motY *= 0.0D; + this.motZ *= 0.9800000190734863D; + } + + super.o(); + } + + public boolean e(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.COAL) { + if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count == 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + + this.c += 3600; + } + + this.a = this.locX - entityhuman.locX; + this.b = this.locZ - entityhuman.locZ; + return true; + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setDouble("PushX", this.a); + nbttagcompound.setDouble("PushZ", this.b); + nbttagcompound.setShort("Fuel", (short) this.c); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.a = nbttagcompound.getDouble("PushX"); + this.b = nbttagcompound.getDouble("PushZ"); + this.c = nbttagcompound.getShort("Fuel"); + } + + protected boolean j() { + return (this.datawatcher.getByte(16) & 1) != 0; + } + + protected void i(boolean flag) { + if (flag) { + this.datawatcher.watch(16, Byte.valueOf((byte) (this.datawatcher.getByte(16) | 1))); + } else { + this.datawatcher.watch(16, Byte.valueOf((byte) (this.datawatcher.getByte(16) & -2))); + } + + } + + public IBlockData u() { + return (this.j() ? Blocks.LIT_FURNACE : Blocks.FURNACE).getBlockData().set(BlockFurnace.FACING, EnumDirection.NORTH); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMonster.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMonster.java new file mode 100644 index 0000000..9fefb86 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMonster.java @@ -0,0 +1,136 @@ +package net.minecraft.server; + +import org.bukkit.event.entity.EntityCombustByEntityEvent; // CraftBukkit + +public abstract class EntityMonster extends EntityCreature implements IMonster { + + public EntityMonster(World world) { + super(world); + this.b_ = 5; + } + + public void m() { + this.bx(); + float f = this.c(1.0F); + + if (f > 0.5F) { + this.ticksFarFromPlayer += 2; + } + + super.m(); + } + + public void t_() { + super.t_(); + if (!this.world.isClientSide && this.world.getDifficulty() == EnumDifficulty.PEACEFUL) { + this.die(); + } + + } + + protected String P() { + return "game.hostile.swim"; + } + + protected String aa() { + return "game.hostile.swim.splash"; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else if (super.damageEntity(damagesource, f)) { + Entity entity = damagesource.getEntity(); + + return this.passenger != entity && this.vehicle != entity ? true : true; + } else { + return false; + } + } + + protected String bo() { + return "game.hostile.hurt"; + } + + protected String bp() { + return "game.hostile.die"; + } + + protected String n(int i) { + return i > 4 ? "game.hostile.hurt.fall.big" : "game.hostile.hurt.fall.small"; + } + + public boolean r(Entity entity) { + float f = (float) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue(); + int i = 0; + + if (entity instanceof EntityLiving) { + f += EnchantmentManager.a(this.bA(), ((EntityLiving) entity).getMonsterType()); + i += EnchantmentManager.a((EntityLiving) this); + } + + boolean flag = entity.damageEntity(DamageSource.mobAttack(this), f); + + if (flag) { + if (i > 0) { + entity.g((double) (-MathHelper.sin(this.yaw * 3.1415927F / 180.0F) * (float) i * 0.5F), 0.1D, (double) (MathHelper.cos(this.yaw * 3.1415927F / 180.0F) * (float) i * 0.5F)); + this.motX *= 0.6D; + this.motZ *= 0.6D; + } + + int j = EnchantmentManager.getFireAspectEnchantmentLevel(this); + + if (j > 0) { + // CraftBukkit start - Call a combust event when somebody hits with a fire enchanted item + EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), j * 4); + org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); + + if (!combustEvent.isCancelled()) { + entity.setOnFire(combustEvent.getDuration()); + } + // CraftBukkit end + } + + this.a((EntityLiving) this, entity); + } + + return flag; + } + + public float a(BlockPosition blockposition) { + return 0.5F - this.world.o(blockposition); + } + + protected boolean n_() { + BlockPosition blockposition = new BlockPosition(this.locX, this.getBoundingBox().b, this.locZ); + + if (this.world.b(EnumSkyBlock.SKY, blockposition) > this.random.nextInt(32)) { + return false; + } else { + int i = this.world.getLightLevel(blockposition); + + if (this.world.R()) { + int j = this.world.ab(); + + this.world.c(10); + i = this.world.getLightLevel(blockposition); + this.world.c(j); + } + + return i <= this.random.nextInt(8); + } + } + + public boolean bR() { + return this.world.getDifficulty() != EnumDifficulty.PEACEFUL && this.n_() && super.bR(); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE); + } + + protected boolean ba() { + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMushroomCow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMushroomCow.java new file mode 100644 index 0000000..fef767c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityMushroomCow.java @@ -0,0 +1,76 @@ +package net.minecraft.server; + +import org.bukkit.event.player.PlayerShearEntityEvent; // CraftBukkit + +public class EntityMushroomCow extends EntityCow { + + public EntityMushroomCow(World world) { + super(world); + this.setSize(0.9F, 1.3F); + this.bn = Blocks.MYCELIUM; + } + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.BOWL && this.getAge() >= 0) { + if (itemstack.count == 1) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, new ItemStack(Items.MUSHROOM_STEW)); + return true; + } + + if (entityhuman.inventory.pickup(new ItemStack(Items.MUSHROOM_STEW)) && !entityhuman.abilities.canInstantlyBuild) { + entityhuman.inventory.splitStack(entityhuman.inventory.itemInHandIndex, 1); + return true; + } + } + + if (itemstack != null && itemstack.getItem() == Items.SHEARS && this.getAge() >= 0) { + // CraftBukkit start + PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return false; + } + // 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]); + if (!this.world.isClientSide) { + EntityCow entitycow = new EntityCow(this.world); + + entitycow.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + entitycow.setHealth(this.getHealth()); + entitycow.aI = this.aI; + if (this.hasCustomName()) { + entitycow.setCustomName(this.getCustomName()); + } + + this.world.addEntity(entitycow); + + for (int i = 0; i < 5; ++i) { + this.world.addEntity(new EntityItem(this.world, this.locX, this.locY + (double) this.length, this.locZ, new ItemStack(Blocks.RED_MUSHROOM))); + } + + itemstack.damage(1, entityhuman); + this.makeSound("mob.sheep.shear", 1.0F, 1.0F); + } + + return true; + } else { + return super.a(entityhuman); + } + } + + public EntityMushroomCow c(EntityAgeable entityageable) { + return new EntityMushroomCow(this.world); + } + + public EntityCow b(EntityAgeable entityageable) { + return this.c(entityageable); + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.c(entityageable); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityOcelot.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityOcelot.java new file mode 100644 index 0000000..edcb307 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityOcelot.java @@ -0,0 +1,250 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; + +public class EntityOcelot extends EntityTameableAnimal { + + private PathfinderGoalAvoidTarget bo; + private PathfinderGoalTempt bp; + public boolean spawnBonus = true; // Spigot + + public EntityOcelot(World world) { + super(world); + this.setSize(0.6F, 0.7F); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, this.bm); + this.goalSelector.a(3, this.bp = new PathfinderGoalTempt(this, 0.6D, Items.FISH, true)); + this.goalSelector.a(5, new PathfinderGoalFollowOwner(this, 1.0D, 10.0F, 5.0F)); + this.goalSelector.a(6, new PathfinderGoalJumpOnBlock(this, 0.8D)); + this.goalSelector.a(7, new PathfinderGoalLeapAtTarget(this, 0.3F)); + this.goalSelector.a(8, new PathfinderGoalOcelotAttack(this)); + this.goalSelector.a(9, new PathfinderGoalBreed(this, 0.8D)); + this.goalSelector.a(10, new PathfinderGoalRandomStroll(this, 0.8D)); + this.goalSelector.a(11, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); + this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed(this, EntityChicken.class, false, (Predicate) null)); + } + + protected void h() { + super.h(); + this.datawatcher.a(18, Byte.valueOf((byte) 0)); + } + + public void E() { + if (this.getControllerMove().a()) { + double d0 = this.getControllerMove().b(); + + if (d0 == 0.6D) { + this.setSneaking(true); + this.setSprinting(false); + } else if (d0 == 1.33D) { + this.setSneaking(false); + this.setSprinting(true); + } else { + this.setSneaking(false); + this.setSprinting(false); + } + } else { + this.setSneaking(false); + this.setSprinting(false); + } + + } + + protected boolean isTypeNotPersistent() { + return !this.isTamed() /*&& this.ticksLived > 2400*/; // CraftBukkit + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); + } + + public void e(float f, float f1) {} + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("CatType", this.getCatType()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setCatType(nbttagcompound.getInt("CatType")); + } + + protected String z() { + return this.isTamed() ? (this.isInLove() ? "mob.cat.purr" : (this.random.nextInt(4) == 0 ? "mob.cat.purreow" : "mob.cat.meow")) : ""; + } + + protected String bo() { + return "mob.cat.hitt"; + } + + protected String bp() { + return "mob.cat.hitt"; + } + + protected float bB() { + return 0.4F; + } + + protected Item getLoot() { + return Items.LEATHER; + } + + public boolean r(Entity entity) { + return entity.damageEntity(DamageSource.mobAttack(this), 3.0F); + } + + /* CraftBukkit start + // Function disabled as it has no special function anymore after + // setSitting is disabled. + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + this.bm.setSitting(false); + return super.damageEntity(damagesource, f); + } + } + // CraftBukkit end */ + + protected void dropDeathLoot(boolean flag, int i) {} + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (this.isTamed()) { + if (this.e((EntityLiving) entityhuman) && !this.world.isClientSide && !this.d(itemstack)) { + this.bm.setSitting(!this.isSitting()); + } + } else if (this.bp.f() && itemstack != null && itemstack.getItem() == Items.FISH && entityhuman.h(this) < 9.0D) { + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + if (itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + + if (!this.world.isClientSide) { + // CraftBukkit - added event call and isCancelled check + if (this.random.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { + this.setTamed(true); + this.setCatType(1 + this.world.random.nextInt(3)); + this.setOwnerUUID(entityhuman.getUniqueID().toString()); + this.l(true); + this.bm.setSitting(true); + this.world.broadcastEntityEffect(this, (byte) 7); + } else { + this.l(false); + this.world.broadcastEntityEffect(this, (byte) 6); + } + } + + return true; + } + + return super.a(entityhuman); + } + + public EntityOcelot b(EntityAgeable entityageable) { + EntityOcelot entityocelot = new EntityOcelot(this.world); + + if (this.isTamed()) { + entityocelot.setOwnerUUID(this.getOwnerUUID()); + entityocelot.setTamed(true); + entityocelot.setCatType(this.getCatType()); + } + + return entityocelot; + } + + public boolean d(ItemStack itemstack) { + return itemstack != null && itemstack.getItem() == Items.FISH; + } + + public boolean mate(EntityAnimal entityanimal) { + if (entityanimal == this) { + return false; + } else if (!this.isTamed()) { + return false; + } else if (!(entityanimal instanceof EntityOcelot)) { + return false; + } else { + EntityOcelot entityocelot = (EntityOcelot) entityanimal; + + return !entityocelot.isTamed() ? false : this.isInLove() && entityocelot.isInLove(); + } + } + + public int getCatType() { + return this.datawatcher.getByte(18); + } + + public void setCatType(int i) { + this.datawatcher.watch(18, Byte.valueOf((byte) i)); + } + + public boolean bR() { + return this.world.random.nextInt(3) != 0; + } + + public boolean canSpawn() { + if (this.world.a(this.getBoundingBox(), (Entity) this) && this.world.getCubes(this, this.getBoundingBox()).isEmpty() && !this.world.containsLiquid(this.getBoundingBox())) { + BlockPosition blockposition = new BlockPosition(this.locX, this.getBoundingBox().b, this.locZ); + + if (blockposition.getY() < this.world.F()) { + return false; + } + + Block block = this.world.getType(blockposition.down()).getBlock(); + + if (block == Blocks.GRASS || block.getMaterial() == Material.LEAVES) { + return true; + } + } + + return false; + } + + public String getName() { + return this.hasCustomName() ? this.getCustomName() : (this.isTamed() ? LocaleI18n.get("entity.Cat.name") : super.getName()); + } + + public void setTamed(boolean flag) { + super.setTamed(flag); + } + + protected void cm() { + if (this.bo == null) { + this.bo = new PathfinderGoalAvoidTarget(this, EntityHuman.class, 16.0F, 0.8D, 1.33D); + } + + this.goalSelector.a((PathfinderGoal) this.bo); + if (!this.isTamed()) { + this.goalSelector.a(4, this.bo); + } + + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + groupdataentity = super.prepare(difficultydamagescaler, groupdataentity); + if (spawnBonus && this.world.random.nextInt(7) == 0) { // Spigot + for (int i = 0; i < 2; ++i) { + EntityOcelot entityocelot = new EntityOcelot(this.world); + + entityocelot.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); + entityocelot.setAgeRaw(-24000); + this.world.addEntity(entityocelot, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.OCELOT_BABY); // CraftBukkit - add SpawnReason + } + } + + return groupdataentity; + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.b(entityageable); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPainting.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPainting.java new file mode 100644 index 0000000..ac94184 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPainting.java @@ -0,0 +1,110 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.ArrayList; + +public class EntityPainting extends EntityHanging { + + public EntityPainting.EnumArt art; + + public EntityPainting(World world) { + super(world); + this.art = EnumArt.values()[this.random.nextInt(EnumArt.values().length)]; // CraftBukkit - generate a non-null painting + } + + public EntityPainting(World world, BlockPosition blockposition, EnumDirection enumdirection) { + super(world, blockposition); + ArrayList arraylist = Lists.newArrayList(); + EntityPainting.EnumArt[] aentitypainting_enumart = EntityPainting.EnumArt.values(); + int i = aentitypainting_enumart.length; + + for (int j = 0; j < i; ++j) { + EntityPainting.EnumArt entitypainting_enumart = aentitypainting_enumart[j]; + + this.art = entitypainting_enumart; + this.setDirection(enumdirection); + if (this.survives()) { + arraylist.add(entitypainting_enumart); + } + } + + if (!arraylist.isEmpty()) { + this.art = (EntityPainting.EnumArt) arraylist.get(this.random.nextInt(arraylist.size())); + } + + this.setDirection(enumdirection); + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setString("Motive", this.art.B); + super.b(nbttagcompound); + } + + public void a(NBTTagCompound nbttagcompound) { + String s = nbttagcompound.getString("Motive"); + EntityPainting.EnumArt[] aentitypainting_enumart = EntityPainting.EnumArt.values(); + int i = aentitypainting_enumart.length; + + for (int j = 0; j < i; ++j) { + EntityPainting.EnumArt entitypainting_enumart = aentitypainting_enumart[j]; + + if (entitypainting_enumart.B.equals(s)) { + this.art = entitypainting_enumart; + } + } + + if (this.art == null) { + this.art = EntityPainting.EnumArt.KEBAB; + } + + super.a(nbttagcompound); + } + + public int l() { + return this.art.C; + } + + public int m() { + return this.art.D; + } + + public void b(Entity entity) { + if (this.world.getGameRules().getBoolean("doEntityDrops")) { + if (entity instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) entity; + + if (entityhuman.abilities.canInstantlyBuild) { + return; + } + } + + this.a(new ItemStack(Items.PAINTING), 0.0F); + } + } + + public void setPositionRotation(double d0, double d1, double d2, float f, float f1) { + BlockPosition blockposition = this.blockPosition.a(d0 - this.locX, d1 - this.locY, d2 - this.locZ); + + this.setPosition((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ()); + } + + public static enum EnumArt { + + KEBAB("Kebab", 16, 16, 0, 0), AZTEC("Aztec", 16, 16, 16, 0), ALBAN("Alban", 16, 16, 32, 0), AZTEC_2("Aztec2", 16, 16, 48, 0), BOMB("Bomb", 16, 16, 64, 0), PLANT("Plant", 16, 16, 80, 0), WASTELAND("Wasteland", 16, 16, 96, 0), POOL("Pool", 32, 16, 0, 32), COURBET("Courbet", 32, 16, 32, 32), SEA("Sea", 32, 16, 64, 32), SUNSET("Sunset", 32, 16, 96, 32), CREEBET("Creebet", 32, 16, 128, 32), WANDERER("Wanderer", 16, 32, 0, 64), GRAHAM("Graham", 16, 32, 16, 64), MATCH("Match", 32, 32, 0, 128), BUST("Bust", 32, 32, 32, 128), STAGE("Stage", 32, 32, 64, 128), VOID("Void", 32, 32, 96, 128), SKULL_AND_ROSES("SkullAndRoses", 32, 32, 128, 128), WITHER("Wither", 32, 32, 160, 128), FIGHTERS("Fighters", 64, 32, 0, 96), POINTER("Pointer", 64, 64, 0, 192), PIGSCENE("Pigscene", 64, 64, 64, 192), BURNING_SKULL("BurningSkull", 64, 64, 128, 192), SKELETON("Skeleton", 64, 48, 192, 64), DONKEY_KONG("DonkeyKong", 64, 48, 192, 112); + + public static final int A = "SkullAndRoses".length(); + public final String B; + public final int C; + public final int D; + public final int E; + public final int F; + + private EnumArt(String s, int i, int j, int k, int l) { + this.B = s; + this.C = i; + this.D = j; + this.E = k; + this.F = l; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPig.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPig.java new file mode 100644 index 0000000..3f2ce15 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPig.java @@ -0,0 +1,160 @@ +package net.minecraft.server; + +import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + +public class EntityPig extends EntityAnimal { + + private final PathfinderGoalPassengerCarrotStick bm; + + public EntityPig(World world) { + super(world); + this.setSize(0.9F, 0.9F); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); + this.goalSelector.a(2, this.bm = new PathfinderGoalPassengerCarrotStick(this, 0.3F)); + this.goalSelector.a(3, new PathfinderGoalBreed(this, 1.0D)); + this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.2D, Items.CARROT_ON_A_STICK, false)); + this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.2D, Items.CARROT, false)); + this.goalSelector.a(5, new PathfinderGoalFollowParent(this, 1.1D)); + this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); + } + + public boolean bW() { + ItemStack itemstack = ((EntityHuman) this.passenger).bA(); + + return itemstack != null && itemstack.getItem() == Items.CARROT_ON_A_STICK; + } + + protected void h() { + super.h(); + this.datawatcher.a(16, Byte.valueOf((byte) 0)); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setBoolean("Saddle", this.hasSaddle()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setSaddle(nbttagcompound.getBoolean("Saddle")); + } + + protected String z() { + return "mob.pig.say"; + } + + protected String bo() { + return "mob.pig.say"; + } + + protected String bp() { + return "mob.pig.death"; + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.pig.step", 0.15F, 1.0F); + } + + public boolean a(EntityHuman entityhuman) { + if (super.a(entityhuman)) { + return true; + } else if (this.hasSaddle() && !this.world.isClientSide && (this.passenger == null || this.passenger == entityhuman)) { + entityhuman.mount(this); + return true; + } else { + return false; + } + } + + protected Item getLoot() { + return this.isBurning() ? Items.COOKED_PORKCHOP : Items.PORKCHOP; + } + + protected void dropDeathLoot(boolean flag, int i) { + int j = this.random.nextInt(3) + 1 + this.random.nextInt(1 + i); + + for (int k = 0; k < j; ++k) { + if (this.isBurning()) { + this.a(Items.COOKED_PORKCHOP, 1); + } else { + this.a(Items.PORKCHOP, 1); + } + } + + if (this.hasSaddle()) { + this.a(Items.SADDLE, 1); + } + + } + + public boolean hasSaddle() { + return (this.datawatcher.getByte(16) & 1) != 0; + } + + public void setSaddle(boolean flag) { + if (flag) { + this.datawatcher.watch(16, Byte.valueOf((byte) 1)); + } else { + this.datawatcher.watch(16, Byte.valueOf((byte) 0)); + } + + } + + public void onLightningStrike(EntityLightning entitylightning) { + if (!this.world.isClientSide && !this.dead) { + EntityPigZombie entitypigzombie = new EntityPigZombie(this.world); + + // CraftBukkit start + if (CraftEventFactory.callPigZapEvent(this, entitylightning, entitypigzombie).isCancelled()) { + return; + } + // CraftBukkit end + + entitypigzombie.setEquipment(0, new ItemStack(Items.GOLDEN_SWORD)); + entitypigzombie.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + entitypigzombie.k(this.ce()); + if (this.hasCustomName()) { + entitypigzombie.setCustomName(this.getCustomName()); + entitypigzombie.setCustomNameVisible(this.getCustomNameVisible()); + } + + // CraftBukkit - added a reason for spawning this creature + this.world.addEntity(entitypigzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); + this.die(); + } + } + + public void e(float f, float f1) { + super.e(f, f1); + if (f > 5.0F && this.passenger instanceof EntityHuman) { + ((EntityHuman) this.passenger).b((Statistic) AchievementList.u); + } + + } + + public EntityPig b(EntityAgeable entityageable) { + return new EntityPig(this.world); + } + + public boolean d(ItemStack itemstack) { + return itemstack != null && itemstack.getItem() == Items.CARROT; + } + + public PathfinderGoalPassengerCarrotStick cm() { + return this.bm; + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.b(entityageable); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPlayer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPlayer.java new file mode 100644 index 0000000..4fd0ecd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPlayer.java @@ -0,0 +1,1246 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.mojang.authlib.GameProfile; +import io.netty.buffer.Unpooled; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import me.levansj01.mythicspigot.kb.KBProfile; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Bukkit; +import org.bukkit.WeatherType; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; + +import java.util.*; +import java.util.logging.Level; + +// CraftBukkit start +// CraftBukkit end + +public class EntityPlayer extends EntityHuman implements ICrafting { + + private static final Logger bH = LogManager.getLogger(); + public String locale = "en_US"; // Spigot + public PlayerConnection playerConnection; + public final MinecraftServer server; + public final PlayerInteractManager playerInteractManager; + public double d; + public double e; + public final List chunkCoordIntPairQueue = Lists.newLinkedList(); + public final List removeQueue = Lists.newLinkedList(); + private final ServerStatisticManager bK; + private float bL = Float.MIN_VALUE; + private float bM = -1.0E8F; + private int bN = -99999999; + private boolean bO = true; + public int lastSentExp = -99999999; + public int invulnerableTicks = 60; + private EntityHuman.EnumChatVisibility bR; + private boolean bS = true; + private long bT = System.currentTimeMillis(); + private Entity bU = null; + private int containerCounter; + public boolean g; + public int ping; + public boolean viewingCredits; + + // CraftBukkit start + public String displayName; + public IChatBaseComponent listName; + public org.bukkit.Location compassTarget; + public int newExp = 0; + public int newLevel = 0; + public int newTotalExp = 0; + public boolean keepLevel = false; + public double maxHealthCache; + public boolean joining = true; + // CraftBukkit end + // Spigot start + public boolean collidesWithEntities = true; + public int viewDistance; // PaperSpigot - Player view distance API + private int containerUpdateDelay; // PaperSpigot + public boolean cosmetics = false; + + @Override + public boolean ad() + { + return this.collidesWithEntities && super.ad(); // (first !this.isDead near bottom of EntityLiving) + } + + @Override + public boolean ae() + { + return this.collidesWithEntities && super.ae(); // (second !this.isDead near bottom of EntityLiving) + } + // Spigot end + + // Mythic - Knockback Profiles + private KBProfile _kBProfile = MythicCore.getCore().getKBManager().getDefaultProfile(); + + public void setKBProfile(KBProfile profile) { + if (profile == null) { + _kBProfile = MythicCore.getCore().getKBManager().getDefaultProfile(); + this.maxNoDamageTicks = MythicCore.getCore().getKBManager().getDefaultProfile().getHitDelay(); + } else { + _kBProfile = profile; + this.maxNoDamageTicks = profile.getHitDelay(); + } + this.noDamageTicks = 0; + } + + public KBProfile getKBProfile() { + if(_kBProfile == null) return MythicCore.getCore().getKBManager().getDefaultProfile(); + return _kBProfile; + } + + public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) { + super(worldserver, gameprofile); + this.viewDistance = world.spigotConfig.viewDistance; // PaperSpigot - Player view distance API + playerinteractmanager.player = this; + this.playerInteractManager = playerinteractmanager; + BlockPosition blockposition = worldserver.getSpawn(); + + if (!worldserver.worldProvider.o() && worldserver.getWorldData().getGameType() != WorldSettings.EnumGamemode.ADVENTURE) { + int i = Math.max(5, minecraftserver.getSpawnProtection() - 6); + int j = MathHelper.floor(worldserver.getWorldBorder().b(blockposition.getX(), blockposition.getZ())); + + if (j < i) { + i = j; + } + + if (j <= 1) { + i = 1; + } + + blockposition = worldserver.r(blockposition.a(this.random.nextInt(i * 2) - i, 0, this.random.nextInt(i * 2) - i)); + } + + this.server = minecraftserver; + this.bK = minecraftserver.getPlayerList().a((EntityHuman) this); + this.S = 0.0F; + this.setPositionRotation(blockposition, 0.0F, 0.0F); + + while (!worldserver.getCubes(this, this.getBoundingBox()).isEmpty() && this.locY < 255.0D) { + this.setPosition(this.locX, this.locY + 1.0D, this.locZ); + } + + // CraftBukkit start + this.displayName = this.getName(); + // this.canPickUpLoot = true; TODO + this.maxHealthCache = this.getMaxHealth(); + // CraftBukkit end + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("playerGameType", 99)) { + if (MinecraftServer.getServer().getForceGamemode()) { + this.playerInteractManager.setGameMode(MinecraftServer.getServer().getGamemode()); + } else { + this.playerInteractManager.setGameMode(WorldSettings.EnumGamemode.getById(nbttagcompound.getInt("playerGameType"))); + } + } + + this.getBukkitEntity().readExtraData(nbttagcompound); // CraftBukkit + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("playerGameType", this.playerInteractManager.getGameMode().getId()); + + this.getBukkitEntity().setExtraData(nbttagcompound); // CraftBukkit + } + + // CraftBukkit start - World fallback code, either respawn location or global spawn + public void spawnIn(World world) { + super.spawnIn(world); + if (world == null) { + this.dead = false; + BlockPosition position = null; + if (this.spawnWorld != null && !this.spawnWorld.equals("")) { + CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(this.spawnWorld); + if (cworld != null && this.getBed() != null) { + world = cworld.getHandle(); + position = EntityHuman.getBed(cworld.getHandle(), this.getBed(), false); + } + } + if (world == null || position == null) { + world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(); + position = world.getSpawn(); + } + this.world = world; + this.setPosition(position.getX() + 0.5, position.getY(), position.getZ() + 0.5); + } + this.dimension = ((WorldServer) this.world).dimension; + this.playerInteractManager.a((WorldServer) world); + } + // CraftBukkit end + + public void levelDown(int i) { + super.levelDown(i); + this.lastSentExp = -1; + } + + public void enchantDone(int i) { + super.enchantDone(i); + this.lastSentExp = -1; + } + + public void syncInventory() { + this.activeContainer.addSlotListener(this); + } + + public void enterCombat() { + super.enterCombat(); + this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.bs(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTER_COMBAT)); + } + + public void exitCombat() { + super.exitCombat(); + this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.bs(), PacketPlayOutCombatEvent.EnumCombatEventType.END_COMBAT)); + } + + public void t_() { + // CraftBukkit start + if (this.joining) { + this.joining = false; + } + // CraftBukkit end + this.playerInteractManager.a(); + --this.invulnerableTicks; + if (this.noDamageTicks > 0) { + --this.noDamageTicks; + } + + // PaperSpigot start - Configurable container update tick rate + if (--containerUpdateDelay <= 0) { + this.activeContainer.b(); + containerUpdateDelay = world.paperSpigotConfig.containerUpdateTickRate; + } + // PaperSpigot end + if (!this.world.isClientSide && !this.activeContainer.a(this)) { + this.closeInventory(); + this.activeContainer = this.defaultContainer; + } + + while (!this.removeQueue.isEmpty()) { + int i = Math.min(this.removeQueue.size(), Integer.MAX_VALUE); + int[] aint = new int[i]; + Iterator iterator = this.removeQueue.iterator(); + int j = 0; + + while (iterator.hasNext() && j < i) { + aint[j++] = ((Integer) iterator.next()).intValue(); + iterator.remove(); + } + + this.playerConnection.sendPacket(new PacketPlayOutEntityDestroy(aint)); + } + + if (!this.chunkCoordIntPairQueue.isEmpty()) { + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator1 = this.chunkCoordIntPairQueue.iterator(); + ArrayList arraylist1 = Lists.newArrayList(); + + Chunk chunk; + + while (iterator1.hasNext() && arraylist.size() < this.world.spigotConfig.maxBulkChunk) { // Spigot + ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator1.next(); + + if (chunkcoordintpair != null) { + if (this.world.isLoaded(chunkcoordintpair.x << 4, 0, chunkcoordintpair.z << 4)) { + 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(); + } + } + } else { + iterator1.remove(); + } + } + + if (!arraylist.isEmpty()) { + if (arraylist.size() == 1) { + this.playerConnection.sendPacket(new PacketPlayOutMapChunk((Chunk) arraylist.get(0), true, '\uffff')); + } else { + this.playerConnection.sendPacket(new PacketPlayOutMapChunkBulk(arraylist)); + } + + Iterator iterator2 = arraylist1.iterator(); + + while (iterator2.hasNext()) { + TileEntity tileentity = (TileEntity) iterator2.next(); + + this.a(tileentity); + } + + iterator2 = arraylist.iterator(); + + while (iterator2.hasNext()) { + chunk = (Chunk) iterator2.next(); + this.u().getTracker().a(this, chunk); + } + } + } + + Entity entity = this.C(); + + if (entity != this) { + if (!entity.isAlive()) { + this.setSpectatorTarget(this); + } else { + this.setLocation(entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch); + this.server.getPlayerList().d(this); + if (this.isSneaking()) { + this.setSpectatorTarget(this); + } + } + } + + } + + public void l() { + try { + super.t_(); + + for (int i = 0; i < this.inventory.getSize(); ++i) { + ItemStack itemstack = this.inventory.getItem(i); + + if (itemstack != null && itemstack.getItem().f()) { + Packet packet = ((ItemWorldMapBase) itemstack.getItem()).c(itemstack, this.world, this); + + if (packet != null) { + this.playerConnection.sendPacket(packet); + } + } + } + + // CraftBukkit - Optionally scale health + if (this.getHealth() != this.bM || this.bN != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.bO) { + this.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel())); + this.bM = this.getHealth(); + this.bN = this.foodData.getFoodLevel(); + this.bO = this.foodData.getSaturationLevel() == 0.0F; + } + + if (this.getHealth() + this.getAbsorptionHearts() != this.bL) { + this.bL = this.getHealth() + this.getAbsorptionHearts(); + Collection collection = this.getScoreboard().getObjectivesForCriteria(IScoreboardCriteria.g); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); + + this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective).updateForList(Arrays.asList(new EntityHuman[] { this})); + } + // CraftBukkit - Update ALL the scores! + this.world.getServer().getScoreboardManager().updateAllScoresForList(IScoreboardCriteria.g, this.getName(), com.google.common.collect.ImmutableList.of(this)); + } + // CraftBukkit start - Force max health updates + if (this.maxHealthCache != this.getMaxHealth()) { + this.getBukkitEntity().updateScaledHealth(); + } + // CraftBukkit end + + if (this.expTotal != this.lastSentExp) { + this.lastSentExp = this.expTotal; + this.playerConnection.sendPacket(new PacketPlayOutExperience(this.exp, this.expTotal, this.expLevel)); + } + + if (this.ticksLived % 20 * 5 == 0 && !this.getStatisticManager().hasAchievement(AchievementList.L)) { + this.i_(); + } + + // CraftBukkit start - initialize oldLevel and fire PlayerLevelChangeEvent + if (this.oldLevel == -1) { + this.oldLevel = this.expLevel; + } + + if (this.oldLevel != this.expLevel) { + CraftEventFactory.callPlayerLevelChangeEvent(this.world.getServer().getPlayer(this), this.oldLevel, this.expLevel); + this.oldLevel = this.expLevel; + } + // CraftBukkit end + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Ticking player"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Player being ticked"); + + this.appendEntityCrashDetails(crashreportsystemdetails); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + + protected void i_() { + BiomeBase biomebase = this.world.getBiome(new BlockPosition(MathHelper.floor(this.locX), 0, MathHelper.floor(this.locZ))); + String s = biomebase.ah; + AchievementSet achievementset = this.getStatisticManager().b((Statistic) AchievementList.L); + + if (achievementset == null) { + achievementset = this.getStatisticManager().a(AchievementList.L, new AchievementSet()); + } + + achievementset.add(s); + if (this.getStatisticManager().b(AchievementList.L) && achievementset.size() >= BiomeBase.n.size()) { + HashSet hashset = Sets.newHashSet(BiomeBase.n); + Iterator iterator = achievementset.iterator(); + + while (iterator.hasNext()) { + String s1 = (String) iterator.next(); + Iterator iterator1 = hashset.iterator(); + + while (iterator1.hasNext()) { + BiomeBase biomebase1 = (BiomeBase) iterator1.next(); + + if (biomebase1.ah.equals(s1)) { + iterator1.remove(); + } + } + + if (hashset.isEmpty()) { + break; + } + } + + if (hashset.isEmpty()) { + this.b(AchievementList.L); + } + } + + } + + public void die(DamageSource damagesource) { + // CraftBukkit start - fire PlayerDeathEvent + if (this.dead) { + return; + } + java.util.List loot = new java.util.ArrayList(); + boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory"); + + if (!keepInventory) { + for (int i = 0; i < this.inventory.items.length; ++i) { + if (this.inventory.items[i] != null) { + loot.add(CraftItemStack.asCraftMirror(this.inventory.items[i])); + this.inventory.setItem(i, null); + } + } + + for (int i = 0; i < this.inventory.armor.length; ++i) { + if (this.inventory.armor[i] != null) { + loot.add(CraftItemStack.asCraftMirror(this.inventory.armor[i])); + this.inventory.player.setEquipment(i, null); + } + } + } + + IChatBaseComponent chatmessage = this.bs().b(); + + String deathmessage = chatmessage.c(); + org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, deathmessage, keepInventory); + + String deathMessage = event.getDeathMessage(); + + if (deathMessage != null && deathMessage.length() > 0 && this.world.getGameRules().getBoolean("showDeathMessages")) { // TODO: allow plugins to override? + if (deathMessage.equals(deathmessage)) { + this.server.getPlayerList().sendMessage(chatmessage); + } else { + this.server.getPlayerList().sendMessage(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(deathMessage)); + } + } + + // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. + if (!event.getKeepInventory()) { + for (int i = 0; i < this.inventory.items.length; ++i) { + this.inventory.setItem(i, null); + } + + for (int i = 0; i < this.inventory.armor.length; ++i) { + this.inventory.player.setEquipment(i, null); + } + } + + this.closeInventory(); + this.setSpectatorTarget(this); // Remove spectated target + // CraftBukkit end + + // CraftBukkit - Get our scores instead + Collection collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.d, this.getName(), new java.util.ArrayList()); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); // CraftBukkit - Use our scores instead + + scoreboardscore.incrementScore(); + } + + EntityLiving entityliving = this.bt(); + + if (entityliving != null) { + EntityTypes.MonsterEggInfo entitytypes_monsteregginfo = EntityTypes.eggInfo.get(Integer.valueOf(EntityTypes.a(entityliving))); + + if (entitytypes_monsteregginfo != null) { + this.b(entitytypes_monsteregginfo.e); + } + + entityliving.b(this, this.aW); + } + + this.b(StatisticList.y); + this.a(StatisticList.h); + this.bs().g(); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + boolean flag = this.server.ae() && this.cr() && "fall".equals(damagesource.translationIndex); + + if (!flag && this.invulnerableTicks > 0 && damagesource != DamageSource.OUT_OF_WORLD) { + return false; + } else { + if (damagesource instanceof EntityDamageSource) { + Entity entity = damagesource.getEntity(); + + if (entity instanceof EntityHuman && !this.a((EntityHuman) entity)) { + return false; + } + + if (entity instanceof EntityArrow) { + EntityArrow entityarrow = (EntityArrow) entity; + + if (entityarrow.shooter instanceof EntityHuman && !this.a((EntityHuman) entityarrow.shooter)) { + return false; + } + } + } + + return super.damageEntity(damagesource, f); + } + } + } + + public boolean a(EntityHuman entityhuman) { + return this.cr() && super.a(entityhuman); + } + + private boolean cr() { + // CraftBukkit - this.server.getPvP() -> this.world.pvpMode + return this.world.pvpMode; + } + + public void c(int i) { + // PaperSpigot start - Allow configurable end portal credits + boolean endPortal = this.dimension == 1 && i == 1; + if (endPortal) { + this.b(AchievementList.D); + if (!world.paperSpigotConfig.disableEndCredits) { + this.world.kill(this); + this.viewingCredits = true; + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, 0.0F)); + } + // PaperSpigot end + } else { + if (this.dimension == 0 && i == 1) { + this.b(AchievementList.C); + // CraftBukkit start - Rely on custom portal management + /* + BlockPosition blockposition = this.server.getWorldServer(i).getDimensionSpawn(); + + if (blockposition != null) { + this.playerConnection.a((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 0.0F, 0.0F); + } + + i = 1; + */ + // CraftBukkit end + } else { + this.b(AchievementList.y); + } + } + + // PaperSpigot start - Allow configurable end portal credits + if (!endPortal || world.paperSpigotConfig.disableEndCredits) { + // CraftBukkit start + TeleportCause cause = (endPortal || (this.dimension == 1 || i == 1)) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL; + this.server.getPlayerList().changeDimension(this, i, cause); + // CraftBukkit end + this.lastSentExp = -1; + this.bM = -1.0F; + this.bN = -1; + } + // PaperSpigot end + + } + + public boolean a(EntityPlayer entityplayer) { + return entityplayer.isSpectator() ? this.C() == this : (!this.isSpectator() && super.a(entityplayer)); + } + + private void a(TileEntity tileentity) { + if (tileentity != null) { + Packet packet = tileentity.getUpdatePacket(); + + if (packet != null) { + this.playerConnection.sendPacket(packet); + } + } + + } + + public void receive(Entity entity, int i) { + super.receive(entity, i); + this.activeContainer.b(); + } + + public EntityHuman.EnumBedResult a(BlockPosition blockposition) { + EntityHuman.EnumBedResult entityhuman_enumbedresult = super.a(blockposition); + + if (entityhuman_enumbedresult == EntityHuman.EnumBedResult.OK) { + PacketPlayOutBed packetplayoutbed = new PacketPlayOutBed(this, blockposition); + + this.u().getTracker().a(this, packetplayoutbed); + this.playerConnection.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + this.playerConnection.sendPacket(packetplayoutbed); + } + + return entityhuman_enumbedresult; + } + + public void a(boolean flag, boolean flag1, boolean flag2) { + if (!this.sleeping) return; // CraftBukkit - Can't leave bed if not in one! + if (this.isSleeping()) { + this.u().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(this, 2)); + } + + super.a(flag, flag1, flag2); + if (this.playerConnection != null) { + this.playerConnection.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + } + + } + + public void mount(Entity entity) { + Entity entity1 = this.vehicle; + + super.mount(entity); + if (this.vehicle != entity1) { // CraftBukkit + this.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this, this.vehicle)); + this.playerConnection.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + } + + } + + protected void a(double d0, boolean flag, Block block, BlockPosition blockposition) {} + + public void a(double d0, boolean flag) { + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY - 0.20000000298023224D); + int k = MathHelper.floor(this.locZ); + BlockPosition blockposition = new BlockPosition(i, j, k); + Block block = this.world.getType(blockposition).getBlock(); + + if (block.getMaterial() == Material.AIR) { + Block block1 = this.world.getType(blockposition.down()).getBlock(); + + if (block1 instanceof BlockFence || block1 instanceof BlockCobbleWall || block1 instanceof BlockFenceGate) { + blockposition = blockposition.down(); + block = this.world.getType(blockposition).getBlock(); + } + } + + super.a(d0, flag, block, blockposition); + } + + public void openSign(TileEntitySign tileentitysign) { + tileentitysign.a(this); + this.playerConnection.sendPacket(new PacketPlayOutOpenSignEditor(tileentitysign.getPosition())); + } + + public int nextContainerCounter() { // CraftBukkit - private void -> public int + this.containerCounter = this.containerCounter % 100 + 1; + return containerCounter; // CraftBukkit + } + + public void openTileEntity(ITileEntityContainer itileentitycontainer) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, itileentitycontainer.createContainer(this.inventory, this)); + if (container == null) { + return; + } + // CraftBukkit end + this.nextContainerCounter(); + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, itileentitycontainer.getContainerName(), itileentitycontainer.getScoreboardDisplayName())); + this.activeContainer = container; // CraftBukkit + this.activeContainer.windowId = this.containerCounter; + this.activeContainer.addSlotListener(this); + } + + public void openContainer(IInventory iinventory) { + // CraftBukkit start - Inventory open hook + // Copied from below + boolean cancelled = false; + if (iinventory instanceof ITileInventory) { + ITileInventory itileinventory = (ITileInventory) iinventory; + cancelled = itileinventory.r_() && !this.a(itileinventory.i()) && !this.isSpectator(); + } + + Container container; + if (iinventory instanceof ITileEntityContainer) { + container = ((ITileEntityContainer)iinventory).createContainer(this.inventory, this); + } else { + container = new ContainerChest(this.inventory, iinventory, this); + } + container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled); + if (container == null && !cancelled) { // Let pre-cancelled events fall through + iinventory.closeContainer(this); + return; + } + // CraftBukkit end + if (this.activeContainer != this.defaultContainer) { + this.closeInventory(); + } + + if (iinventory instanceof ITileInventory) { + ITileInventory itileinventory = (ITileInventory) iinventory; + + if (itileinventory.r_() && !this.a(itileinventory.i()) && !this.isSpectator() && container == null) { // CraftBukkit - allow plugins to uncancel the lock + this.playerConnection.sendPacket(new PacketPlayOutChat(new ChatMessage("container.isLocked", iinventory.getScoreboardDisplayName()), (byte) 2)); + this.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("random.door_close", this.locX, this.locY, this.locZ, 1.0F, 1.0F)); + + iinventory.closeContainer(this); // CraftBukkit + return; + } + } + + this.nextContainerCounter(); + if (iinventory instanceof ITileEntityContainer) { + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, ((ITileEntityContainer) iinventory).getContainerName(), iinventory.getScoreboardDisplayName(), iinventory.getSize())); + this.activeContainer = container; // CraftBukkit + } else { + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "minecraft:container", iinventory.getScoreboardDisplayName(), iinventory.getSize())); + this.activeContainer = container; // CraftBukkit + } + + this.activeContainer.windowId = this.containerCounter; + this.activeContainer.addSlotListener(this); + } + + public void openTrade(IMerchant imerchant) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerMerchant(this.inventory, imerchant, this.world)); + if (container == null) { + return; + } + // CraftBukkit end + this.nextContainerCounter(); + this.activeContainer = container; // CraftBukkit + this.activeContainer.windowId = this.containerCounter; + this.activeContainer.addSlotListener(this); + InventoryMerchant inventorymerchant = ((ContainerMerchant) this.activeContainer).e(); + IChatBaseComponent ichatbasecomponent = imerchant.getScoreboardDisplayName(); + + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "minecraft:villager", ichatbasecomponent, inventorymerchant.getSize())); + MerchantRecipeList merchantrecipelist = imerchant.getOffers(this); + + if (merchantrecipelist != null) { + PacketDataSerializer packetdataserializer = new PacketDataSerializer(Unpooled.buffer()); + + packetdataserializer.writeInt(this.containerCounter); + merchantrecipelist.a(packetdataserializer); + this.playerConnection.sendPacket(new PacketPlayOutCustomPayload("MC|TrList", packetdataserializer)); + } + + } + + public void openHorseInventory(EntityHorse entityhorse, IInventory iinventory) { + // CraftBukkit start - Inventory open hook + Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHorse(this.inventory, iinventory, entityhorse, this)); + if (container == null) { + iinventory.closeContainer(this); + return; + } + // CraftBukkit end + if (this.activeContainer != this.defaultContainer) { + this.closeInventory(); + } + + this.nextContainerCounter(); + this.playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.containerCounter, "EntityHorse", iinventory.getScoreboardDisplayName(), iinventory.getSize(), entityhorse.getId())); + this.activeContainer = container; + this.activeContainer.windowId = this.containerCounter; + this.activeContainer.addSlotListener(this); + } + + public void openBook(ItemStack itemstack) { + Item item = itemstack.getItem(); + + if (item == Items.WRITTEN_BOOK) { + this.playerConnection.sendPacket(new PacketPlayOutCustomPayload("MC|BOpen", new PacketDataSerializer(Unpooled.buffer()))); + } + + } + + public void a(Container container, int i, ItemStack itemstack) { + if (!(container.getSlot(i) instanceof SlotResult)) { + if (!this.g) { + this.playerConnection.sendPacket(new PacketPlayOutSetSlot(container.windowId, i, itemstack)); + } + } + } + + public void updateInventory(Container container) { + this.a(container, container.a()); + } + + public void a(Container container, List list) { + this.playerConnection.sendPacket(new PacketPlayOutWindowItems(container.windowId, list)); + this.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.inventory.getCarried())); + // CraftBukkit start - Send a Set Slot to update the crafting result slot + if (java.util.EnumSet.of(InventoryType.CRAFTING,InventoryType.WORKBENCH).contains(container.getBukkitView().getType())) { + this.playerConnection.sendPacket(new PacketPlayOutSetSlot(container.windowId, 0, container.getSlot(0).getItem())); + } + // CraftBukkit end + } + + public void setContainerData(Container container, int i, int j) { + this.playerConnection.sendPacket(new PacketPlayOutWindowData(container.windowId, i, j)); + } + + public void setContainerData(Container container, IInventory iinventory) { + for (int i = 0; i < iinventory.g(); ++i) { + this.playerConnection.sendPacket(new PacketPlayOutWindowData(container.windowId, i, iinventory.getProperty(i))); + } + + } + + public void closeInventory() { + CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit + this.playerConnection.sendPacket(new PacketPlayOutCloseWindow(this.activeContainer.windowId)); + this.p(); + } + + public void broadcastCarriedItem() { + if (!this.g) { + this.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.inventory.getCarried())); + } + } + + public void p() { + this.activeContainer.b(this); + this.activeContainer = this.defaultContainer; + } + + public void a(float f, float f1, boolean flag, boolean flag1) { + if (this.vehicle != null) { + if (f >= -1.0F && f <= 1.0F) { + this.aZ = f; + } + + if (f1 >= -1.0F && f1 <= 1.0F) { + this.ba = f1; + } + + this.aY = flag; + this.setSneaking(flag1); + } + + } + + public void a(Statistic statistic, int i) { + if (statistic != null) { + this.bK.b(this, statistic, i); + Iterator iterator = this.getScoreboard().getObjectivesForCriteria(statistic.k()).iterator(); + + while (iterator.hasNext()) { + ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); + + this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective).addScore(i); + } + + if (this.bK.e()) { + this.bK.a(this); + } + + } + } + + public void a(Statistic statistic) { + if (statistic != null) { + this.bK.setStatistic(this, statistic, 0); + Iterator iterator = this.getScoreboard().getObjectivesForCriteria(statistic.k()).iterator(); + + while (iterator.hasNext()) { + ScoreboardObjective scoreboardobjective = (ScoreboardObjective) iterator.next(); + + this.getScoreboard().getPlayerScoreForObjective(this.getName(), scoreboardobjective).setScore(0); + } + + if (this.bK.e()) { + this.bK.a(this); + } + + } + } + + public void q() { + if (this.passenger != null) { + this.passenger.mount(this); + } + + if (this.sleeping) { + this.a(true, false, false); + } + + } + + public void triggerHealthUpdate() { + this.bM = -1.0E8F; + this.lastSentExp = -1; // CraftBukkit - Added to reset + } + + // CraftBukkit start - Support multi-line messages + public void sendMessage(IChatBaseComponent[] ichatbasecomponent) { + for (IChatBaseComponent component : ichatbasecomponent) { + this.sendMessage(component); + } + } + // CraftBukkit end + + public void b(IChatBaseComponent ichatbasecomponent) { + this.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent)); + } + + protected void s() { + this.playerConnection.sendPacket(new PacketPlayOutEntityStatus(this, (byte) 9)); + super.s(); + } + + public void a(ItemStack itemstack, int i) { + super.a(itemstack, i); + if (itemstack != null && itemstack.getItem() != null && itemstack.getItem().e(itemstack) == EnumAnimation.EAT) { + this.u().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(this, 3)); + } + + } + + public void copyTo(EntityHuman entityhuman, boolean flag) { + super.copyTo(entityhuman, flag); + this.lastSentExp = -1; + this.bM = -1.0F; + this.bN = -1; + this.removeQueue.addAll(((EntityPlayer) entityhuman).removeQueue); + } + + protected void a(MobEffect mobeffect) { + super.a(mobeffect); + this.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.getId(), mobeffect)); + } + + protected void a(MobEffect mobeffect, boolean flag) { + super.a(mobeffect, flag); + this.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.getId(), mobeffect)); + } + + protected void b(MobEffect mobeffect) { + super.b(mobeffect); + this.playerConnection.sendPacket(new PacketPlayOutRemoveEntityEffect(this.getId(), mobeffect)); + } + + public void enderTeleportTo(double d0, double d1, double d2) { + this.playerConnection.a(d0, d1, d2, this.yaw, this.pitch); + } + + public void b(Entity entity) { + this.u().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(entity, 4)); + } + + public void c(Entity entity) { + this.u().getTracker().sendPacketToEntity(this, new PacketPlayOutAnimation(entity, 5)); + } + + public void updateAbilities() { + if (this.playerConnection != null) { + this.playerConnection.sendPacket(new PacketPlayOutAbilities(this.abilities)); + this.B(); + } + } + + public WorldServer u() { + return (WorldServer) this.world; + } + + public void a(WorldSettings.EnumGamemode worldsettings_enumgamemode) { + getBukkitEntity().setGameMode(org.bukkit.GameMode.getByValue(worldsettings_enumgamemode.getId())); + /* CraftBukkit start - defer to our setGameMode + this.playerInteractManager.setGameMode(worldsettings_enumgamemode); + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(3, (float) worldsettings_enumgamemode.getId())); + if (worldsettings_enumgamemode == WorldSettings.EnumGamemode.SPECTATOR) { + this.mount((Entity) null); + } else { + this.setSpectatorTarget(this); + } + + this.updateAbilities(); + this.bP(); + // CraftBukkit end */ + } + + public boolean isSpectator() { + return this.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.SPECTATOR; + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + this.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent)); + } + + public boolean a(int i, String s) { + /* CraftBukkit start + if ("seed".equals(s) && !this.server.ad()) { + return true; + } else if (!"tell".equals(s) && !"help".equals(s) && !"me".equals(s) && !"trigger".equals(s)) { + if (this.server.getPlayerList().isOp(this.getProfile())) { + OpListEntry oplistentry = (OpListEntry) this.server.getPlayerList().getOPs().get(this.getProfile()); + + return oplistentry != null ? oplistentry.a() >= i : this.server.p() >= i; + } else { + return false; + } + } else { + return true; + } + */ + if ("@".equals(s)) { + return getBukkitEntity().hasPermission("minecraft.command.selector"); + } + return true; + // CraftBukkit end + } + + public String w() { + String s = this.playerConnection.networkManager.getSocketAddress().toString(); + + s = s.substring(s.indexOf("/") + 1); + s = s.substring(0, s.indexOf(":")); + return s; + } + + public void a(PacketPlayInSettings packetplayinsettings) { + // PaperSpigot start - Add PlayerLocaleChangeEvent + String oldLocale = this.locale; + this.locale = packetplayinsettings.a(); + if (!this.locale.equals(oldLocale)) { + CraftEventFactory.callPlayerLocaleChangeEvent(this, oldLocale, this.locale); + } + // PaperSpigot end + this.bR = packetplayinsettings.c(); + this.bS = packetplayinsettings.d(); + this.getDataWatcher().watch(10, Byte.valueOf((byte) packetplayinsettings.e())); + } + + public EntityHuman.EnumChatVisibility getChatFlags() { + return this.bR; + } + + public void setResourcePack(String s, String s1) { + this.playerConnection.sendPacket(new PacketPlayOutResourcePackSend(s, s1)); + } + + public BlockPosition getChunkCoordinates() { + return new BlockPosition(this.locX, this.locY + 0.5D, this.locZ); + } + + public void resetIdleTimer() { + this.bT = MinecraftServer.az(); + } + + public ServerStatisticManager getStatisticManager() { + return this.bK; + } + + public void d(Entity entity) { + if (entity instanceof EntityHuman) { + this.playerConnection.sendPacket(new PacketPlayOutEntityDestroy(entity.getId())); + } else { + this.removeQueue.add(Integer.valueOf(entity.getId())); + } + + } + + protected void B() { + if (this.isSpectator()) { + this.bj(); + this.setInvisible(true); + } else { + super.B(); + } + + this.u().getTracker().a(this); + } + + public Entity C() { + return this.bU == null ? this : this.bU; + } + + public void setSpectatorTarget(Entity entity) { + Entity entity1 = this.C(); + + this.bU = entity == null ? this : entity; + if (entity1 != this.bU) { + this.playerConnection.sendPacket(new PacketPlayOutCamera(this.bU)); + this.enderTeleportTo(this.bU.locX, this.bU.locY, this.bU.locZ); + } + + } + + public void attack(Entity entity) { + if (this.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.SPECTATOR) { + this.setSpectatorTarget(entity); + } else { + super.attack(entity); + } + + } + + public long D() { + return this.bT; + } + + public IChatBaseComponent getPlayerListName() { + return listName; // CraftBukkit + } + + // CraftBukkit start - Add per-player time and weather. + public long timeOffset = 0; + public boolean relativeTime = true; + + public long getPlayerTime() { + if (this.relativeTime) { + // Adds timeOffset to the current server time. + return this.world.getDayTime() + this.timeOffset; + } else { + // Adds timeOffset to the beginning of this day. + return this.world.getDayTime() - (this.world.getDayTime() % 24000) + this.timeOffset; + } + } + + public WeatherType weather = null; + + public WeatherType getPlayerWeather() { + return this.weather; + } + + public void setPlayerWeather(WeatherType type, boolean plugin) { + if (!plugin && this.weather != null) { + return; + } + + if (plugin) { + this.weather = type; + } + + if (type == WeatherType.DOWNFALL) { + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(2, 0)); + } else { + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(1, 0)); + } + } + + private float pluginRainPosition; + private float pluginRainPositionPrevious; + + public void updateWeather(float oldRain, float newRain, float oldThunder, float newThunder) { + if (this.weather == null) { + // Vanilla + if (oldRain != newRain) { + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, newRain)); + } + } else { + // Plugin + if (pluginRainPositionPrevious != pluginRainPosition) { + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, pluginRainPosition)); + } + } + + if (oldThunder != newThunder) { + if (weather == WeatherType.DOWNFALL || weather == null) { + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, newThunder)); + } else { + this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, 0)); + } + } + } + + public void tickWeather() { + if (this.weather == null) return; + + pluginRainPositionPrevious = pluginRainPosition; + if (weather == WeatherType.DOWNFALL) { + pluginRainPosition += 0.01; + } else { + pluginRainPosition -= 0.01; + } + + pluginRainPosition = MathHelper.a(pluginRainPosition, 0.0F, 1.0F); + } + + public void resetPlayerWeather() { + this.weather = null; + this.setPlayerWeather(this.world.getWorldData().hasStorm() ? WeatherType.DOWNFALL : WeatherType.CLEAR, false); + } + + @Override + public String toString() { + return super.toString() + "(" + this.getName() + " at " + this.locX + "," + this.locY + "," + this.locZ + ")"; + } + + public void reset() { + float exp = 0; + boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory"); + + if (this.keepLevel || keepInventory) { + exp = this.exp; + this.newTotalExp = this.expTotal; + this.newLevel = this.expLevel; + } + + this.setHealth(this.getMaxHealth()); + this.fireTicks = 0; + this.fallDistance = 0; + this.foodData = new FoodMetaData(this); + this.expLevel = this.newLevel; + this.expTotal = this.newTotalExp; + this.exp = 0; + this.deathTicks = 0; + this.removeAllEffects(); + this.updateEffects = true; + this.activeContainer = this.defaultContainer; + this.killer = null; + this.lastDamager = null; + this.combatTracker = new CombatTracker(this); + this.lastSentExp = -1; + if (this.keepLevel || keepInventory) { + this.exp = exp; + } else { + this.giveExp(this.newExp); + } + this.keepLevel = false; + } + + @Override + public CraftPlayer getBukkitEntity() { + return (CraftPlayer) super.getBukkitEntity(); + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPotion.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPotion.java new file mode 100644 index 0000000..d023641 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityPotion.java @@ -0,0 +1,177 @@ +package net.minecraft.server; + +import me.levansj01.mythicspigot.MythicConfiguration; +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.entity.LivingEntity; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +// CraftBukkit start +// CraftBukkit end + +public class EntityPotion extends EntityProjectile { + + public ItemStack item; + + public EntityPotion(World world) { + super(world); + } + + public EntityPotion(World world, EntityLiving entityliving, int i) { + this(world, entityliving, new ItemStack(Items.POTION, 1, i)); + } + + public EntityPotion(World world, EntityLiving entityliving, ItemStack itemstack) { + super(world, entityliving); + this.item = itemstack; + } + + public EntityPotion(World world, double d0, double d1, double d2, ItemStack itemstack) { + super(world, d0, d1, d2); + this.item = itemstack; + } + + protected float m() { + return 0.05F; + } + + protected float j() { + // return MythicConfiguration.Options.Combat.Potions.potDistance; + return 0.5F; + } + + protected float l() { + return -20.0F; + // return MythicConfiguration.Options.Combat.Potions.potOffY; + } + + public void setPotionValue(int i) { + if (this.item == null) { + this.item = new ItemStack(Items.POTION, 1, 0); + } + + this.item.setData(i); + } + + public int getPotionValue() { + if (this.item == null) { + this.item = new ItemStack(Items.POTION, 1, 0); + } + + return this.item.getData(); + } + + protected void a(MovingObjectPosition movingobjectposition) { + if (!this.world.isClientSide) { + List list = Items.POTION.h(this.item); + + if (true || list != null && !list.isEmpty()) { // CraftBukkit - Call event even if no effects to apply + AxisAlignedBB axisalignedbb = this.getBoundingBox().grow(4.0D, 2.0D, 4.0D); + List list1 = this.world.a(EntityLiving.class, axisalignedbb); + + if (true || !list1.isEmpty()) { // CraftBukkit - Run code even if there are no entities around + Iterator iterator = list1.iterator(); + + // CraftBukkit + HashMap affected = new HashMap(); + + while (iterator.hasNext()) { + EntityLiving entityliving = (EntityLiving) iterator.next(); + double d0 = this.h(entityliving); + + if (d0 < 16.0D) { + if(entityliving instanceof EntityPlayer && shooter instanceof EntityPlayer && MythicConfiguration.Options.Tracking.Hide.projectiles) { + EntityPlayer entityPlayer = (EntityPlayer) entityliving, shooterPlayer = (EntityPlayer) shooter; + if(!shooterPlayer.getBukkitEntity().canSee(entityPlayer.getBukkitEntity())) { + continue; + } + } + + double d1 = 1.0D - Math.sqrt(d0) / 4.0D; + + if (entityliving == movingobjectposition.entity) { + d1 = 1.0D; + } + + // CraftBukkit start + affected.put((LivingEntity) entityliving.getBukkitEntity(), d1); + } + } + + org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, affected); + if (!event.isCancelled() && list != null && !list.isEmpty()) { // do not process effects if there are no effects to process + for (LivingEntity victim : event.getAffectedEntities()) { + if (!(victim instanceof CraftLivingEntity)) { + continue; + } + + EntityLiving entityliving = ((CraftLivingEntity) victim).getHandle(); + double d1 = event.getIntensity(victim); + // CraftBukkit end + + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { + MobEffect mobeffect = (MobEffect) iterator1.next(); + int i = mobeffect.getEffectId(); + + // CraftBukkit start - Abide by PVP settings - for players only! + if (!this.world.pvpMode && this.getShooter() instanceof EntityPlayer && entityliving instanceof EntityPlayer && entityliving != this.getShooter()) { + // Block SLOWER_MOVEMENT, SLOWER_DIG, HARM, BLINDNESS, HUNGER, WEAKNESS and POISON potions + if (i == 2 || i == 4 || i == 7 || i == 15 || i == 17 || i == 18 || i == 19) continue; + } + // CraftBukkit end + + if (MobEffectList.byId[i].isInstant()) { + MobEffectList.byId[i].applyInstantEffect(this, this.getShooter(), entityliving, mobeffect.getAmplifier(), d1); + } else { + int j = (int) (d1 * (double) mobeffect.getDuration() + 0.5D); + + if (j > 20) { + entityliving.addEffect(new MobEffect(i, j, mobeffect.getAmplifier())); + } + } + } + } + } + } + } + + BlockPosition position = new BlockPosition(this); + int value = getPotionValue(); + if(shooter instanceof EntityPlayer && MythicConfiguration.Options.Tracking.Hide.projectiles) { + EntityPlayer entityPlayer = (EntityPlayer) shooter; + if(entityPlayer.playerConnection != null) entityPlayer.playerConnection.sendPacket(new PacketPlayOutWorldEvent(2002, position, value, false)); + world.a(entityPlayer, 2002, position, value); + } else { + world.triggerEffect(2002, position, value); + } + this.die(); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("Potion", 10)) { + this.item = ItemStack.createStack(nbttagcompound.getCompound("Potion")); + } else { + this.setPotionValue(nbttagcompound.getInt("potionValue")); + } + + if (this.item == null) { + this.die(); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + if (this.item != null) { + nbttagcompound.set("Potion", this.item.save(new NBTTagCompound())); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java new file mode 100644 index 0000000..5ea0f80 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityProjectile.java @@ -0,0 +1,305 @@ +package net.minecraft.server; + +import me.levansj01.mythicspigot.MythicConfiguration; + +import java.util.List; +import java.util.UUID; + +public abstract class EntityProjectile extends Entity implements IProjectile { + + private int blockX = -1; + private int blockY = -1; + private int blockZ = -1; + private Block inBlockId; + protected boolean inGround; + public int shake; + public EntityLiving shooter; + public String shooterName; + private int i; + private int ar; + + public EntityProjectile(World world) { + super(world); + this.setSize(0.25F, 0.25F); + } + + protected void h() {} + + protected int gateX, gateY, gateZ; + protected boolean throughGate; + + public EntityProjectile(World world, EntityLiving entityliving) { + super(world); + this.shooter = entityliving; + this.projectileSource = (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity(); // CraftBukkit + this.setSize(0.25F, 0.25F); + this.setPositionRotation(entityliving.locX, entityliving.locY + (double) entityliving.getHeadHeight(), entityliving.locZ, entityliving.yaw, entityliving.pitch); + this.locX -= MathHelper.cos(this.yaw / 180.0F * 3.1415927F) * 0.16F; + this.locY -= 0.10000000149011612D; + this.locZ -= MathHelper.sin(this.yaw / 180.0F * 3.1415927F) * 0.16F; + this.setPosition(this.locX, this.locY, this.locZ); + float f = 0.4F; + + this.motX = -MathHelper.sin(this.yaw / 180.0F * 3.1415927F) * MathHelper.cos(this.pitch / 180.0F * 3.1415927F) * f; + this.motZ = MathHelper.cos(this.yaw / 180.0F * 3.1415927F) * MathHelper.cos(this.pitch / 180.0F * 3.1415927F) * f; + this.motY = -MathHelper.sin((this.pitch + this.l()) / 180.0F * 3.1415927F) * f; + if (this instanceof EntityPotion) { + // this.shoot(this.motX, this.motY, this.motZ, this.j(), MythicConfiguration.Options.Combat.Potions.potSpeed); + this.shoot(this.motX, this.motY, this.motZ, this.j(), 1.0F); + } else { + this.shoot(this.motX, this.motY, this.motZ, this.j(), 1.0F); + } + } + + public EntityProjectile(World world, double d0, double d1, double d2) { + super(world); + this.i = 0; + this.setSize(0.25F, 0.25F); + this.setPosition(d0, d1, d2); + } + + protected float j() { + return 1.5F; + } + + protected float l() { + return 0.0F; + } + + public void shoot(double d0, double d1, double d2, float f, float f1) { + float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + + d0 /= f2; + d1 /= f2; + d2 /= f2; + d0 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d1 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d2 += this.random.nextGaussian() * 0.007499999832361937D * (double) f1; + d0 *= f; + d1 *= f; + d2 *= f; + this.motX = d0; + this.motY = d1; + this.motZ = d2; + float f3 = MathHelper.sqrt(d0 * d0 + d2 * d2); + + this.lastYaw = this.yaw = (float) (MathHelper.b(d0, d2) * 180.0D / 3.1415927410125732D); + this.lastPitch = this.pitch = (float) (MathHelper.b(d1, f3) * 180.0D / 3.1415927410125732D); + this.i = 0; + } + + public void t_() { + this.P = this.locX; + this.Q = this.locY; + this.R = this.locZ; + super.t_(); + if (this.shake > 0) { + --this.shake; + } + + if (this.inGround) { + if (this.world.getType(this.blockX, this.blockY, this.blockZ).getBlock() == this.inBlockId) { + ++this.i; + if (this.i == 1200) { + this.die(); + } + + return; + } + + this.inGround = false; + this.motX *= this.random.nextFloat() * 0.2F; + this.motY *= this.random.nextFloat() * 0.2F; + this.motZ *= this.random.nextFloat() * 0.2F; + this.i = 0; + this.ar = 0; + } else { + ++this.ar; + } + + Vec3D vec3d = new Vec3D(this.locX, this.locY, this.locZ); + Vec3D vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + MovingObjectPosition movingobjectposition = this.world.rayTrace(vec3d, vec3d1); + + vec3d = new Vec3D(this.locX, this.locY, this.locZ); + vec3d1 = new Vec3D(this.locX + this.motX, this.locY + this.motY, this.locZ + this.motZ); + if (movingobjectposition != null) { + vec3d1 = new Vec3D(movingobjectposition.pos.a, movingobjectposition.pos.b, movingobjectposition.pos.c); + } + + if (!this.world.isClientSide) { + Entity entity = null; + List list = this.world.getEntities(this, this.getBoundingBox().a(this.motX, this.motY, this.motZ).grow(1.0D, 1.0D, 1.0D)); + double d0 = 0.0D; + EntityLiving entityliving = this.getShooter(); + + for (int i = 0; i < list.size(); ++i) { + Entity entity1 = (Entity) list.get(i); + + int minTicks = 5; + if(this instanceof EntityPotion && ((EntityPotion) this).getPotionValue() == 16421) { // Mythic - Custom potion ticks + minTicks = MythicConfiguration.Options.Potions.minimumTicks; + } + + if (entity1.ad() && (entity1 != entityliving || this.ar >= minTicks)) { + float f = 0.3F; + AxisAlignedBB axisalignedbb = entity1.getBoundingBox().grow(f, f, f); + MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1); + + if (movingobjectposition1 != null) { + double d1 = vec3d.distanceSquared(movingobjectposition1.pos); + + if (d1 < d0 || d0 == 0.0D) { + entity = entity1; + d0 = d1; + } + } + } + } + + if (entity != null) { + movingobjectposition = new MovingObjectPosition(entity); + } + } + + // PaperSpigot start - Allow projectiles to fly through vanished players the shooter can't see + if (movingobjectposition != null && movingobjectposition.entity instanceof EntityPlayer && shooter != null && shooter instanceof EntityPlayer) { + if (!((EntityPlayer) shooter).getBukkitEntity().canSee(((EntityPlayer) movingobjectposition.entity).getBukkitEntity())) { + movingobjectposition = null; + } + } + // PaperSpigot end + + if (movingobjectposition != null) { + if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK && this.world.getType(movingobjectposition.a()).getBlock() == Blocks.PORTAL) { + this.d(movingobjectposition.a()); + } else { + this.a(movingobjectposition); + // CraftBukkit start + if (this.dead) { + org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); + } + // CraftBukkit end + } + } + + this.locX += this.motX; + this.locY += this.motY; + this.locZ += this.motZ; + float f1 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + + this.yaw = (float) (MathHelper.b(this.motX, this.motZ) * 180.0D / 3.1415927410125732D); + + for (this.pitch = (float) (MathHelper.b(this.motY, f1) * 180.0D / 3.1415927410125732D); this.pitch - this.lastPitch < -180.0F; this.lastPitch -= 360.0F) { + } + + while (this.pitch - this.lastPitch >= 180.0F) { + this.lastPitch += 360.0F; + } + + while (this.yaw - this.lastYaw < -180.0F) { + this.lastYaw -= 360.0F; + } + + while (this.yaw - this.lastYaw >= 180.0F) { + this.lastYaw += 360.0F; + } + + this.pitch = this.lastPitch + (this.pitch - this.lastPitch) * 0.2F; + this.yaw = this.lastYaw + (this.yaw - this.lastYaw) * 0.2F; + float f2 = 0.99F; + float f3 = this.m(); + + if (this.V()) { + 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); + } + + f2 = 0.8F; + } + + this.motX *= f2; + this.motY *= f2; + this.motZ *= f2; + this.motY -= f3; + this.setPosition(this.locX, this.locY, this.locZ); + } + + protected float m() { + return 0.03F; + } + + protected abstract void a(MovingObjectPosition movingobjectposition); + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setShort("xTile", (short) this.blockX); + nbttagcompound.setShort("yTile", (short) this.blockY); + nbttagcompound.setShort("zTile", (short) this.blockZ); + MinecraftKey minecraftkey = Block.REGISTRY.c(this.inBlockId); + + nbttagcompound.setString("inTile", minecraftkey == null ? "" : minecraftkey.toString()); + nbttagcompound.setByte("shake", (byte) this.shake); + nbttagcompound.setByte("inGround", (byte) (this.inGround ? 1 : 0)); + if ((this.shooterName == null || this.shooterName.length() == 0) && this.shooter instanceof EntityHuman) { + this.shooterName = this.shooter.getName(); + } + + nbttagcompound.setString("ownerName", this.shooterName == null ? "" : this.shooterName); + } + + public void a(NBTTagCompound nbttagcompound) { + this.blockX = nbttagcompound.getShort("xTile"); + this.blockY = nbttagcompound.getShort("yTile"); + this.blockZ = nbttagcompound.getShort("zTile"); + if (nbttagcompound.hasKeyOfType("inTile", 8)) { + this.inBlockId = Block.getByName(nbttagcompound.getString("inTile")); + } else { + this.inBlockId = Block.getById(nbttagcompound.getByte("inTile") & 255); + } + + this.shake = nbttagcompound.getByte("shake") & 255; + this.inGround = nbttagcompound.getByte("inGround") == 1; + this.shooter = null; + this.shooterName = nbttagcompound.getString("ownerName"); + if (this.shooterName != null && this.shooterName.length() == 0) { + this.shooterName = null; + } + + this.shooter = this.getShooter(); + } + + public EntityLiving getShooter() { + if (this.shooter == null && this.shooterName != null && this.shooterName.length() > 0) { + 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)); + + if (entity instanceof EntityLiving) { + this.shooter = (EntityLiving) entity; + } + } catch (Throwable throwable) { + this.shooter = null; + } + } + } + + return this.shooter; + } + + // Mythic - Hide projectiles for practice + public boolean a(EntityPlayer entityplayer) { + if(!super.a(entityplayer)) return false; + + if(MythicConfiguration.Options.Tracking.Hide.projectiles) { + EntityLiving shooter = getShooter(); + if (shooter instanceof EntityPlayer) { + EntityPlayer otherPlayer = (EntityPlayer) shooter; + return entityplayer.getBukkitEntity().canSee(otherPlayer.getBukkitEntity()); + } + } + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityRabbit.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityRabbit.java new file mode 100644 index 0000000..bb47e09 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityRabbit.java @@ -0,0 +1,537 @@ +package net.minecraft.server; + +public class EntityRabbit extends EntityAnimal { + + private EntityRabbit.PathfinderGoalRabbitAvoidTarget bm; + private int bo = 0; + private int bp = 0; + private boolean bq = false; + private boolean br = false; + private int bs = 0; + private EntityRabbit.EnumRabbitState bt; + private int bu; + private EntityHuman bv; + + public EntityRabbit(World world) { + super(world); + this.bt = EntityRabbit.EnumRabbitState.HOP; + this.bu = 0; + this.bv = null; + this.setSize(0.6F, 0.7F); + this.g = new EntityRabbit.ControllerJumpRabbit(this); + this.moveController = new EntityRabbit.ControllerMoveRabbit(this); + ((Navigation) this.getNavigation()).a(true); + this.initializePathFinderGoals(); // CraftBukkit - moved code + this.b(0.0D); + } + + // CraftBukkit start - code from constructor + public void initializePathFinderGoals(){ + this.navigation.a(2.5F); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new EntityRabbit.PathfinderGoalRabbitPanic(this, 1.33D)); + this.goalSelector.a(2, new PathfinderGoalTempt(this, 1.0D, Items.CARROT, false)); + this.goalSelector.a(2, new PathfinderGoalTempt(this, 1.0D, Items.GOLDEN_CARROT, false)); + this.goalSelector.a(2, new PathfinderGoalTempt(this, 1.0D, Item.getItemOf(Blocks.YELLOW_FLOWER), false)); + this.goalSelector.a(3, new PathfinderGoalBreed(this, 0.8D)); + this.goalSelector.a(5, new EntityRabbit.PathfinderGoalEatCarrots(this)); + this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 0.6D)); + this.goalSelector.a(11, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); + this.bm = new EntityRabbit.PathfinderGoalRabbitAvoidTarget(this, EntityWolf.class, 16.0F, 1.33D, 1.33D); + this.goalSelector.a(4, this.bm); + } + // CraftBukkit end + + protected float bE() { + return this.moveController.a() && this.moveController.e() > this.locY + 0.5D ? 0.5F : this.bt.b(); + } + + public void a(EntityRabbit.EnumRabbitState entityrabbit_enumrabbitstate) { + this.bt = entityrabbit_enumrabbitstate; + } + + public void b(double d0) { + this.getNavigation().a(d0); + this.moveController.a(this.moveController.d(), this.moveController.e(), this.moveController.f(), d0); + } + + public void a(boolean flag, EntityRabbit.EnumRabbitState entityrabbit_enumrabbitstate) { + super.i(flag); + if (!flag) { + if (this.bt == EntityRabbit.EnumRabbitState.ATTACK) { + this.bt = EntityRabbit.EnumRabbitState.HOP; + } + } else { + this.b(1.5D * (double) entityrabbit_enumrabbitstate.a()); + this.makeSound(this.cm(), this.bB(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) * 0.8F); + } + + this.bq = flag; + } + + public void b(EntityRabbit.EnumRabbitState entityrabbit_enumrabbitstate) { + this.a(true, entityrabbit_enumrabbitstate); + this.bp = entityrabbit_enumrabbitstate.d(); + this.bo = 0; + } + + public boolean cl() { + return this.bq; + } + + protected void h() { + super.h(); + this.datawatcher.a(18, Byte.valueOf((byte) 0)); + } + + public void E() { + if (this.moveController.b() > 0.8D) { + this.a(EntityRabbit.EnumRabbitState.SPRINT); + } else if (this.bt != EntityRabbit.EnumRabbitState.ATTACK) { + this.a(EntityRabbit.EnumRabbitState.HOP); + } + + if (this.bs > 0) { + --this.bs; + } + + if (this.bu > 0) { + this.bu -= this.random.nextInt(3); + if (this.bu < 0) { + this.bu = 0; + } + } + + if (this.onGround) { + if (!this.br) { + this.a(false, EntityRabbit.EnumRabbitState.NONE); + this.cw(); + } + + if (this.getRabbitType() == 99 && this.bs == 0) { + EntityLiving entityliving = this.getGoalTarget(); + + if (entityliving != null && this.h(entityliving) < 16.0D) { + this.a(entityliving.locX, entityliving.locZ); + this.moveController.a(entityliving.locX, entityliving.locY, entityliving.locZ, this.moveController.b()); + this.b(EntityRabbit.EnumRabbitState.ATTACK); + this.br = true; + } + } + + EntityRabbit.ControllerJumpRabbit entityrabbit_controllerjumprabbit = (EntityRabbit.ControllerJumpRabbit) this.g; + + if (!entityrabbit_controllerjumprabbit.c()) { + if (this.moveController.a() && this.bs == 0) { + PathEntity pathentity = this.navigation.j(); + Vec3D vec3d = new Vec3D(this.moveController.d(), this.moveController.e(), this.moveController.f()); + + if (pathentity != null && pathentity.e() < pathentity.d()) { + vec3d = pathentity.a((Entity) this); + } + + this.a(vec3d.a, vec3d.c); + this.b(this.bt); + } + } else if (!entityrabbit_controllerjumprabbit.d()) { + this.ct(); + } + } + + this.br = this.onGround; + } + + public void Y() {} + + private void a(double d0, double d1) { + this.yaw = (float) (MathHelper.b(d1 - this.locZ, d0 - this.locX) * 180.0D / 3.1415927410125732D) - 90.0F; + } + + private void ct() { + ((EntityRabbit.ControllerJumpRabbit) this.g).a(true); + } + + private void cu() { + ((EntityRabbit.ControllerJumpRabbit) this.g).a(false); + } + + private void cv() { + this.bs = this.co(); + } + + private void cw() { + this.cv(); + this.cu(); + } + + public void m() { + super.m(); + if (this.bo != this.bp) { + if (this.bo == 0 && !this.world.isClientSide) { + this.world.broadcastEntityEffect(this, (byte) 1); + } + + ++this.bo; + } else if (this.bp != 0) { + this.bo = 0; + this.bp = 0; + } + + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("RabbitType", this.getRabbitType()); + nbttagcompound.setInt("MoreCarrotTicks", this.bu); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setRabbitType(nbttagcompound.getInt("RabbitType")); + this.bu = nbttagcompound.getInt("MoreCarrotTicks"); + } + + protected String cm() { + return "mob.rabbit.hop"; + } + + protected String z() { + return "mob.rabbit.idle"; + } + + protected String bo() { + return "mob.rabbit.hurt"; + } + + protected String bp() { + return "mob.rabbit.death"; + } + + public boolean r(Entity entity) { + if (this.getRabbitType() == 99) { + this.makeSound("mob.attack", 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + return entity.damageEntity(DamageSource.mobAttack(this), 8.0F); + } else { + return entity.damageEntity(DamageSource.mobAttack(this), 3.0F); + } + } + + public int br() { + return this.getRabbitType() == 99 ? 8 : super.br(); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + return this.isInvulnerable(damagesource) ? false : super.damageEntity(damagesource, f); + } + + protected void getRareDrop() { + this.a(new ItemStack(Items.RABBIT_FOOT, 1), 0.0F); + } + + protected void dropDeathLoot(boolean flag, int i) { + int j = this.random.nextInt(2) + this.random.nextInt(1 + i); + + int k; + + for (k = 0; k < j; ++k) { + this.a(Items.RABBIT_HIDE, 1); + } + + j = this.random.nextInt(2); + + for (k = 0; k < j; ++k) { + if (this.isBurning()) { + this.a(Items.COOKED_RABBIT, 1); + } else { + this.a(Items.RABBIT, 1); + } + } + + } + + private boolean a(Item item) { + return item == Items.CARROT || item == Items.GOLDEN_CARROT || item == Item.getItemOf(Blocks.YELLOW_FLOWER); + } + + public EntityRabbit b(EntityAgeable entityageable) { + EntityRabbit entityrabbit = new EntityRabbit(this.world); + + if (entityageable instanceof EntityRabbit) { + entityrabbit.setRabbitType(this.random.nextBoolean() ? this.getRabbitType() : ((EntityRabbit) entityageable).getRabbitType()); + } + + return entityrabbit; + } + + public boolean d(ItemStack itemstack) { + return itemstack != null && this.a(itemstack.getItem()); + } + + public int getRabbitType() { + return this.datawatcher.getByte(18); + } + + public void setRabbitType(int i) { + if (i == 99) { + this.goalSelector.a((PathfinderGoal) this.bm); + this.goalSelector.a(4, new EntityRabbit.PathfinderGoalKillerRabbitMeleeAttack(this)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true)); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityWolf.class, true)); + if (!this.hasCustomName()) { + this.setCustomName(LocaleI18n.get("entity.KillerBunny.name")); + } + } + + this.datawatcher.watch(18, Byte.valueOf((byte) i)); + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + Object object = super.prepare(difficultydamagescaler, groupdataentity); + int i = this.random.nextInt(6); + boolean flag = false; + + if (object instanceof EntityRabbit.GroupDataRabbit) { + i = ((EntityRabbit.GroupDataRabbit) object).a; + flag = true; + } else { + object = new EntityRabbit.GroupDataRabbit(i); + } + + this.setRabbitType(i); + if (flag) { + this.setAgeRaw(-24000); + } + + return (GroupDataEntity) object; + } + + private boolean cx() { + return this.bu == 0; + } + + protected int co() { + return this.bt.c(); + } + + protected void cp() { + this.world.addParticle(EnumParticle.BLOCK_DUST, 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[] { Block.getCombinedId(Blocks.CARROTS.fromLegacyData(7))}); + this.bu = 100; + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.b(entityageable); + } + + static enum EnumRabbitState { + + NONE(0.0F, 0.0F, 30, 1), HOP(0.8F, 0.2F, 20, 10), STEP(1.0F, 0.45F, 14, 14), SPRINT(1.75F, 0.4F, 1, 8), ATTACK(2.0F, 0.7F, 7, 8); + + private final float f; + private final float g; + private final int h; + private final int i; + + private EnumRabbitState(float f, float f1, int i, int j) { + this.f = f; + this.g = f1; + this.h = i; + this.i = j; + } + + public float a() { + return this.f; + } + + public float b() { + return this.g; + } + + public int c() { + return this.h; + } + + public int d() { + return this.i; + } + } + + static class PathfinderGoalKillerRabbitMeleeAttack extends PathfinderGoalMeleeAttack { + + public PathfinderGoalKillerRabbitMeleeAttack(EntityRabbit entityrabbit) { + super(entityrabbit, EntityLiving.class, 1.4D, true); + } + + protected double a(EntityLiving entityliving) { + return (double) (4.0F + entityliving.width); + } + } + + static class PathfinderGoalRabbitPanic extends PathfinderGoalPanic { + + private EntityRabbit b; + + public PathfinderGoalRabbitPanic(EntityRabbit entityrabbit, double d0) { + super(entityrabbit, d0); + this.b = entityrabbit; + } + + public void e() { + super.e(); + this.b.b(this.a); + } + } + + static class PathfinderGoalEatCarrots extends PathfinderGoalGotoTarget { + + private final EntityRabbit c; + private boolean d; + private boolean e = false; + + public PathfinderGoalEatCarrots(EntityRabbit entityrabbit) { + super(entityrabbit, 0.699999988079071D, 16); + this.c = entityrabbit; + } + + public boolean a() { + if (this.a <= 0) { + if (!this.c.world.getGameRules().getBoolean("mobGriefing")) { + return false; + } + + this.e = false; + this.d = this.c.cx(); + } + + return super.a(); + } + + public boolean b() { + return this.e && super.b(); + } + + public void c() { + super.c(); + } + + public void d() { + super.d(); + } + + public void e() { + super.e(); + this.c.getControllerLook().a((double) this.b.getX() + 0.5D, (double) (this.b.getY() + 1), (double) this.b.getZ() + 0.5D, 10.0F, (float) this.c.bQ()); + if (this.f()) { + World world = this.c.world; + BlockPosition blockposition = this.b.up(); + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (this.e && block instanceof BlockCarrots && ((Integer) iblockdata.get(BlockCarrots.AGE)).intValue() == 7) { + world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 2); + world.setAir(blockposition, true); + this.c.cp(); + } + + this.e = false; + this.a = 10; + } + + } + + protected boolean a(World world, BlockPosition blockposition) { + Block block = world.getType(blockposition).getBlock(); + + if (block == Blocks.FARMLAND) { + blockposition = blockposition.up(); + IBlockData iblockdata = world.getType(blockposition); + + block = iblockdata.getBlock(); + if (block instanceof BlockCarrots && ((Integer) iblockdata.get(BlockCarrots.AGE)).intValue() == 7 && this.d && !this.e) { + this.e = true; + return true; + } + } + + return false; + } + } + + static class PathfinderGoalRabbitAvoidTarget extends PathfinderGoalAvoidTarget { + + private EntityRabbit c; + + public PathfinderGoalRabbitAvoidTarget(EntityRabbit entityrabbit, Class oclass, float f, double d0, double d1) { + super(entityrabbit, oclass, f, d0, d1); + this.c = entityrabbit; + } + + public void e() { + super.e(); + } + } + + static class ControllerMoveRabbit extends ControllerMove { + + private EntityRabbit g; + + public ControllerMoveRabbit(EntityRabbit entityrabbit) { + super(entityrabbit); + this.g = entityrabbit; + } + + public void c() { + if (this.g.onGround && !this.g.cl()) { + this.g.b(0.0D); + } + + super.c(); + } + } + + public class ControllerJumpRabbit extends ControllerJump { + + private EntityRabbit c; + private boolean d = false; + + public ControllerJumpRabbit(EntityRabbit entityrabbit) { + super(entityrabbit); + this.c = entityrabbit; + } + + public boolean c() { + return this.a; + } + + public boolean d() { + return this.d; + } + + public void a(boolean flag) { + this.d = flag; + } + + public void b() { + if (this.a) { + this.c.b(EntityRabbit.EnumRabbitState.STEP); + this.a = false; + } + + } + } + + public static class GroupDataRabbit implements GroupDataEntity { + + public int a; + + public GroupDataRabbit(int i) { + this.a = i; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySheep.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySheep.java new file mode 100644 index 0000000..29611a1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySheep.java @@ -0,0 +1,263 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Map; +import java.util.Random; + +// CraftBukkit start +import org.bukkit.event.entity.SheepRegrowWoolEvent; +import org.bukkit.event.player.PlayerShearEntityEvent; +import org.bukkit.inventory.InventoryView; +// CraftBukkit end + +public class EntitySheep extends EntityAnimal { + + private final InventoryCrafting bm = new InventoryCrafting(new Container() { + public boolean a(EntityHuman entityhuman) { + return false; + } + + // CraftBukkit start + @Override + public InventoryView getBukkitView() { + return null; // TODO: O.O + } + // CraftBukkit end + }, 2, 1); + private static final Map bo = Maps.newEnumMap(EnumColor.class); + private int bp; + private PathfinderGoalEatTile bq = new PathfinderGoalEatTile(this); + + public static float[] a(EnumColor enumcolor) { + return (float[]) EntitySheep.bo.get(enumcolor); + } + + public EntitySheep(World world) { + super(world); + this.setSize(0.9F, 1.3F); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); + this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); + this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.1D, Items.WHEAT, false)); + this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.1D)); + this.goalSelector.a(5, this.bq); + this.goalSelector.a(6, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.bm.setItem(0, new ItemStack(Items.DYE, 1, 0)); + this.bm.setItem(1, new ItemStack(Items.DYE, 1, 0)); + this.bm.resultInventory = new InventoryCraftResult(); // CraftBukkit - add result slot for event + } + + protected void E() { + this.bp = this.bq.f(); + super.E(); + } + + public void m() { + if (this.world.isClientSide) { + this.bp = Math.max(0, this.bp - 1); + } + + super.m(); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(8.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.23000000417232513D); + } + + protected void h() { + super.h(); + this.datawatcher.a(16, new Byte((byte) 0)); + } + + protected void dropDeathLoot(boolean flag, int i) { + if (!this.isSheared()) { + this.a(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, this.getColor().getColorIndex()), 0.0F); + } + + int j = this.random.nextInt(2) + 1 + this.random.nextInt(1 + i); + + for (int k = 0; k < j; ++k) { + if (this.isBurning()) { + this.a(Items.COOKED_MUTTON, 1); + } else { + this.a(Items.MUTTON, 1); + } + } + + } + + protected Item getLoot() { + return Item.getItemOf(Blocks.WOOL); + } + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (itemstack != null && itemstack.getItem() == Items.SHEARS && !this.isSheared() && !this.isBaby()) { + if (!this.world.isClientSide) { + // CraftBukkit start + PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), this.getBukkitEntity()); + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return false; + } + // CraftBukkit end + + this.setSheared(true); + int i = 1 + this.random.nextInt(3); + + for (int j = 0; j < i; ++j) { + EntityItem entityitem = this.a(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, this.getColor().getColorIndex()), 1.0F); + + entityitem.motY += (double) (this.random.nextFloat() * 0.05F); + entityitem.motX += (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F); + entityitem.motZ += (double) ((this.random.nextFloat() - this.random.nextFloat()) * 0.1F); + } + } + + itemstack.damage(1, entityhuman); + this.makeSound("mob.sheep.shear", 1.0F, 1.0F); + } + + return super.a(entityhuman); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setBoolean("Sheared", this.isSheared()); + nbttagcompound.setByte("Color", (byte) this.getColor().getColorIndex()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setSheared(nbttagcompound.getBoolean("Sheared")); + this.setColor(EnumColor.fromColorIndex(nbttagcompound.getByte("Color"))); + } + + protected String z() { + return "mob.sheep.say"; + } + + protected String bo() { + return "mob.sheep.say"; + } + + protected String bp() { + return "mob.sheep.say"; + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.sheep.step", 0.15F, 1.0F); + } + + public EnumColor getColor() { + return EnumColor.fromColorIndex(this.datawatcher.getByte(16) & 15); + } + + public void setColor(EnumColor enumcolor) { + byte b0 = this.datawatcher.getByte(16); + + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & 240 | enumcolor.getColorIndex() & 15))); + } + + public boolean isSheared() { + return (this.datawatcher.getByte(16) & 16) != 0; + } + + public void setSheared(boolean flag) { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 16))); + } else { + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -17))); + } + + } + + public static EnumColor a(Random random) { + int i = random.nextInt(100); + + return i < 5 ? EnumColor.BLACK : (i < 10 ? EnumColor.GRAY : (i < 15 ? EnumColor.SILVER : (i < 18 ? EnumColor.BROWN : (random.nextInt(500) == 0 ? EnumColor.PINK : EnumColor.WHITE)))); + } + + public EntitySheep b(EntityAgeable entityageable) { + EntitySheep entitysheep = (EntitySheep) entityageable; + EntitySheep entitysheep1 = new EntitySheep(this.world); + + entitysheep1.setColor(this.a((EntityAnimal) this, (EntityAnimal) entitysheep)); + return entitysheep1; + } + + public void v() { + // CraftBukkit start + SheepRegrowWoolEvent event = new SheepRegrowWoolEvent((org.bukkit.entity.Sheep) this.getBukkitEntity()); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + this.setSheared(false); + } + // CraftBukkit end + if (this.isBaby()) { + this.setAge(60); + } + + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + groupdataentity = super.prepare(difficultydamagescaler, groupdataentity); + this.setColor(a(this.world.random)); + return groupdataentity; + } + + private EnumColor a(EntityAnimal entityanimal, EntityAnimal entityanimal1) { + int i = ((EntitySheep) entityanimal).getColor().getInvColorIndex(); + int j = ((EntitySheep) entityanimal1).getColor().getInvColorIndex(); + + this.bm.getItem(0).setData(i); + this.bm.getItem(1).setData(j); + ItemStack itemstack = CraftingManager.getInstance().craft(this.bm, ((EntitySheep) entityanimal).world); + int k; + + if (itemstack != null && itemstack.getItem() == Items.DYE) { + k = itemstack.getData(); + } else { + k = this.world.random.nextBoolean() ? i : j; + } + + return EnumColor.fromInvColorIndex(k); + } + + public float getHeadHeight() { + return 0.95F * this.length; + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.b(entityageable); + } + + static { + EntitySheep.bo.put(EnumColor.WHITE, new float[] { 1.0F, 1.0F, 1.0F}); + EntitySheep.bo.put(EnumColor.ORANGE, new float[] { 0.85F, 0.5F, 0.2F}); + EntitySheep.bo.put(EnumColor.MAGENTA, new float[] { 0.7F, 0.3F, 0.85F}); + EntitySheep.bo.put(EnumColor.LIGHT_BLUE, new float[] { 0.4F, 0.6F, 0.85F}); + EntitySheep.bo.put(EnumColor.YELLOW, new float[] { 0.9F, 0.9F, 0.2F}); + EntitySheep.bo.put(EnumColor.LIME, new float[] { 0.5F, 0.8F, 0.1F}); + EntitySheep.bo.put(EnumColor.PINK, new float[] { 0.95F, 0.5F, 0.65F}); + EntitySheep.bo.put(EnumColor.GRAY, new float[] { 0.3F, 0.3F, 0.3F}); + EntitySheep.bo.put(EnumColor.SILVER, new float[] { 0.6F, 0.6F, 0.6F}); + EntitySheep.bo.put(EnumColor.CYAN, new float[] { 0.3F, 0.5F, 0.6F}); + EntitySheep.bo.put(EnumColor.PURPLE, new float[] { 0.5F, 0.25F, 0.7F}); + EntitySheep.bo.put(EnumColor.BLUE, new float[] { 0.2F, 0.3F, 0.7F}); + EntitySheep.bo.put(EnumColor.BROWN, new float[] { 0.4F, 0.3F, 0.2F}); + EntitySheep.bo.put(EnumColor.GREEN, new float[] { 0.4F, 0.5F, 0.2F}); + EntitySheep.bo.put(EnumColor.RED, new float[] { 0.6F, 0.2F, 0.2F}); + EntitySheep.bo.put(EnumColor.BLACK, new float[] { 0.1F, 0.1F, 0.1F}); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySilverfish.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySilverfish.java new file mode 100644 index 0000000..b982154 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySilverfish.java @@ -0,0 +1,217 @@ +package net.minecraft.server; + +import java.util.Random; + +public class EntitySilverfish extends EntityMonster { + + private EntitySilverfish.PathfinderGoalSilverfishWakeOthers a; + + public EntitySilverfish(World world) { + super(world); + this.setSize(0.4F, 0.3F); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(3, this.a = new EntitySilverfish.PathfinderGoalSilverfishWakeOthers(this)); + this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntityHuman.class, 1.0D, false)); + this.goalSelector.a(5, new EntitySilverfish.PathfinderGoalSilverfishHideInBlock(this)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[0])); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true)); + } + + public double am() { + return 0.2D; + } + + public float getHeadHeight() { + return 0.1F; + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(8.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(1.0D); + } + + protected boolean s_() { + return false; + } + + protected String z() { + return "mob.silverfish.say"; + } + + protected String bo() { + return "mob.silverfish.hit"; + } + + protected String bp() { + return "mob.silverfish.kill"; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + if (damagesource instanceof EntityDamageSource || damagesource == DamageSource.MAGIC) { + this.a.f(); + } + + return super.damageEntity(damagesource, f); + } + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.silverfish.step", 0.15F, 1.0F); + } + + protected Item getLoot() { + return null; + } + + public void t_() { + this.aI = this.yaw; + super.t_(); + } + + public float a(BlockPosition blockposition) { + return this.world.getType(blockposition.down()).getBlock() == Blocks.STONE ? 10.0F : super.a(blockposition); + } + + protected boolean n_() { + return true; + } + + public boolean bR() { + if (super.bR()) { + EntityHuman entityhuman = this.world.findNearbyPlayer(this, 5.0D); + + return entityhuman == null; + } else { + return false; + } + } + + public EnumMonsterType getMonsterType() { + return EnumMonsterType.ARTHROPOD; + } + + static class PathfinderGoalSilverfishHideInBlock extends PathfinderGoalRandomStroll { + + private final EntitySilverfish silverfish; + private EnumDirection b; + private boolean c; + + public PathfinderGoalSilverfishHideInBlock(EntitySilverfish entitysilverfish) { + super(entitysilverfish, 1.0D, 10); + this.silverfish = entitysilverfish; + this.a(1); + } + + public boolean a() { + if (this.silverfish.getGoalTarget() != null) { + return false; + } else if (!this.silverfish.getNavigation().m()) { + return false; + } else { + Random random = this.silverfish.bc(); + + if (random.nextInt(10) == 0) { + this.b = EnumDirection.a(random); + BlockPosition blockposition = (new BlockPosition(this.silverfish.locX, this.silverfish.locY + 0.5D, this.silverfish.locZ)).shift(this.b); + IBlockData iblockdata = this.silverfish.world.getType(blockposition); + + if (BlockMonsterEggs.d(iblockdata)) { + this.c = true; + return true; + } + } + + this.c = false; + return super.a(); + } + } + + public boolean b() { + return this.c ? false : super.b(); + } + + public void c() { + if (!this.c) { + super.c(); + } else { + World world = this.silverfish.world; + BlockPosition blockposition = (new BlockPosition(this.silverfish.locX, this.silverfish.locY + 0.5D, this.silverfish.locZ)).shift(this.b); + IBlockData iblockdata = world.getType(blockposition); + + if (BlockMonsterEggs.d(iblockdata)) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.MONSTER_EGG, Block.getId(BlockMonsterEggs.getById(iblockdata.getBlock().toLegacyData(iblockdata)))).isCancelled()) { + return; + } + // CraftBukkit end + world.setTypeAndData(blockposition, Blocks.MONSTER_EGG.getBlockData().set(BlockMonsterEggs.VARIANT, BlockMonsterEggs.EnumMonsterEggVarient.a(iblockdata)), 3); + this.silverfish.y(); + this.silverfish.die(); + } + + } + } + } + + static class PathfinderGoalSilverfishWakeOthers extends PathfinderGoal { + + private EntitySilverfish silverfish; + private int b; + + public PathfinderGoalSilverfishWakeOthers(EntitySilverfish entitysilverfish) { + this.silverfish = entitysilverfish; + } + + public void f() { + if (this.b == 0) { + this.b = 20; + } + + } + + public boolean a() { + return this.b > 0; + } + + public void e() { + --this.b; + if (this.b <= 0) { + World world = this.silverfish.world; + Random random = this.silverfish.bc(); + BlockPosition blockposition = new BlockPosition(this.silverfish); + + for (int i = 0; i <= 5 && i >= -5; i = i <= 0 ? 1 - i : 0 - i) { + for (int j = 0; j <= 10 && j >= -10; j = j <= 0 ? 1 - j : 0 - j) { + for (int k = 0; k <= 10 && k >= -10; k = k <= 0 ? 1 - k : 0 - k) { + BlockPosition blockposition1 = blockposition.a(j, i, k); + IBlockData iblockdata = world.getType(blockposition1); + + if (iblockdata.getBlock() == Blocks.MONSTER_EGG) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.silverfish, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), Blocks.AIR, 0).isCancelled()) { + continue; + } + // CraftBukkit end + if (world.getGameRules().getBoolean("mobGriefing")) { + world.setAir(blockposition1, true); + } else { + world.setTypeAndData(blockposition1, ((BlockMonsterEggs.EnumMonsterEggVarient) iblockdata.get(BlockMonsterEggs.VARIANT)).d(), 3); + } + + if (random.nextBoolean()) { + return; + } + } + } + } + } + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySkeleton.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySkeleton.java new file mode 100644 index 0000000..46bff95 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySkeleton.java @@ -0,0 +1,317 @@ +package net.minecraft.server; + +import java.util.Calendar; + +import org.bukkit.event.entity.EntityCombustEvent; // CraftBukkit + +public class EntitySkeleton extends EntityMonster implements IRangedEntity { + + private PathfinderGoalArrowAttack a = new PathfinderGoalArrowAttack(this, 1.0D, 20, 60, 15.0F); + private PathfinderGoalMeleeAttack b = new PathfinderGoalMeleeAttack(this, EntityHuman.class, 1.2D, false); + + public EntitySkeleton(World world) { + super(world); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, new PathfinderGoalRestrictSun(this)); + this.goalSelector.a(3, new PathfinderGoalFleeSun(this, 1.0D)); + this.goalSelector.a(3, new PathfinderGoalAvoidTarget(this, EntityWolf.class, 6.0F, 1.0D, 1.2D)); + this.goalSelector.a(4, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); + this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget(this, EntityIronGolem.class, true)); + if (world != null && !world.isClientSide) { + this.n(); + } + + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); + } + + protected void h() { + super.h(); + this.datawatcher.a(13, new Byte((byte) 0)); + } + + protected String z() { + return "mob.skeleton.say"; + } + + protected String bo() { + return "mob.skeleton.hurt"; + } + + protected String bp() { + return "mob.skeleton.death"; + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.skeleton.step", 0.15F, 1.0F); + } + + public boolean r(Entity entity) { + if (super.r(entity)) { + if (this.getSkeletonType() == 1 && entity instanceof EntityLiving) { + ((EntityLiving) entity).addEffect(new MobEffect(MobEffectList.WITHER.id, 200)); + } + + return true; + } else { + return false; + } + } + + public EnumMonsterType getMonsterType() { + return EnumMonsterType.UNDEAD; + } + + public void m() { + if (this.world.w() && !this.world.isClientSide) { + float f = this.c(1.0F); + BlockPosition blockposition = new BlockPosition(this.locX, (double) Math.round(this.locY), this.locZ); + + if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.world.i(blockposition)) { + boolean flag = true; + ItemStack itemstack = this.getEquipment(4); + + if (itemstack != null) { + if (itemstack.e()) { + itemstack.setData(itemstack.h() + this.random.nextInt(2)); + if (itemstack.h() >= itemstack.j()) { + this.b(itemstack); + this.setEquipment(4, (ItemStack) null); + } + } + + flag = false; + } + + if (flag) { + // CraftBukkit start + EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + this.setOnFire(event.getDuration()); + } + // CraftBukkit end + } + } + } + + if (this.world.isClientSide && this.getSkeletonType() == 1) { + this.setSize(0.72F, 2.535F); + } + + super.m(); + } + + public void ak() { + super.ak(); + if (this.vehicle instanceof EntityCreature) { + EntityCreature entitycreature = (EntityCreature) this.vehicle; + + this.aI = entitycreature.aI; + } + + } + + public void die(DamageSource damagesource) { + // super.die(damagesource); // CraftBukkit + if (damagesource.i() instanceof EntityArrow && damagesource.getEntity() instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) damagesource.getEntity(); + double d0 = entityhuman.locX - this.locX; + double d1 = entityhuman.locZ - this.locZ; + + if (d0 * d0 + d1 * d1 >= 2500.0D) { + entityhuman.b((Statistic) AchievementList.v); + } + } else if (damagesource.getEntity() instanceof EntityCreeper && ((EntityCreeper) damagesource.getEntity()).isPowered() && ((EntityCreeper) damagesource.getEntity()).cp()) { + ((EntityCreeper) damagesource.getEntity()).cq(); + // CraftBukkit start + // this.a(new ItemStack(Items.SKULL, 1, this.getSkeletonType() == 1 ? 1 : 0), 0.0F); + headDrop = new ItemStack(Items.SKULL, 1, this.getSkeletonType() == 1 ? 1 : 0); + // CraftBukkit end + + } + + super.die(damagesource); // CraftBukkit - moved from above + + } + + /* CraftBukkit start + protected Item getLoot() { + return Items.ARROW; + } + // CraftBukkit end */ + + protected void dropDeathLoot(boolean flag, int i) { + super.dropDeathLoot(flag, i); // CraftBukkit + int j; + int k; + + if (this.getSkeletonType() == 1) { + j = this.random.nextInt(3 + i) - 1; + + for (k = 0; k < j; ++k) { + this.a(Items.COAL, 1); + } + } else { + j = this.random.nextInt(3 + i); + + for (k = 0; k < j; ++k) { + this.a(Items.ARROW, 1); + } + } + + j = this.random.nextInt(3 + i); + + for (k = 0; k < j; ++k) { + this.a(Items.BONE, 1); + } + + } + + protected void getRareDrop() { + if (this.getSkeletonType() == 1) { + this.a(new ItemStack(Items.SKULL, 1, 1), 0.0F); + } + + } + + protected void a(DifficultyDamageScaler difficultydamagescaler) { + super.a(difficultydamagescaler); + this.setEquipment(0, new ItemStack(Items.BOW)); + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + groupdataentity = super.prepare(difficultydamagescaler, groupdataentity); + if (this.world.worldProvider instanceof WorldProviderHell && this.bc().nextInt(5) > 0) { + this.goalSelector.a(4, this.b); + this.setSkeletonType(1); + this.setEquipment(0, new ItemStack(Items.STONE_SWORD)); + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(4.0D); + } else { + this.goalSelector.a(4, this.a); + this.a(difficultydamagescaler); + this.b(difficultydamagescaler); + } + + this.j(this.random.nextFloat() < 0.55F * difficultydamagescaler.c()); + if (this.getEquipment(4) == null) { + Calendar calendar = this.world.Y(); + + if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && this.random.nextFloat() < 0.25F) { + this.setEquipment(4, new ItemStack(this.random.nextFloat() < 0.1F ? Blocks.LIT_PUMPKIN : Blocks.PUMPKIN)); + this.dropChances[4] = 0.0F; + } + } + + return groupdataentity; + } + + public void n() { + this.goalSelector.a((PathfinderGoal) this.b); + this.goalSelector.a((PathfinderGoal) this.a); + ItemStack itemstack = this.bA(); + + if (itemstack != null && itemstack.getItem() == Items.BOW) { + this.goalSelector.a(4, this.a); + } else { + this.goalSelector.a(4, this.b); + } + + } + + public void a(EntityLiving entityliving, float f) { + EntityArrow entityarrow = new EntityArrow(this.world, this, entityliving, 1.6F, (float) (14 - this.world.getDifficulty().a() * 4)); + int i = EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_DAMAGE.id, this.bA()); + int j = EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_KNOCKBACK.id, this.bA()); + + entityarrow.b((double) (f * 2.0F) + this.random.nextGaussian() * 0.25D + (double) ((float) this.world.getDifficulty().a() * 0.11F)); + if (i > 0) { + entityarrow.b(entityarrow.j() + (double) i * 0.5D + 0.5D); + } + + if (j > 0) { + entityarrow.setKnockbackStrength(j); + } + + if (EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_FIRE.id, this.bA()) > 0 || this.getSkeletonType() == 1) { + // CraftBukkit start - call EntityCombustEvent + EntityCombustEvent event = new EntityCombustEvent(entityarrow.getBukkitEntity(), 100); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + entityarrow.setOnFire(event.getDuration()); + } + // CraftBukkit end + } + + // CraftBukkit start + org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.bA(), entityarrow, 0.8F); + if (event.isCancelled()) { + event.getProjectile().remove(); + return; + } + + if (event.getProjectile() == entityarrow.getBukkitEntity()) { + world.addEntity(entityarrow); + } + // CraftBukkit end + + this.makeSound("random.bow", 1.0F, 1.0F / (this.bc().nextFloat() * 0.4F + 0.8F)); + // this.world.addEntity(entityarrow); // CraftBukkit - moved up + } + + public int getSkeletonType() { + return this.datawatcher.getByte(13); + } + + public void setSkeletonType(int i) { + this.datawatcher.watch(13, Byte.valueOf((byte) i)); + this.fireProof = i == 1; + if (i == 1) { + this.setSize(0.72F, 2.535F); + } else { + this.setSize(0.6F, 1.95F); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("SkeletonType", 99)) { + byte b0 = nbttagcompound.getByte("SkeletonType"); + + this.setSkeletonType(b0); + } + + this.n(); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setByte("SkeletonType", (byte) this.getSkeletonType()); + } + + public void setEquipment(int i, ItemStack itemstack) { + super.setEquipment(i, itemstack); + if (!this.world.isClientSide && i == 0) { + this.n(); + } + + } + + public float getHeadHeight() { + return this.getSkeletonType() == 1 ? super.getHeadHeight() : 1.74F; + } + + public double am() { + return this.isBaby() ? 0.0D : -0.35D; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySlice.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySlice.java new file mode 100644 index 0000000..ae6c52f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySlice.java @@ -0,0 +1,134 @@ +package net.minecraft.server; + +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.AbstractSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class EntitySlice extends AbstractSet { + + private static final Set> a = Sets.newConcurrentHashSet(); // CraftBukkit + private final Map, List> b = Maps.newHashMap(); + private final Set> c = Sets.newIdentityHashSet(); + private final Class d; + private final List e = Lists.newArrayList(); + + public EntitySlice(Class oclass) { + this.d = oclass; + this.c.add(oclass); + this.b.put(oclass, this.e); + Iterator iterator = EntitySlice.a.iterator(); + + while (iterator.hasNext()) { + Class oclass1 = (Class) iterator.next(); + + this.a(oclass1); + } + + } + + protected void a(Class oclass) { + EntitySlice.a.add(oclass); + Iterator iterator = this.e.iterator(); + + while (iterator.hasNext()) { + Object object = iterator.next(); + + if (oclass.isAssignableFrom(object.getClass())) { + this.a((T) object, oclass); + } + } + + this.c.add(oclass); + } + + protected Class b(Class oclass) { + if (this.d.isAssignableFrom(oclass)) { + if (!this.c.contains(oclass)) { + this.a(oclass); + } + + return oclass; + } else { + throw new IllegalArgumentException("Don\'t know how to search for " + oclass); + } + } + + public boolean add(T t0) { + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + Class oclass = (Class) iterator.next(); + + if (oclass.isAssignableFrom(t0.getClass())) { + this.a(t0, oclass); + } + } + + return true; + } + + private void a(T t0, Class oclass) { + List list = (List) this.b.get(oclass); + + if (list == null) { + this.b.put(oclass, Lists.newArrayList(t0)); + } else { + list.add(t0); + } + + } + + public boolean remove(Object object) { + Object object1 = object; + boolean flag = false; + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + Class oclass = (Class) iterator.next(); + + if (oclass.isAssignableFrom(object1.getClass())) { + List list = (List) this.b.get(oclass); + + if (list != null && list.remove(object1)) { + flag = true; + } + } + } + + return flag; + } + + public boolean contains(Object object) { + return Iterators.contains(this.c(object.getClass()).iterator(), object); + } + + public Iterable c(final Class oclass) { + return new Iterable() { + public Iterator iterator() { + List list = (List) EntitySlice.this.b.get(EntitySlice.this.b(oclass)); + + if (list == null) { + return Iterators.emptyIterator(); + } else { + Iterator iterator = list.iterator(); + + return Iterators.filter(iterator, oclass); + } + } + }; + } + + public Iterator iterator() { + return this.e.isEmpty() ? Iterators.emptyIterator() : Iterators.unmodifiableIterator(this.e.iterator()); + } + + public int size() { + return this.e.size(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySlime.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySlime.java new file mode 100644 index 0000000..c927832 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySlime.java @@ -0,0 +1,434 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.event.entity.SlimeSplitEvent; +// CraftBukkit end + +public class EntitySlime extends EntityInsentient implements IMonster { + + public float a; + public float b; + public float c; + private boolean bk; + + public EntitySlime(World world) { + super(world); + this.moveController = new EntitySlime.ControllerMoveSlime(this); + this.goalSelector.a(1, new EntitySlime.PathfinderGoalSlimeRandomJump(this)); + this.goalSelector.a(2, new EntitySlime.PathfinderGoalSlimeNearestPlayer(this)); + this.goalSelector.a(3, new EntitySlime.PathfinderGoalSlimeRandomDirection(this)); + this.goalSelector.a(5, new EntitySlime.PathfinderGoalSlimeIdle(this)); + this.targetSelector.a(1, new PathfinderGoalTargetNearestPlayer(this)); + this.targetSelector.a(3, new PathfinderGoalNearestAttackableTargetInsentient(this, EntityIronGolem.class)); + } + + protected void h() { + super.h(); + this.datawatcher.a(16, Byte.valueOf((byte) 1)); + } + + public void setSize(int i) { + this.datawatcher.watch(16, Byte.valueOf((byte) i)); + this.setSize(0.51000005F * (float) i, 0.51000005F * (float) i); + this.setPosition(this.locX, this.locY, this.locZ); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) (i * i)); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue((double) (0.2F + 0.1F * (float) i)); + this.setHealth(this.getMaxHealth()); + this.b_ = i; + } + + public int getSize() { + return this.datawatcher.getByte(16); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("Size", this.getSize() - 1); + nbttagcompound.setBoolean("wasOnGround", this.bk); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + int i = nbttagcompound.getInt("Size"); + + if (i < 0) { + i = 0; + } + + this.setSize(i + 1); + this.bk = nbttagcompound.getBoolean("wasOnGround"); + } + + protected EnumParticle n() { + return EnumParticle.SLIME; + } + + protected String ck() { + return "mob.slime." + (this.getSize() > 1 ? "big" : "small"); + } + + public void t_() { + if (!this.world.isClientSide && this.world.getDifficulty() == EnumDifficulty.PEACEFUL && this.getSize() > 0) { + this.dead = true; + } + + this.b += (this.a - this.b) * 0.5F; + this.c = this.b; + super.t_(); + if (this.onGround && !this.bk) { + int i = this.getSize(); + + for (int j = 0; j < i * 8; ++j) { + float f = this.random.nextFloat() * 3.1415927F * 2.0F; + float f1 = this.random.nextFloat() * 0.5F + 0.5F; + float f2 = MathHelper.sin(f) * (float) i * 0.5F * f1; + float f3 = MathHelper.cos(f) * (float) i * 0.5F * f1; + World world = this.world; + EnumParticle enumparticle = this.n(); + 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]); + } + + if (this.cl()) { + this.makeSound(this.ck(), this.bB(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) / 0.8F); + } + + this.a = -0.5F; + } else if (!this.onGround && this.bk) { + this.a = 1.0F; + } + + this.bk = this.onGround; + this.ch(); + } + + protected void ch() { + this.a *= 0.6F; + } + + protected int cg() { + return this.random.nextInt(20) + 10; + } + + protected EntitySlime cf() { + return new EntitySlime(this.world); + } + + public void i(int i) { + if (i == 16) { + int j = this.getSize(); + + this.setSize(0.51000005F * (float) j, 0.51000005F * (float) j); + this.yaw = this.aK; + this.aI = this.aK; + if (this.V() && this.random.nextInt(20) == 0) { + this.X(); + } + } + + super.i(i); + } + + public void die() { + int i = this.getSize(); + + if (!this.world.isClientSide && i > 1 && this.getHealth() <= 0.0F) { + int j = 2 + this.random.nextInt(3); + + // CraftBukkit start + SlimeSplitEvent event = new SlimeSplitEvent((org.bukkit.entity.Slime) this.getBukkitEntity(), j); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled() && event.getCount() > 0) { + j = event.getCount(); + } else { + super.die(); + return; + } + // CraftBukkit end + + for (int k = 0; k < j; ++k) { + float f = ((float) (k % 2) - 0.5F) * (float) i / 4.0F; + float f1 = ((float) (k / 2) - 0.5F) * (float) i / 4.0F; + EntitySlime entityslime = this.cf(); + + if (this.hasCustomName()) { + entityslime.setCustomName(this.getCustomName()); + } + + if (this.isPersistent()) { + entityslime.bX(); + } + + entityslime.setSize(i / 2); + entityslime.setPositionRotation(this.locX + (double) f, this.locY + 0.5D, this.locZ + (double) f1, this.random.nextFloat() * 360.0F, 0.0F); + this.world.addEntity(entityslime, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SLIME_SPLIT); // CraftBukkit - SpawnReason + } + } + + super.die(); + } + + public void collide(Entity entity) { + super.collide(entity); + if (entity instanceof EntityIronGolem && this.ci()) { + this.e((EntityLiving) entity); + } + + } + + public void d(EntityHuman entityhuman) { + if (this.ci()) { + this.e((EntityLiving) entityhuman); + } + + } + + protected void e(EntityLiving entityliving) { + int i = this.getSize(); + + if (this.hasLineOfSight(entityliving) && this.h(entityliving) < 0.6D * (double) i * 0.6D * (double) i && entityliving.damageEntity(DamageSource.mobAttack(this), (float) this.cj())) { + this.makeSound("mob.attack", 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + this.a((EntityLiving) this, (Entity) entityliving); + } + + } + + public float getHeadHeight() { + return 0.625F * this.length; + } + + protected boolean ci() { + return this.getSize() > 1; + } + + protected int cj() { + return this.getSize(); + } + + protected String bo() { + return "mob.slime." + (this.getSize() > 1 ? "big" : "small"); + } + + protected String bp() { + return "mob.slime." + (this.getSize() > 1 ? "big" : "small"); + } + + protected Item getLoot() { + return this.getSize() == 1 ? Items.SLIME : null; + } + + public boolean bR() { + BlockPosition blockposition = new BlockPosition(MathHelper.floor(this.locX), 0, MathHelper.floor(this.locZ)); + Chunk chunk = this.world.getChunkAtWorldCoords(blockposition); + + if (this.world.getWorldData().getType() == WorldType.FLAT && this.random.nextInt(4) != 1) { + return false; + } else { + if (this.world.getDifficulty() != EnumDifficulty.PEACEFUL) { + BiomeBase biomebase = this.world.getBiome(blockposition); + + if (biomebase == BiomeBase.SWAMPLAND && this.locY > 50.0D && this.locY < 70.0D && this.random.nextFloat() < 0.5F && this.random.nextFloat() < this.world.y() && this.world.getLightLevel(new BlockPosition(this)) <= this.random.nextInt(8)) { + return super.bR(); + } + + // PaperSpigot - Toggle to make all chunks spawn chunks + boolean isSlimeChunk = world.paperSpigotConfig.allChunksAreSlimeChunks || chunk.a(987234911L).nextInt(10) == 0; + if (this.random.nextInt(10) == 0 && isSlimeChunk && this.locY < 40.0D) { + return super.bR(); + } + } + + return false; + } + } + + protected float bB() { + return 0.4F * (float) this.getSize(); + } + + public int bQ() { + return 0; + } + + protected boolean cn() { + return this.getSize() > 0; + } + + protected boolean cl() { + return this.getSize() > 2; + } + + protected void bF() { + this.motY = 0.41999998688697815D; + this.ai = true; + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + int i = this.random.nextInt(3); + + if (i < 2 && this.random.nextFloat() < 0.5F * difficultydamagescaler.c()) { + ++i; + } + + int j = 1 << i; + + this.setSize(j); + return super.prepare(difficultydamagescaler, groupdataentity); + } + + static class PathfinderGoalSlimeIdle extends PathfinderGoal { + + private EntitySlime a; + + public PathfinderGoalSlimeIdle(EntitySlime entityslime) { + this.a = entityslime; + this.a(5); + } + + public boolean a() { + return true; + } + + public void e() { + ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(1.0D); + } + } + + static class PathfinderGoalSlimeRandomJump extends PathfinderGoal { + + private EntitySlime a; + + public PathfinderGoalSlimeRandomJump(EntitySlime entityslime) { + this.a = entityslime; + this.a(5); + ((Navigation) entityslime.getNavigation()).d(true); + } + + public boolean a() { + return this.a.V() || this.a.ab(); + } + + public void e() { + if (this.a.bc().nextFloat() < 0.8F) { + this.a.getControllerJump().a(); + } + + ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(1.2D); + } + } + + static class PathfinderGoalSlimeRandomDirection extends PathfinderGoal { + + private EntitySlime a; + private float b; + private int c; + + public PathfinderGoalSlimeRandomDirection(EntitySlime entityslime) { + this.a = entityslime; + this.a(2); + } + + public boolean a() { + return this.a.getGoalTarget() == null && (this.a.onGround || this.a.V() || this.a.ab()); + } + + public void e() { + if (--this.c <= 0) { + this.c = 40 + this.a.bc().nextInt(60); + this.b = (float) this.a.bc().nextInt(360); + } + + ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(this.b, false); + } + } + + static class PathfinderGoalSlimeNearestPlayer extends PathfinderGoal { + + private EntitySlime a; + private int b; + + public PathfinderGoalSlimeNearestPlayer(EntitySlime entityslime) { + this.a = entityslime; + this.a(2); + } + + public boolean a() { + EntityLiving entityliving = this.a.getGoalTarget(); + + return entityliving == null ? false : (!entityliving.isAlive() ? false : !(entityliving instanceof EntityHuman) || !((EntityHuman) entityliving).abilities.isInvulnerable); + } + + public void c() { + this.b = 300; + super.c(); + } + + public boolean b() { + EntityLiving entityliving = this.a.getGoalTarget(); + + return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.isInvulnerable ? false : --this.b > 0)); + } + + public void e() { + this.a.a(this.a.getGoalTarget(), 10.0F, 10.0F); + ((EntitySlime.ControllerMoveSlime) this.a.getControllerMove()).a(this.a.yaw, this.a.ci()); + } + } + + static class ControllerMoveSlime extends ControllerMove { + + private float g; + private int h; + private EntitySlime i; + private boolean j; + + public ControllerMoveSlime(EntitySlime entityslime) { + super(entityslime); + this.i = entityslime; + } + + public void a(float f, boolean flag) { + this.g = f; + this.j = flag; + } + + public void a(double d0) { + this.e = d0; + this.f = true; + } + + public void c() { + this.a.yaw = this.a(this.a.yaw, this.g, 30.0F); + this.a.aK = this.a.yaw; + this.a.aI = this.a.yaw; + if (!this.f) { + this.a.n(0.0F); + } else { + this.f = false; + if (this.a.onGround) { + this.a.k((float) (this.e * this.a.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue())); + if (this.h-- <= 0) { + this.h = this.i.cg(); + if (this.j) { + this.h /= 3; + } + + this.i.getControllerJump().a(); + if (this.i.cn()) { + this.i.makeSound(this.i.ck(), this.i.bB(), ((this.i.bc().nextFloat() - this.i.bc().nextFloat()) * 0.2F + 1.0F) * 0.8F); + } + } else { + this.i.aZ = this.i.ba = 0.0F; + this.a.k(0.0F); + } + } else { + this.a.k((float) (this.e * this.a.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue())); + } + + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySmallFireball.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySmallFireball.java new file mode 100644 index 0000000..f769de5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySmallFireball.java @@ -0,0 +1,72 @@ +package net.minecraft.server; + +import org.bukkit.event.entity.EntityCombustByEntityEvent; // CraftBukkit + +public class EntitySmallFireball extends EntityFireball { + + public EntitySmallFireball(World world) { + super(world); + this.setSize(0.3125F, 0.3125F); + } + + public EntitySmallFireball(World world, EntityLiving entityliving, double d0, double d1, double d2) { + super(world, entityliving, d0, d1, d2); + this.setSize(0.3125F, 0.3125F); + } + + public EntitySmallFireball(World world, double d0, double d1, double d2, double d3, double d4, double d5) { + super(world, d0, d1, d2, d3, d4, d5); + this.setSize(0.3125F, 0.3125F); + } + + protected void a(MovingObjectPosition movingobjectposition) { + if (!this.world.isClientSide) { + boolean flag; + + if (movingobjectposition.entity != null) { + flag = movingobjectposition.entity.damageEntity(DamageSource.fireball(this, this.shooter), 5.0F); + if (flag) { + this.a(this.shooter, movingobjectposition.entity); + if (!movingobjectposition.entity.isFireProof()) { + // CraftBukkit start - Entity damage by entity event + combust event + EntityCombustByEntityEvent event = new EntityCombustByEntityEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), movingobjectposition.entity.getBukkitEntity(), 5); + movingobjectposition.entity.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + movingobjectposition.entity.setOnFire(event.getDuration()); + } + // CraftBukkit end + } + } + } else { + flag = true; + if (this.shooter != null && this.shooter instanceof EntityInsentient) { + flag = this.world.getGameRules().getBoolean("mobGriefing"); + } + + if (flag) { + BlockPosition blockposition = movingobjectposition.a().shift(movingobjectposition.direction); + + if (this.world.isEmpty(blockposition)) { + // CraftBukkit start + if (isIncendiary && !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { + this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + } + // CraftBukkit end + } + } + } + + this.die(); + } + + } + + public boolean ad() { + return false; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + return false; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySnowman.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySnowman.java new file mode 100644 index 0000000..cb875c7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySnowman.java @@ -0,0 +1,96 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.event.block.EntityBlockFormEvent; +// CraftBukkit end + +public class EntitySnowman extends EntityGolem implements IRangedEntity { + + public EntitySnowman(World world) { + super(world); + this.setSize(0.7F, 1.9F); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(1, new PathfinderGoalArrowAttack(this, 1.25D, 20, 10.0F)); + this.goalSelector.a(2, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); + this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget(this, EntityInsentient.class, 10, true, false, IMonster.d)); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(4.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.20000000298023224D); + } + + public void m() { + super.m(); + if (!this.world.isClientSide) { + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY); + int k = MathHelper.floor(this.locZ); + + if (this.U()) { + this.damageEntity(DamageSource.DROWN, 1.0F); + } + + if (this.world.getBiome(new BlockPosition(i, 0, k)).a(new BlockPosition(i, j, k)) > 1.0F) { + this.damageEntity(CraftEventFactory.MELTING, 1.0F); // CraftBukkit - DamageSource.BURN -> CraftEventFactory.MELTING + } + + for (int l = 0; l < 4; ++l) { + i = MathHelper.floor(this.locX + (double) ((float) (l % 2 * 2 - 1) * 0.25F)); + j = MathHelper.floor(this.locY); + k = MathHelper.floor(this.locZ + (double) ((float) (l / 2 % 2 * 2 - 1) * 0.25F)); + BlockPosition blockposition = new BlockPosition(i, j, k); + + if (this.world.getType(blockposition).getBlock().getMaterial() == Material.AIR && this.world.getBiome(new BlockPosition(i, 0, k)).a(blockposition) < 0.8F && Blocks.SNOW_LAYER.canPlace(this.world, blockposition)) { + // CraftBukkit start + org.bukkit.block.BlockState blockState = this.world.getWorld().getBlockAt(i, j, k).getState(); + blockState.setType(CraftMagicNumbers.getMaterial(Blocks.SNOW_LAYER)); + + EntityBlockFormEvent event = new EntityBlockFormEvent(this.getBukkitEntity(), blockState.getBlock(), blockState); + this.world.getServer().getPluginManager().callEvent(event); + + if(!event.isCancelled()) { + blockState.update(true); + } + // CraftBukkit end + } + } + } + + } + + protected Item getLoot() { + return Items.SNOWBALL; + } + + protected void dropDeathLoot(boolean flag, int i) { + int j = this.random.nextInt(16); + + for (int k = 0; k < j; ++k) { + this.a(Items.SNOWBALL, 1); + } + + } + + public void a(EntityLiving entityliving, float f) { + EntitySnowball entitysnowball = new EntitySnowball(this.world, this); + double d0 = entityliving.locY + (double) entityliving.getHeadHeight() - 1.100000023841858D; + double d1 = entityliving.locX - this.locX; + double d2 = d0 - entitysnowball.locY; + double d3 = entityliving.locZ - this.locZ; + float f1 = MathHelper.sqrt(d1 * d1 + d3 * d3) * 0.2F; + + entitysnowball.shoot(d1, d2 + (double) f1, d3, 1.6F, 12.0F); + this.makeSound("random.bow", 1.0F, 1.0F / (this.bc().nextFloat() * 0.4F + 0.8F)); + this.world.addEntity(entitysnowball); + } + + public float getHeadHeight() { + return 1.7F; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySpider.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySpider.java new file mode 100644 index 0000000..68a253c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySpider.java @@ -0,0 +1,197 @@ +package net.minecraft.server; + +import java.util.Random; + +public class EntitySpider extends EntityMonster { + + public EntitySpider(World world) { + super(world); + this.setSize(1.4F, 0.9F); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(3, new PathfinderGoalLeapAtTarget(this, 0.4F)); + this.goalSelector.a(4, new EntitySpider.PathfinderGoalSpiderMeleeAttack(this, EntityHuman.class)); + this.goalSelector.a(4, new EntitySpider.PathfinderGoalSpiderMeleeAttack(this, EntityIronGolem.class)); + this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 0.8D)); + this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); + this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(2, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget(this, EntityHuman.class)); + this.targetSelector.a(3, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget(this, EntityIronGolem.class)); + } + + public double an() { + return (double) (this.length * 0.5F); + } + + protected NavigationAbstract b(World world) { + return new NavigationSpider(this, world); + } + + protected void h() { + super.h(); + this.datawatcher.a(16, new Byte((byte) 0)); + } + + public void t_() { + super.t_(); + if (!this.world.isClientSide) { + this.a(this.positionChanged); + } + + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(16.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); + } + + protected String z() { + return "mob.spider.say"; + } + + protected String bo() { + return "mob.spider.say"; + } + + protected String bp() { + return "mob.spider.death"; + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.spider.step", 0.15F, 1.0F); + } + + protected Item getLoot() { + return Items.STRING; + } + + protected void dropDeathLoot(boolean flag, int i) { + super.dropDeathLoot(flag, i); + if (flag && (this.random.nextInt(3) == 0 || this.random.nextInt(1 + i) > 0)) { + this.a(Items.SPIDER_EYE, 1); + } + + } + + public boolean k_() { + return this.n(); + } + + public void aA() {} + + public EnumMonsterType getMonsterType() { + return EnumMonsterType.ARTHROPOD; + } + + public boolean d(MobEffect mobeffect) { + return mobeffect.getEffectId() == MobEffectList.POISON.id ? false : super.d(mobeffect); + } + + public boolean n() { + return (this.datawatcher.getByte(16) & 1) != 0; + } + + public void a(boolean flag) { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { + b0 = (byte) (b0 | 1); + } else { + b0 &= -2; + } + + this.datawatcher.watch(16, Byte.valueOf(b0)); + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + Object object = super.prepare(difficultydamagescaler, groupdataentity); + + if (this.world.random.nextInt(100) == 0) { + EntitySkeleton entityskeleton = new EntitySkeleton(this.world); + + entityskeleton.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); + entityskeleton.prepare(difficultydamagescaler, (GroupDataEntity) null); + this.world.addEntity(entityskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.JOCKEY); // CraftBukkit - add SpawnReason + entityskeleton.mount(this); + } + + if (object == null) { + object = new EntitySpider.GroupDataSpider(); + if (this.world.getDifficulty() == EnumDifficulty.HARD && this.world.random.nextFloat() < 0.1F * difficultydamagescaler.c()) { + ((EntitySpider.GroupDataSpider) object).a(this.world.random); + } + } + + if (object instanceof EntitySpider.GroupDataSpider) { + int i = ((EntitySpider.GroupDataSpider) object).a; + + if (i > 0 && MobEffectList.byId[i] != null) { + this.addEffect(new MobEffect(i, Integer.MAX_VALUE)); + } + } + + return (GroupDataEntity) object; + } + + public float getHeadHeight() { + return 0.65F; + } + + static class PathfinderGoalSpiderNearestAttackableTarget extends PathfinderGoalNearestAttackableTarget { + + public PathfinderGoalSpiderNearestAttackableTarget(EntitySpider entityspider, Class oclass) { + super(entityspider, oclass, true); + } + + public boolean a() { + float f = this.e.c(1.0F); + + return f >= 0.5F ? false : super.a(); + } + } + + static class PathfinderGoalSpiderMeleeAttack extends PathfinderGoalMeleeAttack { + + public PathfinderGoalSpiderMeleeAttack(EntitySpider entityspider, Class oclass) { + super(entityspider, oclass, 1.0D, true); + } + + public boolean b() { + float f = this.b.c(1.0F); + + if (f >= 0.5F && this.b.bc().nextInt(100) == 0) { + this.b.setGoalTarget((EntityLiving) null); + return false; + } else { + return super.b(); + } + } + + protected double a(EntityLiving entityliving) { + return (double) (4.0F + entityliving.width); + } + } + + public static class GroupDataSpider implements GroupDataEntity { + + public int a; + + public GroupDataSpider() {} + + public void a(Random random) { + int i = random.nextInt(5); + + if (i <= 1) { + this.a = MobEffectList.FASTER_MOVEMENT.id; + } else if (i <= 2) { + this.a = MobEffectList.INCREASE_DAMAGE.id; + } else if (i <= 3) { + this.a = MobEffectList.REGENERATION.id; + } else if (i <= 4) { + this.a = MobEffectList.INVISIBILITY.id; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySquid.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySquid.java new file mode 100644 index 0000000..31996b4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntitySquid.java @@ -0,0 +1,186 @@ +package net.minecraft.server; + +public class EntitySquid extends EntityWaterAnimal { + + public float a; + public float b; + public float c; + public float bk; + public float bl; + public float bm; + public float bn; + public float bo; + private float bp; + private float bq; + private float br; + private float bs; + private float bt; + private float bu; + + public EntitySquid(World world) { + super(world); + this.setSize(0.95F, 0.95F); + this.random.setSeed((long) (1 + this.getId())); + this.bq = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; + this.goalSelector.a(0, new EntitySquid.PathfinderGoalSquid(this)); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(10.0D); + } + + public float getHeadHeight() { + return this.length * 0.5F; + } + + protected String z() { + return null; + } + + protected String bo() { + return null; + } + + protected String bp() { + return null; + } + + protected float bB() { + return 0.4F; + } + + protected Item getLoot() { + return null; + } + + protected boolean s_() { + return false; + } + + protected void dropDeathLoot(boolean flag, int i) { + int j = this.random.nextInt(3 + i) + 1; + + for (int k = 0; k < j; ++k) { + this.a(new ItemStack(Items.DYE, 1, EnumColor.BLACK.getInvColorIndex()), 0.0F); + } + + } + + /* CraftBukkit start - Delegate to Entity to use existing inWater value + public boolean V() { + return this.world.a(this.getBoundingBox().grow(0.0D, -0.6000000238418579D, 0.0D), Material.WATER, (Entity) this); + } + // CraftBukkit end */ + + public void m() { + super.m(); + this.b = this.a; + this.bk = this.c; + this.bm = this.bl; + this.bo = this.bn; + this.bl += this.bq; + if ((double) this.bl > 6.283185307179586D) { + if (this.world.isClientSide) { + this.bl = 6.2831855F; + } else { + this.bl = (float) ((double) this.bl - 6.283185307179586D); + if (this.random.nextInt(10) == 0) { + this.bq = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; + } + + this.world.broadcastEntityEffect(this, (byte) 19); + } + } + + if (this.inWater) { + float f; + + if (this.bl < 3.1415927F) { + f = this.bl / 3.1415927F; + this.bn = MathHelper.sin(f * f * 3.1415927F) * 3.1415927F * 0.25F; + if ((double) f > 0.75D) { + this.bp = 1.0F; + this.br = 1.0F; + } else { + this.br *= 0.8F; + } + } else { + this.bn = 0.0F; + this.bp *= 0.9F; + this.br *= 0.99F; + } + + if (!this.world.isClientSide) { + this.motX = (double) (this.bs * this.bp); + this.motY = (double) (this.bt * this.bp); + this.motZ = (double) (this.bu * this.bp); + } + + f = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ); + this.aI += (-((float) MathHelper.b(this.motX, this.motZ)) * 180.0F / 3.1415927F - this.aI) * 0.1F; + this.yaw = this.aI; + this.c = (float) ((double) this.c + 3.141592653589793D * (double) this.br * 1.5D); + this.a += (-((float) MathHelper.b((double) f, this.motY)) * 180.0F / 3.1415927F - this.a) * 0.1F; + } else { + this.bn = MathHelper.e(MathHelper.sin(this.bl)) * 3.1415927F * 0.25F; + if (!this.world.isClientSide) { + this.motX = 0.0D; + this.motY -= 0.08D; + this.motY *= 0.9800000190734863D; + this.motZ = 0.0D; + } + + this.a = (float) ((double) this.a + (double) (-90.0F - this.a) * 0.02D); + } + + } + + public void g(float f, float f1) { + this.move(this.motX, this.motY, this.motZ); + } + + public boolean bR() { + // PaperSpigot - Configurable squid spawn range + return this.locY > this.world.paperSpigotConfig.squidMinSpawnHeight && this.locY < (double) this.world.paperSpigotConfig.squidMaxSpawnHeight && super.bR(); + } + + public void b(float f, float f1, float f2) { + this.bs = f; + this.bt = f1; + this.bu = f2; + } + + public boolean n() { + return this.bs != 0.0F || this.bt != 0.0F || this.bu != 0.0F; + } + + static class PathfinderGoalSquid extends PathfinderGoal { + + private EntitySquid a; + + public PathfinderGoalSquid(EntitySquid entitysquid) { + this.a = entitysquid; + } + + public boolean a() { + return true; + } + + public void e() { + int i = this.a.bh(); + + if (i > 100) { + this.a.b(0.0F, 0.0F, 0.0F); + } else if (this.a.bc().nextInt(50) == 0 || !this.a.inWater || !this.a.n()) { + float f = this.a.bc().nextFloat() * 3.1415927F * 2.0F; + float f1 = MathHelper.cos(f) * 0.2F; + float f2 = -0.1F + this.a.bc().nextFloat() * 0.2F; + float f3 = MathHelper.sin(f) * 0.2F; + + this.a.b(f1, f2, f3); + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java new file mode 100644 index 0000000..f7056cc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTNTPrimed.java @@ -0,0 +1,215 @@ +package net.minecraft.server; + +import net.jafama.FastMath; +import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit + +public class EntityTNTPrimed extends Entity { + + public int fuseTicks; + private EntityLiving source; + public float yield = 4; // CraftBukkit - add field + public boolean isIncendiary = false; // CraftBukkit - add field + public org.bukkit.Location sourceLoc; // PaperSpigot + + // PaperSpigot start - TNT source location API + public EntityTNTPrimed(World world) { + this(null, world); + } + + public EntityTNTPrimed(org.bukkit.Location loc, World world) { + super(world); + sourceLoc = loc; + // PaperSpigot end + this.k = true; + this.setSize(0.98F, 0.98F); + this.loadChunks = world.paperSpigotConfig.loadUnloadedTNTEntities; // PaperSpigot + } + + public EntityTNTPrimed(org.bukkit.Location loc, World world, double d0, double d1, double d2, EntityLiving entityliving) { + this(loc, world); + this.setPosition(d0, d1, d2); + float f = (float) (FastMath.random() * 3.1415927410125732D * 2.0D); + + this.motX = (double) (-((float) FastMath.sin((double) f)) * 0.02F); + this.motY = 0.20000000298023224D; + this.motZ = (double) (-((float) FastMath.cos((double) f)) * 0.02F); + this.fuseTicks = 80; + this.lastX = d0; + this.lastY = d1; + this.lastZ = d2; + this.source = entityliving; + if (world.paperSpigotConfig.fixCannons) this.motX = this.motZ = 0.0F; // PaperSpigot - Fix cannons + } + + protected void h() {} + + protected boolean s_() { + return false; + } + + public boolean ad() { + return !this.dead; + } + + public void t_() { + if (world.spigotConfig.currentPrimedTnt++ > world.spigotConfig.maxTntTicksPerTick) { return; } // Spigot + this.lastX = this.locX; + this.lastY = this.locY; + this.lastZ = this.locZ; + this.motY -= 0.03999999910593033D; + this.move(this.motX, this.motY, this.motZ); + + // PaperSpigot start - Drop TNT entities above the specified height + if (this.world.paperSpigotConfig.tntEntityHeightNerf != 0 && this.locY > this.world.paperSpigotConfig.tntEntityHeightNerf) { + this.die(); + } + // PaperSpigot end + + // PaperSpigot start - Remove entities in unloaded chunks + if (this.inUnloadedChunk && world.paperSpigotConfig.removeUnloadedTNTEntities) { + this.die(); + this.fuseTicks = 2; + } + // PaperSpigot end + + this.motX *= 0.9800000190734863D; + this.motY *= 0.9800000190734863D; + this.motZ *= 0.9800000190734863D; + if (this.onGround) { + this.motX *= 0.699999988079071D; + this.motZ *= 0.699999988079071D; + this.motY *= -0.5D; + } + + if (this.fuseTicks-- <= 0) { + // CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event + // this.die(); + if (!this.world.isClientSide) { + this.explode(); + } + this.die(); + // 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]); + } + + } + + private void explode() { + // CraftBukkit start + // float f = 4.0F; + + // PaperSpigot start - Force load chunks during TNT explosions + ChunkProviderServer chunkProviderServer = ((ChunkProviderServer) world.chunkProvider); + boolean forceChunkLoad = chunkProviderServer.forceChunkLoad; + if (world.paperSpigotConfig.loadUnloadedTNTEntities) { + chunkProviderServer.forceChunkLoad = true; + } + // PaperSpigot end + + org.bukkit.craftbukkit.CraftServer server = this.world.getServer(); + + ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) org.bukkit.craftbukkit.entity.CraftEntity.getEntity(server, this)); + server.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + this.world.createExplosion(this, this.locX, this.locY + (double) (this.length / 2.0F), this.locZ, event.getRadius(), event.getFire(), true); + } + // CraftBukkit end + + // PaperSpigot start - Force load chunks during TNT explosions + if (world.paperSpigotConfig.loadUnloadedTNTEntities) { + chunkProviderServer.forceChunkLoad = forceChunkLoad; + } + // PaperSpigot end + } + + protected void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setByte("Fuse", (byte) this.fuseTicks); + // PaperSpigot start - TNT source location API + if (sourceLoc != null) { + nbttagcompound.setInt("SourceLoc_x", sourceLoc.getBlockX()); + nbttagcompound.setInt("SourceLoc_y", sourceLoc.getBlockY()); + nbttagcompound.setInt("SourceLoc_z", sourceLoc.getBlockZ()); + } + // PaperSpigot end + } + + protected void a(NBTTagCompound nbttagcompound) { + this.fuseTicks = nbttagcompound.getByte("Fuse"); + // PaperSpigot start - TNT source location API + if (nbttagcompound.hasKey("SourceLoc_x")) { + int srcX = nbttagcompound.getInt("SourceLoc_x"); + int srcY = nbttagcompound.getInt("SourceLoc_y"); + int srcZ = nbttagcompound.getInt("SourceLoc_z"); + sourceLoc = new org.bukkit.Location(world.getWorld(), srcX, srcY, srcZ); + } + // PaperSpigot end + } + + public EntityLiving getSource() { + return this.source; + } + + // PaperSpigot start - Fix cannons + @Override + public double f(double d0, double d1, double d2) { + if (!world.paperSpigotConfig.fixCannons) return super.f(d0, d1, d2); + + double d3 = this.locX - d0; + double d4 = this.locY + this.getHeadHeight() - d1; + double d5 = this.locZ - d2; + + return (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); + } + + @Override + public boolean aL() { + return !world.paperSpigotConfig.fixCannons && super.aL(); + } + + @Override + public float getHeadHeight() { + return world.paperSpigotConfig.fixCannons ? this.length / 2 : 0.0F; + } + + /** + * Author: Jedediah Smith + */ + @Override + public boolean W() { + if (!world.paperSpigotConfig.fixCannons) return super.W(); + + // Preserve velocity while calling the super method + double oldMotX = this.motX; + double oldMotY = this.motY; + double oldMotZ = this.motZ; + + super.W(); + + this.motX = oldMotX; + this.motY = oldMotY; + this.motZ = oldMotZ; + + if (this.inWater) { + // Send position and velocity updates to nearby players on every tick while the TNT is in water. + // This does pretty well at keeping their clients in sync with the server. + EntityTrackerEntry ete = ((WorldServer) this.getWorld()).getTracker().trackedEntities.get(this.getId()); + if (ete != null) { + PacketPlayOutEntityVelocity velocityPacket = new PacketPlayOutEntityVelocity(this); + PacketPlayOutEntityTeleport positionPacket = new PacketPlayOutEntityTeleport(this); + + for (EntityPlayer viewer : ete.trackedPlayers) { + if ((viewer.locX - this.locX) * (viewer.locY - this.locY) * (viewer.locZ - this.locZ) < 16 * 16) { + viewer.playerConnection.sendPacket(velocityPacket); + viewer.playerConnection.sendPacket(positionPacket); + } + } + } + } + + return this.inWater; + } + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityThrownExpBottle.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityThrownExpBottle.java new file mode 100644 index 0000000..23a2d5d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityThrownExpBottle.java @@ -0,0 +1,54 @@ +package net.minecraft.server; + +public class EntityThrownExpBottle extends EntityProjectile { + + public EntityThrownExpBottle(World world) { + super(world); + } + + public EntityThrownExpBottle(World world, EntityLiving entityliving) { + super(world, entityliving); + } + + public EntityThrownExpBottle(World world, double d0, double d1, double d2) { + super(world, d0, d1, d2); + } + + protected float m() { + return 0.07F; + } + + protected float j() { + return 0.7F; + } + + protected float l() { + return -20.0F; + } + + protected void a(MovingObjectPosition movingobjectposition) { + if (!this.world.isClientSide) { + // CraftBukkit - moved to after event + // this.world.triggerEffect(2002, new BlockPosition(this), 0); + int i = 3 + this.world.random.nextInt(5) + this.world.random.nextInt(5); + + // CraftBukkit start + org.bukkit.event.entity.ExpBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExpBottleEvent(this, i); + i = event.getExperience(); + if (event.getShowEffect()) { + this.world.triggerEffect(2002, new BlockPosition(this), 0); + } + // CraftBukkit end + + while (i > 0) { + int j = EntityExperienceOrb.getOrbValue(i); + + i -= j; + this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY, this.locZ, j)); + } + + this.die(); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTracker.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTracker.java new file mode 100644 index 0000000..fe4b736 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTracker.java @@ -0,0 +1,256 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import me.levansj01.mythicspigot.MythicConfiguration; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.Callable; + +public class EntityTracker { + + private static final Logger a = LogManager.getLogger(); + private final WorldServer world; + private Set c = Sets.newHashSet(); + public IntHashMap trackedEntities = new IntHashMap(); + private int e; + + public EntityTracker(WorldServer worldserver) { + this.world = worldserver; + this.e = worldserver.getMinecraftServer().getPlayerList().d(); + } + + public void track(Entity entity) { + if (entity instanceof EntityPlayer) { + this.addEntity(entity, 512, MythicConfiguration.Options.Tracking.updateTicks); // Mythic - Use configuration for updateTicks + EntityPlayer entityplayer = (EntityPlayer) entity; + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); + + if (entitytrackerentry.tracker != entityplayer) { + entitytrackerentry.updatePlayer(entityplayer); + } + } + } else if (entity instanceof EntityFishingHook) { + this.addEntity(entity, 64, 5, true); + } else if (entity instanceof EntityArrow) { + this.addEntity(entity, 64, 20, false); + } else if (entity instanceof EntitySmallFireball) { + this.addEntity(entity, 64, 10, false); + } else if (entity instanceof EntityFireball) { + this.addEntity(entity, 64, 10, false); + } else if (entity instanceof EntitySnowball) { + this.addEntity(entity, 64, 10, true); + } else if (entity instanceof EntityEnderPearl) { + this.addEntity(entity, 64, 10, true); + } else if (entity instanceof EntityEnderSignal) { + this.addEntity(entity, 64, 4, true); + } else if (entity instanceof EntityEgg) { + this.addEntity(entity, 64, 10, true); + } else if (entity instanceof EntityPotion) { + this.addEntity(entity, 64, 10, true); + } else if (entity instanceof EntityThrownExpBottle) { + this.addEntity(entity, 64, 10, true); + } else if (entity instanceof EntityFireworks) { + this.addEntity(entity, 64, 10, true); + } else if (entity instanceof EntityItem) { + this.addEntity(entity, 64, 20, true); + } else if (entity instanceof EntityMinecartAbstract) { + this.addEntity(entity, 80, 3, true); + } else if (entity instanceof EntityBoat) { + this.addEntity(entity, 80, 3, true); + } else if (entity instanceof EntitySquid) { + this.addEntity(entity, 64, 3, true); + } else if (entity instanceof EntityWither) { + this.addEntity(entity, 80, 3, false); + } else if (entity instanceof EntityBat) { + this.addEntity(entity, 80, 3, false); + } else if (entity instanceof EntityEnderDragon) { + this.addEntity(entity, 160, 3, true); + } else if (entity instanceof IAnimal) { + this.addEntity(entity, 80, 3, true); + } else if (entity instanceof EntityTNTPrimed) { + this.addEntity(entity, 160, 10, true); + } else if (entity instanceof EntityFallingBlock) { + this.addEntity(entity, 160, 20, true); + } else if (entity instanceof EntityHanging) { + this.addEntity(entity, 160, Integer.MAX_VALUE, false); + } else if (entity instanceof EntityArmorStand) { + this.addEntity(entity, 160, 3, true); + } else if (entity instanceof EntityExperienceOrb) { + this.addEntity(entity, 160, 20, true); + } else if (entity instanceof EntityEnderCrystal) { + this.addEntity(entity, 256, Integer.MAX_VALUE, false); + } + + } + + public void addEntity(Entity entity, int i, int j) { + this.addEntity(entity, i, j, false); + } + + public void addEntity(Entity entity, int i, final int j, boolean flag) { + org.spigotmc.AsyncCatcher.catchOp( "entity track"); // Spigot + i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot + if (i > this.e) { + i = this.e; + } + + try { + if (this.trackedEntities.b(entity.getId())) { + throw new IllegalStateException("Entity is already tracked!"); + } + + EntityTrackerEntry entitytrackerentry = new EntityTrackerEntry(entity, i, j, flag); + + this.c.add(entitytrackerentry); + this.trackedEntities.a(entity.getId(), entitytrackerentry); + entitytrackerentry.scanPlayers(this.world.players); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Adding entity to track"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity To Track"); + + crashreportsystemdetails.a("Tracking range", i + " blocks"); + final int finalI = i; // CraftBukkit - fix decompile error + crashreportsystemdetails.a("Update interval", new Callable() { + public String a() throws Exception { + String s = "Once per " + finalI + " ticks"; // CraftBukkit + + if (finalI == Integer.MAX_VALUE) { // CraftBukkit + s = "Maximum (" + s + ")"; + } + + return s; + } + + public Object call() throws Exception { + return this.a(); + } + }); + entity.appendEntityCrashDetails(crashreportsystemdetails); + CrashReportSystemDetails crashreportsystemdetails1 = crashreport.a("Entity That Is Already Tracked"); + + this.trackedEntities.get(entity.getId()).tracker.appendEntityCrashDetails(crashreportsystemdetails1); + + try { + throw new ReportedException(crashreport); + } catch (ReportedException reportedexception) { + EntityTracker.a.error("\"Silently\" catching entity tracking error.", reportedexception); + } + } + + } + + public void untrackEntity(Entity entity) { + org.spigotmc.AsyncCatcher.catchOp( "entity untrack"); // Spigot + if (entity instanceof EntityPlayer) { + EntityPlayer entityplayer = (EntityPlayer) entity; + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); + + entitytrackerentry.a(entityplayer); + } + } + + EntityTrackerEntry entitytrackerentry1 = this.trackedEntities.d(entity.getId()); + + if (entitytrackerentry1 != null) { + this.c.remove(entitytrackerentry1); + entitytrackerentry1.a(); + } + + } + + public void updatePlayers() { + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); + + entitytrackerentry.track(this.world.players); + if (entitytrackerentry.n && entitytrackerentry.tracker instanceof EntityPlayer) { + arraylist.add(entitytrackerentry.tracker); + } + } + + for (int i = 0; i < arraylist.size(); ++i) { + EntityPlayer entityplayer = (EntityPlayer) arraylist.get(i); + Iterator iterator1 = this.c.iterator(); + + while (iterator1.hasNext()) { + EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry) iterator1.next(); + + if (entitytrackerentry1.tracker != entityplayer) { + entitytrackerentry1.updatePlayer(entityplayer); + } + } + } + + } + + public void a(EntityPlayer entityplayer) { + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); + + if (entitytrackerentry.tracker == entityplayer) { + entitytrackerentry.scanPlayers(this.world.players); + } else { + entitytrackerentry.updatePlayer(entityplayer); + } + } + + } + + public void a(Entity entity, Packet packet) { + EntityTrackerEntry entitytrackerentry = this.trackedEntities.get(entity.getId()); + + if (entitytrackerentry != null) { + entitytrackerentry.broadcast(packet); + } + + } + + public void sendPacketToEntity(Entity entity, Packet packet) { + EntityTrackerEntry entitytrackerentry = this.trackedEntities.get(entity.getId()); + + if (entitytrackerentry != null) { + entitytrackerentry.broadcastIncludingSelf(packet); + } + + } + + public void untrackPlayer(EntityPlayer entityplayer) { + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); + + entitytrackerentry.clear(entityplayer); + } + + } + + public void a(EntityPlayer entityplayer, Chunk chunk) { + Iterator iterator = this.c.iterator(); + + while (iterator.hasNext()) { + EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry) iterator.next(); + + if (entitytrackerentry.tracker != entityplayer && entitytrackerentry.tracker.ae == chunk.locX && entitytrackerentry.tracker.ag == chunk.locZ) { + entitytrackerentry.updatePlayer(entityplayer); + } + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java new file mode 100644 index 0000000..5d90188 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityTrackerEntry.java @@ -0,0 +1,576 @@ +package net.minecraft.server; + +import me.levansj01.mythicspigot.MythicConfiguration; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerVelocityEvent; + +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +// CraftBukkit start +// CraftBukkit end + +public class EntityTrackerEntry { + + private static final Logger p = LogManager.getLogger(); + public Entity tracker; + public int b; + public int c; + public int xLoc; + public int yLoc; + public int zLoc; + public int yRot; + public int xRot; + public int i; + public double j; + public double k; + public double l; + public int m; + private double q; + private double r; + private double s; + private boolean isMoving; + private boolean u; + private int v; + private Entity w; + private boolean x; + private boolean y; + public boolean n; + // PaperSpigot start + // Replace trackedPlayers Set with a Map. The value is true until the player receives + // their first update (which is forced to have absolute coordinates), false afterward. + public java.util.Map trackedPlayerMap = new java.util.HashMap(); + public Set trackedPlayers = trackedPlayerMap.keySet(); + // PaperSpigot end + + public EntityTrackerEntry(Entity entity, int i, int j, boolean flag) { + this.tracker = entity; + this.b = i; + this.c = j; + this.u = flag; + this.xLoc = MathHelper.floor(entity.locX * 32.0D); + this.yLoc = MathHelper.floor(entity.locY * 32.0D); + this.zLoc = MathHelper.floor(entity.locZ * 32.0D); + this.yRot = MathHelper.d(entity.yaw * 256.0F / 360.0F); + this.xRot = MathHelper.d(entity.pitch * 256.0F / 360.0F); + this.i = MathHelper.d(entity.getHeadRotation() * 256.0F / 360.0F); + this.y = entity.onGround; + } + + public boolean equals(Object object) { + return object instanceof EntityTrackerEntry && ((EntityTrackerEntry) object).tracker.getId() == this.tracker.getId(); + } + + public int hashCode() { + return this.tracker.getId(); + } + + public void track(List list) { + this.n = false; + if (!this.isMoving || this.tracker.e(this.q, this.r, this.s) > 16.0D) { + this.q = this.tracker.locX; + this.r = this.tracker.locY; + this.s = this.tracker.locZ; + this.isMoving = true; + this.n = true; + this.scanPlayers(list); + } + + if (this.w != this.tracker.vehicle || this.tracker.vehicle != null && this.m % 60 == 0) { + this.w = this.tracker.vehicle; + this.broadcast(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle)); + } + + if (this.tracker instanceof EntityItemFrame /*&& this.m % 10 == 0*/) { // CraftBukkit - Moved below, should always enter this block + EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker; + ItemStack itemstack = entityitemframe.getItem(); + + if (this.m % 10 == 0 && itemstack != null && itemstack.getItem() instanceof ItemWorldMap) { // CraftBukkit - Moved this.m % 10 logic here so item frames do not enter the other blocks + WorldMap worldmap = Items.FILLED_MAP.getSavedMap(itemstack, this.tracker.world); + Iterator iterator = this.trackedPlayers.iterator(); // CraftBukkit + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + EntityPlayer entityplayer = (EntityPlayer) entityhuman; + + worldmap.a(entityplayer, itemstack); + Packet packet = Items.FILLED_MAP.c(itemstack, this.tracker.world, entityplayer); + + if (packet != null) { + entityplayer.playerConnection.sendPacket(packet); + } + } + } + + this.b(); + } + + if (this.m % this.c == 0 || this.tracker.ai || this.tracker.getDataWatcher().a()) { + int i; + int j; + + if (this.tracker.vehicle == null) { + ++this.v; + i = MathHelper.floor(this.tracker.locX * 32.0D); + j = MathHelper.floor(this.tracker.locY * 32.0D); + int k = MathHelper.floor(this.tracker.locZ * 32.0D); + int l = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F); + int i1 = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F); + int j1 = i - this.xLoc; + int k1 = j - this.yLoc; + int l1 = k - this.zLoc; + Object object = null; + + int diff = MythicConfiguration.Options.Tracking.minimumDistance; // Mythic - Use MythicConfiguration + + boolean flag = Math.abs(j1) >= diff || Math.abs(k1) >= diff || Math.abs(l1) >= diff || this.m % 60 == 0; + boolean flag1 = Math.abs(l - this.yRot) >= diff || Math.abs(i1 - this.xRot) >= diff; + + if (this.m > 0 || this.tracker instanceof EntityArrow) { // PaperSpigot - Moved up + // CraftBukkit start - Code moved from below + if (flag) { + this.xLoc = i; + this.yLoc = j; + this.zLoc = k; + } + + if (flag1) { + this.yRot = l; + this.xRot = i1; + } + // CraftBukkit end + + if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.v <= 400 && !this.x && this.y == this.tracker.onGround) { + if ((!flag || !flag1) && !(this.tracker instanceof EntityArrow)) { + if (flag) { + object = new PacketPlayOutEntity.PacketPlayOutRelEntityMove(this.tracker.getId(), (byte) j1, (byte) k1, (byte) l1, this.tracker.onGround); + } else if (flag1) { + object = new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) l, (byte) i1, this.tracker.onGround); + } + } else { + object = new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook(this.tracker.getId(), (byte) j1, (byte) k1, (byte) l1, (byte) l, (byte) i1, this.tracker.onGround); + } + } else { + this.y = this.tracker.onGround; + this.v = 0; + // CraftBukkit start - Refresh list of who can see a player before sending teleport packet + if (this.tracker instanceof EntityPlayer) { + this.scanPlayers(new java.util.ArrayList(this.trackedPlayers)); + } + // CraftBukkit end + object = new PacketPlayOutEntityTeleport(this.tracker.getId(), i, j, k, (byte) l, (byte) i1, this.tracker.onGround); + } + } + + if (this.u) { + double d0 = this.tracker.motX - this.j; + double d1 = this.tracker.motY - this.k; + double d2 = this.tracker.motZ - this.l; + double d3 = 0.02D; + double d4 = d0 * d0 + d1 * d1 + d2 * d2; + + if (d4 > d3 * d3 || d4 > 0.0D && this.tracker.motX == 0.0D && this.tracker.motY == 0.0D && this.tracker.motZ == 0.0D) { + this.j = this.tracker.motX; + this.k = this.tracker.motY; + this.l = this.tracker.motZ; + this.broadcast(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.j, this.k, this.l)); + } + } + + if (object != null) { + // PaperSpigot start - ensure fresh viewers get an absolute position on their first update, + // since we can't be certain what position they received in the spawn packet. + if (object instanceof PacketPlayOutEntityTeleport) { + this.broadcast((Packet) object); + } else { + PacketPlayOutEntityTeleport teleportPacket = null; + + for (java.util.Map.Entry viewer : trackedPlayerMap.entrySet()) { + if (viewer.getValue()) { + viewer.setValue(false); + if (teleportPacket == null) { + teleportPacket = new PacketPlayOutEntityTeleport(this.tracker.getId(), i, j, k, (byte) l, (byte) i1, this.tracker.onGround); + } + viewer.getKey().playerConnection.sendPacket(teleportPacket); + } else { + viewer.getKey().playerConnection.sendPacket((Packet) object); + } + } + } + // PaperSpigot end + } + + this.b(); + /* CraftBukkit start - Code moved up + if (flag) { + this.xLoc = i; + this.yLoc = j; + this.zLoc = k; + } + + if (flag1) { + this.yRot = l; + this.xRot = i1; + } + // CraftBukkit end */ + + this.x = false; + } else { + i = MathHelper.d(this.tracker.yaw * 256.0F / 360.0F); + j = MathHelper.d(this.tracker.pitch * 256.0F / 360.0F); + boolean flag2 = Math.abs(i - this.yRot) >= 4 || Math.abs(j - this.xRot) >= 4; + + if (flag2) { + this.broadcast(new PacketPlayOutEntity.PacketPlayOutEntityLook(this.tracker.getId(), (byte) i, (byte) j, this.tracker.onGround)); + this.yRot = i; + this.xRot = j; + } + + this.xLoc = MathHelper.floor(this.tracker.locX * 32.0D); + this.yLoc = MathHelper.floor(this.tracker.locY * 32.0D); + this.zLoc = MathHelper.floor(this.tracker.locZ * 32.0D); + this.b(); + this.x = true; + } + + i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); + if (Math.abs(i - this.i) >= 4) { + this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i)); + this.i = i; + } + + this.tracker.ai = false; + } + + ++this.m; + if (this.tracker.velocityChanged) { + // CraftBukkit start - Create PlayerVelocity event + boolean cancelled = false; + + if (this.tracker instanceof EntityPlayer) { + Player player = (Player) this.tracker.getBukkitEntity(); + org.bukkit.util.Vector velocity = player.getVelocity(); + + PlayerVelocityEvent event = new PlayerVelocityEvent(player, velocity.clone()); + this.tracker.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + cancelled = true; + } else if (!velocity.equals(event.getVelocity())) { + player.setVelocity(event.getVelocity()); + } + } + + if (!cancelled) { + this.broadcastIncludingSelf(new PacketPlayOutEntityVelocity(this.tracker)); + } + // CraftBukkit end + this.tracker.velocityChanged = false; + } + + } + + private void b() { + DataWatcher datawatcher = this.tracker.getDataWatcher(); + + if (datawatcher.a()) { + this.broadcastIncludingSelf(new PacketPlayOutEntityMetadata(this.tracker.getId(), datawatcher, false)); + } + + if (this.tracker instanceof EntityLiving) { + AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap(); + Set set = attributemapserver.getAttributes(); + + if (!set.isEmpty()) { + // CraftBukkit start - Send scaled max health + if (this.tracker instanceof EntityPlayer) { + ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(set, false); + } + // CraftBukkit end + this.broadcastIncludingSelf(new PacketPlayOutUpdateAttributes(this.tracker.getId(), set)); + } + + set.clear(); + } + + } + + public void broadcast(Packet packet) { + Iterator iterator = this.trackedPlayers.iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + entityplayer.playerConnection.sendPacket(packet); + } + + } + + public void broadcastIncludingSelf(Packet packet) { + this.broadcast(packet); + if (this.tracker instanceof EntityPlayer) { + ((EntityPlayer) this.tracker).playerConnection.sendPacket(packet); + } + + } + + public void a() { + Iterator iterator = this.trackedPlayers.iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + entityplayer.d(this.tracker); + } + + } + + public void a(EntityPlayer entityplayer) { + if (this.trackedPlayers.contains(entityplayer)) { + entityplayer.d(this.tracker); + this.trackedPlayers.remove(entityplayer); + } + + } + + public void updatePlayer(EntityPlayer entityplayer) { + org.spigotmc.AsyncCatcher.catchOp( "player tracker update"); // Spigot + if (entityplayer != this.tracker) { + if (this.c(entityplayer)) { + if (!this.trackedPlayers.contains(entityplayer) && (this.e(entityplayer) || this.tracker.attachedToPlayer)) { + // CraftBukkit start - respect vanish API + if (!entityplayer.getBukkitEntity().canSeeEntity(this.tracker.getBukkitEntity())) { + return; + } + + entityplayer.removeQueue.remove(Integer.valueOf(this.tracker.getId())); + // CraftBukkit end + this.trackedPlayerMap.put(entityplayer, true); // PaperBukkit + Packet packet = this.c(); + + entityplayer.playerConnection.sendPacket(packet); + if (!this.tracker.getDataWatcher().d()) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityMetadata(this.tracker.getId(), this.tracker.getDataWatcher(), true)); + } + + NBTTagCompound nbttagcompound = this.tracker.getNBTTag(); + + if (nbttagcompound != null) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateEntityNBT(this.tracker.getId(), nbttagcompound)); + } + + if (this.tracker instanceof EntityLiving) { + AttributeMapServer attributemapserver = (AttributeMapServer) ((EntityLiving) this.tracker).getAttributeMap(); + Collection collection = attributemapserver.c(); + + // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health + if (this.tracker.getId() == entityplayer.getId()) { + ((EntityPlayer) this.tracker).getBukkitEntity().injectScaledMaxHealth(collection, false); + } + // CraftBukkit end + + if (!collection.isEmpty()) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(this.tracker.getId(), collection)); + } + } + + this.j = this.tracker.motX; + this.k = this.tracker.motY; + this.l = this.tracker.motZ; + if (this.u && !(packet instanceof PacketPlayOutSpawnEntityLiving)) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityVelocity(this.tracker.getId(), this.tracker.motX, this.tracker.motY, this.tracker.motZ)); + } + + if (this.tracker.vehicle != null) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle)); + } + + if (this.tracker instanceof EntityInsentient && ((EntityInsentient) this.tracker).getLeashHolder() != null) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutAttachEntity(1, this.tracker, ((EntityInsentient) this.tracker).getLeashHolder())); + } + + if (this.tracker instanceof EntityLiving) { + for (int i = 0; i < 5; ++i) { + ItemStack itemstack = ((EntityLiving) this.tracker).getEquipment(i); + + if (itemstack != null) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEquipment(this.tracker.getId(), i, itemstack)); + } + } + } + + if (this.tracker instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) this.tracker; + + if (entityhuman.isSleeping()) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutBed(entityhuman, new BlockPosition(this.tracker))); + } + } + + // CraftBukkit start - Fix for nonsensical head yaw + this.i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); + this.broadcast(new PacketPlayOutEntityHeadRotation(this.tracker, (byte) i)); + // CraftBukkit end + + if (this.tracker instanceof EntityLiving) { + EntityLiving entityliving = (EntityLiving) this.tracker; + Iterator iterator = entityliving.getEffects().iterator(); + + while (iterator.hasNext()) { + MobEffect mobeffect = (MobEffect) iterator.next(); + + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.tracker.getId(), mobeffect)); + } + } + } + } else if (this.trackedPlayers.contains(entityplayer)) { + this.trackedPlayers.remove(entityplayer); + entityplayer.d(this.tracker); + } + + } + } + + public boolean c(EntityPlayer entityplayer) { + // CraftBukkit start - this.*Loc / 30 -> this.tracker.loc* + double d0 = entityplayer.locX - this.tracker.locX; + double d1 = entityplayer.locZ - this.tracker.locZ; + // CraftBukkit end + + return d0 >= (double) (-this.b) && d0 <= (double) this.b && d1 >= (double) (-this.b) && d1 <= (double) this.b && this.tracker.a(entityplayer); + } + + private boolean e(EntityPlayer entityplayer) { + return entityplayer.u().getPlayerChunkMap().a(entityplayer, this.tracker.ae, this.tracker.ag); + } + + public void scanPlayers(List list) { + for (int i = 0; i < list.size(); ++i) { + this.updatePlayer((EntityPlayer) list.get(i)); + } + + } + + private Packet c() { + if (this.tracker.dead) { + // CraftBukkit start - Remove useless error spam, just return + // EntityTrackerEntry.p.warn("Fetching addPacket for removed entity"); + return null; + // CraftBukkit end + } + + if (this.tracker instanceof EntityItem) { + return new PacketPlayOutSpawnEntity(this.tracker, 2, 1); + } else if (this.tracker instanceof EntityPlayer) { + return new PacketPlayOutNamedEntitySpawn((EntityHuman) this.tracker); + } else if (this.tracker instanceof EntityMinecartAbstract) { + EntityMinecartAbstract entityminecartabstract = (EntityMinecartAbstract) this.tracker; + + return new PacketPlayOutSpawnEntity(this.tracker, 10, entityminecartabstract.s().a()); + } else if (this.tracker instanceof EntityBoat) { + return new PacketPlayOutSpawnEntity(this.tracker, 1); + } else if (this.tracker instanceof IAnimal) { + this.i = MathHelper.d(this.tracker.getHeadRotation() * 256.0F / 360.0F); + return new PacketPlayOutSpawnEntityLiving((EntityLiving) this.tracker); + } else if (this.tracker instanceof EntityFishingHook) { + EntityHuman entityhuman = ((EntityFishingHook) this.tracker).owner; + + return new PacketPlayOutSpawnEntity(this.tracker, 90, entityhuman != null ? entityhuman.getId() : this.tracker.getId()); + } else if (this.tracker instanceof EntityArrow) { + Entity entity = ((EntityArrow) this.tracker).shooter; + + return new PacketPlayOutSpawnEntity(this.tracker, 60, entity != null ? entity.getId() : this.tracker.getId()); + } else if (this.tracker instanceof EntitySnowball) { + return new PacketPlayOutSpawnEntity(this.tracker, 61); + } else if (this.tracker instanceof EntityPotion) { + return new PacketPlayOutSpawnEntity(this.tracker, 73, ((EntityPotion) this.tracker).getPotionValue()); + } else if (this.tracker instanceof EntityThrownExpBottle) { + return new PacketPlayOutSpawnEntity(this.tracker, 75); + } else if (this.tracker instanceof EntityEnderPearl) { + return new PacketPlayOutSpawnEntity(this.tracker, 65); + } else if (this.tracker instanceof EntityEnderSignal) { + return new PacketPlayOutSpawnEntity(this.tracker, 72); + } else if (this.tracker instanceof EntityFireworks) { + return new PacketPlayOutSpawnEntity(this.tracker, 76); + } else { + PacketPlayOutSpawnEntity packetplayoutspawnentity; + + if (this.tracker instanceof EntityFireball) { + EntityFireball entityfireball = (EntityFireball) this.tracker; + + packetplayoutspawnentity = null; + byte b0 = 63; + + if (this.tracker instanceof EntitySmallFireball) { + b0 = 64; + } else if (this.tracker instanceof EntityWitherSkull) { + b0 = 66; + } + + if (entityfireball.shooter != null) { + packetplayoutspawnentity = new PacketPlayOutSpawnEntity(this.tracker, b0, ((EntityFireball) this.tracker).shooter.getId()); + } else { + packetplayoutspawnentity = new PacketPlayOutSpawnEntity(this.tracker, b0, 0); + } + + packetplayoutspawnentity.d((int) (entityfireball.dirX * 8000.0D)); + packetplayoutspawnentity.e((int) (entityfireball.dirY * 8000.0D)); + packetplayoutspawnentity.f((int) (entityfireball.dirZ * 8000.0D)); + return packetplayoutspawnentity; + } else if (this.tracker instanceof EntityEgg) { + return new PacketPlayOutSpawnEntity(this.tracker, 62); + } else if (this.tracker instanceof EntityTNTPrimed) { + return new PacketPlayOutSpawnEntity(this.tracker, 50); + } else if (this.tracker instanceof EntityEnderCrystal) { + return new PacketPlayOutSpawnEntity(this.tracker, 51); + } else if (this.tracker instanceof EntityFallingBlock) { + EntityFallingBlock entityfallingblock = (EntityFallingBlock) this.tracker; + + return new PacketPlayOutSpawnEntity(this.tracker, 70, Block.getCombinedId(entityfallingblock.getBlock())); + } else if (this.tracker instanceof EntityArmorStand) { + return new PacketPlayOutSpawnEntity(this.tracker, 78); + } else if (this.tracker instanceof EntityPainting) { + return new PacketPlayOutSpawnEntityPainting((EntityPainting) this.tracker); + } else { + BlockPosition blockposition; + + if (this.tracker instanceof EntityItemFrame) { + EntityItemFrame entityitemframe = (EntityItemFrame) this.tracker; + + packetplayoutspawnentity = new PacketPlayOutSpawnEntity(this.tracker, 71, entityitemframe.direction.b()); + blockposition = entityitemframe.getBlockPosition(); + packetplayoutspawnentity.a(MathHelper.d((float) (blockposition.getX() * 32))); + packetplayoutspawnentity.b(MathHelper.d((float) (blockposition.getY() * 32))); + packetplayoutspawnentity.c(MathHelper.d((float) (blockposition.getZ() * 32))); + return packetplayoutspawnentity; + } else if (this.tracker instanceof EntityLeash) { + EntityLeash entityleash = (EntityLeash) this.tracker; + + packetplayoutspawnentity = new PacketPlayOutSpawnEntity(this.tracker, 77); + blockposition = entityleash.getBlockPosition(); + packetplayoutspawnentity.a(MathHelper.d((float) (blockposition.getX() * 32))); + packetplayoutspawnentity.b(MathHelper.d((float) (blockposition.getY() * 32))); + packetplayoutspawnentity.c(MathHelper.d((float) (blockposition.getZ() * 32))); + return packetplayoutspawnentity; + } else if (this.tracker instanceof EntityExperienceOrb) { + return new PacketPlayOutSpawnEntityExperienceOrb((EntityExperienceOrb) this.tracker); + } else { + throw new IllegalArgumentException("Don't know how to add " + this.tracker.getClass() + "!"); + } + } + } + } + + public void clear(EntityPlayer entityplayer) { + org.spigotmc.AsyncCatcher.catchOp( "player tracker clear"); // Spigot + if (this.trackedPlayers.contains(entityplayer)) { + this.trackedPlayers.remove(entityplayer); + entityplayer.d(this.tracker); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityVillager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityVillager.java new file mode 100644 index 0000000..01fe700 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityVillager.java @@ -0,0 +1,763 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.Random; + +import net.jafama.FastMath; +import org.bukkit.craftbukkit.entity.CraftVillager; // CraftBukkit + +public class EntityVillager extends EntityAgeable implements IMerchant, NPC { + + private int profession; + private boolean bo; + private boolean bp; + Village village; + private EntityHuman tradingPlayer; + private MerchantRecipeList br; + private int bs; + private boolean bt; + private boolean bu; + private int riches; + private String bw; + private int bx; + private int by; + private boolean bz; + private boolean bA; + public InventorySubcontainer inventory; + private static final EntityVillager.IMerchantRecipeOption[][][][] bC = new EntityVillager.IMerchantRecipeOption[][][][] { { { { new EntityVillager.MerchantRecipeOptionBuy(Items.WHEAT, new EntityVillager.MerchantOptionRandomRange(18, 22)), new EntityVillager.MerchantRecipeOptionBuy(Items.POTATO, new EntityVillager.MerchantOptionRandomRange(15, 19)), new EntityVillager.MerchantRecipeOptionBuy(Items.CARROT, new EntityVillager.MerchantOptionRandomRange(15, 19)), new EntityVillager.MerchantRecipeOptionSell(Items.BREAD, new EntityVillager.MerchantOptionRandomRange(-4, -2))}, { new EntityVillager.MerchantRecipeOptionBuy(Item.getItemOf(Blocks.PUMPKIN), new EntityVillager.MerchantOptionRandomRange(8, 13)), new EntityVillager.MerchantRecipeOptionSell(Items.PUMPKIN_PIE, new EntityVillager.MerchantOptionRandomRange(-3, -2))}, { new EntityVillager.MerchantRecipeOptionBuy(Item.getItemOf(Blocks.MELON_BLOCK), new EntityVillager.MerchantOptionRandomRange(7, 12)), new EntityVillager.MerchantRecipeOptionSell(Items.APPLE, new EntityVillager.MerchantOptionRandomRange(-5, -7))}, { new EntityVillager.MerchantRecipeOptionSell(Items.COOKIE, new EntityVillager.MerchantOptionRandomRange(-6, -10)), new EntityVillager.MerchantRecipeOptionSell(Items.CAKE, new EntityVillager.MerchantOptionRandomRange(1, 1))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.STRING, new EntityVillager.MerchantOptionRandomRange(15, 20)), new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionProcess(Items.FISH, new EntityVillager.MerchantOptionRandomRange(6, 6), Items.COOKED_FISH, new EntityVillager.MerchantOptionRandomRange(6, 6))}, { new EntityVillager.MerchantRecipeOptionEnchant(Items.FISHING_ROD, new EntityVillager.MerchantOptionRandomRange(7, 8))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Item.getItemOf(Blocks.WOOL), new EntityVillager.MerchantOptionRandomRange(16, 22)), new EntityVillager.MerchantRecipeOptionSell(Items.SHEARS, new EntityVillager.MerchantOptionRandomRange(3, 4))}, { new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 0), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 1), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 2), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 3), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 4), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 5), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 6), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 7), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 8), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 9), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 10), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 11), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 12), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 13), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 14), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 15), new EntityVillager.MerchantOptionRandomRange(1, 2))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.STRING, new EntityVillager.MerchantOptionRandomRange(15, 20)), new EntityVillager.MerchantRecipeOptionSell(Items.ARROW, new EntityVillager.MerchantOptionRandomRange(-12, -8))}, { new EntityVillager.MerchantRecipeOptionSell(Items.BOW, new EntityVillager.MerchantOptionRandomRange(2, 3)), new EntityVillager.MerchantRecipeOptionProcess(Item.getItemOf(Blocks.GRAVEL), new EntityVillager.MerchantOptionRandomRange(10, 10), Items.FLINT, new EntityVillager.MerchantOptionRandomRange(6, 10))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.PAPER, new EntityVillager.MerchantOptionRandomRange(24, 36)), new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionBuy(Items.BOOK, new EntityVillager.MerchantOptionRandomRange(8, 10)), new EntityVillager.MerchantRecipeOptionSell(Items.COMPASS, new EntityVillager.MerchantOptionRandomRange(10, 12)), new EntityVillager.MerchantRecipeOptionSell(Item.getItemOf(Blocks.BOOKSHELF), new EntityVillager.MerchantOptionRandomRange(3, 4))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.WRITTEN_BOOK, new EntityVillager.MerchantOptionRandomRange(2, 2)), new EntityVillager.MerchantRecipeOptionSell(Items.CLOCK, new EntityVillager.MerchantOptionRandomRange(10, 12)), new EntityVillager.MerchantRecipeOptionSell(Item.getItemOf(Blocks.GLASS), new EntityVillager.MerchantOptionRandomRange(-5, -3))}, { new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionSell(Items.NAME_TAG, new EntityVillager.MerchantOptionRandomRange(20, 22))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.ROTTEN_FLESH, new EntityVillager.MerchantOptionRandomRange(36, 40)), new EntityVillager.MerchantRecipeOptionBuy(Items.GOLD_INGOT, new EntityVillager.MerchantOptionRandomRange(8, 10))}, { new EntityVillager.MerchantRecipeOptionSell(Items.REDSTONE, new EntityVillager.MerchantOptionRandomRange(-4, -1)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Items.DYE, 1, EnumColor.BLUE.getInvColorIndex()), new EntityVillager.MerchantOptionRandomRange(-2, -1))}, { new EntityVillager.MerchantRecipeOptionSell(Items.ENDER_EYE, new EntityVillager.MerchantOptionRandomRange(7, 11)), new EntityVillager.MerchantRecipeOptionSell(Item.getItemOf(Blocks.GLOWSTONE), new EntityVillager.MerchantOptionRandomRange(-3, -1))}, { new EntityVillager.MerchantRecipeOptionSell(Items.EXPERIENCE_BOTTLE, new EntityVillager.MerchantOptionRandomRange(3, 11))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_HELMET, new EntityVillager.MerchantOptionRandomRange(4, 6))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(10, 14))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(16, 19))}, { new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_BOOTS, new EntityVillager.MerchantOptionRandomRange(5, 7)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_LEGGINGS, new EntityVillager.MerchantOptionRandomRange(9, 11)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_HELMET, new EntityVillager.MerchantOptionRandomRange(5, 7)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(11, 15))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_AXE, new EntityVillager.MerchantOptionRandomRange(6, 8))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_SWORD, new EntityVillager.MerchantOptionRandomRange(9, 10))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_SWORD, new EntityVillager.MerchantOptionRandomRange(12, 15)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_AXE, new EntityVillager.MerchantOptionRandomRange(9, 12))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_SHOVEL, new EntityVillager.MerchantOptionRandomRange(5, 7))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_PICKAXE, new EntityVillager.MerchantOptionRandomRange(9, 11))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_PICKAXE, new EntityVillager.MerchantOptionRandomRange(12, 15))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.PORKCHOP, new EntityVillager.MerchantOptionRandomRange(14, 18)), new EntityVillager.MerchantRecipeOptionBuy(Items.CHICKEN, new EntityVillager.MerchantOptionRandomRange(14, 18))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.COOKED_PORKCHOP, new EntityVillager.MerchantOptionRandomRange(-7, -5)), new EntityVillager.MerchantRecipeOptionSell(Items.COOKED_CHICKEN, new EntityVillager.MerchantOptionRandomRange(-8, -6))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.LEATHER, new EntityVillager.MerchantOptionRandomRange(9, 12)), new EntityVillager.MerchantRecipeOptionSell(Items.LEATHER_LEGGINGS, new EntityVillager.MerchantOptionRandomRange(2, 4))}, { new EntityVillager.MerchantRecipeOptionEnchant(Items.LEATHER_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(7, 12))}, { new EntityVillager.MerchantRecipeOptionSell(Items.SADDLE, new EntityVillager.MerchantOptionRandomRange(8, 10))}}}}; + + public EntityVillager(World world) { + this(world, 0); + } + + public EntityVillager(World world, int i) { + super(world); + this.inventory = new InventorySubcontainer("Items", false, 8, (CraftVillager) this.getBukkitEntity()); // CraftBukkit add argument + this.setProfession(i); + this.setSize(0.6F, 1.8F); + ((Navigation) this.getNavigation()).b(true); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalAvoidTarget(this, EntityZombie.class, 8.0F, 0.6D, 0.6D)); + this.goalSelector.a(1, new PathfinderGoalTradeWithPlayer(this)); + this.goalSelector.a(1, new PathfinderGoalLookAtTradingPlayer(this)); + this.goalSelector.a(2, new PathfinderGoalMoveIndoors(this)); + this.goalSelector.a(3, new PathfinderGoalRestrictOpenDoor(this)); + this.goalSelector.a(4, new PathfinderGoalOpenDoor(this, true)); + this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 0.6D)); + this.goalSelector.a(6, new PathfinderGoalMakeLove(this)); + this.goalSelector.a(7, new PathfinderGoalTakeFlower(this)); + this.goalSelector.a(9, new PathfinderGoalInteract(this, EntityHuman.class, 3.0F, 1.0F)); + this.goalSelector.a(9, new PathfinderGoalInteractVillagers(this)); + this.goalSelector.a(9, new PathfinderGoalRandomStroll(this, 0.6D)); + this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + this.j(true); + } + + private void cv() { + if (!this.bA) { + this.bA = true; + if (this.isBaby()) { + this.goalSelector.a(8, new PathfinderGoalPlay(this, 0.32D)); + } else if (this.getProfession() == 0) { + this.goalSelector.a(6, new PathfinderGoalVillagerFarm(this, 0.6D)); + } + + } + } + + protected void n() { + if (this.getProfession() == 0) { + this.goalSelector.a(8, new PathfinderGoalVillagerFarm(this, 0.6D)); + } + + super.n(); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.5D); + } + + protected void E() { + if (--this.profession <= 0) { + BlockPosition blockposition = new BlockPosition(this); + + this.world.ae().a(blockposition); + this.profession = 70 + this.random.nextInt(50); + this.village = this.world.ae().getClosestVillage(blockposition, 32); + if (this.village == null) { + this.cj(); + } else { + BlockPosition blockposition1 = this.village.a(); + + this.a(blockposition1, (int) ((float) this.village.b() * 1.0F)); + if (this.bz) { + this.bz = false; + this.village.b(5); + } + } + } + + if (!this.co() && this.bs > 0) { + --this.bs; + if (this.bs <= 0) { + if (this.bt) { + Iterator iterator = this.br.iterator(); + + while (iterator.hasNext()) { + MerchantRecipe merchantrecipe = (MerchantRecipe) iterator.next(); + + if (merchantrecipe.h()) { + merchantrecipe.a(this.random.nextInt(6) + this.random.nextInt(6) + 2); + } + } + + this.cw(); + this.bt = false; + if (this.village != null && this.bw != null) { + this.world.broadcastEntityEffect(this, (byte) 14); + this.village.a(this.bw, 1); + } + } + + this.addEffect(new MobEffect(MobEffectList.REGENERATION.id, 200, 0)); + } + } + + super.E(); + } + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + boolean flag = itemstack != null && itemstack.getItem() == Items.SPAWN_EGG; + + if (!flag && this.isAlive() && !this.co() && !this.isBaby()) { + if (!this.world.isClientSide && (this.br == null || this.br.size() > 0)) { + this.a_(entityhuman); + entityhuman.openTrade(this); + } + + entityhuman.b(StatisticList.F); + return true; + } else { + return super.a(entityhuman); + } + } + + protected void h() { + super.h(); + this.datawatcher.a(16, Integer.valueOf(0)); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("Profession", this.getProfession()); + nbttagcompound.setInt("Riches", this.riches); + nbttagcompound.setInt("Career", this.bx); + nbttagcompound.setInt("CareerLevel", this.by); + nbttagcompound.setBoolean("Willing", this.bu); + if (this.br != null) { + nbttagcompound.set("Offers", this.br.a()); + } + + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.inventory.getSize(); ++i) { + ItemStack itemstack = this.inventory.getItem(i); + + if (itemstack != null) { + nbttaglist.add(itemstack.save(new NBTTagCompound())); + } + } + + nbttagcompound.set("Inventory", nbttaglist); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setProfession(nbttagcompound.getInt("Profession")); + this.riches = nbttagcompound.getInt("Riches"); + this.bx = nbttagcompound.getInt("Career"); + this.by = nbttagcompound.getInt("CareerLevel"); + this.bu = nbttagcompound.getBoolean("Willing"); + if (nbttagcompound.hasKeyOfType("Offers", 10)) { + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Offers"); + + this.br = new MerchantRecipeList(nbttagcompound1); + } + + NBTTagList nbttaglist = nbttagcompound.getList("Inventory", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + ItemStack itemstack = ItemStack.createStack(nbttaglist.get(i)); + + if (itemstack != null) { + this.inventory.a(itemstack); + } + } + + this.j(true); + this.cv(); + } + + protected boolean isTypeNotPersistent() { + return false; + } + + protected String z() { + return this.co() ? "mob.villager.haggle" : "mob.villager.idle"; + } + + protected String bo() { + return "mob.villager.hit"; + } + + protected String bp() { + return "mob.villager.death"; + } + + public void setProfession(int i) { + this.datawatcher.watch(16, Integer.valueOf(i)); + } + + public int getProfession() { + return FastMath.max(this.datawatcher.getInt(16) % 5, 0); + } + + public boolean cm() { + return this.bo; + } + + public void l(boolean flag) { + this.bo = flag; + } + + public void m(boolean flag) { + this.bp = flag; + } + + public boolean cn() { + return this.bp; + } + + public void b(EntityLiving entityliving) { + super.b(entityliving); + if (this.village != null && entityliving != null) { + this.village.a(entityliving); + if (entityliving instanceof EntityHuman) { + byte b0 = -1; + + if (this.isBaby()) { + b0 = -3; + } + + this.village.a(entityliving.getName(), b0); + if (this.isAlive()) { + this.world.broadcastEntityEffect(this, (byte) 13); + } + } + } + + } + + public void die(DamageSource damagesource) { + if (this.village != null) { + Entity entity = damagesource.getEntity(); + + if (entity != null) { + if (entity instanceof EntityHuman) { + this.village.a(entity.getName(), -2); + } else if (entity instanceof IMonster) { + this.village.h(); + } + } else { + EntityHuman entityhuman = this.world.findNearbyPlayer(this, 16.0D); + + if (entityhuman != null) { + this.village.h(); + } + } + } + + super.die(damagesource); + } + + public void a_(EntityHuman entityhuman) { + this.tradingPlayer = entityhuman; + } + + public EntityHuman v_() { + return this.tradingPlayer; + } + + public boolean co() { + return this.tradingPlayer != null; + } + + public boolean n(boolean flag) { + if (!this.bu && flag && this.cr()) { + boolean flag1 = false; + + for (int i = 0; i < this.inventory.getSize(); ++i) { + ItemStack itemstack = this.inventory.getItem(i); + + if (itemstack != null) { + if (itemstack.getItem() == Items.BREAD && itemstack.count >= 3) { + flag1 = true; + this.inventory.splitStack(i, 3); + } else if ((itemstack.getItem() == Items.POTATO || itemstack.getItem() == Items.CARROT) && itemstack.count >= 12) { + flag1 = true; + this.inventory.splitStack(i, 12); + } + } + + if (flag1) { + this.world.broadcastEntityEffect(this, (byte) 18); + this.bu = true; + break; + } + } + } + + return this.bu; + } + + public void o(boolean flag) { + this.bu = flag; + } + + public void a(MerchantRecipe merchantrecipe) { + merchantrecipe.g(); + this.a_ = -this.w(); + this.makeSound("mob.villager.yes", this.bB(), this.bC()); + int i = 3 + this.random.nextInt(4); + + if (merchantrecipe.e() == 1 || this.random.nextInt(5) == 0) { + this.bs = 40; + this.bt = true; + this.bu = true; + if (this.tradingPlayer != null) { + this.bw = this.tradingPlayer.getName(); + } else { + this.bw = null; + } + + i += 5; + } + + if (merchantrecipe.getBuyItem1().getItem() == Items.EMERALD) { + this.riches += merchantrecipe.getBuyItem1().count; + } + + if (merchantrecipe.j()) { + this.world.addEntity(new EntityExperienceOrb(this.world, this.locX, this.locY + 0.5D, this.locZ, i)); + } + + } + + public void a_(ItemStack itemstack) { + if (!this.world.isClientSide && this.a_ > -this.w() + 20) { + this.a_ = -this.w(); + if (itemstack != null) { + this.makeSound("mob.villager.yes", this.bB(), this.bC()); + } else { + this.makeSound("mob.villager.no", this.bB(), this.bC()); + } + } + + } + + public MerchantRecipeList getOffers(EntityHuman entityhuman) { + if (this.br == null) { + this.cw(); + } + + return this.br; + } + + private void cw() { + EntityVillager.IMerchantRecipeOption[][][] aentityvillager_imerchantrecipeoption = EntityVillager.bC[this.getProfession()]; + + if (this.bx != 0 && this.by != 0) { + ++this.by; + } else { + this.bx = this.random.nextInt(aentityvillager_imerchantrecipeoption.length) + 1; + this.by = 1; + } + + if (this.br == null) { + this.br = new MerchantRecipeList(); + } + + int i = this.bx - 1; + int j = this.by - 1; + EntityVillager.IMerchantRecipeOption[][] aentityvillager_imerchantrecipeoption1 = aentityvillager_imerchantrecipeoption[i]; + + if (j >= 0 && j < aentityvillager_imerchantrecipeoption1.length) { + EntityVillager.IMerchantRecipeOption[] aentityvillager_imerchantrecipeoption2 = aentityvillager_imerchantrecipeoption1[j]; + EntityVillager.IMerchantRecipeOption[] aentityvillager_imerchantrecipeoption3 = aentityvillager_imerchantrecipeoption2; + int k = aentityvillager_imerchantrecipeoption2.length; + + for (int l = 0; l < k; ++l) { + EntityVillager.IMerchantRecipeOption entityvillager_imerchantrecipeoption = aentityvillager_imerchantrecipeoption3[l]; + + entityvillager_imerchantrecipeoption.a(this.br, this.random); + } + } + + } + + public IChatBaseComponent getScoreboardDisplayName() { + String s = this.getCustomName(); + + if (s != null && s.length() > 0) { + ChatComponentText chatcomponenttext = new ChatComponentText(s); + + chatcomponenttext.getChatModifier().setChatHoverable(this.aQ()); + chatcomponenttext.getChatModifier().setInsertion(this.getUniqueID().toString()); + return chatcomponenttext; + } else { + if (this.br == null) { + this.cw(); + } + + String s1 = null; + + switch (this.getProfession()) { + case 0: + if (this.bx == 1) { + s1 = "farmer"; + } else if (this.bx == 2) { + s1 = "fisherman"; + } else if (this.bx == 3) { + s1 = "shepherd"; + } else if (this.bx == 4) { + s1 = "fletcher"; + } + break; + + case 1: + s1 = "librarian"; + break; + + case 2: + s1 = "cleric"; + break; + + case 3: + if (this.bx == 1) { + s1 = "armor"; + } else if (this.bx == 2) { + s1 = "weapon"; + } else if (this.bx == 3) { + s1 = "tool"; + } + break; + + case 4: + if (this.bx == 1) { + s1 = "butcher"; + } else if (this.bx == 2) { + s1 = "leather"; + } + } + + if (s1 != null) { + ChatMessage chatmessage = new ChatMessage("entity.Villager." + s1, new Object[0]); + + chatmessage.getChatModifier().setChatHoverable(this.aQ()); + chatmessage.getChatModifier().setInsertion(this.getUniqueID().toString()); + return chatmessage; + } else { + return super.getScoreboardDisplayName(); + } + } + } + + public float getHeadHeight() { + float f = 1.62F; + + if (this.isBaby()) { + f = (float) ((double) f - 0.81D); + } + + return f; + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + groupdataentity = super.prepare(difficultydamagescaler, groupdataentity); + this.setProfession(this.world.random.nextInt(5)); + this.cv(); + return groupdataentity; + } + + public void cp() { + this.bz = true; + } + + public EntityVillager b(EntityAgeable entityageable) { + EntityVillager entityvillager = new EntityVillager(this.world); + + entityvillager.prepare(this.world.E(new BlockPosition(entityvillager)), (GroupDataEntity) null); + return entityvillager; + } + + public boolean cb() { + return false; + } + + public void onLightningStrike(EntityLightning entitylightning) { + if (!this.world.isClientSide && !this.dead) { + EntityWitch entitywitch = new EntityWitch(this.world); + + entitywitch.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + entitywitch.prepare(this.world.E(new BlockPosition(entitywitch)), (GroupDataEntity) null); + entitywitch.k(this.ce()); + if (this.hasCustomName()) { + entitywitch.setCustomName(this.getCustomName()); + entitywitch.setCustomNameVisible(this.getCustomNameVisible()); + } + + this.world.addEntity(entitywitch); + this.die(); + } + } + + public InventorySubcontainer cq() { + return this.inventory; + } + + protected void a(EntityItem entityitem) { + ItemStack itemstack = entityitem.getItemStack(); + Item item = itemstack.getItem(); + + if (this.a(item)) { + ItemStack itemstack1 = this.inventory.a(itemstack); + + if (itemstack1 == null) { + entityitem.die(); + } else { + itemstack.count = itemstack1.count; + } + } + + } + + private boolean a(Item item) { + return item == Items.BREAD || item == Items.POTATO || item == Items.CARROT || item == Items.WHEAT || item == Items.WHEAT_SEEDS; + } + + public boolean cr() { + return this.s(1); + } + + public boolean cs() { + return this.s(2); + } + + public boolean ct() { + boolean flag = this.getProfession() == 0; + + return flag ? !this.s(5) : !this.s(1); + } + + private boolean s(int i) { + boolean flag = this.getProfession() == 0; + + for (int j = 0; j < this.inventory.getSize(); ++j) { + ItemStack itemstack = this.inventory.getItem(j); + + if (itemstack != null) { + if (itemstack.getItem() == Items.BREAD && itemstack.count >= 3 * i || itemstack.getItem() == Items.POTATO && itemstack.count >= 12 * i || itemstack.getItem() == Items.CARROT && itemstack.count >= 12 * i) { + return true; + } + + if (flag && itemstack.getItem() == Items.WHEAT && itemstack.count >= 9 * i) { + return true; + } + } + } + + return false; + } + + public boolean cu() { + for (int i = 0; i < this.inventory.getSize(); ++i) { + ItemStack itemstack = this.inventory.getItem(i); + + if (itemstack != null && (itemstack.getItem() == Items.WHEAT_SEEDS || itemstack.getItem() == Items.POTATO || itemstack.getItem() == Items.CARROT)) { + return true; + } + } + + return false; + } + + public boolean d(int i, ItemStack itemstack) { + if (super.d(i, itemstack)) { + return true; + } else { + int j = i - 300; + + if (j >= 0 && j < this.inventory.getSize()) { + this.inventory.setItem(j, itemstack); + return true; + } else { + return false; + } + } + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.b(entityageable); + } + + static class MerchantRecipeOptionProcess implements EntityVillager.IMerchantRecipeOption { + + public ItemStack a; + public EntityVillager.MerchantOptionRandomRange b; + public ItemStack c; + public EntityVillager.MerchantOptionRandomRange d; + + public MerchantRecipeOptionProcess(Item item, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange, Item item1, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange1) { + this.a = new ItemStack(item); + this.b = entityvillager_merchantoptionrandomrange; + this.c = new ItemStack(item1); + this.d = entityvillager_merchantoptionrandomrange1; + } + + public void a(MerchantRecipeList merchantrecipelist, Random random) { + int i = 1; + + if (this.b != null) { + i = this.b.a(random); + } + + int j = 1; + + if (this.d != null) { + j = this.d.a(random); + } + + merchantrecipelist.add(new MerchantRecipe(new ItemStack(this.a.getItem(), i, this.a.getData()), new ItemStack(Items.EMERALD), new ItemStack(this.c.getItem(), j, this.c.getData()))); + } + } + + static class MerchantRecipeOptionBook implements EntityVillager.IMerchantRecipeOption { + + public MerchantRecipeOptionBook() {} + + public void a(MerchantRecipeList merchantrecipelist, Random random) { + Enchantment enchantment = Enchantment.b[random.nextInt(Enchantment.b.length)]; + int i = MathHelper.nextInt(random, enchantment.getStartLevel(), enchantment.getMaxLevel()); + ItemStack itemstack = Items.ENCHANTED_BOOK.a(new WeightedRandomEnchant(enchantment, i)); + int j = 2 + random.nextInt(5 + i * 10) + 3 * i; + + if (j > 64) { + j = 64; + } + + merchantrecipelist.add(new MerchantRecipe(new ItemStack(Items.BOOK), new ItemStack(Items.EMERALD, j), itemstack)); + } + } + + static class MerchantRecipeOptionEnchant implements EntityVillager.IMerchantRecipeOption { + + public ItemStack a; + public EntityVillager.MerchantOptionRandomRange b; + + public MerchantRecipeOptionEnchant(Item item, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { + this.a = new ItemStack(item); + this.b = entityvillager_merchantoptionrandomrange; + } + + public void a(MerchantRecipeList merchantrecipelist, Random random) { + int i = 1; + + if (this.b != null) { + i = this.b.a(random); + } + + ItemStack itemstack = new ItemStack(Items.EMERALD, i, 0); + ItemStack itemstack1 = new ItemStack(this.a.getItem(), 1, this.a.getData()); + + itemstack1 = EnchantmentManager.a(random, itemstack1, 5 + random.nextInt(15)); + merchantrecipelist.add(new MerchantRecipe(itemstack, itemstack1)); + } + } + + static class MerchantRecipeOptionSell implements EntityVillager.IMerchantRecipeOption { + + public ItemStack a; + public EntityVillager.MerchantOptionRandomRange b; + + public MerchantRecipeOptionSell(Item item, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { + this.a = new ItemStack(item); + this.b = entityvillager_merchantoptionrandomrange; + } + + public MerchantRecipeOptionSell(ItemStack itemstack, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { + this.a = itemstack; + this.b = entityvillager_merchantoptionrandomrange; + } + + public void a(MerchantRecipeList merchantrecipelist, Random random) { + int i = 1; + + if (this.b != null) { + i = this.b.a(random); + } + + ItemStack itemstack; + ItemStack itemstack1; + + if (i < 0) { + itemstack = new ItemStack(Items.EMERALD, 1, 0); + itemstack1 = new ItemStack(this.a.getItem(), -i, this.a.getData()); + } else { + itemstack = new ItemStack(Items.EMERALD, i, 0); + itemstack1 = new ItemStack(this.a.getItem(), 1, this.a.getData()); + } + + merchantrecipelist.add(new MerchantRecipe(itemstack, itemstack1)); + } + } + + static class MerchantRecipeOptionBuy implements EntityVillager.IMerchantRecipeOption { + + public Item a; + public EntityVillager.MerchantOptionRandomRange b; + + public MerchantRecipeOptionBuy(Item item, EntityVillager.MerchantOptionRandomRange entityvillager_merchantoptionrandomrange) { + this.a = item; + this.b = entityvillager_merchantoptionrandomrange; + } + + public void a(MerchantRecipeList merchantrecipelist, Random random) { + int i = 1; + + if (this.b != null) { + i = this.b.a(random); + } + + merchantrecipelist.add(new MerchantRecipe(new ItemStack(this.a, i, 0), Items.EMERALD)); + } + } + + interface IMerchantRecipeOption { + + void a(MerchantRecipeList merchantrecipelist, Random random); + } + + static class MerchantOptionRandomRange extends Tuple { + + public MerchantOptionRandomRange(int i, int j) { + super(Integer.valueOf(i), Integer.valueOf(j)); + } + + public int a(Random random) { + return ((Integer) this.a()).intValue() >= ((Integer) this.b()).intValue() ? ((Integer) this.a()).intValue() : ((Integer) this.a()).intValue() + random.nextInt(((Integer) this.b()).intValue() - ((Integer) this.a()).intValue() + 1); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWither.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWither.java new file mode 100644 index 0000000..fb19bad --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWither.java @@ -0,0 +1,503 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import java.util.Iterator; +import java.util.List; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; +// CraftBukkit end + +public class EntityWither extends EntityMonster implements IRangedEntity { + + private float[] a = new float[2]; + private float[] b = new float[2]; + private float[] c = new float[2]; + private float[] bm = new float[2]; + private int[] bn = new int[2]; + private int[] bo = new int[2]; + private int bp; + private static final Predicate bq = new Predicate() { + public boolean a(Entity entity) { + return entity instanceof EntityLiving && ((EntityLiving) entity).getMonsterType() != EnumMonsterType.UNDEAD; + } + + public boolean apply(Object object) { + return this.a((Entity) object); + } + }; + + public EntityWither(World world) { + super(world); + this.setHealth(this.getMaxHealth()); + this.setSize(0.9F, 3.5F); + this.fireProof = true; + ((Navigation) this.getNavigation()).d(true); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 40, 20.0F)); + this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); + this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityInsentient.class, 0, false, false, EntityWither.bq)); + this.b_ = 50; + } + + protected void h() { + super.h(); + this.datawatcher.a(17, new Integer(0)); + this.datawatcher.a(18, new Integer(0)); + this.datawatcher.a(19, new Integer(0)); + this.datawatcher.a(20, new Integer(0)); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("Invul", this.cl()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.r(nbttagcompound.getInt("Invul")); + } + + protected String z() { + return "mob.wither.idle"; + } + + protected String bo() { + return "mob.wither.hurt"; + } + + protected String bp() { + return "mob.wither.death"; + } + + public void m() { + this.motY *= 0.6000000238418579D; + double d0; + double d1; + double d2; + + if (!this.world.isClientSide && this.s(0) > 0) { + Entity entity = this.world.a(this.s(0)); + + if (entity != null) { + if (this.locY < entity.locY || !this.cm() && this.locY < entity.locY + 5.0D) { + if (this.motY < 0.0D) { + this.motY = 0.0D; + } + + this.motY += (0.5D - this.motY) * 0.6000000238418579D; + } + + double d3 = entity.locX - this.locX; + + d0 = entity.locZ - this.locZ; + d1 = d3 * d3 + d0 * d0; + if (d1 > 9.0D) { + d2 = (double) MathHelper.sqrt(d1); + this.motX += (d3 / d2 * 0.5D - this.motX) * 0.6000000238418579D; + this.motZ += (d0 / d2 * 0.5D - this.motZ) * 0.6000000238418579D; + } + } + } + + if (this.motX * this.motX + this.motZ * this.motZ > 0.05000000074505806D) { + this.yaw = (float) MathHelper.b(this.motZ, this.motX) * 57.295776F - 90.0F; + } + + super.m(); + + int i; + + for (i = 0; i < 2; ++i) { + this.bm[i] = this.b[i]; + this.c[i] = this.a[i]; + } + + int j; + + for (i = 0; i < 2; ++i) { + j = this.s(i + 1); + Entity entity1 = null; + + if (j > 0) { + entity1 = this.world.a(j); + } + + if (entity1 != null) { + d0 = this.t(i + 1); + d1 = this.u(i + 1); + d2 = this.v(i + 1); + double d4 = entity1.locX - d0; + double d5 = entity1.locY + (double) entity1.getHeadHeight() - d1; + double d6 = entity1.locZ - d2; + double d7 = (double) MathHelper.sqrt(d4 * d4 + d6 * d6); + float f = (float) (MathHelper.b(d6, d4) * 180.0D / 3.1415927410125732D) - 90.0F; + float f1 = (float) (-(MathHelper.b(d5, d7) * 180.0D / 3.1415927410125732D)); + + this.a[i] = this.b(this.a[i], f1, 40.0F); + this.b[i] = this.b(this.b[i], f, 10.0F); + } else { + this.b[i] = this.b(this.b[i], this.aI, 10.0F); + } + } + + boolean flag = this.cm(); + + for (j = 0; j < 3; ++j) { + double d8 = this.t(j); + 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]); + 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]); + } + } + + 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]); + } + } + + } + + protected void E() { + int i; + + if (this.cl() > 0) { + i = this.cl() - 1; + if (i <= 0) { + // CraftBukkit start + // this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, 7.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); + ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + this.world.createExplosion(this, this.locX, this.locY + (double) this.getHeadHeight(), this.locZ, event.getRadius(), event.getFire(), this.world.getGameRules().getBoolean("mobGriefing")); + } + // CraftBukkit end + + // CraftBukkit start - Use relative location for far away sounds + // this.world.a(1013, new BlockPosition(this), 0); + int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; + for (EntityPlayer player : (List) MinecraftServer.getServer().getPlayerList().players) { + double deltaX = this.locX - player.locX; + double deltaZ = this.locZ - player.locZ; + double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; + if ( world.spigotConfig.witherSpawnSoundRadius > 0 && distanceSquared > world.spigotConfig.witherSpawnSoundRadius * world.spigotConfig.witherSpawnSoundRadius ) continue; // Spigot + if (distanceSquared > viewDistance * viewDistance) { + double deltaLength = Math.sqrt(distanceSquared); + double relativeX = player.locX + (deltaX / deltaLength) * viewDistance; + double relativeZ = player.locZ + (deltaZ / deltaLength) * viewDistance; + player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1013, new BlockPosition((int) relativeX, (int) this.locY, (int) relativeZ), 0, true)); + } else { + player.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1013, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0, true)); + } + } + // CraftBukkit end + } + + this.r(i); + if (this.ticksLived % 10 == 0) { + this.heal(10.0F, EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit + } + + } else { + super.E(); + + int j; + + for (i = 1; i < 3; ++i) { + if (this.ticksLived >= this.bn[i - 1]) { + this.bn[i - 1] = this.ticksLived + 10 + this.random.nextInt(10); + if (this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) { + int k = i - 1; + int l = this.bo[i - 1]; + + this.bo[k] = this.bo[i - 1] + 1; + if (l > 15) { + float f = 10.0F; + float f1 = 5.0F; + double d0 = MathHelper.a(this.random, this.locX - (double) f, this.locX + (double) f); + double d1 = MathHelper.a(this.random, this.locY - (double) f1, this.locY + (double) f1); + double d2 = MathHelper.a(this.random, this.locZ - (double) f, this.locZ + (double) f); + + this.a(i + 1, d0, d1, d2, true); + this.bo[i - 1] = 0; + } + } + + j = this.s(i); + if (j > 0) { + Entity entity = this.world.a(j); + + if (entity != null && entity.isAlive() && this.h(entity) <= 900.0D && this.hasLineOfSight(entity)) { + if (entity instanceof EntityHuman && ((EntityHuman) entity).abilities.isInvulnerable) { + this.b(i, 0); + } else { + this.a(i + 1, (EntityLiving) entity); + this.bn[i - 1] = this.ticksLived + 40 + this.random.nextInt(20); + this.bo[i - 1] = 0; + } + } else { + this.b(i, 0); + } + } else { + List list = this.world.a(EntityLiving.class, this.getBoundingBox().grow(20.0D, 8.0D, 20.0D), Predicates.and(EntityWither.bq, IEntitySelector.d)); + + for (int i1 = 0; i1 < 10 && !list.isEmpty(); ++i1) { + EntityLiving entityliving = (EntityLiving) list.get(this.random.nextInt(list.size())); + + if (entityliving != this && entityliving.isAlive() && this.hasLineOfSight(entityliving)) { + if (entityliving instanceof EntityHuman) { + if (!((EntityHuman) entityliving).abilities.isInvulnerable) { + this.b(i, entityliving.getId()); + } + } else { + this.b(i, entityliving.getId()); + } + break; + } + + list.remove(entityliving); + } + } + } + } + + if (this.getGoalTarget() != null) { + this.b(0, this.getGoalTarget().getId()); + } else { + this.b(0, 0); + } + + if (this.bp > 0) { + --this.bp; + if (this.bp == 0 && this.world.getGameRules().getBoolean("mobGriefing")) { + i = MathHelper.floor(this.locY); + j = MathHelper.floor(this.locX); + int j1 = MathHelper.floor(this.locZ); + boolean flag = false; + + for (int k1 = -1; k1 <= 1; ++k1) { + for (int l1 = -1; l1 <= 1; ++l1) { + for (int i2 = 0; i2 <= 3; ++i2) { + int j2 = j + k1; + int k2 = i + i2; + int l2 = j1 + l1; + BlockPosition blockposition = new BlockPosition(j2, k2, l2); + Block block = this.world.getType(blockposition).getBlock(); + + if (block.getMaterial() != Material.AIR && a(block)) { + // CraftBukkit start + if (CraftEventFactory.callEntityChangeBlockEvent(this, j2, k2, l2, Blocks.AIR, 0).isCancelled()) { + continue; + } + // CraftBukkit end + flag = this.world.setAir(blockposition, true) || flag; + } + } + } + } + + if (flag) { + this.world.a((EntityHuman) null, 1012, new BlockPosition(this), 0); + } + } + } + + if (this.ticksLived % 20 == 0) { + this.heal(1.0F, EntityRegainHealthEvent.RegainReason.REGEN); // CraftBukkit + } + + } + } + + public static boolean a(Block block) { + return block != Blocks.BEDROCK && block != Blocks.END_PORTAL && block != Blocks.END_PORTAL_FRAME && block != Blocks.COMMAND_BLOCK && block != Blocks.BARRIER; + } + + public void n() { + this.r(220); + this.setHealth(this.getMaxHealth() / 3.0F); + } + + public void aA() {} + + public int br() { + return 4; + } + + private double t(int i) { + if (i <= 0) { + return this.locX; + } else { + float f = (this.aI + (float) (180 * (i - 1))) / 180.0F * 3.1415927F; + float f1 = MathHelper.cos(f); + + return this.locX + (double) f1 * 1.3D; + } + } + + private double u(int i) { + return i <= 0 ? this.locY + 3.0D : this.locY + 2.2D; + } + + private double v(int i) { + if (i <= 0) { + return this.locZ; + } else { + float f = (this.aI + (float) (180 * (i - 1))) / 180.0F * 3.1415927F; + float f1 = MathHelper.sin(f); + + return this.locZ + (double) f1 * 1.3D; + } + } + + private float b(float f, float f1, float f2) { + float f3 = MathHelper.g(f1 - f); + + if (f3 > f2) { + f3 = f2; + } + + if (f3 < -f2) { + f3 = -f2; + } + + return f + f3; + } + + private void a(int i, EntityLiving entityliving) { + this.a(i, entityliving.locX, entityliving.locY + (double) entityliving.getHeadHeight() * 0.5D, entityliving.locZ, i == 0 && this.random.nextFloat() < 0.001F); + } + + private void a(int i, double d0, double d1, double d2, boolean flag) { + this.world.a((EntityHuman) null, 1014, new BlockPosition(this), 0); + double d3 = this.t(i); + double d4 = this.u(i); + double d5 = this.v(i); + double d6 = d0 - d3; + double d7 = d1 - d4; + double d8 = d2 - d5; + EntityWitherSkull entitywitherskull = new EntityWitherSkull(this.world, this, d6, d7, d8); + + if (flag) { + entitywitherskull.setCharged(true); + } + + entitywitherskull.locY = d4; + entitywitherskull.locX = d3; + entitywitherskull.locZ = d5; + this.world.addEntity(entitywitherskull); + } + + public void a(EntityLiving entityliving, float f) { + this.a(0, entityliving); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else if (damagesource != DamageSource.DROWN && !(damagesource.getEntity() instanceof EntityWither)) { + if (this.cl() > 0 && damagesource != DamageSource.OUT_OF_WORLD) { + return false; + } else { + Entity entity; + + if (this.cm()) { + entity = damagesource.i(); + if (entity instanceof EntityArrow) { + return false; + } + } + + entity = damagesource.getEntity(); + if (entity != null && !(entity instanceof EntityHuman) && entity instanceof EntityLiving && ((EntityLiving) entity).getMonsterType() == this.getMonsterType()) { + return false; + } else { + if (this.bp <= 0) { + this.bp = 20; + } + + for (int i = 0; i < this.bo.length; ++i) { + this.bo[i] += 3; + } + + return super.damageEntity(damagesource, f); + } + } + } else { + return false; + } + } + + protected void dropDeathLoot(boolean flag, int i) { + EntityItem entityitem = this.a(Items.NETHER_STAR, 1); + + if (entityitem != null) { + entityitem.u(); + } + + if (!this.world.isClientSide) { + Iterator iterator = this.world.a(EntityHuman.class, this.getBoundingBox().grow(50.0D, 100.0D, 50.0D)).iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + entityhuman.b((Statistic) AchievementList.J); + } + } + + } + + protected void D() { + this.ticksFarFromPlayer = 0; + } + + public void e(float f, float f1) {} + + public void addEffect(MobEffect mobeffect) {} + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(300.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.6000000238418579D); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(40.0D); + } + + public int cl() { + return this.datawatcher.getInt(20); + } + + public void r(int i) { + this.datawatcher.watch(20, Integer.valueOf(i)); + } + + public int s(int i) { + return this.datawatcher.getInt(17 + i); + } + + public void b(int i, int j) { + this.datawatcher.watch(17 + i, Integer.valueOf(j)); + } + + public boolean cm() { + return this.getHealth() <= this.getMaxHealth() / 2.0F; + } + + public EnumMonsterType getMonsterType() { + return EnumMonsterType.UNDEAD; + } + + public void mount(Entity entity) { + this.vehicle = null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWitherSkull.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWitherSkull.java new file mode 100644 index 0000000..f0e627b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWitherSkull.java @@ -0,0 +1,103 @@ +package net.minecraft.server; + +import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit + +public class EntityWitherSkull extends EntityFireball { + + public EntityWitherSkull(World world) { + super(world); + this.setSize(0.3125F, 0.3125F); + } + + public EntityWitherSkull(World world, EntityLiving entityliving, double d0, double d1, double d2) { + super(world, entityliving, d0, d1, d2); + this.setSize(0.3125F, 0.3125F); + } + + protected float j() { + return this.isCharged() ? 0.73F : super.j(); + } + + public boolean isBurning() { + return false; + } + + public float a(Explosion explosion, World world, BlockPosition blockposition, IBlockData iblockdata) { + float f = super.a(explosion, world, blockposition, iblockdata); + Block block = iblockdata.getBlock(); + + if (this.isCharged() && EntityWither.a(block)) { + f = Math.min(0.8F, f); + } + + return f; + } + + protected void a(MovingObjectPosition movingobjectposition) { + if (!this.world.isClientSide) { + if (movingobjectposition.entity != null) { + // Spigot start + boolean didDamage = false; + if (this.shooter != null) { + didDamage = movingobjectposition.entity.damageEntity(DamageSource.projectile(this, shooter), 8.0F); + if (didDamage) { + if (!movingobjectposition.entity.isAlive()) { + this.shooter.heal(5.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER); // CraftBukkit + } else { + this.a(this.shooter, movingobjectposition.entity); + } + } + } else { + didDamage = movingobjectposition.entity.damageEntity(DamageSource.MAGIC, 5.0F); + } + + if (didDamage && movingobjectposition.entity instanceof EntityLiving) { + // Spigot end + byte b0 = 0; + + if (this.world.getDifficulty() == EnumDifficulty.NORMAL) { + b0 = 10; + } else if (this.world.getDifficulty() == EnumDifficulty.HARD) { + b0 = 40; + } + + if (b0 > 0) { + ((EntityLiving) movingobjectposition.entity).addEffect(new MobEffect(MobEffectList.WITHER.id, 20 * b0, 1)); + } + } + } + + // CraftBukkit start + // this.world.createExplosion(this, this.locX, this.locY, this.locZ, 1.0F, false, this.world.getGameRules().getBoolean("mobGriefing")); + ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + this.world.createExplosion(this, this.locX, this.locY, this.locZ, event.getRadius(), event.getFire(), this.world.getGameRules().getBoolean("mobGriefing")); + } + // CraftBukkit end + this.die(); + } + + } + + public boolean ad() { + return false; + } + + public boolean damageEntity(DamageSource damagesource, float f) { + return false; + } + + protected void h() { + this.datawatcher.a(10, Byte.valueOf((byte) 0)); + } + + public boolean isCharged() { + return this.datawatcher.getByte(10) == 1; + } + + public void setCharged(boolean flag) { + this.datawatcher.watch(10, Byte.valueOf((byte) (flag ? 1 : 0))); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWolf.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWolf.java new file mode 100644 index 0000000..469c87a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityWolf.java @@ -0,0 +1,407 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; +// CraftBukkit end + +public class EntityWolf extends EntityTameableAnimal { + + private float bo; + private float bp; + private boolean bq; + private boolean br; + private float bs; + private float bt; + + public EntityWolf(World world) { + super(world); + this.setSize(0.6F, 0.8F); + ((Navigation) this.getNavigation()).a(true); + this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, this.bm); + this.goalSelector.a(3, new PathfinderGoalLeapAtTarget(this, 0.4F)); + this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, true)); + this.goalSelector.a(5, new PathfinderGoalFollowOwner(this, 1.0D, 10.0F, 2.0F)); + this.goalSelector.a(6, new PathfinderGoalBreed(this, 1.0D)); + this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(8, new PathfinderGoalBeg(this, 8.0F)); + this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); + this.goalSelector.a(9, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(1, new PathfinderGoalOwnerHurtByTarget(this)); + this.targetSelector.a(2, new PathfinderGoalOwnerHurtTarget(this)); + this.targetSelector.a(3, new PathfinderGoalHurtByTarget(this, true, new Class[0])); + this.targetSelector.a(4, new PathfinderGoalRandomTargetNonTamed(this, EntityAnimal.class, false, new Predicate() { + public boolean a(Entity entity) { + return entity instanceof EntitySheep || entity instanceof EntityRabbit; + } + + public boolean apply(Object object) { + return this.a((Entity) object); + } + })); + this.targetSelector.a(5, new PathfinderGoalNearestAttackableTarget(this, EntitySkeleton.class, false)); + this.setTamed(false); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.30000001192092896D); + if (this.isTamed()) { + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(20.0D); + } else { + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(8.0D); + } + + this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE); + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(2.0D); + } + + public void setGoalTarget(EntityLiving entityliving) { + super.setGoalTarget(entityliving); + if (entityliving == null) { + this.setAngry(false); + } else if (!this.isTamed()) { + this.setAngry(true); + } + + } + + // CraftBukkit - add overriden version + @Override + public void setGoalTarget(EntityLiving entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason reason, boolean fire) { + super.setGoalTarget(entityliving, reason, fire); + if (entityliving == null) { + this.setAngry(false); + } else if (!this.isTamed()) { + this.setAngry(true); + } + } + // CraftBukkit end + + protected void E() { + this.datawatcher.watch(18, Float.valueOf(this.getHealth())); + } + + protected void h() { + super.h(); + this.datawatcher.a(18, new Float(this.getHealth())); + this.datawatcher.a(19, new Byte((byte) 0)); + this.datawatcher.a(20, new Byte((byte) EnumColor.RED.getColorIndex())); + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.wolf.step", 0.15F, 1.0F); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setBoolean("Angry", this.isAngry()); + nbttagcompound.setByte("CollarColor", (byte) this.getCollarColor().getInvColorIndex()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.setAngry(nbttagcompound.getBoolean("Angry")); + if (nbttagcompound.hasKeyOfType("CollarColor", 99)) { + this.setCollarColor(EnumColor.fromInvColorIndex(nbttagcompound.getByte("CollarColor"))); + } + + } + + protected String z() { + // CraftBukkit - (getFloat(18) < 10) -> (getFloat(18) < this.getMaxHealth() / 2) + return this.isAngry() ? "mob.wolf.growl" : (this.random.nextInt(3) == 0 ? (this.isTamed() && this.datawatcher.getFloat(18) < this.getMaxHealth() / 2 ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark"); + } + + protected String bo() { + return "mob.wolf.hurt"; + } + + protected String bp() { + return "mob.wolf.death"; + } + + protected float bB() { + return 0.4F; + } + + protected Item getLoot() { + return Item.getById(-1); + } + + public void m() { + super.m(); + if (!this.world.isClientSide && this.bq && !this.br && !this.cf() && this.onGround) { + this.br = true; + this.bs = 0.0F; + this.bt = 0.0F; + this.world.broadcastEntityEffect(this, (byte) 8); + } + + if (!this.world.isClientSide && this.getGoalTarget() == null && this.isAngry()) { + this.setAngry(false); + } + + } + + public void t_() { + super.t_(); + this.bp = this.bo; + if (this.cx()) { + this.bo += (1.0F - this.bo) * 0.4F; + } else { + this.bo += (0.0F - this.bo) * 0.4F; + } + + if (this.U()) { + this.bq = true; + this.br = false; + this.bs = 0.0F; + this.bt = 0.0F; + } else if ((this.bq || this.br) && this.br) { + if (this.bs == 0.0F) { + this.makeSound("mob.wolf.shake", this.bB(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + } + + this.bt = this.bs; + this.bs += 0.05F; + if (this.bt >= 2.0F) { + this.bq = false; + this.br = false; + this.bt = 0.0F; + this.bs = 0.0F; + } + + if (this.bs > 0.4F) { + float f = (float) this.getBoundingBox().b; + int i = (int) (MathHelper.sin((this.bs - 0.4F) * 3.1415927F) * 7.0F); + + for (int j = 0; j < i; ++j) { + 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, (double) (f + 0.8F), this.locZ + (double) f2, this.motX, this.motY, this.motZ, new int[0]); + } + } + } + + } + + public float getHeadHeight() { + return this.length * 0.8F; + } + + public int bQ() { + return this.isSitting() ? 20 : super.bQ(); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (this.isInvulnerable(damagesource)) { + return false; + } else { + Entity entity = damagesource.getEntity(); + + // CraftBukkit - moved into EntityLiving.d(DamageSource, float) + // this.bm.setSitting(false); + if (entity != null && !(entity instanceof EntityHuman) && !(entity instanceof EntityArrow)) { + f = (f + 1.0F) / 2.0F; + } + + return super.damageEntity(damagesource, f); + } + } + + public boolean r(Entity entity) { + boolean flag = entity.damageEntity(DamageSource.mobAttack(this), (float) ((int) this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).getValue())); + + if (flag) { + this.a((EntityLiving) this, entity); + } + + return flag; + } + + public void setTamed(boolean flag) { + super.setTamed(flag); + if (flag) { + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(20.0D); + } else { + this.getAttributeInstance(GenericAttributes.maxHealth).setValue(8.0D); + } + + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(4.0D); + } + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.inventory.getItemInHand(); + + if (this.isTamed()) { + if (itemstack != null) { + if (itemstack.getItem() instanceof ItemFood) { + ItemFood itemfood = (ItemFood) itemstack.getItem(); + + if (itemfood.g() && this.datawatcher.getFloat(18) < 20.0F) { + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + this.heal((float) itemfood.getNutrition(itemstack), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit + if (itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + + return true; + } + } else if (itemstack.getItem() == Items.DYE) { + EnumColor enumcolor = EnumColor.fromInvColorIndex(itemstack.getData()); + + if (enumcolor != this.getCollarColor()) { + this.setCollarColor(enumcolor); + if (!entityhuman.abilities.canInstantlyBuild && --itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + + return true; + } + } + } + + if (this.e((EntityLiving) entityhuman) && !this.world.isClientSide && !this.d(itemstack)) { + this.bm.setSitting(!this.isSitting()); + this.aY = false; + this.navigation.n(); + this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason + } + } else if (itemstack != null && itemstack.getItem() == Items.BONE && !this.isAngry()) { + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + if (itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, (ItemStack) null); + } + + if (!this.world.isClientSide) { + // CraftBukkit - added event call and isCancelled check. + if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { + this.setTamed(true); + this.navigation.n(); + this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); + this.bm.setSitting(true); + this.setHealth(this.getMaxHealth()); // CraftBukkit - 20.0 -> getMaxHealth() + this.setOwnerUUID(entityhuman.getUniqueID().toString()); + this.l(true); + this.world.broadcastEntityEffect(this, (byte) 7); + } else { + this.l(false); + this.world.broadcastEntityEffect(this, (byte) 6); + } + } + + return true; + } + + return super.a(entityhuman); + } + + public boolean d(ItemStack itemstack) { + return itemstack == null ? false : (!(itemstack.getItem() instanceof ItemFood) ? false : ((ItemFood) itemstack.getItem()).g()); + } + + public int bV() { + return 8; + } + + public boolean isAngry() { + return (this.datawatcher.getByte(16) & 2) != 0; + } + + public void setAngry(boolean flag) { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 2))); + } else { + this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -3))); + } + + } + + public EnumColor getCollarColor() { + return EnumColor.fromInvColorIndex(this.datawatcher.getByte(20) & 15); + } + + public void setCollarColor(EnumColor enumcolor) { + this.datawatcher.watch(20, Byte.valueOf((byte) (enumcolor.getInvColorIndex() & 15))); + } + + public EntityWolf b(EntityAgeable entityageable) { + EntityWolf entitywolf = new EntityWolf(this.world); + String s = this.getOwnerUUID(); + + if (s != null && s.trim().length() > 0) { + entitywolf.setOwnerUUID(s); + entitywolf.setTamed(true); + } + + return entitywolf; + } + + public void p(boolean flag) { + if (flag) { + this.datawatcher.watch(19, Byte.valueOf((byte) 1)); + } else { + this.datawatcher.watch(19, Byte.valueOf((byte) 0)); + } + + } + + public boolean mate(EntityAnimal entityanimal) { + if (entityanimal == this) { + return false; + } else if (!this.isTamed()) { + return false; + } else if (!(entityanimal instanceof EntityWolf)) { + return false; + } else { + EntityWolf entitywolf = (EntityWolf) entityanimal; + + return !entitywolf.isTamed() ? false : (entitywolf.isSitting() ? false : this.isInLove() && entitywolf.isInLove()); + } + } + + public boolean cx() { + return this.datawatcher.getByte(19) == 1; + } + + protected boolean isTypeNotPersistent() { + return !this.isTamed() /*&& this.ticksLived > 2400*/; // CraftBukkit + } + + public boolean a(EntityLiving entityliving, EntityLiving entityliving1) { + if (!(entityliving instanceof EntityCreeper) && !(entityliving instanceof EntityGhast)) { + if (entityliving instanceof EntityWolf) { + EntityWolf entitywolf = (EntityWolf) entityliving; + + if (entitywolf.isTamed() && entitywolf.getOwner() == entityliving1) { + return false; + } + } + + return entityliving instanceof EntityHuman && entityliving1 instanceof EntityHuman && !((EntityHuman) entityliving1).a((EntityHuman) entityliving) ? false : !(entityliving instanceof EntityHorse) || !((EntityHorse) entityliving).isTame(); + } else { + return false; + } + } + + public boolean cb() { + return !this.isAngry() && super.cb(); + } + + public EntityAgeable createChild(EntityAgeable entityageable) { + return this.b(entityageable); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityZombie.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityZombie.java new file mode 100644 index 0000000..a8e15aa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/EntityZombie.java @@ -0,0 +1,582 @@ +package net.minecraft.server; + +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityCombustByEntityEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityTargetEvent; + +import java.util.Calendar; +import java.util.List; +import java.util.UUID; + +//CraftBukkit start +//CraftBukkit end + +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 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; + private boolean bo = false; + private float bp = -1.0F; + private float bq; + private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field + + public EntityZombie(World world) { + super(world); + ((Navigation) this.getNavigation()).b(true); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, 1.0D, false)); + this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); + this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D)); + this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); + this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.n(); + this.setSize(0.6F, 1.95F); + } + + protected void n() { + if ( world.spigotConfig.zombieAggressiveTowardsVillager ) this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntityVillager.class, 1.0D, true)); // Spigot + this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntityIronGolem.class, 1.0D, true)); + this.goalSelector.a(6, new PathfinderGoalMoveThroughVillage(this, 1.0D, false)); + this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, EntityPigZombie.class)); + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true)); + if ( world.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, false)); // Spigot + this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityIronGolem.class, true)); + } + + protected void initAttributes() { + super.initAttributes(); + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(35.0D); + this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.23000000417232513D); + this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(3.0D); + this.getAttributeMap().b(EntityZombie.a).setValue(this.random.nextDouble() * 0.10000000149011612D); + } + + protected void h() { + super.h(); + this.getDataWatcher().a(12, Byte.valueOf((byte) 0)); + this.getDataWatcher().a(13, Byte.valueOf((byte) 0)); + this.getDataWatcher().a(14, Byte.valueOf((byte) 0)); + } + + public int br() { + int i = super.br() + 2; + + if (i > 20) { + i = 20; + } + + return i; + } + + public boolean cn() { + return this.bo; + } + + public void a(boolean flag) { + if (this.bo != flag) { + this.bo = flag; + if (flag) { + this.goalSelector.a(1, this.bm); + } else { + this.goalSelector.a(this.bm); + } + } + + } + + public boolean isBaby() { + return this.getDataWatcher().getByte(12) == 1; + } + + protected int getExpValue(EntityHuman entityhuman) { + if (this.isBaby()) { + this.b_ = (int) ((float) this.b_ * 2.5F); + } + + return super.getExpValue(entityhuman); + } + + public void setBaby(boolean flag) { + this.getDataWatcher().watch(12, Byte.valueOf((byte) (flag ? 1 : 0))); + if (this.world != null && !this.world.isClientSide) { + AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); + + attributeinstance.c(EntityZombie.c); + if (flag) { + attributeinstance.b(EntityZombie.c); + } + } + + this.n(flag); + } + + public boolean isVillager() { + return this.getDataWatcher().getByte(13) == 1; + } + + public void setVillager(boolean flag) { + this.getDataWatcher().watch(13, Byte.valueOf((byte) (flag ? 1 : 0))); + } + + public void m() { + if (this.world.w() && !this.world.isClientSide && !this.isBaby()) { + float f = this.c(1.0F); + BlockPosition blockposition = new BlockPosition(this.locX, (double) Math.round(this.locY), this.locZ); + + if (f > 0.5F && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.world.i(blockposition)) { + boolean flag = true; + ItemStack itemstack = this.getEquipment(4); + + if (itemstack != null) { + if (itemstack.e()) { + itemstack.setData(itemstack.h() + this.random.nextInt(2)); + if (itemstack.h() >= itemstack.j()) { + this.b(itemstack); + this.setEquipment(4, null); + } + } + + flag = false; + } + + if (flag) { + // CraftBukkit start + EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + this.setOnFire(event.getDuration()); + } + // CraftBukkit end + } + } + } + + if (this.au() && this.getGoalTarget() != null && this.vehicle instanceof EntityChicken) { + ((EntityInsentient) this.vehicle).getNavigation().a(this.getNavigation().j(), 1.5D); + } + + super.m(); + } + + public boolean damageEntity(DamageSource damagesource, float f) { + if (super.damageEntity(damagesource, f)) { + EntityLiving entityliving = this.getGoalTarget(); + + if (entityliving == null && damagesource.getEntity() instanceof EntityLiving) { + entityliving = (EntityLiving) damagesource.getEntity(); + } + + if (entityliving != null && this.world.getDifficulty() == EnumDifficulty.HARD && (double) this.random.nextFloat() < this.getAttributeInstance(EntityZombie.a).getValue()) { + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY); + int k = MathHelper.floor(this.locZ); + EntityZombie entityzombie = new EntityZombie(this.world); + + for (int l = 0; l < 50; ++l) { + int i1 = i + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1); + int j1 = j + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1); + int k1 = k + MathHelper.nextInt(this.random, 7, 40) * MathHelper.nextInt(this.random, -1, 1); + + if (World.a(this.world, i1, j1 - 1, k1) && this.world.getLightLevel(i1, j1, k1) < 10) { + entityzombie.setPosition(i1, j1, k1); + if (!this.world.isPlayerNearby(i1, j1, k1, 7.0D) && this.world.a(entityzombie.getBoundingBox(), entityzombie) && this.world.getCubes(entityzombie, entityzombie.getBoundingBox()).isEmpty() && !this.world.containsLiquid(entityzombie.getBoundingBox())) { + this.world.addEntity(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit + entityzombie.setGoalTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); + entityzombie.prepare(this.world.E(new BlockPosition(entityzombie)), null); + this.getAttributeInstance(EntityZombie.a).b(new AttributeModifier("Zombie reinforcement caller charge", -0.05000000074505806D, 0)); + entityzombie.getAttributeInstance(EntityZombie.a).b(new AttributeModifier("Zombie reinforcement callee charge", -0.05000000074505806D, 0)); + break; + } + } + } + } + + return true; + } else { + return false; + } + } + + public void t_() { + if (!this.world.isClientSide && this.cp()) { + int i = this.cr(); + + // CraftBukkit start - Use wall time instead of ticks for villager conversion + int elapsedTicks = MinecraftServer.currentTick - this.lastTick; + this.lastTick = MinecraftServer.currentTick; + i *= elapsedTicks; + // CraftBukkit end + + this.bn -= i; + if (this.bn <= 0) { + this.cq(); + } + } + + super.t_(); + } + + public boolean r(Entity entity) { + boolean flag = super.r(entity); + + if (flag) { + int i = this.world.getDifficulty().a(); + + if (this.bA() == null && this.isBurning() && this.random.nextFloat() < (float) i * 0.3F) { + // CraftBukkit start + EntityCombustByEntityEvent event = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 2 * i); + this.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + entity.setOnFire(event.getDuration()); + } + // CraftBukkit end + } + } + + return flag; + } + + protected String z() { + return "mob.zombie.say"; + } + + protected String bo() { + return "mob.zombie.hurt"; + } + + protected String bp() { + return "mob.zombie.death"; + } + + protected void a(BlockPosition blockposition, Block block) { + this.makeSound("mob.zombie.step", 0.15F, 1.0F); + } + + protected Item getLoot() { + return Items.ROTTEN_FLESH; + } + + public EnumMonsterType getMonsterType() { + return EnumMonsterType.UNDEAD; + } + + protected void getRareDrop() { + switch (this.random.nextInt(3)) { + case 0: + this.a(Items.IRON_INGOT, 1); + break; + + case 1: + this.a(Items.CARROT, 1); + break; + + case 2: + this.a(Items.POTATO, 1); + } + + } + + protected void a(DifficultyDamageScaler difficultydamagescaler) { + super.a(difficultydamagescaler); + if (this.random.nextFloat() < (this.world.getDifficulty() == EnumDifficulty.HARD ? 0.05F : 0.01F)) { + int i = this.random.nextInt(3); + + if (i == 0) { + this.setEquipment(0, new ItemStack(Items.IRON_SWORD)); + } else { + this.setEquipment(0, new ItemStack(Items.IRON_SHOVEL)); + } + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + if (this.isBaby()) { + nbttagcompound.setBoolean("IsBaby", true); + } + + if (this.isVillager()) { + nbttagcompound.setBoolean("IsVillager", true); + } + + nbttagcompound.setInt("ConversionTime", this.cp() ? this.bn : -1); + nbttagcompound.setBoolean("CanBreakDoors", this.cn()); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + if (nbttagcompound.getBoolean("IsBaby")) { + this.setBaby(true); + } + + if (nbttagcompound.getBoolean("IsVillager")) { + this.setVillager(true); + } + + if (nbttagcompound.hasKeyOfType("ConversionTime", 99) && nbttagcompound.getInt("ConversionTime") > -1) { + this.a(nbttagcompound.getInt("ConversionTime")); + } + + this.a(nbttagcompound.getBoolean("CanBreakDoors")); + } + + public void a(EntityLiving entityliving) { + super.a(entityliving); + if ((this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) && entityliving instanceof EntityVillager) { + if (this.world.getDifficulty() != EnumDifficulty.HARD && this.random.nextBoolean()) { + return; + } + + EntityInsentient entityinsentient = (EntityInsentient) entityliving; + EntityZombie entityzombie = new EntityZombie(this.world); + + entityzombie.m(entityliving); + this.world.kill(entityliving); + entityzombie.prepare(this.world.E(new BlockPosition(entityzombie)), null); + entityzombie.setVillager(true); + if (entityliving.isBaby()) { + entityzombie.setBaby(true); + } + + entityzombie.k(entityinsentient.ce()); + if (entityinsentient.hasCustomName()) { + entityzombie.setCustomName(entityinsentient.getCustomName()); + entityzombie.setCustomNameVisible(entityinsentient.getCustomNameVisible()); + } + + this.world.addEntity(entityzombie, CreatureSpawnEvent.SpawnReason.INFECTION); // CraftBukkit - add SpawnReason + this.world.a(null, 1016, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0); + } + + } + + public float getHeadHeight() { + float f = 1.74F; + + if (this.isBaby()) { + f = (float) ((double) f - 0.81D); + } + + return f; + } + + protected boolean a(ItemStack itemstack) { + return (itemstack.getItem() != Items.EGG || !this.isBaby() || !this.au()) && super.a(itemstack); + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { + Object object = super.prepare(difficultydamagescaler, groupdataentity); + float f = difficultydamagescaler.c(); + + this.j(this.random.nextFloat() < 0.55F * f); + if (object == null) { + object = new EntityZombie.GroupDataZombie(this.world.random.nextFloat() < 0.05F, this.world.random.nextFloat() < 0.05F, null); + } + + if (object instanceof EntityZombie.GroupDataZombie) { + EntityZombie.GroupDataZombie entityzombie_groupdatazombie = (EntityZombie.GroupDataZombie) object; + + if (entityzombie_groupdatazombie.b) { + this.setVillager(true); + } + + if (entityzombie_groupdatazombie.a) { + this.setBaby(true); + if ((double) this.world.random.nextFloat() < 0.05D) { + List list = this.world.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.b); + + if (!list.isEmpty()) { + EntityChicken entitychicken = (EntityChicken) list.get(0); + + entitychicken.l(true); + this.mount(entitychicken); + } + } else if ((double) this.world.random.nextFloat() < 0.05D) { + EntityChicken entitychicken1 = new EntityChicken(this.world); + + entitychicken1.setPositionRotation(this.locX, this.locY, this.locZ, this.yaw, 0.0F); + entitychicken1.prepare(difficultydamagescaler, null); + entitychicken1.l(true); + this.world.addEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); + this.mount(entitychicken1); + } + } + } + + this.a(this.random.nextFloat() < f * 0.1F); + this.a(difficultydamagescaler); + this.b(difficultydamagescaler); + if (this.getEquipment(4) == null) { + Calendar calendar = this.world.Y(); + + if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && this.random.nextFloat() < 0.25F) { + this.setEquipment(4, new ItemStack(this.random.nextFloat() < 0.1F ? Blocks.LIT_PUMPKIN : Blocks.PUMPKIN)); + this.dropChances[4] = 0.0F; + } + } + + this.getAttributeInstance(GenericAttributes.c).b(new AttributeModifier("Random spawn bonus", this.random.nextDouble() * 0.05000000074505806D, 0)); + double d0 = this.random.nextDouble() * 1.5D * (double) f; + + if (d0 > 1.0D) { + this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).b(new AttributeModifier("Random zombie-spawn bonus", d0, 2)); + } + + if (this.random.nextFloat() < f * 0.05F) { + this.getAttributeInstance(EntityZombie.a).b(new AttributeModifier("Leader zombie bonus", this.random.nextDouble() * 0.25D + 0.5D, 0)); + this.getAttributeInstance(GenericAttributes.maxHealth).b(new AttributeModifier("Leader zombie bonus", this.random.nextDouble() * 3.0D + 1.0D, 2)); + this.a(true); + } + + return (GroupDataEntity) object; + } + + public boolean a(EntityHuman entityhuman) { + ItemStack itemstack = entityhuman.bZ(); + + if (itemstack != null && itemstack.getItem() == Items.GOLDEN_APPLE && itemstack.getData() == 0 && this.isVillager() && this.hasEffect(MobEffectList.WEAKNESS)) { + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + if (itemstack.count <= 0) { + entityhuman.inventory.setItem(entityhuman.inventory.itemInHandIndex, null); + } + + if (!this.world.isClientSide) { + this.a(this.random.nextInt(2401) + 3600); + } + + return true; + } else { + return false; + } + } + + protected void a(int i) { + this.bn = i; + this.getDataWatcher().watch(14, Byte.valueOf((byte) 1)); + this.removeEffect(MobEffectList.WEAKNESS.id); + this.addEffect(new MobEffect(MobEffectList.INCREASE_DAMAGE.id, i, Math.min(this.world.getDifficulty().a() - 1, 0))); + this.world.broadcastEntityEffect(this, (byte) 16); + } + + protected boolean isTypeNotPersistent() { + return !this.cp(); + } + + public boolean cp() { + return this.getDataWatcher().getByte(14) == 1; + } + + protected void cq() { + EntityVillager entityvillager = new EntityVillager(this.world); + + entityvillager.m(this); + entityvillager.prepare(this.world.E(new BlockPosition(entityvillager)), null); + entityvillager.cp(); + if (this.isBaby()) { + entityvillager.setAgeRaw(-24000); + } + + this.world.kill(this); + entityvillager.k(this.ce()); + if (this.hasCustomName()) { + entityvillager.setCustomName(this.getCustomName()); + entityvillager.setCustomNameVisible(this.getCustomNameVisible()); + } + + this.world.addEntity(entityvillager, CreatureSpawnEvent.SpawnReason.CURED); // CraftBukkit - add SpawnReason + entityvillager.addEffect(new MobEffect(MobEffectList.CONFUSION.id, 200, 0)); + this.world.a(null, 1017, new BlockPosition((int) this.locX, (int) this.locY, (int) this.locZ), 0); + } + + protected int cr() { + int i = 1; + + if (this.random.nextFloat() < 0.01F) { + int j = 0; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k = (int) this.locX - 4; k < (int) this.locX + 4 && j < 14; ++k) { + for (int l = (int) this.locY - 4; l < (int) this.locY + 4 && j < 14; ++l) { + for (int i1 = (int) this.locZ - 4; i1 < (int) this.locZ + 4 && j < 14; ++i1) { + Block block = this.world.getType(blockposition_mutableblockposition.c(k, l, i1)).getBlock(); + + if (block == Blocks.IRON_BARS || block == Blocks.BED) { + if (this.random.nextFloat() < 0.3F) { + ++i; + } + + ++j; + } + } + } + } + } + + return i; + } + + public void n(boolean flag) { + this.a(flag ? 0.5F : 1.0F); + } + + public final void setSize(float f, float f1) { // CraftBukkit - public + boolean flag = this.bp > 0.0F && this.bq > 0.0F; + + this.bp = f; + this.bq = f1; + if (!flag) { + this.a(1.0F); + } + + } + + protected final void a(float f) { + super.setSize(this.bp * f, this.bq * f); + } + + public double am() { + return this.isBaby() ? 0.0D : -0.35D; + } + + public void die(DamageSource damagesource) { + // super.die(damagesource); // CraftBukkit + if (damagesource.getEntity() instanceof EntityCreeper && !(this instanceof EntityPigZombie) && ((EntityCreeper) damagesource.getEntity()).isPowered() && ((EntityCreeper) damagesource.getEntity()).cp()) { + ((EntityCreeper) damagesource.getEntity()).cq(); + // CraftBukkit start + // this.a(new ItemStack(Items.SKULL, 1, 2), 0.0F); + headDrop = new ItemStack(Items.SKULL, 1, 2); + // CraftBukkit end + } + + super.die(damagesource); // CraftBukkit - moved from above + } + + static class SyntheticClass_1 { } + + class GroupDataZombie implements GroupDataEntity { + + public boolean a; + public boolean b; + + private GroupDataZombie(boolean flag, boolean flag1) { + this.a = false; + this.b = false; + this.a = flag; + this.b = flag1; + } + + GroupDataZombie(boolean flag, boolean flag1, EntityZombie.SyntheticClass_1 entityzombie_syntheticclass_1) { + this(flag, flag1); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ExpirableListEntry.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ExpirableListEntry.java new file mode 100644 index 0000000..e643741 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ExpirableListEntry.java @@ -0,0 +1,94 @@ +package net.minecraft.server; + +import com.google.gson.JsonObject; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public abstract class ExpirableListEntry extends JsonListEntry { + + public static final SimpleDateFormat a = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); + protected final Date b; + protected final String c; + protected final Date d; + protected final String e; + + public ExpirableListEntry(T t0, Date date, String s, Date date1, String s1) { + super(t0); + this.b = date == null ? new Date() : date; + this.c = s == null ? "(Unknown)" : s; + this.d = date1; + this.e = s1 == null ? "Banned by an operator." : s1; + } + + protected ExpirableListEntry(T t0, JsonObject jsonobject) { + super(checkExpiry(t0, jsonobject), jsonobject); + + Date date; + + try { + date = jsonobject.has("created") ? ExpirableListEntry.a.parse(jsonobject.get("created").getAsString()) : new Date(); + } catch (ParseException parseexception) { + date = new Date(); + } + + this.b = date; + this.c = jsonobject.has("source") ? jsonobject.get("source").getAsString() : "(Unknown)"; + + Date date1; + + try { + date1 = jsonobject.has("expires") ? ExpirableListEntry.a.parse(jsonobject.get("expires").getAsString()) : null; + } catch (ParseException parseexception1) { + date1 = null; + } + + this.d = date1; + this.e = jsonobject.has("reason") ? jsonobject.get("reason").getAsString() : "Banned by an operator."; + } + + public Date getExpires() { + return this.d; + } + + public String getReason() { + return this.e; + } + + boolean hasExpired() { + return this.d == null ? false : this.d.before(new Date()); + } + + protected void a(JsonObject jsonobject) { + jsonobject.addProperty("created", ExpirableListEntry.a.format(this.b)); + jsonobject.addProperty("source", this.c); + jsonobject.addProperty("expires", this.d == null ? "forever" : ExpirableListEntry.a.format(this.d)); + jsonobject.addProperty("reason", this.e); + } + + // CraftBukkit start + public String getSource() { + return this.c; + } + + public Date getCreated() { + return this.b; + } + + private static T checkExpiry(T object, JsonObject jsonobject) { + Date expires = null; + + try { + expires = jsonobject.has("expires") ? a.parse(jsonobject.get("expires").getAsString()) : null; + } catch (ParseException ex) { + // Guess we don't have a date + } + + if (expires == null || expires.after(new Date())) { + return object; + } else { + return null; + } + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Explosion.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Explosion.java new file mode 100644 index 0000000..f4ccd8d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Explosion.java @@ -0,0 +1,386 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.Location; +import org.bukkit.event.block.BlockExplodeEvent; +// CraftBukkit end + +public class Explosion { + + private final boolean a; + private final boolean b; + private final Random c = new Random(); + private final World world; + private final double posX; + private final double posY; + private final double posZ; + public final Entity source; + private final float size; + private final List blocks = Lists.newArrayList(); + private final Map k = Maps.newHashMap(); + public boolean wasCanceled = false; // CraftBukkit - add field + + public Explosion(World world, Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { + this.world = world; + this.source = entity; + this.size = (float) Math.max(f, 0.0); // CraftBukkit - clamp bad values + this.posX = d0; + this.posY = d1; + this.posZ = d2; + this.a = flag; + this.b = flag1; + } + + public void a() { + // CraftBukkit start + if (this.size < 0.1F) { + return; + } + // CraftBukkit end + HashSet hashset = Sets.newHashSet(); + boolean flag = true; + + int i; + int j; + + 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 + for (int k = 0; k < 16; ++k) { + for (i = 0; i < 16; ++i) { + for (j = 0; j < 16; ++j) { + if (k == 0 || k == 15 || i == 0 || i == 15 || j == 0 || j == 15) { + double d0 = (double) ((float) k / 15.0F * 2.0F - 1.0F); + double d1 = (double) ((float) i / 15.0F * 2.0F - 1.0F); + double d2 = (double) ((float) j / 15.0F * 2.0F - 1.0F); + double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + + d0 /= d3; + d1 /= d3; + d2 /= d3; + float f = this.size * (0.7F + this.world.random.nextFloat() * 0.6F); + double d4 = this.posX; + double d5 = this.posY; + double d6 = this.posZ; + + for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) { + BlockPosition blockposition = new BlockPosition(d4, d5, d6); + IBlockData iblockdata = this.world.getType(blockposition); + + if (iblockdata.getBlock().getMaterial() != Material.AIR) { + float f2 = this.source != null ? this.source.a(this, this.world, blockposition, iblockdata) : iblockdata.getBlock().a((Entity) null); + + f -= (f2 + 0.3F) * 0.3F; + } + + if (f > 0.0F && (this.source == null || this.source.a(this, this.world, blockposition, iblockdata, f)) && blockposition.getY() < 256 && blockposition.getY() >= 0) { // CraftBukkit - don't wrap explosions + hashset.add(blockposition); + } + + d4 += d0 * 0.30000001192092896D; + d5 += d1 * 0.30000001192092896D; + d6 += d2 * 0.30000001192092896D; + } + } + } + } + } + } + + this.blocks.addAll(hashset); + float f3 = this.size * 2.0F; + + i = MathHelper.floor(this.posX - (double) f3 - 1.0D); + j = MathHelper.floor(this.posX + (double) f3 + 1.0D); + int l = MathHelper.floor(this.posY - (double) f3 - 1.0D); + int i1 = MathHelper.floor(this.posY + (double) f3 + 1.0D); + int j1 = MathHelper.floor(this.posZ - (double) f3 - 1.0D); + int k1 = MathHelper.floor(this.posZ + (double) f3 + 1.0D); + // PaperSpigot start - Fix lag from explosions processing dead entities + List list = this.world.a(this.source, new AxisAlignedBB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), new com.google.common.base.Predicate() { + @Override + public boolean apply(Entity entity) { + return IEntitySelector.d.apply(entity) && !entity.dead; + } + }); + // PaperSpigot end + Vec3D vec3d = new Vec3D(this.posX, this.posY, this.posZ); + + for (int l1 = 0; l1 < list.size(); ++l1) { + Entity entity = (Entity) list.get(l1); + + if (!entity.aW()) { + double d7 = entity.f(this.posX, this.posY, this.posZ) / (double) f3; + + if (d7 <= 1.0D) { + double d8 = entity.locX - this.posX; + double d9 = entity.locY + (double) entity.getHeadHeight() - this.posY; + double d10 = entity.locZ - this.posZ; + double d11 = (double) MathHelper.sqrt(d8 * d8 + d9 * d9 + d10 * d10); + + if (d11 != 0.0D) { + d8 /= d11; + d9 /= d11; + d10 /= d11; + double d12 = this.getBlockDensity(vec3d, entity.getBoundingBox()); // PaperSpigot - Optimize explosions + double d13 = (1.0D - d7) * d12; + + // entity.damageEntity(DamageSource.explosion(this), (float) ((int) ((d13 * d13 + d13) / 2.0D * 8.0D * (double) f3 + 1.0D)));+ // CraftBukkit start + CraftEventFactory.entityDamage = source; + entity.forceExplosionKnockback = false; + boolean wasDamaged = entity.damageEntity(DamageSource.explosion(this), (float) ((int) ((d13 * d13 + d13) / 2.0D * 8.0D * (double) f3 + 1.0D))); + CraftEventFactory.entityDamage = null; + if (!wasDamaged && !(entity instanceof EntityTNTPrimed || entity instanceof EntityFallingBlock) && !entity.forceExplosionKnockback) { + continue; + } + // CraftBukkit end + double d14 = entity instanceof EntityHuman && world.paperSpigotConfig.disableExplosionKnockback ? 0 : EnchantmentProtection.a(entity, d13); // PaperSpigot + + // PaperSpigot start - Fix cannons + /* + entity.motX += d8 * d14; + entity.motY += d9 * d14; + entity.motZ += d10 * d14; + */ + // This impulse method sets the dirty flag, so clients will get an immediate velocity update + entity.g(d8 * d14, d9 * d14, d10 * d14); + // PaperSpigot end + + if (entity instanceof EntityHuman && !((EntityHuman) entity).abilities.isInvulnerable && !world.paperSpigotConfig.disableExplosionKnockback) { // PaperSpigot + this.k.put((EntityHuman) entity, new Vec3D(d8 * d13, d9 * d13, d10 * d13)); + } + } + } + } + } + + } + + public void a(boolean flag) { + // PaperSpigot start - Configurable TNT explosion volume. + float volume = source instanceof EntityTNTPrimed ? world.paperSpigotConfig.tntExplosionVolume : 4.0F; + 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]); + } else { + this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 1.0D, 0.0D, 0.0D, new int[0]); + } + + Iterator iterator; + BlockPosition blockposition; + + if (this.b) { + // CraftBukkit start + org.bukkit.World bworld = this.world.getWorld(); + org.bukkit.entity.Entity explode = this.source == null ? null : this.source.getBukkitEntity(); + Location location = new Location(bworld, this.posX, this.posY, this.posZ); + + List blockList = Lists.newArrayList(); + for (int i1 = this.blocks.size() - 1; i1 >= 0; i1--) { + BlockPosition cpos = (BlockPosition) this.blocks.get(i1); + org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.getX(), cpos.getY(), cpos.getZ()); + if (bblock.getType() != org.bukkit.Material.AIR) { + blockList.add(bblock); + } + } + + boolean cancelled; + List bukkitBlocks; + float yield; + + if (explode != null) { + EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, 0.3F); + this.world.getServer().getPluginManager().callEvent(event); + cancelled = event.isCancelled(); + bukkitBlocks = event.blockList(); + yield = event.getYield(); + } else { + BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, 0.3F); + this.world.getServer().getPluginManager().callEvent(event); + cancelled = event.isCancelled(); + bukkitBlocks = event.blockList(); + yield = event.getYield(); + } + + this.blocks.clear(); + + for (org.bukkit.block.Block bblock : bukkitBlocks) { + BlockPosition coords = new BlockPosition(bblock.getX(), bblock.getY(), bblock.getZ()); + blocks.add(coords); + } + + if (cancelled) { + this.wasCanceled = true; + return; + } + // CraftBukkit end + iterator = this.blocks.iterator(); + + while (iterator.hasNext()) { + blockposition = (BlockPosition) iterator.next(); + Block block = this.world.getType(blockposition).getBlock(); + + world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, blockposition); // Spigot + if (flag) { + double d0 = (double) ((float) blockposition.getX() + this.world.random.nextFloat()); + double d1 = (double) ((float) blockposition.getY() + this.world.random.nextFloat()); + double d2 = (double) ((float) blockposition.getZ() + this.world.random.nextFloat()); + double d3 = d0 - this.posX; + double d4 = d1 - this.posY; + double d5 = d2 - this.posZ; + double d6 = (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); + + d3 /= d6; + d4 /= d6; + d5 /= d6; + double d7 = 0.5D / (d6 / (double) this.size + 0.1D); + + d7 *= (double) (this.world.random.nextFloat() * this.world.random.nextFloat() + 0.3F); + 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]); + } + + if (block.getMaterial() != Material.AIR) { + if (block.a(this)) { + // CraftBukkit - add yield + block.dropNaturally(this.world, blockposition, this.world.getType(blockposition), yield, 0); + } + + this.world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); + block.wasExploded(this.world, blockposition, this); + } + } + } + + if (this.a) { + iterator = this.blocks.iterator(); + + while (iterator.hasNext()) { + blockposition = (BlockPosition) iterator.next(); + if (this.world.getType(blockposition).getBlock().getMaterial() == Material.AIR && this.world.getType(blockposition.down()).getBlock().o() && this.c.nextInt(3) == 0) { + // CraftBukkit start - Ignition by explosion + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(this.world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this).isCancelled()) { + this.world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + } + // CraftBukkit end + } + } + } + + } + + public Map b() { + return this.k; + } + + public EntityLiving getSource() { + // CraftBukkit start - obtain Fireball shooter for explosion tracking + return this.source == null ? null : (this.source instanceof EntityTNTPrimed ? ((EntityTNTPrimed) this.source).getSource() : (this.source instanceof EntityLiving ? (EntityLiving) this.source : (this.source instanceof EntityFireball ? ((EntityFireball) this.source).shooter : null))); + // CraftBukkit end + } + + public void clearBlocks() { + this.blocks.clear(); + } + + public List getBlocks() { + return this.blocks; + } + + // PaperSpigot start - Optimize explosions + private float getBlockDensity(Vec3D vec3d, AxisAlignedBB aabb) { + if (!this.world.paperSpigotConfig.optimizeExplosions) { + return this.world.a(vec3d, aabb); + } + + CacheKey key = new CacheKey(this, aabb); + Float blockDensity = this.world.explosionDensityCache.get(key); + if (blockDensity == null) { + blockDensity = this.world.a(vec3d, aabb); + this.world.explosionDensityCache.put(key, blockDensity); + } + + return blockDensity; + } + + static class CacheKey { + private final World world; + private final double posX, posY, posZ; + private final double minX, minY, minZ; + private final double maxX, maxY, maxZ; + + public CacheKey(Explosion explosion, AxisAlignedBB aabb) { + this.world = explosion.world; + this.posX = explosion.posX; + this.posY = explosion.posY; + this.posZ = explosion.posZ; + this.minX = aabb.a; + this.minY = aabb.b; + this.minZ = aabb.c; + this.maxX = aabb.d; + this.maxY = aabb.e; + this.maxZ = aabb.f; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CacheKey cacheKey = (CacheKey) o; + + if (Double.compare(cacheKey.posX, posX) != 0) return false; + if (Double.compare(cacheKey.posY, posY) != 0) return false; + if (Double.compare(cacheKey.posZ, posZ) != 0) return false; + if (Double.compare(cacheKey.minX, minX) != 0) return false; + if (Double.compare(cacheKey.minY, minY) != 0) return false; + if (Double.compare(cacheKey.minZ, minZ) != 0) return false; + if (Double.compare(cacheKey.maxX, maxX) != 0) return false; + if (Double.compare(cacheKey.maxY, maxY) != 0) return false; + if (Double.compare(cacheKey.maxZ, maxZ) != 0) return false; + return world.equals(cacheKey.world); + } + + @Override + public int hashCode() { + int result; + long temp; + result = world.hashCode(); + temp = Double.doubleToLongBits(posX); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(posY); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(posZ); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(minX); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(minY); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(minZ); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(maxX); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(maxY); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(maxZ); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } + } + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/FileIOThread.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/FileIOThread.java new file mode 100644 index 0000000..c9b3bf4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/FileIOThread.java @@ -0,0 +1,76 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Collections; +import java.util.List; + +public class FileIOThread implements Runnable { + + private static final FileIOThread a = new FileIOThread(); + private List b = Collections.synchronizedList(Lists.newArrayList()); + private volatile long c; + private volatile long d; + private volatile boolean e; + + private FileIOThread() { + Thread thread = new Thread(this, "File IO Thread"); + + thread.setPriority(1); + thread.start(); + } + + public static FileIOThread a() { + return FileIOThread.a; + } + + public void run() { + while (true) { + this.c(); + } + } + + private void c() { + for (int i = 0; i < this.b.size(); ++i) { + IAsyncChunkSaver iasyncchunksaver = (IAsyncChunkSaver) this.b.get(i); + boolean flag = iasyncchunksaver.c(); + + if (!flag) { + this.b.remove(i--); + ++this.d; + } + + /* // Spigot start - don't sleep in between chunks so we unload faster. + try { + Thread.sleep(this.e ? 0L : 10L); + } catch (InterruptedException interruptedexception) { + interruptedexception.printStackTrace(); + } */ // Spigot end + } + + if (this.b.isEmpty()) { + try { + Thread.sleep(25L); + } catch (InterruptedException interruptedexception1) { + interruptedexception1.printStackTrace(); + } + } + + } + + public void a(IAsyncChunkSaver iasyncchunksaver) { + if (!this.b.contains(iasyncchunksaver)) { + ++this.c; + this.b.add(iasyncchunksaver); + } + } + + public void b() throws InterruptedException { + this.e = true; + + while (this.c != this.d) { + Thread.sleep(10L); + } + + this.e = false; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/FoodMetaData.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/FoodMetaData.java new file mode 100644 index 0000000..d0bcad6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/FoodMetaData.java @@ -0,0 +1,120 @@ +package net.minecraft.server; + +public class FoodMetaData { + + public int foodLevel = 20; + public float saturationLevel = 5.0F; + public float exhaustionLevel; + private int foodTickTimer; + private EntityHuman entityhuman; // CraftBukkit + private int e = 20; + + public FoodMetaData() { throw new AssertionError("Whoopsie, we missed the bukkit."); } // CraftBukkit start - throw an error + + // CraftBukkit start - added EntityHuman constructor + public FoodMetaData(EntityHuman entityhuman) { + org.apache.commons.lang.Validate.notNull(entityhuman); + this.entityhuman = entityhuman; + } + // CraftBukkit end + + public void eat(int i, float f) { + this.foodLevel = Math.min(i + this.foodLevel, 20); + this.saturationLevel = Math.min(this.saturationLevel + (float) i * f * 2.0F, (float) this.foodLevel); + } + + public void a(ItemFood itemfood, ItemStack itemstack) { + // CraftBukkit start + int oldFoodLevel = foodLevel; + + org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, itemfood.getNutrition(itemstack) + oldFoodLevel); + + if (!event.isCancelled()) { + this.eat(event.getFoodLevel() - oldFoodLevel, itemfood.getSaturationModifier(itemstack)); + } + + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel)); + // CraftBukkit end + } + + public void a(EntityHuman entityhuman) { + EnumDifficulty enumdifficulty = entityhuman.world.getDifficulty(); + + this.e = this.foodLevel; + if (this.exhaustionLevel > 4.0F) { + this.exhaustionLevel -= 4.0F; + if (this.saturationLevel > 0.0F) { + this.saturationLevel = Math.max(this.saturationLevel - 1.0F, 0.0F); + } else if (enumdifficulty != EnumDifficulty.PEACEFUL) { + // CraftBukkit start + org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityhuman, Math.max(this.foodLevel - 1, 0)); + + if (!event.isCancelled()) { + this.foodLevel = event.getFoodLevel(); + } + + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), this.foodLevel, this.saturationLevel)); + // CraftBukkit end + } + } + + if (entityhuman.world.getGameRules().getBoolean("naturalRegeneration") && this.foodLevel >= 18 && entityhuman.cm()) { + ++this.foodTickTimer; + if (this.foodTickTimer >= 80) { + // CraftBukkit - added RegainReason + entityhuman.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.SATIATED); + this.a(entityhuman.world.spigotConfig.regenExhaustion); // Spigot - Change to use configurable value + this.foodTickTimer = 0; + } + } else if (this.foodLevel <= 0) { + ++this.foodTickTimer; + if (this.foodTickTimer >= 80) { + if (entityhuman.getHealth() > 10.0F || enumdifficulty == EnumDifficulty.HARD || entityhuman.getHealth() > 1.0F && enumdifficulty == EnumDifficulty.NORMAL) { + entityhuman.damageEntity(DamageSource.STARVE, 1.0F); + } + + this.foodTickTimer = 0; + } + } else { + this.foodTickTimer = 0; + } + + } + + public void a(NBTTagCompound nbttagcompound) { + if (nbttagcompound.hasKeyOfType("foodLevel", 99)) { + this.foodLevel = nbttagcompound.getInt("foodLevel"); + this.foodTickTimer = nbttagcompound.getInt("foodTickTimer"); + this.saturationLevel = nbttagcompound.getFloat("foodSaturationLevel"); + this.exhaustionLevel = nbttagcompound.getFloat("foodExhaustionLevel"); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setInt("foodLevel", this.foodLevel); + nbttagcompound.setInt("foodTickTimer", this.foodTickTimer); + nbttagcompound.setFloat("foodSaturationLevel", this.saturationLevel); + nbttagcompound.setFloat("foodExhaustionLevel", this.exhaustionLevel); + } + + public int getFoodLevel() { + return this.foodLevel; + } + + public boolean c() { + return this.foodLevel < 20; + } + + public void a(float f) { + this.exhaustionLevel = Math.min(this.exhaustionLevel + f, 40.0F); + } + + public float getSaturationLevel() { + return this.saturationLevel; + } + + public void a(int i) { + this.foodLevel = i; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/GameProfileBanEntry.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/GameProfileBanEntry.java new file mode 100644 index 0000000..16fe481 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/GameProfileBanEntry.java @@ -0,0 +1,56 @@ +package net.minecraft.server; + +import com.google.gson.JsonObject; +import com.mojang.authlib.GameProfile; +import java.util.Date; +import java.util.UUID; + +public class GameProfileBanEntry extends ExpirableListEntry { + + public GameProfileBanEntry(GameProfile gameprofile) { + this(gameprofile, (Date) null, (String) null, (Date) null, (String) null); + } + + public GameProfileBanEntry(GameProfile gameprofile, Date date, String s, Date date1, String s1) { + super(gameprofile, date, s, date1, s1); // Spigot + } + + public GameProfileBanEntry(JsonObject jsonobject) { + super(b(jsonobject), jsonobject); + } + + protected void a(JsonObject jsonobject) { + if (this.getKey() != null) { + jsonobject.addProperty("uuid", ((GameProfile) this.getKey()).getId() == null ? "" : ((GameProfile) this.getKey()).getId().toString()); + jsonobject.addProperty("name", ((GameProfile) this.getKey()).getName()); + super.a(jsonobject); + } + } + + private static GameProfile b(JsonObject jsonobject) { + // Spigot start + // this whole method has to be reworked to account for the fact Bukkit only accepts UUID bans and gives no way for usernames to be stored! + UUID uuid = null; + String name = null; + if (jsonobject.has("uuid")) { + String s = jsonobject.get("uuid").getAsString(); + + try { + uuid = UUID.fromString(s); + } catch (Throwable throwable) { + } + + } + if ( jsonobject.has("name")) + { + name = jsonobject.get("name").getAsString(); + } + if ( uuid != null || name != null ) + { + return new GameProfile( uuid, name ); + } else { + return null; + } + // Spigot End + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/GenericAttributes.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/GenericAttributes.java new file mode 100644 index 0000000..0cc3e2f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/GenericAttributes.java @@ -0,0 +1,116 @@ +package net.minecraft.server; + +import java.util.Collection; +import java.util.Iterator; +import java.util.UUID; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class GenericAttributes { + + private static final Logger f = LogManager.getLogger(); + // Spigot start + public static final IAttribute maxHealth = (new AttributeRanged((IAttribute) null, "generic.maxHealth", 20.0D, 0.1D, org.spigotmc.SpigotConfig.maxHealth)).a("Max Health").a(true); + public static final IAttribute FOLLOW_RANGE = (new AttributeRanged((IAttribute) null, "generic.followRange", 32.0D, 0.0D, 2048.0D)).a("Follow Range"); + public static final IAttribute c = (new AttributeRanged((IAttribute) null, "generic.knockbackResistance", 0.0D, 0.0D, 1.0D)).a("Knockback Resistance"); + public static final IAttribute MOVEMENT_SPEED = (new AttributeRanged((IAttribute) null, "generic.movementSpeed", 0.699999988079071D, 0.0D, org.spigotmc.SpigotConfig.movementSpeed)).a("Movement Speed").a(true); + public static final IAttribute ATTACK_DAMAGE = new AttributeRanged((IAttribute) null, "generic.attackDamage", 2.0D, 0.0D, org.spigotmc.SpigotConfig.attackDamage); + // Spigot end + + public static NBTTagList a(AttributeMapBase attributemapbase) { + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = attributemapbase.a().iterator(); + + while (iterator.hasNext()) { + AttributeInstance attributeinstance = (AttributeInstance) iterator.next(); + + nbttaglist.add(a(attributeinstance)); + } + + return nbttaglist; + } + + private static NBTTagCompound a(AttributeInstance attributeinstance) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + IAttribute iattribute = attributeinstance.getAttribute(); + + nbttagcompound.setString("Name", iattribute.getName()); + nbttagcompound.setDouble("Base", attributeinstance.b()); + Collection collection = attributeinstance.c(); + + if (collection != null && !collection.isEmpty()) { + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + AttributeModifier attributemodifier = (AttributeModifier) iterator.next(); + + if (attributemodifier.e()) { + nbttaglist.add(a(attributemodifier)); + } + } + + nbttagcompound.set("Modifiers", nbttaglist); + } + + return nbttagcompound; + } + + private static NBTTagCompound a(AttributeModifier attributemodifier) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + nbttagcompound.setString("Name", attributemodifier.b()); + nbttagcompound.setDouble("Amount", attributemodifier.d()); + nbttagcompound.setInt("Operation", attributemodifier.c()); + nbttagcompound.setLong("UUIDMost", attributemodifier.a().getMostSignificantBits()); + nbttagcompound.setLong("UUIDLeast", attributemodifier.a().getLeastSignificantBits()); + return nbttagcompound; + } + + public static void a(AttributeMapBase attributemapbase, NBTTagList nbttaglist) { + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound = nbttaglist.get(i); + AttributeInstance attributeinstance = attributemapbase.a(nbttagcompound.getString("Name")); + + if (attributeinstance != null) { + a(attributeinstance, nbttagcompound); + } else { + GenericAttributes.f.warn("Ignoring unknown attribute \'" + nbttagcompound.getString("Name") + "\'"); + } + } + + } + + private static void a(AttributeInstance attributeinstance, NBTTagCompound nbttagcompound) { + attributeinstance.setValue(nbttagcompound.getDouble("Base")); + if (nbttagcompound.hasKeyOfType("Modifiers", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("Modifiers", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + AttributeModifier attributemodifier = a(nbttaglist.get(i)); + + if (attributemodifier != null) { + AttributeModifier attributemodifier1 = attributeinstance.a(attributemodifier.a()); + + if (attributemodifier1 != null) { + attributeinstance.c(attributemodifier1); + } + + attributeinstance.b(attributemodifier); + } + } + } + + } + + public static AttributeModifier a(NBTTagCompound nbttagcompound) { + UUID uuid = new UUID(nbttagcompound.getLong("UUIDMost"), nbttagcompound.getLong("UUIDLeast")); + + try { + return new AttributeModifier(uuid, nbttagcompound.getString("Name"), nbttagcompound.getDouble("Amount"), nbttagcompound.getInt("Operation")); + } catch (Exception exception) { + GenericAttributes.f.warn("Unable to create attribute: " + exception.getMessage()); + return null; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/HandshakeListener.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/HandshakeListener.java new file mode 100644 index 0000000..64f6a9b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/HandshakeListener.java @@ -0,0 +1,131 @@ +package net.minecraft.server; + +// CraftBukkit start +import java.net.InetAddress; +import java.util.HashMap; +// CraftBukkit end + +public class HandshakeListener implements PacketHandshakingInListener { + + private static final com.google.gson.Gson gson = new com.google.gson.Gson(); // Spigot + // CraftBukkit start - add fields + private static final HashMap throttleTracker = new HashMap(); + private static int throttleCounter = 0; + // CraftBukkit end + + private final MinecraftServer a; + private final NetworkManager b; + + public HandshakeListener(MinecraftServer minecraftserver, NetworkManager networkmanager) { + this.a = minecraftserver; + this.b = networkmanager; + } + + public void a(PacketHandshakingInSetProtocol packethandshakinginsetprotocol) { + switch (HandshakeListener.SyntheticClass_1.a[packethandshakinginsetprotocol.a().ordinal()]) { + case 1: + this.b.a(EnumProtocol.LOGIN); + ChatComponentText chatcomponenttext; + + // CraftBukkit start - Connection throttle + try { + long currentTime = System.currentTimeMillis(); + long connectionThrottle = MinecraftServer.getServer().server.getConnectionThrottle(); + InetAddress address = ((java.net.InetSocketAddress) this.b.getSocketAddress()).getAddress(); + + synchronized (throttleTracker) { + if (throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - throttleTracker.get(address) < connectionThrottle) { + throttleTracker.put(address, currentTime); + chatcomponenttext = new ChatComponentText("Connection throttled! Please wait before reconnecting."); + this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext)); + this.b.close(chatcomponenttext); + return; + } + + throttleTracker.put(address, currentTime); + throttleCounter++; + if (throttleCounter > 200) { + throttleCounter = 0; + + // Cleanup stale entries + java.util.Iterator iter = throttleTracker.entrySet().iterator(); + while (iter.hasNext()) { + java.util.Map.Entry entry = (java.util.Map.Entry) iter.next(); + if (entry.getValue() > connectionThrottle) { + iter.remove(); + } + } + } + } + } catch (Throwable t) { + org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); + } + // CraftBukkit end + + if (packethandshakinginsetprotocol.b() > 47) { + chatcomponenttext = new ChatComponentText( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage, "1.8.8" ) ); // Spigot + this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext)); + this.b.close(chatcomponenttext); + } else if (packethandshakinginsetprotocol.b() < 47) { + chatcomponenttext = new ChatComponentText( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage, "1.8.8" ) ); // Spigot + this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext)); + this.b.close(chatcomponenttext); + } else { + this.b.a((PacketListener) (new LoginListener(this.a, this.b))); + // Spigot Start + if (org.spigotmc.SpigotConfig.bungee) { + String[] split = packethandshakinginsetprotocol.hostname.split("\00"); + if ( split.length == 3 || split.length == 4 ) { + packethandshakinginsetprotocol.hostname = split[0]; + b.l = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) b.getSocketAddress()).getPort()); + b.spoofedUUID = com.mojang.util.UUIDTypeAdapter.fromString( split[2] ); + } else + { + chatcomponenttext = new ChatComponentText("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"); + this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext)); + this.b.close(chatcomponenttext); + return; + } + if ( split.length == 4 ) + { + b.spoofedProfile = gson.fromJson(split[3], com.mojang.authlib.properties.Property[].class); + } + } + // Spigot End + ((LoginListener) this.b.getPacketListener()).hostname = packethandshakinginsetprotocol.hostname + ":" + packethandshakinginsetprotocol.port; // CraftBukkit - set hostname + } + break; + + case 2: + this.b.a(EnumProtocol.STATUS); + this.b.a((PacketListener) (new PacketStatusListener(this.a, this.b))); + break; + + default: + throw new UnsupportedOperationException("Invalid intention " + packethandshakinginsetprotocol.a()); + } + + } + + public void a(IChatBaseComponent ichatbasecomponent) {} + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumProtocol.values().length]; + + static { + try { + HandshakeListener.SyntheticClass_1.a[EnumProtocol.LOGIN.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + HandshakeListener.SyntheticClass_1.a[EnumProtocol.STATUS.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IBlockAccess.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IBlockAccess.java new file mode 100644 index 0000000..01df112 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IBlockAccess.java @@ -0,0 +1,16 @@ +package net.minecraft.server; + +public interface IBlockAccess { + TileEntity getTileEntity(BlockPosition blockposition); + + IBlockData getType(BlockPosition blockposition); + // Mythic - Reduce churn rate + IBlockData getType(int x, int y, int z); + + boolean isEmpty(BlockPosition blockposition); + // Mythic - Reduce churn rate + boolean isEmpty(int x, int y, int z); + + int getBlockPower(BlockPosition blockposition, EnumDirection enumdirection); +} + diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IBlockState.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IBlockState.java new file mode 100644 index 0000000..fdb0cf8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IBlockState.java @@ -0,0 +1,36 @@ +package net.minecraft.server; + +import java.util.Collection; + +// TacoSpigot start +import net.techcable.tacospigot.Indexer; +// TacoSpigot end + +public interface IBlockState> { + + String a(); + + Collection c(); + + Class b(); + + String a(T t0); + + // TacoSpigot start + @SuppressWarnings("Convert2Lambda") // We have to use anon for performance reasons :/ + public static final Indexer INDEXER = new Indexer() { + @Override + public int getId(IBlockState state) { + return state.getId(); + } + }; + + public default void tryInitId() {} + + public int getId(); + + public int getValueId(T value); + + public T getByValueId(int id); + // TacoSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IDataManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IDataManager.java new file mode 100644 index 0000000..09597aa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IDataManager.java @@ -0,0 +1,28 @@ +package net.minecraft.server; + +import java.io.File; + +public interface IDataManager { + + WorldData getWorldData(); + + void checkSession() throws ExceptionWorldConflict; + + IChunkLoader createChunkLoader(WorldProvider worldprovider); + + void saveWorldData(WorldData worlddata, NBTTagCompound nbttagcompound); + + void saveWorldData(WorldData worlddata); + + IPlayerFileData getPlayerFileData(); + + void a(); + + File getDirectory(); + + File getDataFile(String s); + + String g(); + + java.util.UUID getUUID(); // CraftBukkit +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IInventory.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IInventory.java new file mode 100644 index 0000000..52b8fc4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IInventory.java @@ -0,0 +1,52 @@ +package net.minecraft.server; + +import org.bukkit.craftbukkit.entity.CraftHumanEntity; // CraftBukkit + +public interface IInventory extends INamableTileEntity { + + int getSize(); + + ItemStack getItem(int i); + + ItemStack splitStack(int i, int j); + + ItemStack splitWithoutUpdate(int i); + + void setItem(int i, ItemStack itemstack); + + int getMaxStackSize(); + + void update(); + + boolean a(EntityHuman entityhuman); + + void startOpen(EntityHuman entityhuman); + + void closeContainer(EntityHuman entityhuman); + + boolean b(int i, ItemStack itemstack); + + int getProperty(int i); + + void b(int i, int j); + + int g(); + + void l(); + + // CraftBukkit start + ItemStack[] getContents(); + + void onOpen(CraftHumanEntity who); + + void onClose(CraftHumanEntity who); + + java.util.List getViewers(); + + org.bukkit.inventory.InventoryHolder getOwner(); + + void setMaxStackSize(int size); + + int MAX_STACK = 64; + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IRecipe.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IRecipe.java new file mode 100644 index 0000000..ffc65a2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IRecipe.java @@ -0,0 +1,18 @@ +package net.minecraft.server; + +public interface IRecipe { + + boolean a(InventoryCrafting inventorycrafting, World world); + + ItemStack craftItem(InventoryCrafting inventorycrafting); + + int a(); + + ItemStack b(); + + ItemStack[] b(InventoryCrafting inventorycrafting); + + org.bukkit.inventory.Recipe toBukkitRecipe(); // CraftBukkit + + java.util.List getIngredients(); // Spigot +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IntCache.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IntCache.java new file mode 100644 index 0000000..95060a4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/IntCache.java @@ -0,0 +1,63 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.List; + +public class IntCache { + + private static int a = 256; + private static List b = Lists.newArrayList(); + private static List c = Lists.newArrayList(); + private static List d = Lists.newArrayList(); + private static List e = Lists.newArrayList(); + + public static synchronized int[] a(int i) { + int[] aint; + + if (i <= 256) { + if (IntCache.b.isEmpty()) { + aint = new int[256]; + if (c.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.c.add(aint); + return aint; + } else { + aint = (int[]) IntCache.b.remove(IntCache.b.size() - 1); + if (c.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.c.add(aint); + return aint; + } + } else if (i > IntCache.a) { + IntCache.a = i; + IntCache.d.clear(); + IntCache.e.clear(); + aint = new int[IntCache.a]; + if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.e.add(aint); + return aint; + } else if (IntCache.d.isEmpty()) { + aint = new int[IntCache.a]; + if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.e.add(aint); + return aint; + } else { + aint = (int[]) IntCache.d.remove(IntCache.d.size() - 1); + if (e.size() < org.spigotmc.SpigotConfig.intCacheLimit) IntCache.e.add(aint); + return aint; + } + } + + public static synchronized void a() { + if (!IntCache.d.isEmpty()) { + IntCache.d.remove(IntCache.d.size() - 1); + } + + if (!IntCache.b.isEmpty()) { + IntCache.b.remove(IntCache.b.size() - 1); + } + + IntCache.d.addAll(IntCache.e); + IntCache.b.addAll(IntCache.c); + IntCache.e.clear(); + IntCache.c.clear(); + } + + public static synchronized String b() { + return "cache: " + IntCache.d.size() + ", tcache: " + IntCache.b.size() + ", allocated: " + IntCache.e.size() + ", tallocated: " + IntCache.c.size(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryCraftResult.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryCraftResult.java new file mode 100644 index 0000000..7802503 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryCraftResult.java @@ -0,0 +1,117 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +// CraftBukkit end + +public class InventoryCraftResult implements IInventory { + + private ItemStack[] items = new ItemStack[1]; + + // CraftBukkit start + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public org.bukkit.inventory.InventoryHolder getOwner() { + return null; // Result slots don't get an owner + } + + // Don't need a transaction; the InventoryCrafting keeps track of it for us + public void onOpen(CraftHumanEntity who) {} + public void onClose(CraftHumanEntity who) {} + public java.util.List getViewers() { + return new java.util.ArrayList(); + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public InventoryCraftResult() {} + + public int getSize() { + return 1; + } + + public ItemStack getItem(int i) { + return this.items[0]; + } + + public String getName() { + return "Result"; + } + + public boolean hasCustomName() { + return false; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return (IChatBaseComponent) (this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatMessage(this.getName(), new Object[0])); + } + + public ItemStack splitStack(int i, int j) { + if (this.items[0] != null) { + ItemStack itemstack = this.items[0]; + + this.items[0] = null; + return itemstack; + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.items[0] != null) { + ItemStack itemstack = this.items[0]; + + this.items[0] = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + this.items[0] = itemstack; + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public void update() {} + + public boolean a(EntityHuman entityhuman) { + return true; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryCrafting.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryCrafting.java new file mode 100644 index 0000000..933d39c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryCrafting.java @@ -0,0 +1,174 @@ +package net.minecraft.server; + +// CraftBukkit start +import java.util.List; + +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; +// CraftBukkit end + +public class InventoryCrafting implements IInventory { + + private final ItemStack[] items; + private final int b; + private final int c; + private final Container d; + + // CraftBukkit start - add fields + public List transaction = new java.util.ArrayList(); + public IRecipe currentRecipe; + public IInventory resultInventory; + private EntityHuman owner; + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public InventoryType getInvType() { + return items.length == 4 ? InventoryType.CRAFTING : InventoryType.WORKBENCH; + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public org.bukkit.inventory.InventoryHolder getOwner() { + return (owner == null) ? null : owner.getBukkitEntity(); + } + + public void setMaxStackSize(int size) { + maxStack = size; + resultInventory.setMaxStackSize(size); + } + + public InventoryCrafting(Container container, int i, int j, EntityHuman player) { + this(container, i, j); + this.owner = player; + } + // CraftBukkit end + + public InventoryCrafting(Container container, int i, int j) { + int k = i * j; + + this.items = new ItemStack[k]; + this.d = container; + this.b = i; + this.c = j; + } + + public int getSize() { + return this.items.length; + } + + public ItemStack getItem(int i) { + return i >= this.getSize() ? null : this.items[i]; + } + + public ItemStack c(int i, int j) { + return i >= 0 && i < this.b && j >= 0 && j <= this.c ? this.getItem(i + j * this.b) : null; + } + + public String getName() { + return "container.crafting"; + } + + public boolean hasCustomName() { + return false; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return (IChatBaseComponent) (this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatMessage(this.getName(), new Object[0])); + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.items[i] != null) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public ItemStack splitStack(int i, int j) { + if (this.items[i] != null) { + ItemStack itemstack; + + if (this.items[i].count <= j) { + itemstack = this.items[i]; + this.items[i] = null; + this.d.a((IInventory) this); + return itemstack; + } else { + itemstack = this.items[i].cloneAndSubtract(j); + if (this.items[i].count == 0) { + this.items[i] = null; + } + + this.d.a((IInventory) this); + return itemstack; + } + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + this.items[i] = itemstack; + this.d.a((IInventory) this); + } + + public int getMaxStackSize() { + return 64; + } + + public void update() {} + + public boolean a(EntityHuman entityhuman) { + return true; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } + + public int h() { + return this.c; + } + + public int i() { + return this.b; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryEnderChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryEnderChest.java new file mode 100644 index 0000000..22c9b0b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryEnderChest.java @@ -0,0 +1,111 @@ +package net.minecraft.server; + +// CraftBukkit start +import java.util.List; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +// CraftBukkit end + +public class InventoryEnderChest extends InventorySubcontainer { + + private TileEntityEnderChest a; + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + public org.bukkit.entity.Player player; + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public org.bukkit.inventory.InventoryHolder getOwner() { + return this.player; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + + public int getMaxStackSize() { + return maxStack; + } + // CraftBukkit end + + public InventoryEnderChest() { + super("container.enderchest", false, 27); + } + + public void a(TileEntityEnderChest tileentityenderchest) { + this.a = tileentityenderchest; + } + + public void a(NBTTagList nbttaglist) { + int i; + + for (i = 0; i < this.getSize(); ++i) { + this.setItem(i, (ItemStack) null); + } + + for (i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound = nbttaglist.get(i); + int j = nbttagcompound.getByte("Slot") & 255; + + if (j >= 0 && j < this.getSize()) { + this.setItem(j, ItemStack.createStack(nbttagcompound)); + } + } + + } + + public NBTTagList h() { + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.getSize(); ++i) { + ItemStack itemstack = this.getItem(i); + + if (itemstack != null) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + nbttagcompound.setByte("Slot", (byte) i); + itemstack.save(nbttagcompound); + nbttaglist.add(nbttagcompound); + } + } + + return nbttaglist; + } + + public boolean a(EntityHuman entityhuman) { + return this.a != null && !this.a.a(entityhuman) ? false : super.a(entityhuman); + } + + public void startOpen(EntityHuman entityhuman) { + if (this.a != null) { + this.a.b(); + } + + super.startOpen(entityhuman); + } + + public void closeContainer(EntityHuman entityhuman) { + if (this.a != null) { + this.a.d(); + } + + super.closeContainer(entityhuman); + this.a = null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryHorseChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryHorseChest.java new file mode 100644 index 0000000..5e913a5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryHorseChest.java @@ -0,0 +1,60 @@ +package net.minecraft.server; + +// CraftBukkit start +import java.util.List; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +// CraftBukkit end + +public class InventoryHorseChest extends InventorySubcontainer { + + public InventoryHorseChest(String s, int i) { + super(s, false, i); + } + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private EntityHorse horse; + private int maxStack = MAX_STACK; + + public InventoryHorseChest(String s, int i, EntityHorse horse) { + super(s, false, i, (org.bukkit.craftbukkit.entity.CraftHorse) horse.getBukkitEntity()); + this.horse = horse; + } + + @Override + public ItemStack[] getContents() { + return this.items; + } + + @Override + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + @Override + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + @Override + public List getViewers() { + return transaction; + } + + @Override + public org.bukkit.inventory.InventoryHolder getOwner() { + return (org.bukkit.entity.Horse) this.horse.getBukkitEntity(); + } + + @Override + public void setMaxStackSize(int size) { + maxStack = size; + } + + @Override + public int getMaxStackSize() { + return maxStack; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryLargeChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryLargeChest.java new file mode 100644 index 0000000..7e83ce3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryLargeChest.java @@ -0,0 +1,176 @@ +package net.minecraft.server; + +// CraftBukkit start +import java.util.List; + +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +// CraftBukkit end + +public class InventoryLargeChest implements ITileInventory { + + private String a; + public ITileInventory left; + public ITileInventory right; + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + + public ItemStack[] getContents() { + ItemStack[] result = new ItemStack[this.getSize()]; + for (int i = 0; i < result.length; i++) { + result[i] = this.getItem(i); + } + return result; + } + + public void onOpen(CraftHumanEntity who) { + this.left.onOpen(who); + this.right.onOpen(who); + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + this.left.onClose(who); + this.right.onClose(who); + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public org.bukkit.inventory.InventoryHolder getOwner() { + return null; // This method won't be called since CraftInventoryDoubleChest doesn't defer to here + } + + public void setMaxStackSize(int size) { + this.left.setMaxStackSize(size); + this.right.setMaxStackSize(size); + } + // CraftBukkit end + + public InventoryLargeChest(String s, ITileInventory itileinventory, ITileInventory itileinventory1) { + this.a = s; + if (itileinventory == null) { + itileinventory = itileinventory1; + } + + if (itileinventory1 == null) { + itileinventory1 = itileinventory; + } + + this.left = itileinventory; + this.right = itileinventory1; + if (itileinventory.r_()) { + itileinventory1.a(itileinventory.i()); + } else if (itileinventory1.r_()) { + itileinventory.a(itileinventory1.i()); + } + + } + + public int getSize() { + return this.left.getSize() + this.right.getSize(); + } + + public boolean a(IInventory iinventory) { + return this.left == iinventory || this.right == iinventory; + } + + public String getName() { + return this.left.hasCustomName() ? this.left.getName() : (this.right.hasCustomName() ? this.right.getName() : this.a); + } + + public boolean hasCustomName() { + return this.left.hasCustomName() || this.right.hasCustomName(); + } + + public IChatBaseComponent getScoreboardDisplayName() { + return (IChatBaseComponent) (this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatMessage(this.getName(), new Object[0])); + } + + public ItemStack getItem(int i) { + return i >= this.left.getSize() ? this.right.getItem(i - this.left.getSize()) : this.left.getItem(i); + } + + public ItemStack splitStack(int i, int j) { + return i >= this.left.getSize() ? this.right.splitStack(i - this.left.getSize(), j) : this.left.splitStack(i, j); + } + + public ItemStack splitWithoutUpdate(int i) { + return i >= this.left.getSize() ? this.right.splitWithoutUpdate(i - this.left.getSize()) : this.left.splitWithoutUpdate(i); + } + + public void setItem(int i, ItemStack itemstack) { + if (i >= this.left.getSize()) { + this.right.setItem(i - this.left.getSize(), itemstack); + } else { + this.left.setItem(i, itemstack); + } + + } + + public int getMaxStackSize() { + return Math.min(this.left.getMaxStackSize(), this.right.getMaxStackSize()); // CraftBukkit - check both sides + } + + public void update() { + this.left.update(); + this.right.update(); + } + + public boolean a(EntityHuman entityhuman) { + return this.left.a(entityhuman) && this.right.a(entityhuman); + } + + public void startOpen(EntityHuman entityhuman) { + this.left.startOpen(entityhuman); + this.right.startOpen(entityhuman); + } + + public void closeContainer(EntityHuman entityhuman) { + this.left.closeContainer(entityhuman); + this.right.closeContainer(entityhuman); + } + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public boolean r_() { + return this.left.r_() || this.right.r_(); + } + + public void a(ChestLock chestlock) { + this.left.a(chestlock); + this.right.a(chestlock); + } + + public ChestLock i() { + return this.left.i(); + } + + public String getContainerName() { + return this.left.getContainerName(); + } + + public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerChest(playerinventory, this, entityhuman); + } + + public void l() { + this.left.l(); + this.right.l(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryMerchant.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryMerchant.java new file mode 100644 index 0000000..66a3bab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventoryMerchant.java @@ -0,0 +1,215 @@ +package net.minecraft.server; + +// CraftBukkit start +import java.util.List; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.entity.CraftVillager; +import org.bukkit.entity.HumanEntity; +// CraftBukkit end + +public class InventoryMerchant implements IInventory { + + private final IMerchant merchant; + private ItemStack[] itemsInSlots = new ItemStack[3]; + private final EntityHuman player; + private MerchantRecipe recipe; + private int e; + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.itemsInSlots; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public void setMaxStackSize(int i) { + maxStack = i; + } + + public org.bukkit.inventory.InventoryHolder getOwner() { + return (CraftVillager) ((EntityVillager) this.merchant).getBukkitEntity(); + } + // CraftBukkit end + + public InventoryMerchant(EntityHuman entityhuman, IMerchant imerchant) { + this.player = entityhuman; + this.merchant = imerchant; + } + + public int getSize() { + return this.itemsInSlots.length; + } + + public ItemStack getItem(int i) { + return this.itemsInSlots[i]; + } + + public ItemStack splitStack(int i, int j) { + if (this.itemsInSlots[i] != null) { + ItemStack itemstack; + + if (i == 2) { + itemstack = this.itemsInSlots[i]; + this.itemsInSlots[i] = null; + return itemstack; + } else if (this.itemsInSlots[i].count <= j) { + itemstack = this.itemsInSlots[i]; + this.itemsInSlots[i] = null; + if (this.e(i)) { + this.h(); + } + + return itemstack; + } else { + itemstack = this.itemsInSlots[i].cloneAndSubtract(j); + if (this.itemsInSlots[i].count == 0) { + this.itemsInSlots[i] = null; + } + + if (this.e(i)) { + this.h(); + } + + return itemstack; + } + } else { + return null; + } + } + + private boolean e(int i) { + return i == 0 || i == 1; + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.itemsInSlots[i] != null) { + ItemStack itemstack = this.itemsInSlots[i]; + + this.itemsInSlots[i] = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + this.itemsInSlots[i] = itemstack; + if (itemstack != null && itemstack.count > this.getMaxStackSize()) { + itemstack.count = this.getMaxStackSize(); + } + + if (this.e(i)) { + this.h(); + } + + } + + public String getName() { + return "mob.villager"; + } + + public boolean hasCustomName() { + return false; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return (IChatBaseComponent) (this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatMessage(this.getName(), new Object[0])); + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { + return this.merchant.v_() == entityhuman; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public void update() { + this.h(); + } + + public void h() { + this.recipe = null; + ItemStack itemstack = this.itemsInSlots[0]; + ItemStack itemstack1 = this.itemsInSlots[1]; + + if (itemstack == null) { + itemstack = itemstack1; + itemstack1 = null; + } + + if (itemstack == null) { + this.setItem(2, (ItemStack) null); + } else { + MerchantRecipeList merchantrecipelist = this.merchant.getOffers(this.player); + + if (merchantrecipelist != null) { + MerchantRecipe merchantrecipe = merchantrecipelist.a(itemstack, itemstack1, this.e); + + if (merchantrecipe != null && !merchantrecipe.h()) { + this.recipe = merchantrecipe; + this.setItem(2, merchantrecipe.getBuyItem3().cloneItemStack()); + } else if (itemstack1 != null) { + merchantrecipe = merchantrecipelist.a(itemstack1, itemstack, this.e); + if (merchantrecipe != null && !merchantrecipe.h()) { + this.recipe = merchantrecipe; + this.setItem(2, merchantrecipe.getBuyItem3().cloneItemStack()); + } else { + this.setItem(2, (ItemStack) null); + } + } else { + this.setItem(2, (ItemStack) null); + } + } + } + + this.merchant.a_(this.getItem(2)); + } + + public MerchantRecipe getRecipe() { + return this.recipe; + } + + public void d(int i) { + this.e = i; + this.h(); + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public void l() { + for (int i = 0; i < this.itemsInSlots.length; ++i) { + this.itemsInSlots[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventorySubcontainer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventorySubcontainer.java new file mode 100644 index 0000000..caab635 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/InventorySubcontainer.java @@ -0,0 +1,219 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.List; + +// CraftBukkit start +import java.util.List; + +import net.jafama.FastMath; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +// CraftBukkit end + +public class InventorySubcontainer implements IInventory { + + private String a; + private int b; + public ItemStack[] items; + private List d; + private boolean e; + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; + protected org.bukkit.inventory.InventoryHolder bukkitOwner; + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public void setMaxStackSize(int i) { + maxStack = i; + } + + public org.bukkit.inventory.InventoryHolder getOwner() { + return bukkitOwner; + } + + public InventorySubcontainer(String s, boolean flag, int i) { + this(s, flag, i, null); + } + + public InventorySubcontainer(String s, boolean flag, int i, org.bukkit.inventory.InventoryHolder owner) { // Added argument + this.bukkitOwner = owner; + // CraftBukkit end + this.a = s; + this.e = flag; + this.b = i; + this.items = new ItemStack[i]; + } + + public void a(IInventoryListener iinventorylistener) { + if (this.d == null) { + this.d = Lists.newArrayList(); + } + + this.d.add(iinventorylistener); + } + + public void b(IInventoryListener iinventorylistener) { + this.d.remove(iinventorylistener); + } + + public ItemStack getItem(int i) { + return i >= 0 && i < this.items.length ? this.items[i] : null; + } + + public ItemStack splitStack(int i, int j) { + if (this.items[i] != null) { + ItemStack itemstack; + + if (this.items[i].count <= j) { + itemstack = this.items[i]; + this.items[i] = null; + this.update(); + return itemstack; + } else { + itemstack = this.items[i].cloneAndSubtract(j); + if (this.items[i].count == 0) { + this.items[i] = null; + } + + this.update(); + return itemstack; + } + } else { + return null; + } + } + + public ItemStack a(ItemStack itemstack) { + ItemStack itemstack1 = itemstack.cloneItemStack(); + + for (int i = 0; i < this.b; ++i) { + ItemStack itemstack2 = this.getItem(i); + + if (itemstack2 == null) { + this.setItem(i, itemstack1); + this.update(); + return null; + } + + if (ItemStack.c(itemstack2, itemstack1)) { + int j = FastMath.min(this.getMaxStackSize(), itemstack2.getMaxStackSize()); + int k = FastMath.min(itemstack1.count, j - itemstack2.count); + + if (k > 0) { + itemstack2.count += k; + itemstack1.count -= k; + if (itemstack1.count <= 0) { + this.update(); + return null; + } + } + } + } + + if (itemstack1.count != itemstack.count) { + this.update(); + } + + return itemstack1; + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.items[i] != null) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + this.items[i] = itemstack; + if (itemstack != null && itemstack.count > this.getMaxStackSize()) { + itemstack.count = this.getMaxStackSize(); + } + + this.update(); + } + + public int getSize() { + return this.b; + } + + public String getName() { + return this.a; + } + + public boolean hasCustomName() { + return this.e; + } + + public void a(String s) { + this.e = true; + this.a = s; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return (IChatBaseComponent) (this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatMessage(this.getName(), new Object[0])); + } + + public int getMaxStackSize() { + return 64; + } + + public void update() { + if (this.d != null) { + for (int i = 0; i < this.d.size(); ++i) { + ((IInventoryListener) this.d.get(i)).a(this); + } + } + + } + + public boolean a(EntityHuman entityhuman) { + return true; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemArmor.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemArmor.java new file mode 100644 index 0000000..cd77ba5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemArmor.java @@ -0,0 +1,200 @@ +package net.minecraft.server; + +import com.google.common.base.Predicates; +import java.util.List; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +// CraftBukkit end + +public class ItemArmor extends Item { + + private static final int[] k = new int[] { 11, 16, 15, 13}; + public static final String[] a = new String[] { "minecraft:items/empty_armor_slot_helmet", "minecraft:items/empty_armor_slot_chestplate", "minecraft:items/empty_armor_slot_leggings", "minecraft:items/empty_armor_slot_boots"}; + private static final IDispenseBehavior l = new DispenseBehaviorItem() { + protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + BlockPosition blockposition = isourceblock.getBlockPosition().shift(BlockDispenser.b(isourceblock.f())); + int i = blockposition.getX(); + int j = blockposition.getY(); + int k = blockposition.getZ(); + AxisAlignedBB axisalignedbb = new AxisAlignedBB((double) i, (double) j, (double) k, (double) (i + 1), (double) (j + 1), (double) (k + 1)); + List list = isourceblock.getWorld().a(EntityLiving.class, axisalignedbb, Predicates.and(IEntitySelector.d, new IEntitySelector.EntitySelectorEquipable(itemstack))); + + if (list.size() > 0) { + EntityLiving entityliving = (EntityLiving) list.get(0); + int l = entityliving instanceof EntityHuman ? 1 : 0; + int i1 = EntityInsentient.c(itemstack); + + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + World world = isourceblock.getWorld(); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.count++; + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.count++; + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + + itemstack1.count = 1; + entityliving.setEquipment(i1 - l, itemstack1); + if (entityliving instanceof EntityInsentient) { + ((EntityInsentient) entityliving).a(i1, 2.0F); + } + + // --itemstack.count; // CraftBukkit - handled above + return itemstack; + } else { + return super.b(isourceblock, itemstack); + } + } + }; + public final int b; + public final int c; + public final int d; + private final ItemArmor.EnumArmorMaterial m; + + public ItemArmor(ItemArmor.EnumArmorMaterial itemarmor_enumarmormaterial, int i, int j) { + this.m = itemarmor_enumarmormaterial; + this.b = j; + this.d = i; + this.c = itemarmor_enumarmormaterial.b(j); + this.setMaxDurability(itemarmor_enumarmormaterial.a(j)); + this.maxStackSize = 1; + this.a(CreativeModeTab.j); + BlockDispenser.REGISTRY.a(this, ItemArmor.l); + } + + public int b() { + return this.m.a(); + } + + public ItemArmor.EnumArmorMaterial x_() { + return this.m; + } + + public boolean d_(ItemStack itemstack) { + return this.m != ItemArmor.EnumArmorMaterial.LEATHER ? false : (!itemstack.hasTag() ? false : (!itemstack.getTag().hasKeyOfType("display", 10) ? false : itemstack.getTag().getCompound("display").hasKeyOfType("color", 3))); + } + + public int b(ItemStack itemstack) { + if (this.m != ItemArmor.EnumArmorMaterial.LEATHER) { + return -1; + } else { + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound != null) { + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("display"); + + if (nbttagcompound1 != null && nbttagcompound1.hasKeyOfType("color", 3)) { + return nbttagcompound1.getInt("color"); + } + } + + return 10511680; + } + } + + public void c(ItemStack itemstack) { + if (this.m == ItemArmor.EnumArmorMaterial.LEATHER) { + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound != null) { + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("display"); + + if (nbttagcompound1.hasKey("color")) { + nbttagcompound1.remove("color"); + } + + } + } + } + + public void b(ItemStack itemstack, int i) { + if (this.m != ItemArmor.EnumArmorMaterial.LEATHER) { + throw new UnsupportedOperationException("Can\'t dye non-leather!"); + } else { + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound == null) { + nbttagcompound = new NBTTagCompound(); + itemstack.setTag(nbttagcompound); + } + + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("display"); + + if (!nbttagcompound.hasKeyOfType("display", 10)) { + nbttagcompound.set("display", nbttagcompound1); + } + + nbttagcompound1.setInt("color", i); + } + } + + public boolean a(ItemStack itemstack, ItemStack itemstack1) { + return this.m.b() == itemstack1.getItem() ? true : super.a(itemstack, itemstack1); + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + int i = EntityInsentient.c(itemstack) - 1; + ItemStack itemstack1 = entityhuman.q(i); + + if (itemstack1 == null) { + entityhuman.setEquipment(i, itemstack.cloneItemStack()); + itemstack.count = 0; + } + + return itemstack; + } + + public static enum EnumArmorMaterial { + + LEATHER("leather", 5, new int[] { 1, 3, 2, 1}, 15), CHAIN("chainmail", 15, new int[] { 2, 5, 4, 1}, 12), IRON("iron", 15, new int[] { 2, 6, 5, 2}, 9), GOLD("gold", 7, new int[] { 2, 5, 3, 1}, 25), DIAMOND("diamond", 33, new int[] { 3, 8, 6, 3}, 10); + + private final String f; + private final int g; + private final int[] h; + private final int i; + + private EnumArmorMaterial(String s, int i, int[] aint, int j) { + this.f = s; + this.g = i; + this.h = aint; + this.i = j; + } + + public int a(int i) { + return ItemArmor.k[i] * this.g; + } + + public int b(int i) { + return this.h[i]; + } + + public int a() { + return this.i; + } + + public Item b() { + return this == ItemArmor.EnumArmorMaterial.LEATHER ? Items.LEATHER : (this == ItemArmor.EnumArmorMaterial.CHAIN ? Items.IRON_INGOT : (this == ItemArmor.EnumArmorMaterial.GOLD ? Items.GOLD_INGOT : (this == ItemArmor.EnumArmorMaterial.IRON ? Items.IRON_INGOT : (this == ItemArmor.EnumArmorMaterial.DIAMOND ? Items.DIAMOND : null)))); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBlock.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBlock.java new file mode 100644 index 0000000..0cd4175 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBlock.java @@ -0,0 +1,100 @@ +package net.minecraft.server; + +public class ItemBlock extends Item { + + protected final Block a; + + public ItemBlock(Block block) { + this.a = block; + } + + public ItemBlock b(String s) { + super.c(s); + return this; + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (!block.a(world, blockposition)) { + blockposition = blockposition.shift(enumdirection); + } + + if (itemstack.count == 0) { + return false; + } else if (!entityhuman.a(blockposition, enumdirection, itemstack)) { + return false; + } else if (world.a(this.a, blockposition, false, enumdirection, entityhuman, itemstack)) { // PaperSpigot - Pass entityhuman instead of null + int i = this.filterData(itemstack.getData()); + IBlockData iblockdata1 = this.a.getPlacedState(world, blockposition, enumdirection, f, f1, f2, i, entityhuman); + + if (world.setTypeAndData(blockposition, iblockdata1, 3)) { + iblockdata1 = world.getType(blockposition); + if (iblockdata1.getBlock() == this.a) { + a(world, entityhuman, blockposition, itemstack); + this.a.postPlace(world, blockposition, iblockdata1, entityhuman, itemstack); + } + + world.makeSound((double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 0.5F), (double) ((float) blockposition.getZ() + 0.5F), this.a.stepSound.getPlaceSound(), (this.a.stepSound.getVolume1() + 1.0F) / 2.0F, this.a.stepSound.getVolume2() * 0.8F); + --itemstack.count; + } + + return true; + } else { + return false; + } + } + + public static boolean a(World world, EntityHuman entityhuman, BlockPosition blockposition, ItemStack itemstack) { + MinecraftServer minecraftserver = MinecraftServer.getServer(); + + if (minecraftserver == null) { + return false; + } else { + if (itemstack.hasTag() && itemstack.getTag().hasKeyOfType("BlockEntityTag", 10)) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity != null) { + if (!world.isClientSide && tileentity.F() && !minecraftserver.getPlayerList().isOp(entityhuman.getProfile())) { + return false; + } + + NBTTagCompound nbttagcompound = new NBTTagCompound(); + NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbttagcompound.clone(); + + tileentity.b(nbttagcompound); + NBTTagCompound nbttagcompound2 = (NBTTagCompound) itemstack.getTag().get("BlockEntityTag"); + + nbttagcompound.a(nbttagcompound2); + nbttagcompound.setInt("x", blockposition.getX()); + nbttagcompound.setInt("y", blockposition.getY()); + nbttagcompound.setInt("z", blockposition.getZ()); + if (!nbttagcompound.equals(nbttagcompound1)) { + tileentity.a(nbttagcompound); + tileentity.update(); + return true; + } + } + } + + return false; + } + } + + public String e_(ItemStack itemstack) { + return this.a.a(); + } + + public String getName() { + return this.a.a(); + } + + public Block d() { + return this.a; + } + + public Item c(String s) { + return this.b(s); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBoat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBoat.java new file mode 100644 index 0000000..eb62bbb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBoat.java @@ -0,0 +1,91 @@ +package net.minecraft.server; + +import java.util.List; + +public class ItemBoat extends Item { + + public ItemBoat() { + this.maxStackSize = 1; + this.a(CreativeModeTab.e); + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + float f = 1.0F; + float f1 = entityhuman.lastPitch + (entityhuman.pitch - entityhuman.lastPitch) * f; + float f2 = entityhuman.lastYaw + (entityhuman.yaw - entityhuman.lastYaw) * f; + double d0 = entityhuman.lastX + (entityhuman.locX - entityhuman.lastX) * (double) f; + double d1 = entityhuman.lastY + (entityhuman.locY - entityhuman.lastY) * (double) f + (double) entityhuman.getHeadHeight(); + double d2 = entityhuman.lastZ + (entityhuman.locZ - entityhuman.lastZ) * (double) f; + Vec3D vec3d = new Vec3D(d0, d1, d2); + float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); + float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); + float f5 = -MathHelper.cos(-f1 * 0.017453292F); + float f6 = MathHelper.sin(-f1 * 0.017453292F); + float f7 = f4 * f5; + float f8 = f3 * f5; + double d3 = 5.0D; + Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); + MovingObjectPosition movingobjectposition = world.rayTrace(vec3d, vec3d1, true); + + if (movingobjectposition == null) { + return itemstack; + } else { + Vec3D vec3d2 = entityhuman.d(f); + boolean flag = false; + float f9 = 1.0F; + List list = world.getEntities(entityhuman, entityhuman.getBoundingBox().a(vec3d2.a * d3, vec3d2.b * d3, vec3d2.c * d3).grow((double) f9, (double) f9, (double) f9)); + + for (int i = 0; i < list.size(); ++i) { + Entity entity = (Entity) list.get(i); + + if (entity.ad()) { + float f10 = entity.ao(); + AxisAlignedBB axisalignedbb = entity.getBoundingBox().grow((double) f10, (double) f10, (double) f10); + + if (axisalignedbb.a(vec3d)) { + flag = true; + } + } + } + + if (flag) { + return itemstack; + } else { + if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + BlockPosition blockposition = movingobjectposition.a(); + + // CraftBukkit start - Boat placement + org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(entityhuman, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, blockposition, movingobjectposition.direction, itemstack); + + if (event.isCancelled()) { + return itemstack; + } + // CraftBukkit end + + if (world.getType(blockposition).getBlock() == Blocks.SNOW_LAYER) { + blockposition = blockposition.down(); + } + + EntityBoat entityboat = new EntityBoat(world, (double) ((float) blockposition.getX() + 0.5F), (double) ((float) blockposition.getY() + 1.0F), (double) ((float) blockposition.getZ() + 0.5F)); + + entityboat.yaw = (float) (((MathHelper.floor((double) (entityhuman.yaw * 4.0F / 360.0F) + 0.5D) & 3) - 1) * 90); + if (!world.getCubes(entityboat, entityboat.getBoundingBox().grow(-0.1D, -0.1D, -0.1D)).isEmpty()) { + return itemstack; + } + + if (!world.isClientSide) { + world.addEntity(entityboat); + } + + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + } + + return itemstack; + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBow.java new file mode 100644 index 0000000..c9738c7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBow.java @@ -0,0 +1,111 @@ +package net.minecraft.server; + +import org.bukkit.event.entity.EntityCombustEvent; // CraftBukkit + +public class ItemBow extends Item { + + public static final String[] a = new String[] { "pulling_0", "pulling_1", "pulling_2"}; + + public ItemBow() { + this.maxStackSize = 1; + this.setMaxDurability(384); + this.a(CreativeModeTab.j); + } + + public void a(ItemStack itemstack, World world, EntityHuman entityhuman, int i) { + boolean flag = entityhuman.abilities.canInstantlyBuild || EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_INFINITE.id, itemstack) > 0; + + if (flag || entityhuman.inventory.b(Items.ARROW)) { + int j = this.d(itemstack) - i; + float f = (float) j / 20.0F; + + f = (f * f + f * 2.0F) / 3.0F; + if ((double) f < 0.1D) { + return; + } + + if (f > 1.0F) { + f = 1.0F; + } + + EntityArrow entityarrow = new EntityArrow(world, entityhuman, f * 2.0F); + + if (f == 1.0F) { + entityarrow.setCritical(true); + } + + int k = EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_DAMAGE.id, itemstack); + + if (k > 0) { + entityarrow.b(entityarrow.j() + (double) k * 0.5D + 0.5D); + } + + int l = EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_KNOCKBACK.id, itemstack); + + if (l > 0) { + entityarrow.setKnockbackStrength(l); + } + + if (EnchantmentManager.getEnchantmentLevel(Enchantment.ARROW_FIRE.id, itemstack) > 0) { + // CraftBukkit start - call EntityCombustEvent + EntityCombustEvent event = new EntityCombustEvent(entityarrow.getBukkitEntity(), 100); + entityarrow.world.getServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + entityarrow.setOnFire(event.getDuration()); + } + // CraftBukkit end + } + + // CraftBukkit start + org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(entityhuman, itemstack, entityarrow, f); + if (event.isCancelled()) { + event.getProjectile().remove(); + return; + } + + if (event.getProjectile() == entityarrow.getBukkitEntity()) { + world.addEntity(entityarrow); + } + // CraftBukkit end + + itemstack.damage(1, entityhuman); + world.makeSound(entityhuman, "random.bow", 1.0F, 1.0F / (ItemBow.g.nextFloat() * 0.4F + 1.2F) + f * 0.5F); + if (flag) { + entityarrow.fromPlayer = 2; + } else { + entityhuman.inventory.a(Items.ARROW); + } + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + if (!world.isClientSide) { + // world.addEntity(entityarrow); // CraftBukkit - moved up + } + } + + } + + public ItemStack b(ItemStack itemstack, World world, EntityHuman entityhuman) { + return itemstack; + } + + public int d(ItemStack itemstack) { + return 72000; + } + + public EnumAnimation e(ItemStack itemstack) { + return EnumAnimation.BOW; + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + if (entityhuman.abilities.canInstantlyBuild || entityhuman.inventory.b(Items.ARROW)) { + entityhuman.a(itemstack, this.d(itemstack)); + } + + return itemstack; + } + + public int b() { + return 1; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBucket.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBucket.java new file mode 100644 index 0000000..b62ea42 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemBucket.java @@ -0,0 +1,166 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerBucketFillEvent; +// CraftBukkit end + +import org.github.paperspigot.PaperSpigotConfig; // PaperSpigot + +public class ItemBucket extends Item { + + private Block a; + + public ItemBucket(Block block) { + this.maxStackSize = 1; + this.a = block; + this.a(CreativeModeTab.f); + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + boolean flag = this.a == Blocks.AIR; + MovingObjectPosition movingobjectposition = this.a(world, entityhuman, flag); + + if (movingobjectposition == null) { + return itemstack; + } else { + if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + BlockPosition blockposition = movingobjectposition.a(); + + if (!world.a(entityhuman, blockposition)) { + return itemstack; + } + + if (flag) { + if (!entityhuman.a(blockposition.shift(movingobjectposition.direction), movingobjectposition.direction, itemstack)) { + return itemstack; + } + + IBlockData iblockdata = world.getType(blockposition); + Material material = iblockdata.getBlock().getMaterial(); + + if (material == Material.WATER && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0) { + // CraftBukkit start + PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), null, itemstack, Items.WATER_BUCKET); + + if (event.isCancelled()) { + return itemstack; + } + // CraftBukkit end + world.setAir(blockposition); + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + return this.a(itemstack, entityhuman, Items.WATER_BUCKET, event.getItemStack()); // CraftBukkit - added Event stack + } + + if (material == Material.LAVA && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0) { + // CraftBukkit start + PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), null, itemstack, Items.LAVA_BUCKET); + + if (event.isCancelled()) { + return itemstack; + } + // CraftBukkit end + world.setAir(blockposition); + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + return this.a(itemstack, entityhuman, Items.LAVA_BUCKET, event.getItemStack()); // CraftBukkit - added Event stack + } + } else { + if (this.a == Blocks.AIR) { + // CraftBukkit start + PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), movingobjectposition.direction, itemstack); + + if (event.isCancelled()) { + return itemstack; + } + + return CraftItemStack.asNMSCopy(event.getItemStack()); + // CraftBukkit end + } + + BlockPosition blockposition1 = blockposition.shift(movingobjectposition.direction); + + if (!entityhuman.a(blockposition1, movingobjectposition.direction, itemstack)) { + return itemstack; + } + + // CraftBukkit start + PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent(entityhuman, blockposition.getX(), blockposition.getY(), blockposition.getZ(), movingobjectposition.direction, itemstack); + + if (event.isCancelled()) { + return itemstack; + } + // CraftBukkit end + + if (this.a(world, blockposition1) && !entityhuman.abilities.canInstantlyBuild) { + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + // PaperSpigot start - Stackable Buckets + if ((this == Items.LAVA_BUCKET && PaperSpigotConfig.stackableLavaBuckets) || + (this == Items.WATER_BUCKET && PaperSpigotConfig.stackableWaterBuckets)) { + if (--itemstack.count <= 0) { + return CraftItemStack.asNMSCopy(event.getItemStack()); + } + if (!entityhuman.inventory.pickup(CraftItemStack.asNMSCopy(event.getItemStack()))) { + entityhuman.drop(CraftItemStack.asNMSCopy(event.getItemStack()), false); + } + return itemstack; + } + // PaperSpigot end + return CraftItemStack.asNMSCopy(event.getItemStack()); // CraftBukkit + } + } + } + + return itemstack; + } + } + + // CraftBukkit - added ob.ItemStack result - TODO: Is this... the right way to handle this? + private ItemStack a(ItemStack itemstack, EntityHuman entityhuman, Item item, org.bukkit.inventory.ItemStack result) { + if (entityhuman.abilities.canInstantlyBuild) { + return itemstack; + } else if (--itemstack.count <= 0) { + return CraftItemStack.asNMSCopy(result); // CraftBukkit + } else { + if (!entityhuman.inventory.pickup(CraftItemStack.asNMSCopy(result))) { + entityhuman.drop(CraftItemStack.asNMSCopy(result), false); + } + + return itemstack; + } + } + + public boolean a(World world, BlockPosition blockposition) { + if (this.a == Blocks.AIR) { + return false; + } else { + Material material = world.getType(blockposition).getBlock().getMaterial(); + boolean flag = !material.isBuildable(); + + if (!world.isEmpty(blockposition) && !flag) { + return false; + } else { + if (world.worldProvider.n() && this.a == Blocks.FLOWING_WATER) { + int i = blockposition.getX(); + int j = blockposition.getY(); + int k = blockposition.getZ(); + + world.makeSound((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((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]); + } + } else { + if (!world.isClientSide && flag && !material.isLiquid()) { + world.setAir(blockposition, true); + } + + world.setTypeAndData(blockposition, this.a.getBlockData(), 3); + } + + return true; + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemDoor.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemDoor.java new file mode 100644 index 0000000..6e92cab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemDoor.java @@ -0,0 +1,58 @@ +package net.minecraft.server; + +public class ItemDoor extends Item { + + private Block a; + + public ItemDoor(Block block) { + this.a = block; + this.a(CreativeModeTab.d); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + if (enumdirection != EnumDirection.UP) { + return false; + } else { + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (!block.a(world, blockposition)) { + blockposition = blockposition.shift(enumdirection); + } + + if (!entityhuman.a(blockposition, enumdirection, itemstack)) { + return false; + } else if (!this.a.canPlace(world, blockposition)) { + return false; + } else { + a(world, blockposition, EnumDirection.fromAngle((double) entityhuman.yaw), this.a); + --itemstack.count; + return true; + } + } + } + + public static void a(World world, BlockPosition blockposition, EnumDirection enumdirection, Block block) { + BlockPosition blockposition1 = blockposition.shift(enumdirection.e()); + BlockPosition blockposition2 = blockposition.shift(enumdirection.f()); + int i = (world.getType(blockposition2).getBlock().isOccluding() ? 1 : 0) + (world.getType(blockposition2.up()).getBlock().isOccluding() ? 1 : 0); + int j = (world.getType(blockposition1).getBlock().isOccluding() ? 1 : 0) + (world.getType(blockposition1.up()).getBlock().isOccluding() ? 1 : 0); + boolean flag = world.getType(blockposition2).getBlock() == block || world.getType(blockposition2.up()).getBlock() == block; + boolean flag1 = world.getType(blockposition1).getBlock() == block || world.getType(blockposition1.up()).getBlock() == block; + boolean flag2 = false; + + if (flag && !flag1 || j > i) { + flag2 = true; + } + + BlockPosition blockposition3 = blockposition.up(); + IBlockData iblockdata = block.getBlockData().set(BlockDoor.FACING, enumdirection).set(BlockDoor.HINGE, flag2 ? BlockDoor.EnumDoorHinge.RIGHT : BlockDoor.EnumDoorHinge.LEFT); + + // Spigot start - update physics after the block multi place event + world.setTypeAndData(blockposition, iblockdata.set(BlockDoor.HALF, BlockDoor.EnumDoorHalf.LOWER), 3); + world.setTypeAndData(blockposition3, iblockdata.set(BlockDoor.HALF, BlockDoor.EnumDoorHalf.UPPER), 3); + // world.applyPhysics(blockposition, block); + // world.applyPhysics(blockposition3, block); + // Spigot end + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemDye.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemDye.java new file mode 100644 index 0000000..81fde59 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemDye.java @@ -0,0 +1,114 @@ +package net.minecraft.server; + +import org.bukkit.event.entity.SheepDyeWoolEvent; // CraftBukkit + +public class ItemDye extends Item { + + public static final int[] a = new int[] { 1973019, 11743532, 3887386, 5320730, 2437522, 8073150, 2651799, 11250603, 4408131, 14188952, 4312372, 14602026, 6719955, 12801229, 15435844, 15790320}; + + public ItemDye() { + this.a(true); + this.setMaxDurability(0); + this.a(CreativeModeTab.l); + } + + public String e_(ItemStack itemstack) { + int i = itemstack.getData(); + + return super.getName() + "." + EnumColor.fromInvColorIndex(i).d(); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + if (!entityhuman.a(blockposition.shift(enumdirection), enumdirection, itemstack)) { + return false; + } else { + EnumColor enumcolor = EnumColor.fromInvColorIndex(itemstack.getData()); + + if (enumcolor == EnumColor.WHITE) { + if (a(itemstack, world, blockposition)) { + if (!world.isClientSide) { + world.triggerEffect(2005, blockposition, 0); + } + + return true; + } + } else if (enumcolor == EnumColor.BROWN) { + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block == Blocks.LOG && iblockdata.get(BlockWood.VARIANT) == BlockWood.EnumLogVariant.JUNGLE) { + if (enumdirection == EnumDirection.DOWN) { + return false; + } + + if (enumdirection == EnumDirection.UP) { + return false; + } + + blockposition = blockposition.shift(enumdirection); + if (world.isEmpty(blockposition)) { + IBlockData iblockdata1 = Blocks.COCOA.getPlacedState(world, blockposition, enumdirection, f, f1, f2, 0, entityhuman); + + world.setTypeAndData(blockposition, iblockdata1, 2); + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + } + + return true; + } + } + + return false; + } + } + + public static boolean a(ItemStack itemstack, World world, BlockPosition blockposition) { + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock() instanceof IBlockFragilePlantElement) { + IBlockFragilePlantElement iblockfragileplantelement = (IBlockFragilePlantElement) iblockdata.getBlock(); + + if (iblockfragileplantelement.a(world, blockposition, iblockdata, world.isClientSide)) { + if (!world.isClientSide) { + if (iblockfragileplantelement.a(world, world.random, blockposition, iblockdata)) { + iblockfragileplantelement.b(world, world.random, blockposition, iblockdata); + } + + --itemstack.count; + } + + return true; + } + } + + return false; + } + + public boolean a(ItemStack itemstack, EntityHuman entityhuman, EntityLiving entityliving) { + if (entityliving instanceof EntitySheep) { + EntitySheep entitysheep = (EntitySheep) entityliving; + EnumColor enumcolor = EnumColor.fromInvColorIndex(itemstack.getData()); + + if (!entitysheep.isSheared() && entitysheep.getColor() != enumcolor) { + // CraftBukkit start + byte bColor = (byte) enumcolor.getColorIndex(); + SheepDyeWoolEvent event = new SheepDyeWoolEvent((org.bukkit.entity.Sheep) entitysheep.getBukkitEntity(), org.bukkit.DyeColor.getByData(bColor)); + entitysheep.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return false; + } + + enumcolor = EnumColor.fromColorIndex((byte) event.getColor().getWoolData()); + // CraftBukkit end + entitysheep.setColor(enumcolor); + --itemstack.count; + } + + return true; + } else { + return false; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemEnderPearl.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemEnderPearl.java new file mode 100644 index 0000000..5a8131c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemEnderPearl.java @@ -0,0 +1,24 @@ +package net.minecraft.server; + +public class ItemEnderPearl extends Item { + public ItemEnderPearl() { + this.maxStackSize = 16; + this.a(CreativeModeTab.f); + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + if (entityhuman.abilities.canInstantlyBuild) { + return itemstack; + } else { + --itemstack.count; + if (!world.isClientSide) { + if(world.addEntity(new EntityEnderPearl(world, entityhuman))) { + world.makeSound(entityhuman, "random.bow", 0.5F, 0.4F / (g.nextFloat() * 0.4F + 0.8F)); + } + } + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + return itemstack; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFireball.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFireball.java new file mode 100644 index 0000000..8680029 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFireball.java @@ -0,0 +1,38 @@ +package net.minecraft.server; + +public class ItemFireball extends Item { + + public ItemFireball() { + this.a(CreativeModeTab.f); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + if (world.isClientSide) { + return true; + } else { + blockposition = blockposition.shift(enumdirection); + if (!entityhuman.a(blockposition, enumdirection, itemstack)) { + return false; + } else { + if (world.getType(blockposition).getBlock().getMaterial() == Material.AIR) { + // CraftBukkit start - fire BlockIgniteEvent + if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, entityhuman).isCancelled()) { + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + return false; + } + // CraftBukkit end + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "item.fireCharge.use", 1.0F, (ItemFireball.g.nextFloat() - ItemFireball.g.nextFloat()) * 0.2F + 1.0F); + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + } + + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + return true; + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFishingRod.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFishingRod.java new file mode 100644 index 0000000..665ce22 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFishingRod.java @@ -0,0 +1,48 @@ +package net.minecraft.server; + +import org.bukkit.event.player.PlayerFishEvent; + +public class ItemFishingRod extends Item { + + public ItemFishingRod() { + this.setMaxDurability(64); + this.c(1); + this.a(CreativeModeTab.i); + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + if (entityhuman.hookedFish != null) { + int i = entityhuman.hookedFish.l(); + + itemstack.damage(i, entityhuman); + entityhuman.bw(); + } else { + // CraftBukkit start + EntityFishingHook hook = new EntityFishingHook(world, entityhuman); + PlayerFishEvent playerFishEvent = new PlayerFishEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), null, (org.bukkit.entity.Fish) hook.getBukkitEntity(), PlayerFishEvent.State.FISHING); + world.getServer().getPluginManager().callEvent(playerFishEvent); + + if (playerFishEvent.isCancelled()) { + entityhuman.hookedFish = null; + return itemstack; + } + // CraftBukkit end + if (!world.isClientSide && world.addEntity(hook)) { + world.makeSound(entityhuman, "random.bow", 0.5F, 0.4F / (ItemFishingRod.g.nextFloat() * 0.4F + 0.8F)); + } + + entityhuman.bw(); + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + } + + return itemstack; + } + + public boolean f_(ItemStack itemstack) { + return super.f_(itemstack); + } + + public int b() { + return 1; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFlintAndSteel.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFlintAndSteel.java new file mode 100644 index 0000000..6b103ff --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemFlintAndSteel.java @@ -0,0 +1,48 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.event.CraftEventFactory; +// CraftBukkit end + +public class ItemFlintAndSteel extends Item { + + public ItemFlintAndSteel() { + this.maxStackSize = 1; + this.setMaxDurability(64); + this.a(CreativeModeTab.i); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + BlockPosition clicked = blockposition; // CraftBukkit + blockposition = blockposition.shift(enumdirection); + if (!entityhuman.a(blockposition, enumdirection, itemstack)) { + return false; + } else { + if (world.getType(blockposition).getBlock().getMaterial() == Material.AIR) { + // CraftBukkit start - Store the clicked block + if (CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, entityhuman).isCancelled()) { + itemstack.damage(1, entityhuman); + return false; + } + + CraftBlockState blockState = CraftBlockState.getBlockState(world, blockposition.getX(), blockposition.getY(), blockposition.getZ()); + // CraftBukkit end + world.makeSound((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, "fire.ignite", 1.0F, ItemFlintAndSteel.g.nextFloat() * 0.4F + 0.8F); + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + + // CraftBukkit start + org.bukkit.event.block.BlockPlaceEvent placeEvent = CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockState, clicked.getX(), clicked.getY(), clicked.getZ()); + + if (placeEvent.isCancelled() || !placeEvent.canBuild()) { + placeEvent.getBlockPlaced().setTypeIdAndData(0, (byte) 0, false); + return false; + } + // CraftBukkit end + } + + itemstack.damage(1, entityhuman); + return true; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemHanging.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemHanging.java new file mode 100644 index 0000000..946a3a7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemHanging.java @@ -0,0 +1,67 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.entity.Player; +import org.bukkit.event.hanging.HangingPlaceEvent; +import org.bukkit.event.painting.PaintingPlaceEvent; +// CraftBukkit end + +public class ItemHanging extends Item { + + private final Class a; + + public ItemHanging(Class oclass) { + this.a = oclass; + this.a(CreativeModeTab.c); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + if (enumdirection == EnumDirection.DOWN) { + return false; + } else if (enumdirection == EnumDirection.UP) { + return false; + } else { + BlockPosition blockposition1 = blockposition.shift(enumdirection); + + if (!entityhuman.a(blockposition1, enumdirection, itemstack)) { + return false; + } else { + EntityHanging entityhanging = this.a(world, blockposition1, enumdirection); + + if (entityhanging != null && entityhanging.survives()) { + if (!world.isClientSide) { + // CraftBukkit start - fire HangingPlaceEvent + Player who = (entityhuman == null) ? null : (Player) entityhuman.getBukkitEntity(); + org.bukkit.block.Block blockClicked = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection); + + HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityhanging.getBukkitEntity(), who, blockClicked, blockFace); + world.getServer().getPluginManager().callEvent(event); + + PaintingPlaceEvent paintingEvent = null; + if (entityhanging instanceof EntityPainting) { + // Fire old painting event until it can be removed + paintingEvent = new PaintingPlaceEvent((org.bukkit.entity.Painting) entityhanging.getBukkitEntity(), who, blockClicked, blockFace); + paintingEvent.setCancelled(event.isCancelled()); + world.getServer().getPluginManager().callEvent(paintingEvent); + } + + if (event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { + return false; + } + // CraftBukkit end + world.addEntity(entityhanging); + } + + --itemstack.count; + } + + return true; + } + } + } + + private EntityHanging a(World world, BlockPosition blockposition, EnumDirection enumdirection) { + return (EntityHanging) (this.a == EntityPainting.class ? new EntityPainting(world, blockposition, enumdirection) : (this.a == EntityItemFrame.class ? new EntityItemFrame(world, blockposition, enumdirection) : null)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemLeash.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemLeash.java new file mode 100644 index 0000000..346cd18 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemLeash.java @@ -0,0 +1,70 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +import org.bukkit.event.hanging.HangingPlaceEvent; // CraftBukkit + +public class ItemLeash extends Item { + + public ItemLeash() { + this.a(CreativeModeTab.i); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + Block block = world.getType(blockposition).getBlock(); + + if (block instanceof BlockFence) { + if (world.isClientSide) { + return true; + } else { + a(entityhuman, world, blockposition); + return true; + } + } else { + return false; + } + } + + public static boolean a(EntityHuman entityhuman, World world, BlockPosition blockposition) { + EntityLeash entityleash = EntityLeash.b(world, blockposition); + boolean flag = false; + double d0 = 7.0D; + int i = blockposition.getX(); + int j = blockposition.getY(); + int k = blockposition.getZ(); + List list = world.a(EntityInsentient.class, new AxisAlignedBB((double) i - d0, (double) j - d0, (double) k - d0, (double) i + d0, (double) j + d0, (double) k + d0)); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityInsentient entityinsentient = (EntityInsentient) iterator.next(); + + if (entityinsentient.cc() && entityinsentient.getLeashHolder() == entityhuman) { + if (entityleash == null) { + entityleash = EntityLeash.a(world, blockposition); + + // CraftBukkit start - fire HangingPlaceEvent + HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityleash.getBukkitEntity(), entityhuman != null ? (org.bukkit.entity.Player) entityhuman.getBukkitEntity() : null, world.getWorld().getBlockAt(i, j, k), org.bukkit.block.BlockFace.SELF); + world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + entityleash.die(); + return false; + } + // CraftBukkit end + } + + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(entityinsentient, entityleash, entityhuman).isCancelled()) { + continue; + } + // CraftBukkit end + + entityinsentient.setLeashHolder(entityleash, true); + flag = true; + } + } + + return flag; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMapEmpty.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMapEmpty.java new file mode 100644 index 0000000..6bf90c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMapEmpty.java @@ -0,0 +1,35 @@ +package net.minecraft.server; + +public class ItemMapEmpty extends ItemWorldMapBase { + + protected ItemMapEmpty() { + this.a(CreativeModeTab.f); + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + World worldMain = world.getServer().getServer().worlds.get(0); // CraftBukkit - store reference to primary world + ItemStack itemstack1 = new ItemStack(Items.FILLED_MAP, 1, worldMain.b("map")); // CraftBukkit - use primary world for maps + String s = "map_" + itemstack1.getData(); + WorldMap worldmap = new WorldMap(s); + + worldMain.a(s, (PersistentBase) worldmap); // CraftBukkit + worldmap.scale = 0; + worldmap.a(entityhuman.locX, entityhuman.locZ, worldmap.scale); + worldmap.map = (byte) ((WorldServer) world).dimension; // CraftBukkit - use bukkit dimension + worldmap.c(); + + org.bukkit.craftbukkit.event.CraftEventFactory.callEvent(new org.bukkit.event.server.MapInitializeEvent(worldmap.mapView)); // CraftBukkit + + --itemstack.count; + if (itemstack.count <= 0) { + return itemstack1; + } else { + if (!entityhuman.inventory.pickup(itemstack1.cloneItemStack())) { + entityhuman.drop(itemstack1, false); + } + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + return itemstack; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMilkBucket.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMilkBucket.java new file mode 100644 index 0000000..8e3d77e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMilkBucket.java @@ -0,0 +1,46 @@ +package net.minecraft.server; + +import org.github.paperspigot.PaperSpigotConfig; // PaperSpigot + +public class ItemMilkBucket extends Item { + + public ItemMilkBucket() { + this.c(1); + this.a(CreativeModeTab.f); + } + + public ItemStack b(ItemStack itemstack, World world, EntityHuman entityhuman) { + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + if (!world.isClientSide) { + entityhuman.removeAllEffects(); + } + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + // PaperSpigot start - Stackable Buckets + if (PaperSpigotConfig.stackableMilkBuckets) { + if (itemstack.count <= 0) { + return new ItemStack(Items.BUCKET); + } else if (!entityhuman.inventory.pickup(new ItemStack(Items.BUCKET))) { + entityhuman.drop(new ItemStack(Items.BUCKET), false); + } + } + // PaperSpigot end + return itemstack.count <= 0 ? new ItemStack(Items.BUCKET) : itemstack; + } + + public int d(ItemStack itemstack) { + return 32; + } + + public EnumAnimation e(ItemStack itemstack) { + return EnumAnimation.DRINK; + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + entityhuman.a(itemstack, this.d(itemstack)); + return itemstack; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMinecart.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMinecart.java new file mode 100644 index 0000000..e9fc40e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMinecart.java @@ -0,0 +1,133 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +// CraftBukkit end + +public class ItemMinecart extends Item { + + private static final IDispenseBehavior a = new DispenseBehaviorItem() { + private final DispenseBehaviorItem b = new DispenseBehaviorItem(); + + public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + World world = isourceblock.getWorld(); + double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX() * 1.125D; + double d1 = Math.floor(isourceblock.getY()) + (double) enumdirection.getAdjacentY(); + double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ() * 1.125D; + BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + IBlockData iblockdata = world.getType(blockposition); + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = iblockdata.getBlock() instanceof BlockMinecartTrackAbstract ? (BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(((BlockMinecartTrackAbstract) iblockdata.getBlock()).n()) : BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + double d3; + + if (BlockMinecartTrackAbstract.d(iblockdata)) { + if (blockminecarttrackabstract_enumtrackposition.c()) { + d3 = 0.6D; + } else { + d3 = 0.1D; + } + } else { + if (iblockdata.getBlock().getMaterial() != Material.AIR || !BlockMinecartTrackAbstract.d(world.getType(blockposition.down()))) { + return this.b.a(isourceblock, itemstack); + } + + IBlockData iblockdata1 = world.getType(blockposition.down()); + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition1 = iblockdata1.getBlock() instanceof BlockMinecartTrackAbstract ? (BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata1.get(((BlockMinecartTrackAbstract) iblockdata1.getBlock()).n()) : BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + + if (enumdirection != EnumDirection.DOWN && blockminecarttrackabstract_enumtrackposition1.c()) { + d3 = -0.4D; + } else { + d3 = -0.9D; + } + } + + // CraftBukkit start + // EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.a(world, d0, d1 + d3, d2, ((ItemMinecart) itemstack.getItem()).b); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block2 = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.count++; + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.count++; + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) { + idispensebehavior.a(isourceblock, eventStack); + return itemstack; + } + } + + itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); + EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.a(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), ((ItemMinecart) itemstack1.getItem()).b); + + if (itemstack.hasName()) { + entityminecartabstract.setCustomName(itemstack.getName()); + } + + world.addEntity(entityminecartabstract); + // itemstack.a(1); // CraftBukkit - handled during event processing + // CraftBukkit end + return itemstack; + } + + protected void a(ISourceBlock isourceblock) { + isourceblock.getWorld().triggerEffect(1000, isourceblock.getBlockPosition(), 0); + } + }; + private final EntityMinecartAbstract.EnumMinecartType b; + + public ItemMinecart(EntityMinecartAbstract.EnumMinecartType entityminecartabstract_enumminecarttype) { + this.maxStackSize = 1; + this.b = entityminecartabstract_enumminecarttype; + this.a(CreativeModeTab.e); + BlockDispenser.REGISTRY.a(this, ItemMinecart.a); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + IBlockData iblockdata = world.getType(blockposition); + + if (BlockMinecartTrackAbstract.d(iblockdata)) { + if (!world.isClientSide) { + BlockMinecartTrackAbstract.EnumTrackPosition blockminecarttrackabstract_enumtrackposition = iblockdata.getBlock() instanceof BlockMinecartTrackAbstract ? (BlockMinecartTrackAbstract.EnumTrackPosition) iblockdata.get(((BlockMinecartTrackAbstract) iblockdata.getBlock()).n()) : BlockMinecartTrackAbstract.EnumTrackPosition.NORTH_SOUTH; + double d0 = 0.0D; + + if (blockminecarttrackabstract_enumtrackposition.c()) { + d0 = 0.5D; + } + + // CraftBukkit start - Minecarts + org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(entityhuman, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, blockposition, enumdirection, itemstack); + + if (event.isCancelled()) { + return false; + } + // CraftBukkit end + + EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.a(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.0625D + d0, (double) blockposition.getZ() + 0.5D, this.b); + + if (itemstack.hasName()) { + entityminecartabstract.setCustomName(itemstack.getName()); + } + + world.addEntity(entityminecartabstract); + } + + --itemstack.count; + return true; + } else { + return false; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMonsterEgg.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMonsterEgg.java new file mode 100644 index 0000000..84f5da5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemMonsterEgg.java @@ -0,0 +1,145 @@ +package net.minecraft.server; + +public class ItemMonsterEgg extends Item { + + public ItemMonsterEgg() { + this.a(true); + this.a(CreativeModeTab.f); + } + + public String a(ItemStack itemstack) { + String s = ("" + LocaleI18n.get(this.getName() + ".name")).trim(); + String s1 = EntityTypes.b(itemstack.getData()); + + if (s1 != null) { + s = s + " " + LocaleI18n.get("entity." + s1 + ".name"); + } + + return s; + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + if (world.isClientSide) { + return true; + } else if (!entityhuman.a(blockposition.shift(enumdirection), enumdirection, itemstack)) { + return false; + } else { + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock() == Blocks.MOB_SPAWNER) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityMobSpawner) { + MobSpawnerAbstract mobspawnerabstract = ((TileEntityMobSpawner) tileentity).getSpawner(); + + mobspawnerabstract.setMobName(EntityTypes.b(itemstack.getData())); + tileentity.update(); + world.notify(blockposition); + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + return true; + } + } + + blockposition = blockposition.shift(enumdirection); + double d0 = 0.0D; + + if (enumdirection == EnumDirection.UP && iblockdata instanceof BlockFence) { + d0 = 0.5D; + } + + Entity entity = a(world, itemstack.getData(), (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + d0, (double) blockposition.getZ() + 0.5D); + + if (entity != null) { + if (entity instanceof EntityLiving && itemstack.hasName()) { + entity.setCustomName(itemstack.getName()); + } + + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + } + + return true; + } + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + if (world.isClientSide) { + return itemstack; + } else { + MovingObjectPosition movingobjectposition = this.a(world, entityhuman, true); + + if (movingobjectposition == null) { + return itemstack; + } else { + if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + BlockPosition blockposition = movingobjectposition.a(); + + if (!world.a(entityhuman, blockposition)) { + return itemstack; + } + + if (!entityhuman.a(blockposition, movingobjectposition.direction, itemstack)) { + return itemstack; + } + + if (world.getType(blockposition).getBlock() instanceof BlockFluids) { + Entity entity = a(world, itemstack.getData(), (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D); + + if (entity != null) { + if (entity instanceof EntityLiving && itemstack.hasName()) { + ((EntityInsentient) entity).setCustomName(itemstack.getName()); + } + + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + } + } + } + + return itemstack; + } + } + } + + public static Entity a(World world, int i, double d0, double d1, double d2) { + // CraftBukkit start - delegate to spawnCreature + return spawnCreature(world, i, d0, d1, d2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); + } + + public static Entity spawnCreature(World world, int i, double d0, double d1, double d2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) { + // CraftBukkit end + if (!EntityTypes.eggInfo.containsKey(Integer.valueOf(i))) { + return null; + } else { + Entity entity = null; + + for (int j = 0; j < 1; ++j) { + entity = EntityTypes.a(i, world); + if (entity instanceof EntityLiving) { + EntityInsentient entityinsentient = (EntityInsentient) entity; + + entity.setPositionRotation(d0, d1, d2, MathHelper.g(world.random.nextFloat() * 360.0F), 0.0F); + entityinsentient.aK = entityinsentient.yaw; + entityinsentient.aI = entityinsentient.yaw; + entityinsentient.prepare(world.E(new BlockPosition(entityinsentient)), (GroupDataEntity) null); + // CraftBukkit start - don't return an entity when CreatureSpawnEvent is canceled + if (!world.addEntity(entity, spawnReason)) { + entity = null; + } else { + entityinsentient.x(); + } + // CraftBukkit end + } + } + + return entity; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemRecord.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemRecord.java new file mode 100644 index 0000000..7b943fd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemRecord.java @@ -0,0 +1,43 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Map; + +public class ItemRecord extends Item { + + private static final Map b = Maps.newHashMap(); + public final String a; + + protected ItemRecord(String s) { + this.a = s; + this.maxStackSize = 1; + this.a(CreativeModeTab.f); + ItemRecord.b.put("records." + s, this); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock() == Blocks.JUKEBOX && !((Boolean) iblockdata.get(BlockJukeBox.HAS_RECORD)).booleanValue()) { + if (world.isClientSide) { + return true; + } else { + // CraftBukkit Start + /* + ((BlockJukeBox) Blocks.JUKEBOX).a(world, blockposition, iblockdata, itemstack); + world.a((EntityHuman) null, 1005, blockposition, Item.getId(this)); + --itemstack.count; + entityhuman.b(StatisticList.X); + */ + // CraftBukkit End + return true; + } + } else { + return false; + } + } + + public EnumItemRarity g(ItemStack itemstack) { + return EnumItemRarity.RARE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemSkull.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemSkull.java new file mode 100644 index 0000000..519574b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemSkull.java @@ -0,0 +1,138 @@ +package net.minecraft.server; + +import com.mojang.authlib.GameProfile; +import java.util.UUID; + +public class ItemSkull extends Item { + + private static final String[] a = new String[] { "skeleton", "wither", "zombie", "char", "creeper"}; + + public ItemSkull() { + this.a(CreativeModeTab.c); + this.setMaxDurability(0); + this.a(true); + } + + public boolean interactWith(ItemStack itemstack, EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + if (enumdirection == EnumDirection.DOWN) { + return false; + } else { + IBlockData iblockdata = world.getType(blockposition); + Block block = iblockdata.getBlock(); + boolean flag = block.a(world, blockposition); + + if (!flag) { + if (!world.getType(blockposition).getBlock().getMaterial().isBuildable()) { + return false; + } + + blockposition = blockposition.shift(enumdirection); + } + + if (!entityhuman.a(blockposition, enumdirection, itemstack)) { + return false; + } else if (!Blocks.SKULL.canPlace(world, blockposition)) { + return false; + } else { + if (!world.isClientSide) { + // Spigot Start + if ( !Blocks.SKULL.canPlace( world, blockposition ) ) + { + return false; + } + // Spigot End + world.setTypeAndData(blockposition, Blocks.SKULL.getBlockData().set(BlockSkull.FACING, enumdirection), 3); + int i = 0; + + if (enumdirection == EnumDirection.UP) { + i = MathHelper.floor((double) (entityhuman.yaw * 16.0F / 360.0F) + 0.5D) & 15; + } + + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntitySkull) { + TileEntitySkull tileentityskull = (TileEntitySkull) tileentity; + + if (itemstack.getData() == 3) { + GameProfile gameprofile = null; + + if (itemstack.hasTag()) { + NBTTagCompound nbttagcompound = itemstack.getTag(); + + if (nbttagcompound.hasKeyOfType("SkullOwner", 10)) { + gameprofile = GameProfileSerializer.deserialize(nbttagcompound.getCompound("SkullOwner")); + } else if (nbttagcompound.hasKeyOfType("SkullOwner", 8) && nbttagcompound.getString("SkullOwner").length() > 0) { + gameprofile = new GameProfile((UUID) null, nbttagcompound.getString("SkullOwner")); + } + } + + tileentityskull.setGameProfile(gameprofile); + } else { + tileentityskull.setSkullType(itemstack.getData()); + } + + tileentityskull.setRotation(i); + Blocks.SKULL.a(world, blockposition, tileentityskull); + } + + --itemstack.count; + } + + return true; + } + } + } + + public int filterData(int i) { + return i; + } + + public String e_(ItemStack itemstack) { + int i = itemstack.getData(); + + if (i < 0 || i >= ItemSkull.a.length) { + i = 0; + } + + return super.getName() + "." + ItemSkull.a[i]; + } + + public String a(ItemStack itemstack) { + if (itemstack.getData() == 3 && itemstack.hasTag()) { + if (itemstack.getTag().hasKeyOfType("SkullOwner", 8)) { + return LocaleI18n.a("item.skull.player.name", new Object[] { itemstack.getTag().getString("SkullOwner")}); + } + + if (itemstack.getTag().hasKeyOfType("SkullOwner", 10)) { + NBTTagCompound nbttagcompound = itemstack.getTag().getCompound("SkullOwner"); + + if (nbttagcompound.hasKeyOfType("Name", 8)) { + return LocaleI18n.a("item.skull.player.name", new Object[] { nbttagcompound.getString("Name")}); + } + } + } + + return super.a(itemstack); + } + + public boolean a(final NBTTagCompound nbttagcompound) { // Spigot - make final + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("SkullOwner", 8) && nbttagcompound.getString("SkullOwner").length() > 0) { + GameProfile gameprofile = new GameProfile((UUID) null, nbttagcompound.getString("SkullOwner")); + + // Spigot start + TileEntitySkull.b(gameprofile, new com.google.common.base.Predicate() { + + @Override + public boolean apply(GameProfile gameprofile) { + nbttagcompound.set("SkullOwner", GameProfileSerializer.serialize(new NBTTagCompound(), gameprofile)); + return false; + } + }); + // Spigot end + return true; + } else { + return false; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemStack.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemStack.java new file mode 100644 index 0000000..015ce28 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemStack.java @@ -0,0 +1,763 @@ +package net.minecraft.server; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import java.text.DecimalFormat; +import java.util.Random; + +// CraftBukkit start +import java.util.List; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.TreeType; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Player; +import org.bukkit.event.world.StructureGrowEvent; +// CraftBukkit end + +import org.github.paperspigot.PaperSpigotConfig; // PaperSpigot + +public final class ItemStack { + + public static final DecimalFormat a = new DecimalFormat("#.###"); + public int count; + public int c; + private Item item; + private NBTTagCompound tag; + private int damage; + private EntityItemFrame g; + private Block h; + private boolean i; + private Block j; + private boolean k; + + public ItemStack(Block block) { + this(block, 1); + } + + public ItemStack(Block block, int i) { + this(block, i, 0); + } + + public ItemStack(Block block, int i, int j) { + this(Item.getItemOf(block), i, j); + } + + public ItemStack(Item item) { + this(item, 1); + } + + public ItemStack(Item item, int i) { + this(item, i, 0); + } + + public ItemStack(Item item, int i, int j) { + this.h = null; + this.i = false; + this.j = null; + this.k = false; + this.item = item; + this.count = i; + + // CraftBukkit start - Pass to setData to do filtering + this.setData(j); + //this.damage = j; + //if (this.damage < 0) { + // this.damage = 0; + //} + // CraftBukkit end + + } + + public static ItemStack createStack(NBTTagCompound nbttagcompound) { + ItemStack itemstack = new ItemStack(); + + itemstack.c(nbttagcompound); + return itemstack.getItem() != null ? itemstack : null; + } + + private ItemStack() { + this.h = null; + this.i = false; + this.j = null; + this.k = false; + } + + public ItemStack cloneAndSubtract(int i) { + ItemStack itemstack = new ItemStack(this.item, i, this.damage); + + if (this.tag != null) { + itemstack.tag = (NBTTagCompound) this.tag.clone(); + } + + this.count -= i; + return itemstack; + } + + public Item getItem() { + return this.item; + } + + public boolean placeItem(EntityHuman entityhuman, World world, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + // CraftBukkit start - handle all block place event logic here + int data = this.getData(); + int count = this.count; + + if (!(this.getItem() instanceof ItemBucket)) { // if not bucket + world.captureBlockStates = true; + // special case bonemeal + if (this.getItem() instanceof ItemDye && this.getData() == 15) { + Block block = world.getType(blockposition).getBlock(); + if (block == Blocks.SAPLING || block instanceof BlockMushroom) { + world.captureTreeGeneration = true; + } + } + } + boolean flag = this.getItem().interactWith(this, entityhuman, world, blockposition, enumdirection, f, f1, f2); + int newData = this.getData(); + int newCount = this.count; + this.count = count; + this.setData(data); + world.captureBlockStates = false; + if (flag && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) { + world.captureTreeGeneration = false; + Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + TreeType treeType = BlockSapling.treeType; + BlockSapling.treeType = null; + List blocks = (List) world.capturedBlockStates.clone(); + world.capturedBlockStates.clear(); + StructureGrowEvent event = null; + if (treeType != null) { + boolean isBonemeal = getItem() == Items.DYE && data == 15; + event = new StructureGrowEvent(location, treeType, isBonemeal, (Player) entityhuman.getBukkitEntity(), blocks); + org.bukkit.Bukkit.getPluginManager().callEvent(event); + } + if (event == null || !event.isCancelled()) { + // Change the stack to its new contents if it hasn't been tampered with. + if (this.count == count && this.getData() == data) { + this.setData(newData); + this.count = newCount; + } + for (BlockState blockstate : blocks) { + blockstate.update(true); + } + } + + return flag; + } + world.captureTreeGeneration = false; + + if (flag) { + org.bukkit.event.block.BlockPlaceEvent placeEvent = null; + List blocks = (List) world.capturedBlockStates.clone(); + world.capturedBlockStates.clear(); + if (blocks.size() > 1) { + placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } else if (blocks.size() == 1) { + placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } + + if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { + flag = false; // cancel placement + // revert back all captured blocks + for (BlockState blockstate : blocks) { + blockstate.update(true, false); + } + } else { + // Change the stack to its new contents if it hasn't been tampered with. + if (this.count == count && this.getData() == data) { + this.setData(newData); + this.count = newCount; + } + for (BlockState blockstate : blocks) { + int x = blockstate.getX(); + int y = blockstate.getY(); + int z = blockstate.getZ(); + int updateFlag = ((CraftBlockState) blockstate).getFlag(); + org.bukkit.Material mat = blockstate.getType(); + Block oldBlock = CraftMagicNumbers.getBlock(mat); + BlockPosition newblockposition = new BlockPosition(x, y, z); + IBlockData block = world.getType(newblockposition); + + if (!(block instanceof BlockContainer)) { // Containers get placed automatically + block.getBlock().onPlace(world, newblockposition, block); + } + + world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block.getBlock(), updateFlag); // send null chunk as chunk.k() returns false by this point + } + + for (Map.Entry e : world.capturedTileEntities.entrySet()) { + world.setTileEntity(e.getKey(), e.getValue()); + } + + // Special case juke boxes as they update their tile entity. Copied from ItemRecord. + if (this.getItem() instanceof ItemRecord) { + ((BlockJukeBox) Blocks.JUKEBOX).a(world, blockposition, world.getType(blockposition), this); + world.a((EntityHuman) null, 1005, blockposition, Item.getId(this.getItem())); + --this.count; + entityhuman.b(StatisticList.X); + } + + if (this.getItem() == Items.SKULL) { // Special case skulls to allow wither spawns to be cancelled + BlockPosition bp = blockposition; + if (!world.getType(blockposition).getBlock().a(world, blockposition)) { + if (!world.getType(blockposition).getBlock().getMaterial().isBuildable()) { + bp = null; + } else { + bp = bp.shift(enumdirection); + } + } + if (bp != null) { + TileEntity te = world.getTileEntity(bp); + if (te instanceof TileEntitySkull) { + Blocks.SKULL.a(world, bp, (TileEntitySkull) te); + } + } + } + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this.item)]); + } + } + world.capturedTileEntities.clear(); + world.capturedBlockStates.clear(); + // CraftBukkit end + + return flag; + } + + public float a(Block block) { + return this.getItem().getDestroySpeed(this, block); + } + + public ItemStack a(World world, EntityHuman entityhuman) { + return this.getItem().a(this, world, entityhuman); + } + + public ItemStack b(World world, EntityHuman entityhuman) { + return this.getItem().b(this, world, entityhuman); + } + + public NBTTagCompound save(NBTTagCompound nbttagcompound) { + MinecraftKey minecraftkey = (MinecraftKey) Item.REGISTRY.c(this.item); + + nbttagcompound.setString("id", minecraftkey == null ? "minecraft:air" : minecraftkey.toString()); + nbttagcompound.setByte("Count", (byte) this.count); + nbttagcompound.setShort("Damage", (short) this.damage); + if (this.tag != null) { + nbttagcompound.set("tag", this.tag.clone()); // CraftBukkit - make defensive copy, data is going to another thread + } + + return nbttagcompound; + } + + public void c(NBTTagCompound nbttagcompound) { + if (nbttagcompound.hasKeyOfType("id", 8)) { + this.item = Item.d(nbttagcompound.getString("id")); + } else { + this.item = Item.getById(nbttagcompound.getShort("id")); + } + + this.count = nbttagcompound.getByte("Count"); + /* CraftBukkit start - Route through setData for filtering + this.damage = nbttagcompound.getShort("Damage"); + if (this.damage < 0) { + this.damage = 0; + } + */ + this.setData(nbttagcompound.getShort("Damage")); + // CraftBukkit end + + if (nbttagcompound.hasKeyOfType("tag", 10)) { + // CraftBukkit - make defensive copy as this data may be coming from the save thread + this.tag = (NBTTagCompound) nbttagcompound.getCompound("tag").clone(); + if (this.item != null) { + this.item.a(this.tag); + } + } + + } + + public int getMaxStackSize() { + return this.getItem().getMaxStackSize(); + } + + public boolean isStackable() { + return this.getMaxStackSize() > 1 && (!this.e() || !this.g()); + } + + public boolean e() { + // Spigot Start + if ( this.item.getMaxDurability() <= 0 ) + { + return false; + } + return ( !hasTag() ) || ( !getTag().getBoolean( "Unbreakable" ) ); + // Spigot End + } + + public boolean usesData() { + return this.item.k(); + } + + public boolean g() { + return this.e() && this.damage > 0; + } + + public int h() { + return this.damage; + } + + public int getData() { + return this.damage; + } + + public void setData(int i) { + // CraftBukkit start - Filter out data for items that shouldn't have it + // The crafting system uses this value for a special purpose so we have to allow it + if (i == 32767) { + this.damage = i; + return; + } + + // Is this a block? + // PaperSpigot start - Allow specific blocks to retain their data values + int id = CraftMagicNumbers.getId(this.getItem()); + if (CraftMagicNumbers.getBlock(id) != Blocks.AIR) { + // If vanilla doesn't use data on it don't allow any + if ((PaperSpigotConfig.dataValueAllowedItems == null || !PaperSpigotConfig.dataValueAllowedItems.contains(id)) && + (!(this.usesData() || this.getItem().usesDurability()))) { + // PaperSpigot end + i = 0; + } + } + + // Filter invalid plant data + if (CraftMagicNumbers.getBlock(CraftMagicNumbers.getId(this.getItem())) == Blocks.DOUBLE_PLANT && (i > 5 || i < 0)) { + i = 0; + } + // CraftBukkit end + this.damage = i; + if (this.damage < -1) { // CraftBukkit + this.damage = 0; + } + + } + + public int j() { + return this.item.getMaxDurability(); + } + + public boolean isDamaged(int i, Random random) { + return isDamaged(i, random, null); + } + + public boolean isDamaged(int i, Random random, EntityLiving entityliving) { + // Spigot end + if (!this.e()) { + return false; + } else { + if (i > 0) { + int j = EnchantmentManager.getEnchantmentLevel(Enchantment.DURABILITY.id, this); + int k = 0; + + for (int l = 0; j > 0 && l < i; ++l) { + if (EnchantmentDurability.a(this, j, random)) { + ++k; + } + } + + i -= k; + // Spigot start + if (entityliving instanceof EntityPlayer) { + org.bukkit.craftbukkit.inventory.CraftItemStack item = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this); + org.bukkit.event.player.PlayerItemDamageEvent event = new org.bukkit.event.player.PlayerItemDamageEvent((org.bukkit.entity.Player) entityliving.getBukkitEntity(), item, i); + org.bukkit.Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) return false; + i = event.getDamage(); + } + // Spigot end + if (i <= 0 ) { + return false; + } + } + + this.damage += i; + return this.damage > this.j(); + } + } + + public void damage(int i, EntityLiving entityliving) { + if (!(entityliving instanceof EntityHuman) || !((EntityHuman) entityliving).abilities.canInstantlyBuild) { + if (this.e()) { + if (this.isDamaged(i, entityliving.bc(), entityliving)) { // Spigot + entityliving.b(this); + --this.count; + if (entityliving instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) entityliving; + + entityhuman.b(StatisticList.BREAK_ITEM_COUNT[Item.getId(this.item)]); + if (this.count == 0 && this.getItem() instanceof ItemBow) { + entityhuman.ca(); + } + } + + if (this.count < 0) { + this.count = 0; + } + + // CraftBukkit start - Check for item breaking + if (this.count == 0 && entityliving instanceof EntityHuman) { + org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((EntityHuman) entityliving, this); + } + // CraftBukkit end + + this.damage = 0; + } + + } + } + } + + public void a(EntityLiving entityliving, EntityHuman entityhuman) { + boolean flag = this.item.a(this, entityliving, (EntityLiving) entityhuman); + + if (flag) { + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this.item)]); + } + + } + + public void a(World world, Block block, BlockPosition blockposition, EntityHuman entityhuman) { + boolean flag = this.item.a(this, world, block, blockposition, entityhuman); + + if (flag) { + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this.item)]); + } + + } + + public boolean b(Block block) { + return this.item.canDestroySpecialBlock(block); + } + + public boolean a(EntityHuman entityhuman, EntityLiving entityliving) { + return this.item.a(this, entityhuman, entityliving); + } + + public ItemStack cloneItemStack() { + ItemStack itemstack = new ItemStack(this.item, this.count, this.damage); + + if (this.tag != null) { + itemstack.tag = (NBTTagCompound) this.tag.clone(); + } + + return itemstack; + } + + public static boolean equals(ItemStack itemstack, ItemStack itemstack1) { + return itemstack == null && itemstack1 == null ? true : (itemstack != null && itemstack1 != null ? (itemstack.tag == null && itemstack1.tag != null ? false : itemstack.tag == null || itemstack.tag.equals(itemstack1.tag)) : false); + } + + // Spigot Start + public static boolean fastMatches(ItemStack itemstack, ItemStack itemstack1) { + if (itemstack == null && itemstack1 == null) { + return true; + } + if (itemstack != null && itemstack1 != null) { + return itemstack.count == itemstack1.count && itemstack.item == itemstack1.item && itemstack.damage == itemstack1.damage; + } + return false; + } + // Spigot End + + public static boolean matches(ItemStack itemstack, ItemStack itemstack1) { + return itemstack == null && itemstack1 == null ? true : (itemstack != null && itemstack1 != null ? itemstack.d(itemstack1) : false); + } + + private boolean d(ItemStack itemstack) { + return this.count != itemstack.count ? false : (this.item != itemstack.item ? false : (this.damage != itemstack.damage ? false : (this.tag == null && itemstack.tag != null ? false : this.tag == null || this.tag.equals(itemstack.tag)))); + } + + public static boolean c(ItemStack itemstack, ItemStack itemstack1) { + return itemstack == null && itemstack1 == null ? true : (itemstack != null && itemstack1 != null ? itemstack.doMaterialsMatch(itemstack1) : false); + } + + public boolean doMaterialsMatch(ItemStack itemstack) { + return itemstack != null && this.item == itemstack.item && this.damage == itemstack.damage; + } + + public String a() { + return this.item.e_(this); + } + + public static ItemStack b(ItemStack itemstack) { + return itemstack == null ? null : itemstack.cloneItemStack(); + } + + public String toString() { + return this.count + "x" + this.item.getName() + "@" + this.damage; + } + + public void a(World world, Entity entity, int i, boolean flag) { + if (this.c > 0) { + --this.c; + } + + this.item.a(this, world, entity, i, flag); + } + + public void a(World world, EntityHuman entityhuman, int i) { + entityhuman.a(StatisticList.CRAFT_BLOCK_COUNT[Item.getId(this.item)], i); + this.item.d(this, world, entityhuman); + } + + public int l() { + return this.getItem().d(this); + } + + public EnumAnimation m() { + return this.getItem().e(this); + } + + public void b(World world, EntityHuman entityhuman, int i) { + this.getItem().a(this, world, entityhuman, i); + } + + public boolean hasTag() { + return this.tag != null; + } + + public NBTTagCompound getTag() { + return this.tag; + } + + public NBTTagCompound a(String s, boolean flag) { + if (this.tag != null && this.tag.hasKeyOfType(s, 10)) { + return this.tag.getCompound(s); + } else if (flag) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + this.a(s, (NBTBase) nbttagcompound); + return nbttagcompound; + } else { + return null; + } + } + + public NBTTagList getEnchantments() { + return this.tag == null ? null : this.tag.getList("ench", 10); + } + + public void setTag(NBTTagCompound nbttagcompound) { + this.tag = nbttagcompound; + } + + public String getName() { + String s = this.getItem().a(this); + + if (this.tag != null && this.tag.hasKeyOfType("display", 10)) { + NBTTagCompound nbttagcompound = this.tag.getCompound("display"); + + if (nbttagcompound.hasKeyOfType("Name", 8)) { + s = nbttagcompound.getString("Name"); + } + } + + return s; + } + + public ItemStack c(String s) { + if (this.tag == null) { + this.tag = new NBTTagCompound(); + } + + if (!this.tag.hasKeyOfType("display", 10)) { + this.tag.set("display", new NBTTagCompound()); + } + + this.tag.getCompound("display").setString("Name", s); + return this; + } + + public void r() { + if (this.tag != null) { + if (this.tag.hasKeyOfType("display", 10)) { + NBTTagCompound nbttagcompound = this.tag.getCompound("display"); + + nbttagcompound.remove("Name"); + if (nbttagcompound.isEmpty()) { + this.tag.remove("display"); + if (this.tag.isEmpty()) { + this.setTag((NBTTagCompound) null); + } + } + + } + } + } + + public boolean hasName() { + return this.tag == null ? false : (!this.tag.hasKeyOfType("display", 10) ? false : this.tag.getCompound("display").hasKeyOfType("Name", 8)); + } + + public EnumItemRarity u() { + return this.getItem().g(this); + } + + public boolean v() { + return !this.getItem().f_(this) ? false : !this.hasEnchantments(); + } + + public void addEnchantment(Enchantment enchantment, int i) { + if (this.tag == null) { + this.setTag(new NBTTagCompound()); + } + + if (!this.tag.hasKeyOfType("ench", 9)) { + this.tag.set("ench", new NBTTagList()); + } + + NBTTagList nbttaglist = this.tag.getList("ench", 10); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + nbttagcompound.setShort("id", (short) enchantment.id); + nbttagcompound.setShort("lvl", (short) ((byte) i)); + nbttaglist.add(nbttagcompound); + } + + public boolean hasEnchantments() { + return this.tag != null && this.tag.hasKeyOfType("ench", 9); + } + + public void a(String s, NBTBase nbtbase) { + if (this.tag == null) { + this.setTag(new NBTTagCompound()); + } + + this.tag.set(s, nbtbase); + } + + public boolean x() { + return this.getItem().s(); + } + + public boolean y() { + return this.g != null; + } + + public void a(EntityItemFrame entityitemframe) { + this.g = entityitemframe; + } + + public EntityItemFrame z() { + return this.g; + } + + public int getRepairCost() { + return this.hasTag() && this.tag.hasKeyOfType("RepairCost", 3) ? this.tag.getInt("RepairCost") : 0; + } + + public void setRepairCost(int i) { + if (!this.hasTag()) { + this.tag = new NBTTagCompound(); + } + + this.tag.setInt("RepairCost", i); + } + + public Multimap B() { + Object object; + + if (this.hasTag() && this.tag.hasKeyOfType("AttributeModifiers", 9)) { + object = HashMultimap.create(); + NBTTagList nbttaglist = this.tag.getList("AttributeModifiers", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound = nbttaglist.get(i); + AttributeModifier attributemodifier = GenericAttributes.a(nbttagcompound); + + if (attributemodifier != null && attributemodifier.a().getLeastSignificantBits() != 0L && attributemodifier.a().getMostSignificantBits() != 0L) { + ((Multimap) object).put(nbttagcompound.getString("AttributeName"), attributemodifier); + } + } + } else { + object = this.getItem().i(); + } + + return (Multimap) object; + } + + public void setItem(Item item) { + this.item = item; + this.setData(this.getData()); // CraftBukkit - Set data again to ensure it is filtered properly + } + + public IChatBaseComponent C() { + ChatComponentText chatcomponenttext = new ChatComponentText(this.getName()); + + if (this.hasName()) { + chatcomponenttext.getChatModifier().setItalic(Boolean.valueOf(true)); + } + + IChatBaseComponent ichatbasecomponent = (new ChatComponentText("[")).addSibling(chatcomponenttext).a("]"); + + if (this.item != null) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + this.save(nbttagcompound); + ichatbasecomponent.getChatModifier().setChatHoverable(new ChatHoverable(ChatHoverable.EnumHoverAction.SHOW_ITEM, new ChatComponentText(nbttagcompound.toString()))); + ichatbasecomponent.getChatModifier().setColor(this.u().e); + } + + return ichatbasecomponent; + } + + public boolean c(Block block) { + if (block == this.h) { + return this.i; + } else { + this.h = block; + if (this.hasTag() && this.tag.hasKeyOfType("CanDestroy", 9)) { + NBTTagList nbttaglist = this.tag.getList("CanDestroy", 8); + + for (int i = 0; i < nbttaglist.size(); ++i) { + Block block1 = Block.getByName(nbttaglist.getString(i)); + + if (block1 == block) { + this.i = true; + return true; + } + } + } + + this.i = false; + return false; + } + } + + public boolean d(Block block) { + if (block == this.j) { + return this.k; + } else { + this.j = block; + if (this.hasTag() && this.tag.hasKeyOfType("CanPlaceOn", 9)) { + NBTTagList nbttaglist = this.tag.getList("CanPlaceOn", 8); + + for (int i = 0; i < nbttaglist.size(); ++i) { + Block block1 = Block.getByName(nbttaglist.getString(i)); + + if (block1 == block) { + this.k = true; + return true; + } + } + } + + this.k = false; + return false; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemWaterLily.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemWaterLily.java new file mode 100644 index 0000000..e8cbf16 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemWaterLily.java @@ -0,0 +1,50 @@ +package net.minecraft.server; + +public class ItemWaterLily extends ItemWithAuxData { + + public ItemWaterLily(Block block) { + super(block, false); + } + + public ItemStack a(ItemStack itemstack, World world, EntityHuman entityhuman) { + MovingObjectPosition movingobjectposition = this.a(world, entityhuman, true); + + if (movingobjectposition == null) { + return itemstack; + } else { + if (movingobjectposition.type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + BlockPosition blockposition = movingobjectposition.a(); + + if (!world.a(entityhuman, blockposition)) { + return itemstack; + } + + if (!entityhuman.a(blockposition.shift(movingobjectposition.direction), movingobjectposition.direction, itemstack)) { + return itemstack; + } + + BlockPosition blockposition1 = blockposition.up(); + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock().getMaterial() == Material.WATER && ((Integer) iblockdata.get(BlockFluids.LEVEL)).intValue() == 0 && world.isEmpty(blockposition1)) { + // CraftBukkit start - special case for handling block placement with water lilies + org.bukkit.block.BlockState blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(world, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); + world.setTypeUpdate(blockposition1, Blocks.WATERLILY.getBlockData()); + org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, blockstate, blockposition.getX(), blockposition.getY(), blockposition.getZ()); + if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { + blockstate.update(true, false); + return itemstack; + } + // CraftBukkit end + if (!entityhuman.abilities.canInstantlyBuild) { + --itemstack.count; + } + + entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this)]); + } + } + + return itemstack; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemWorldMap.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemWorldMap.java new file mode 100644 index 0000000..b49cbdc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ItemWorldMap.java @@ -0,0 +1,218 @@ +package net.minecraft.server; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multisets; +import org.bukkit.Bukkit; +import org.bukkit.event.server.MapInitializeEvent; + +// CraftBukkit start +// CraftBukkit end + +public class ItemWorldMap extends ItemWorldMapBase { + + protected ItemWorldMap() { + this.a(true); + } + + public WorldMap getSavedMap(ItemStack itemstack, World world) { + World worldMain = world.getServer().getServer().worlds.get(0); // CraftBukkit - store reference to primary world + String s = "map_" + itemstack.getData(); + WorldMap worldmap = (WorldMap) worldMain.a(WorldMap.class, s); // CraftBukkit - use primary world for maps + + if (worldmap == null && !world.isClientSide) { + itemstack.setData(worldMain.b("map")); // CraftBukkit - use primary world for maps + s = "map_" + itemstack.getData(); + worldmap = new WorldMap(s); + worldmap.scale = 3; + worldmap.a(world.getWorldData().c(), world.getWorldData().e(), worldmap.scale); + worldmap.map = (byte) ((WorldServer) world).dimension; // CraftBukkit - fixes Bukkit multiworld maps + worldmap.c(); + worldMain.a(s, worldmap); // CraftBukkit - use primary world for maps + + // CraftBukkit start + MapInitializeEvent event = new MapInitializeEvent(worldmap.mapView); + Bukkit.getServer().getPluginManager().callEvent(event); + // CraftBukkit end + } + + return worldmap; + } + + public void a(World world, Entity entity, WorldMap worldmap) { + // CraftBukkit - world.worldProvider -> ((WorldServer) world) + if (((WorldServer) world).dimension == worldmap.map && entity instanceof EntityHuman) { + int i = 1 << worldmap.scale; + int j = worldmap.centerX; + int k = worldmap.centerZ; + int l = MathHelper.floor(entity.locX - (double) j) / i + 64; + int i1 = MathHelper.floor(entity.locZ - (double) k) / i + 64; + int j1 = 128 / i; + + if (world.worldProvider.o()) { + j1 /= 2; + } + + WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker = worldmap.a((EntityHuman) entity); + + ++worldmap_worldmaphumantracker.b; + boolean flag = false; + + for (int k1 = l - j1 + 1; k1 < l + j1; ++k1) { + if ((k1 & 15) == (worldmap_worldmaphumantracker.b & 15) || flag) { + flag = false; + double d0 = 0.0D; + + for (int l1 = i1 - j1 - 1; l1 < i1 + j1; ++l1) { + if (k1 >= 0 && l1 >= -1 && k1 < 128 && l1 < 128) { + int i2 = k1 - l; + int j2 = l1 - i1; + boolean flag1 = i2 * i2 + j2 * j2 > (j1 - 2) * (j1 - 2); + int k2 = (j / i + k1 - 64) * i; + int l2 = (k / i + l1 - 64) * i; + HashMultiset hashmultiset = HashMultiset.create(); + Chunk chunk = world.getChunkAtWorldCoords(k2, l2); + + if (!chunk.isEmpty()) { + int i3 = k2 & 15; + int j3 = l2 & 15; + int k3 = 0; + double d1 = 0.0D; + + if (world.worldProvider.o()) { + int l3 = k2 + l2 * 231871; + + l3 = l3 * l3 * 31287121 + l3 * 11; + if ((l3 >> 20 & 1) == 0) { + hashmultiset.add(Blocks.DIRT.g(Blocks.DIRT.getBlockData().set(BlockDirt.VARIANT, BlockDirt.EnumDirtVariant.DIRT)), 10); + } else { + hashmultiset.add(Blocks.STONE.g(Blocks.STONE.getBlockData().set(BlockStone.VARIANT, BlockStone.EnumStoneVariant.STONE)), 100); + } + + d1 = 100.0D; + } else { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int i4 = 0; i4 < i; ++i4) { + for (int j4 = 0; j4 < i; ++j4) { + int k4 = chunk.b(i4 + i3, j4 + j3) + 1; + IBlockData iblockdata = Blocks.AIR.getBlockData(); + + if (k4 > 1) { + do { + --k4; + iblockdata = chunk.getBlockData(blockposition_mutableblockposition.c(i4 + i3, k4, j4 + j3)); + } while (iblockdata.getBlock().g(iblockdata) == MaterialMapColor.b && k4 > 0); + + if (k4 > 0 && iblockdata.getBlock().getMaterial().isLiquid()) { + int l4 = k4 - 1; + + Block block; + + do { + block = chunk.getTypeAbs(i4 + i3, l4--, j4 + j3); + ++k3; + } while (l4 > 0 && block.getMaterial().isLiquid()); + } + } + + d1 += (double) k4 / (double) (i * i); + hashmultiset.add(iblockdata.getBlock().g(iblockdata)); + } + } + } + + k3 /= i * i; + double d2 = (d1 - d0) * 4.0D / (double) (i + 4) + ((double) (k1 + l1 & 1) - 0.5D) * 0.4D; + byte b0 = 1; + + if (d2 > 0.6D) { + b0 = 2; + } + + if (d2 < -0.6D) { + b0 = 0; + } + + MaterialMapColor materialmapcolor = Iterables.getFirst(Multisets.copyHighestCountFirst(hashmultiset), MaterialMapColor.b); + + if (materialmapcolor == MaterialMapColor.n) { + d2 = (double) k3 * 0.1D + (double) (k1 + l1 & 1) * 0.2D; + b0 = 1; + if (d2 < 0.5D) { + b0 = 2; + } + + if (d2 > 0.9D) { + b0 = 0; + } + } + + d0 = d1; + if (l1 >= 0 && i2 * i2 + j2 * j2 < j1 * j1 && (!flag1 || (k1 + l1 & 1) != 0)) { + byte b1 = worldmap.colors[k1 + l1 * 128]; + byte b2 = (byte) (materialmapcolor.M * 4 + b0); + + if (b1 != b2) { + worldmap.colors[k1 + l1 * 128] = b2; + worldmap.flagDirty(k1, l1); + flag = true; + } + } + } + } + } + } + } + + } + } + + public void a(ItemStack itemstack, World world, Entity entity, int i, boolean flag) { + if (!world.isClientSide) { + WorldMap worldmap = this.getSavedMap(itemstack, world); + + if (entity instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) entity; + + worldmap.a(entityhuman, itemstack); + } + + if (flag) { + this.a(world, entity, worldmap); + } + + } + } + + public Packet c(ItemStack itemstack, World world, EntityHuman entityhuman) { + return this.getSavedMap(itemstack, world).a(itemstack, world, entityhuman); + } + + public void d(ItemStack itemstack, World world, EntityHuman entityhuman) { + if (itemstack.hasTag() && itemstack.getTag().getBoolean("map_is_scaling")) { + WorldMap worldmap = Items.FILLED_MAP.getSavedMap(itemstack, world); + + world = world.getServer().getServer().worlds.get(0); // CraftBukkit - use primary world for maps + + itemstack.setData(world.b("map")); + WorldMap worldmap1 = new WorldMap("map_" + itemstack.getData()); + + worldmap1.scale = (byte) (worldmap.scale + 1); + if (worldmap1.scale > 4) { + worldmap1.scale = 4; + } + + worldmap1.a(worldmap.centerX, worldmap.centerZ, worldmap1.scale); + worldmap1.map = worldmap.map; + worldmap1.c(); + world.a("map_" + itemstack.getData(), worldmap1); + + // CraftBukkit start + MapInitializeEvent event = new MapInitializeEvent(worldmap1.mapView); + Bukkit.getServer().getPluginManager().callEvent(event); + // CraftBukkit end + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/JsonList.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/JsonList.java new file mode 100644 index 0000000..8e4ecfd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/JsonList.java @@ -0,0 +1,237 @@ +package net.minecraft.server; + +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.io.Files; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class JsonList> { + + protected static final Logger a = LogManager.getLogger(); + protected final Gson b; + private final File c; + private final Map d = Maps.newHashMap(); + private boolean e = true; + private static final ParameterizedType f = new ParameterizedType() { + public Type[] getActualTypeArguments() { + return new Type[] { JsonListEntry.class}; + } + + public Type getRawType() { + return List.class; + } + + public Type getOwnerType() { + return null; + } + }; + + public JsonList(File file) { + this.c = file; + GsonBuilder gsonbuilder = (new GsonBuilder()).setPrettyPrinting(); + + gsonbuilder.registerTypeHierarchyAdapter(JsonListEntry.class, new JsonList.JsonListEntrySerializer(null)); + this.b = gsonbuilder.create(); + } + + public boolean isEnabled() { + return this.e; + } + + public void a(boolean flag) { + this.e = flag; + } + + public File c() { + return this.c; + } + + public void add(V v0) { + this.d.put(this.a(v0.getKey()), v0); + + try { + this.save(); + } catch (IOException ioexception) { + JsonList.a.warn("Could not save the list after adding a user.", ioexception); + } + + } + + public V get(K k0) { + this.h(); + return (V) this.d.get(this.a(k0)); // CraftBukkit - fix decompile error + } + + public void remove(K k0) { + this.d.remove(this.a(k0)); + + try { + this.save(); + } catch (IOException ioexception) { + JsonList.a.warn("Could not save the list after removing a user.", ioexception); + } + + } + + public String[] getEntries() { + return (String[]) this.d.keySet().toArray(new String[this.d.size()]); + } + + // CraftBukkit start + public Collection getValues() { + return this.d.values(); + } + // CraftBukkit end + + public boolean isEmpty() { + return this.d.size() < 1; + } + + protected String a(K k0) { + return k0.toString(); + } + + protected boolean d(K k0) { + return this.d.containsKey(this.a(k0)); + } + + private void h() { + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = this.d.values().iterator(); + + while (iterator.hasNext()) { + JsonListEntry jsonlistentry = (JsonListEntry) iterator.next(); + + if (jsonlistentry.hasExpired()) { + arraylist.add(jsonlistentry.getKey()); + } + } + + iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + Object object = iterator.next(); + + this.d.remove(object); + } + + } + + protected JsonListEntry a(JsonObject jsonobject) { + return new JsonListEntry((Object) null, jsonobject); + } + + protected Map e() { + return this.d; + } + + public void save() throws IOException { + Collection collection = this.d.values(); + String s = this.b.toJson(collection); + BufferedWriter bufferedwriter = null; + + try { + bufferedwriter = Files.newWriter(this.c, Charsets.UTF_8); + bufferedwriter.write(s); + } finally { + IOUtils.closeQuietly(bufferedwriter); + } + + } + + public void load() throws FileNotFoundException { + Collection collection = null; + BufferedReader bufferedreader = null; + + try { + bufferedreader = Files.newReader(this.c, Charsets.UTF_8); + collection = (Collection) this.b.fromJson(bufferedreader, JsonList.f); + // Spigot Start + } catch ( java.io.FileNotFoundException ex ) + { + org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.INFO, "Unable to find file {0}, creating it.", this.c ); + } catch ( com.google.gson.JsonSyntaxException ex ) + { + org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.WARNING, "Unable to read file {0}, backing it up to {0}.backup and creating new copy.", this.c ); + File backup = new File( this.c + ".backup" ); + this.c.renameTo( backup ); + this.c.delete(); + // Spigot End + } finally { + IOUtils.closeQuietly(bufferedreader); + } + + if (collection != null) { + this.d.clear(); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + JsonListEntry jsonlistentry = (JsonListEntry) iterator.next(); + + if (jsonlistentry.getKey() != null) { + this.d.put(this.a((K) jsonlistentry.getKey()), (V) jsonlistentry); // CraftBukkit - fix decompile error + } + } + } + + } + + class JsonListEntrySerializer implements JsonDeserializer>, JsonSerializer> { + + private JsonListEntrySerializer() {} + + public JsonElement a(JsonListEntry jsonlistentry, Type type, JsonSerializationContext jsonserializationcontext) { + JsonObject jsonobject = new JsonObject(); + + jsonlistentry.a(jsonobject); + return jsonobject; + } + + public JsonListEntry a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { + if (jsonelement.isJsonObject()) { + JsonObject jsonobject = jsonelement.getAsJsonObject(); + JsonListEntry jsonlistentry = JsonList.this.a(jsonobject); + + return jsonlistentry; + } else { + return null; + } + } + + public JsonElement serialize(JsonListEntry object, Type type, JsonSerializationContext jsonserializationcontext) { // CraftBukkit - fix decompile error + return this.a((JsonListEntry) object, type, jsonserializationcontext); + } + + public JsonListEntry deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { // CraftBukkit - fix decompile error + return this.a(jsonelement, type, jsondeserializationcontext); + } + + JsonListEntrySerializer(Object object) { + this(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/LoginListener.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/LoginListener.java new file mode 100644 index 0000000..541cec7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/LoginListener.java @@ -0,0 +1,292 @@ +package net.minecraft.server; + +import com.google.common.base.Charsets; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.exceptions.AuthenticationUnavailableException; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; +import java.math.BigInteger; +import java.security.PrivateKey; +import java.util.Arrays; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import javax.crypto.SecretKey; +import org.apache.commons.lang3.Validate; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +// CraftBukkit start +import org.bukkit.craftbukkit.util.Waitable; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerPreLoginEvent; +// CraftBukkit end + +public class LoginListener implements PacketLoginInListener, IUpdatePlayerListBox { + + private static final AtomicInteger b = new AtomicInteger(0); + private static final Logger c = LogManager.getLogger(); + private static final Random random = new Random(); + private final byte[] e = new byte[4]; + private final MinecraftServer server; + public final NetworkManager networkManager; + private LoginListener.EnumProtocolState g; + private int h; + private GameProfile i; + private String j; + private SecretKey loginKey; + private EntityPlayer l; + public String hostname = ""; // CraftBukkit - add field + + public LoginListener(MinecraftServer minecraftserver, NetworkManager networkmanager) { + this.g = LoginListener.EnumProtocolState.HELLO; + this.j = ""; + this.server = minecraftserver; + this.networkManager = networkmanager; + LoginListener.random.nextBytes(this.e); + } + + public void c() { + if (this.g == LoginListener.EnumProtocolState.READY_TO_ACCEPT) { + this.b(); + } else if (this.g == LoginListener.EnumProtocolState.e) { + EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId()); + + if (entityplayer == null) { + this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; + this.server.getPlayerList().a(this.networkManager, this.l); + this.l = null; + } + } + + if (this.h++ == 600) { + this.disconnect("Took too long to log in"); + } + + } + + public void disconnect(String s) { + try { + LoginListener.c.info("Disconnecting " + this.d() + ": " + s); + ChatComponentText chatcomponenttext = new ChatComponentText(s); + + this.networkManager.handle(new PacketLoginOutDisconnect(chatcomponenttext)); + this.networkManager.close(chatcomponenttext); + } catch (Exception exception) { + LoginListener.c.error("Error whilst disconnecting player", exception); + } + + } + + // Spigot start + public void initUUID() + { + UUID uuid; + if ( networkManager.spoofedUUID != null ) + { + uuid = networkManager.spoofedUUID; + } else + { + uuid = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + this.i.getName() ).getBytes( Charsets.UTF_8 ) ); + } + + this.i = new GameProfile( uuid, this.i.getName() ); + + if (networkManager.spoofedProfile != null) + { + for ( com.mojang.authlib.properties.Property property : networkManager.spoofedProfile ) + { + this.i.getProperties().put( property.getName(), property ); + } + } + } + // Spigot end + + public void b() { + // Spigot start - Moved to initUUID + /* + if (!this.i.isComplete()) { + this.i = this.a(this.i); + } + */ + // Spigot end + + // CraftBukkit start - fire PlayerLoginEvent + EntityPlayer s = this.server.getPlayerList().attemptLogin(this, this.i, hostname); + + if (s == null) { + // this.disconnect(s); + // CraftBukkit end + } else { + this.g = LoginListener.EnumProtocolState.ACCEPTED; + if (this.server.aK() >= 0 && !this.networkManager.c()) { + this.networkManager.a(new PacketLoginOutSetCompression(this.server.aK()), new ChannelFutureListener() { + public void a(ChannelFuture channelfuture) throws Exception { + LoginListener.this.networkManager.a(LoginListener.this.server.aK()); + } + + public void operationComplete(ChannelFuture future) throws Exception { // CraftBukkit - fix decompile error + this.a((ChannelFuture) future); + } + }, new GenericFutureListener[0]); + } + + this.networkManager.handle(new PacketLoginOutSuccess(this.i)); + EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId()); + + if (entityplayer != null) { + this.g = LoginListener.EnumProtocolState.e; + this.l = this.server.getPlayerList().processLogin(this.i, s); // CraftBukkit - add player reference + } else { + this.server.getPlayerList().a(this.networkManager, this.server.getPlayerList().processLogin(this.i, s)); // CraftBukkit - add player reference + } + } + + } + + public void a(IChatBaseComponent ichatbasecomponent) { + LoginListener.c.info(this.d() + " lost connection: " + ichatbasecomponent.c()); + } + + public String d() { + return this.i != null ? this.i.toString() + " (" + this.networkManager.getSocketAddress().toString() + ")" : String.valueOf(this.networkManager.getSocketAddress()); + } + + public void a(PacketLoginInStart packetlogininstart) { + Validate.validState(this.g == LoginListener.EnumProtocolState.HELLO, "Unexpected hello packet", new Object[0]); + this.i = packetlogininstart.a(); + if (this.server.getOnlineMode() && !this.networkManager.c()) { + this.g = LoginListener.EnumProtocolState.KEY; + this.networkManager.handle(new PacketLoginOutEncryptionBegin(this.j, this.server.Q().getPublic(), this.e)); + } else { + // Spigot start + initUUID(); + new Thread(new Runnable() { + + @Override + public void run() { + try{ + new LoginHandler().fireEvents(); + } catch (Exception ex) { + disconnect("Failed to verify username!"); + server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + i.getName(), ex); + } + } + }).start(); + // Spigot end + } + + } + + public void a(PacketLoginInEncryptionBegin packetlogininencryptionbegin) { + Validate.validState(this.g == LoginListener.EnumProtocolState.KEY, "Unexpected key packet", new Object[0]); + PrivateKey privatekey = this.server.Q().getPrivate(); + + if (!Arrays.equals(this.e, packetlogininencryptionbegin.b(privatekey))) { + throw new IllegalStateException("Invalid nonce!"); + } else { + this.loginKey = packetlogininencryptionbegin.a(privatekey); + this.g = LoginListener.EnumProtocolState.AUTHENTICATING; + this.networkManager.a(this.loginKey); + (new Thread("User Authenticator #" + LoginListener.b.incrementAndGet()) { + public void run() { + GameProfile gameprofile = LoginListener.this.i; + + try { + String s = (new BigInteger(MinecraftEncryption.a(LoginListener.this.j, LoginListener.this.server.Q().getPublic(), LoginListener.this.loginKey))).toString(16); + + LoginListener.this.i = LoginListener.this.server.aD().hasJoinedServer(new GameProfile((UUID) null, gameprofile.getName()), s); + if (LoginListener.this.i != null) { + // CraftBukkit start - fire PlayerPreLoginEvent + if (!networkManager.g()) { + return; + } + + new LoginHandler().fireEvents(); + } else if (LoginListener.this.server.T()) { + LoginListener.c.warn("Failed to verify username but will let them in anyway!"); + LoginListener.this.i = LoginListener.this.a(gameprofile); + LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; + } else { + LoginListener.this.disconnect("Failed to verify username!"); + LoginListener.c.error("Username \'" + gameprofile.getName() + "\' tried to join with an invalid session"); // CraftBukkit - fix null pointer + } + } catch (AuthenticationUnavailableException authenticationunavailableexception) { + if (LoginListener.this.server.T()) { + LoginListener.c.warn("Authentication servers are down but will let them in anyway!"); + LoginListener.this.i = LoginListener.this.a(gameprofile); + LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; + } else { + LoginListener.this.disconnect("Authentication servers are down. Please try again later, sorry!"); + LoginListener.c.error("Couldn\'t verify username because servers are unavailable"); + } + // CraftBukkit start - catch all exceptions + } catch (Exception exception) { + disconnect("Failed to verify username!"); + server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + gameprofile.getName(), exception); + // CraftBukkit end + } + + } + }).start(); + } + } + + // Spigot start + public class LoginHandler { + + public void fireEvents() throws Exception { + String playerName = i.getName(); + java.net.InetAddress address = ((java.net.InetSocketAddress) networkManager.getSocketAddress()).getAddress(); + java.util.UUID uniqueId = i.getId(); + final org.bukkit.craftbukkit.CraftServer server = LoginListener.this.server.server; + + AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId); + server.getPluginManager().callEvent(asyncEvent); + + if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) { + final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId); + if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) { + event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage()); + } + Waitable waitable = new Waitable() { + @Override + protected PlayerPreLoginEvent.Result evaluate() { + server.getPluginManager().callEvent(event); + return event.getResult(); + }}; + + LoginListener.this.server.processQueue.add(waitable); + if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED) { + disconnect(event.getKickMessage()); + return; + } + } else { + if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) { + disconnect(asyncEvent.getKickMessage()); + return; + } + } + // CraftBukkit end + LoginListener.c.info("UUID of player " + LoginListener.this.i.getName() + " is " + LoginListener.this.i.getId()); + LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT; + } + } + // Spigot end + + protected GameProfile a(GameProfile gameprofile) { + UUID uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + gameprofile.getName()).getBytes(Charsets.UTF_8)); + + return new GameProfile(uuid, gameprofile.getName()); + } + + static enum EnumProtocolState { + + HELLO, KEY, AUTHENTICATING, READY_TO_ACCEPT, e, ACCEPTED; + + private EnumProtocolState() {} + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MethodProfiler.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MethodProfiler.java new file mode 100644 index 0000000..2aea31b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MethodProfiler.java @@ -0,0 +1,59 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +// CraftBukkit start - Strip down to empty methods, performance cost +public class MethodProfiler { + + public boolean a; + public MethodProfiler() {} + + public void a() { + } + + public void a(String s) { + } + + public void b() { + } + + public List b(String s) { + return null; + } + + public void c(String s) { + } + + public String c() { + return ""; + } + + public static final class ProfilerInfo implements Comparable { + + public double a; + public double b; + public String c; + + public ProfilerInfo(String s, double d0, double d1) { + this.c = s; + this.a = d0; + this.b = d1; + } + + public int a(MethodProfiler.ProfilerInfo methodprofiler_profilerinfo) { + return methodprofiler_profilerinfo.a < this.a ? -1 : (methodprofiler_profilerinfo.a > this.a ? 1 : methodprofiler_profilerinfo.c.compareTo(this.c)); + } + + public int compareTo(MethodProfiler.ProfilerInfo object) { + return this.a((MethodProfiler.ProfilerInfo) object); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java new file mode 100644 index 0000000..3b1fc6a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MinecraftServer.java @@ -0,0 +1,1655 @@ +package net.minecraft.server; + +import co.aikar.timings.SpigotTimings; +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListenableFutureTask; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.GameProfileRepository; +import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.base64.Base64; +import jline.console.ConsoleReader; +import joptsimple.OptionSet; +import me.levansj01.mythicspigot.MythicConfiguration; +import org.apache.commons.lang3.Validate; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.craftbukkit.Main; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.net.Proxy; +import java.security.KeyPair; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Queue; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + +// CraftBukkit start +// CraftBukkit end + +public abstract class MinecraftServer implements Runnable, ICommandListener, IAsyncTaskHandler, IMojangStatistics { + + public static final Logger LOGGER = LogManager.getLogger(); + public static final File a = new File("usercache.json"); + private static MinecraftServer l; + public Convertable convertable; + private final MojangStatisticsGenerator n = new MojangStatisticsGenerator("server", this, az()); + public File universe; + private final List p = Lists.newArrayList(); + protected final ICommandHandler b; + public final MethodProfiler methodProfiler = new MethodProfiler(); + private ServerConnection q; // Spigot + private final ServerPing r = new ServerPing(); + private final Random s = new Random(); + private String serverIp; + private int u = -1; + public WorldServer[] worldServer; + private PlayerList v; + private boolean isRunning = true; + private boolean isStopped; + private int ticks; + protected final Proxy e; + public String f; + public int g; + private boolean onlineMode; + private boolean spawnAnimals; + private boolean spawnNPCs; + private boolean pvpMode; + private boolean allowFlight; + private String motd; + private int F; + private int G = 0; + public final long[] h = new long[100]; + public long[][] i; + private KeyPair H; + private String I; + private String J; + private boolean demoMode; + private boolean M; + private boolean N; + private String O = ""; + private String P = ""; + private boolean Q; + private long R; + private String S; + private boolean T; + private boolean U; + private final YggdrasilAuthenticationService V; + private final MinecraftSessionService W; + private long X = 0L; + private final GameProfileRepository Y; + private final UserCache Z; + protected final Queue> j = new java.util.concurrent.ConcurrentLinkedQueue>(); // Spigot, PAIL: Rename + private Thread serverThread; + private long ab = az(); + + // CraftBukkit start + public List worlds = new ArrayList(); + public org.bukkit.craftbukkit.CraftServer server; + public OptionSet options; + public org.bukkit.command.ConsoleCommandSender console; + public org.bukkit.command.RemoteConsoleCommandSender remoteConsole; + public ConsoleReader reader; + public static int currentTick = 0; // PaperSpigot - Further improve tick loop + public final Thread primaryThread; + public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); + public int autosavePeriod; + // CraftBukkit end + + public MinecraftServer(OptionSet options, Proxy proxy, File file1) { + io.netty.util.ResourceLeakDetector.setEnabled( false ); // Spigot - disable + this.e = proxy; + MinecraftServer.l = this; + // this.universe = file; // CraftBukkit + // this.q = new ServerConnection(this); // Spigot + this.Z = new UserCache(this, file1); + this.b = this.h(); + // this.convertable = new WorldLoaderServer(file); // CraftBukkit - moved to DedicatedServer.init + this.V = new YggdrasilAuthenticationService(proxy, UUID.randomUUID().toString()); + this.W = this.V.createMinecraftSessionService(); + this.Y = this.V.createProfileRepository(); + // CraftBukkit start + this.options = options; + // Try to see if we're actually running in a terminal, disable jline if not + if (System.console() == null && System.getProperty("jline.terminal") == null) { + System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); + Main.useJline = false; + } + + try { + reader = new ConsoleReader(System.in, System.out); + reader.setExpandEvents(false); // Avoid parsing exceptions for uncommonly used event designators + } catch (Throwable e) { + try { + // Try again with jline disabled for Windows users without C++ 2008 Redistributable + System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); + System.setProperty("user.language", "en"); + Main.useJline = false; + reader = new ConsoleReader(System.in, System.out); + reader.setExpandEvents(false); + } catch (IOException ex) { + LOGGER.warn((String) null, ex); + } + } + Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this)); + + this.serverThread = primaryThread = new Thread(this, "Server thread"); // Moved from main + } + + public abstract PropertyManager getPropertyManager(); + // CraftBukkit end + + protected CommandDispatcher h() { + return new CommandDispatcher(); + } + + protected abstract boolean init() throws IOException; + + protected void a(String s) { + if (this.getConvertable().isConvertable(s)) { + MinecraftServer.LOGGER.info("Converting map!"); + this.b("menu.convertingLevel"); + this.getConvertable().convert(s, new IProgressUpdate() { + private long b = System.currentTimeMillis(); + + public void a(String s) {} + + public void a(int i) { + if (System.currentTimeMillis() - this.b >= 1000L) { + this.b = System.currentTimeMillis(); + MinecraftServer.LOGGER.info("Converting... " + i + "%"); + } + + } + + public void c(String s) {} + }); + } + + } + + protected synchronized void b(String s) { + this.S = s; + } + + protected void a(String s, String s1, long i, WorldType worldtype, String s2) { + this.a(s); + this.b("menu.loadingLevel"); + this.worldServer = new WorldServer[3]; + /* CraftBukkit start - Remove ticktime arrays and worldsettings + this.i = new long[this.worldServer.length][100]; + IDataManager idatamanager = this.convertable.a(s, true); + + this.a(this.U(), idatamanager); + WorldData worlddata = idatamanager.getWorldData(); + WorldSettings worldsettings; + + if (worlddata == null) { + if (this.X()) { + worldsettings = DemoWorldServer.a; + } else { + worldsettings = new WorldSettings(i, this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype); + worldsettings.setGeneratorSettings(s2); + if (this.M) { + worldsettings.a(); + } + } + + worlddata = new WorldData(worldsettings, s1); + } else { + worlddata.a(s1); + worldsettings = new WorldSettings(worlddata); + } + */ + int worldCount = 3; + + for (int j = 0; j < worldCount; ++j) { + WorldServer world; + byte dimension = 0; + + if (j == 1) { + if (getAllowNether()) { + dimension = -1; + } else { + continue; + } + } + + if (j == 2) { + if (server.getAllowEnd()) { + dimension = 1; + } else { + continue; + } + } + + String worldType = org.bukkit.World.Environment.getEnvironment(dimension).toString().toLowerCase(); + String name = (dimension == 0) ? s : s + "_" + worldType; + + org.bukkit.generator.ChunkGenerator gen = this.server.getGenerator(name); + WorldSettings worldsettings = new WorldSettings(i, this.getGamemode(), this.getGenerateStructures(), this.isHardcore(), worldtype); + worldsettings.setGeneratorSettings(s2); + + if (j == 0) { + IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), s1, true); + WorldData worlddata = idatamanager.getWorldData(); + if (worlddata == null) { + worlddata = new WorldData(worldsettings, s1); + } + worlddata.checkName(s1); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) + if (this.X()) { + world = (WorldServer) (new DemoWorldServer(this, idatamanager, worlddata, dimension, this.methodProfiler)).b(); + } else { + world = (WorldServer) (new WorldServer(this, idatamanager, worlddata, dimension, this.methodProfiler, org.bukkit.World.Environment.getEnvironment(dimension), gen)).b(); + } + + world.a(worldsettings); + this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard()); + } else { + String dim = "DIM" + dimension; + + File newWorld = new File(new File(name), dim); + File oldWorld = new File(new File(s), dim); + + if ((!newWorld.isDirectory()) && (oldWorld.isDirectory())) { + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder required ----"); + MinecraftServer.LOGGER.info("Unfortunately due to the way that Minecraft implemented multiworld support in 1.6, Bukkit requires that you move your " + worldType + " folder to a new location in order to operate correctly."); + MinecraftServer.LOGGER.info("We will move this folder for you, but it will mean that you need to move it back should you wish to stop using Bukkit in the future."); + MinecraftServer.LOGGER.info("Attempting to move " + oldWorld + " to " + newWorld + "..."); + + if (newWorld.exists()) { + MinecraftServer.LOGGER.warn("A file or folder already exists at " + newWorld + "!"); + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); + } else if (newWorld.getParentFile().mkdirs()) { + if (oldWorld.renameTo(newWorld)) { + MinecraftServer.LOGGER.info("Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld); + // Migrate world data too. + try { + com.google.common.io.Files.copy(new File(new File(s), "level.dat"), new File(new File(name), "level.dat")); + } catch (IOException exception) { + MinecraftServer.LOGGER.warn("Unable to migrate world data."); + } + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder complete ----"); + } else { + MinecraftServer.LOGGER.warn("Could not move folder " + oldWorld + " to " + newWorld + "!"); + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); + } + } else { + MinecraftServer.LOGGER.warn("Could not create path for " + newWorld + "!"); + MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----"); + } + } + + IDataManager idatamanager = new ServerNBTManager(server.getWorldContainer(), name, true); + // world =, b0 to dimension, s1 to name, added Environment and gen + WorldData worlddata = idatamanager.getWorldData(); + if (worlddata == null) { + worlddata = new WorldData(worldsettings, name); + } + worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) + world = (WorldServer) new SecondaryWorldServer(this, idatamanager, dimension, this.worlds.get(0), this.methodProfiler, worlddata, org.bukkit.World.Environment.getEnvironment(dimension), gen).b(); + } + + this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld())); + + world.addIWorldAccess(new WorldManager(this, world)); + if (!this.T()) { + world.getWorldData().setGameType(this.getGamemode()); + } + + worlds.add(world); + getPlayerList().setPlayerFileData(worlds.toArray(new WorldServer[worlds.size()])); + } + + // CraftBukkit end + this.a(this.getDifficulty()); + this.k(); + } + + protected void k() { + boolean flag = true; + boolean flag1 = true; + boolean flag2 = true; + boolean flag3 = true; + int i = 0; + + this.b("menu.generatingTerrain"); + byte b0 = 0; + + // CraftBukkit start - fire WorldLoadEvent and handle whether or not to keep the spawn in memory + for (int m = 0; m < worlds.size(); m++) { + WorldServer worldserver = this.worlds.get(m); + LOGGER.info("Preparing start region for level " + m + " (Seed: " + worldserver.getSeed() + ")"); + + if (!worldserver.getWorld().getKeepSpawnInMemory()) { + continue; + } + + BlockPosition blockposition = worldserver.getSpawn(); + long j = az(); + i = 0; + + for (int k = -192; k <= 192 && this.isRunning(); k += 16) { + for (int l = -192; l <= 192 && this.isRunning(); l += 16) { + long i1 = az(); + + if (i1 - j > 1000L) { + this.a_("Preparing spawn area", i * 100 / 625); + j = i1; + } + + ++i; + worldserver.chunkProviderServer.getChunkAt(blockposition.getX() + k >> 4, blockposition.getZ() + l >> 4); + } + } + } + + for (WorldServer world : this.worlds) { + this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(world.getWorld())); + } + // CraftBukkit end + this.s(); + } + + protected void a(String s, IDataManager idatamanager) { + File file = new File(idatamanager.getDirectory(), "resources.zip"); + + if (file.isFile()) { + this.setResourcePack("level://" + s + "/" + file.getName(), ""); + } + + } + + public abstract boolean getGenerateStructures(); + + public abstract WorldSettings.EnumGamemode getGamemode(); + + public abstract EnumDifficulty getDifficulty(); + + public abstract boolean isHardcore(); + + public abstract int p(); + + public abstract boolean q(); + + public abstract boolean r(); + + protected void a_(String s, int i) { + this.f = s; + this.g = i; + MinecraftServer.LOGGER.info(s + ": " + i + "%"); + } + + protected void s() { + this.f = null; + this.g = 0; + + this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); // CraftBukkit + } + + protected void saveChunks(boolean flag) throws ExceptionWorldConflict { // CraftBukkit - added throws + if (!this.N) { + WorldServer[] aworldserver = this.worldServer; + int i = aworldserver.length; + + // CraftBukkit start + for (int j = 0; j < worlds.size(); ++j) { + WorldServer worldserver = worlds.get(j); + // CraftBukkit end + + if (worldserver != null) { + if (!flag) { + MinecraftServer.LOGGER.info("Saving chunks for level '" + worldserver.getWorldData().getName() + "'/" + worldserver.worldProvider.getName()); + } + + try { + worldserver.save(true, null); + worldserver.saveLevel(); // CraftBukkit + } catch (ExceptionWorldConflict exceptionworldconflict) { + MinecraftServer.LOGGER.warn(exceptionworldconflict.getMessage()); + } + } + } + + } + } + + // CraftBukkit start + private boolean hasStopped = false; + private final Object stopLock = new Object(); + // CraftBukkit end + + public void stop() throws ExceptionWorldConflict { // CraftBukkit - added throws + // CraftBukkit start - prevent double stopping on multiple threads + synchronized(stopLock) { + if (hasStopped) return; + hasStopped = true; + } + // CraftBukkit end + if (!this.N) { + MinecraftServer.LOGGER.info("Stopping server"); + SpigotTimings.stopServer(); // Spigot + + // CraftBukkit start + if (this.server != null) { + this.server.disablePlugins(); + } + // CraftBukkit end + if (this.aq() != null) { + this.aq().b(); + } + + if (this.v != null) { + MinecraftServer.LOGGER.info("Saving players"); + this.v.savePlayers(); + this.v.u(); + try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets + } + + if (this.worldServer != null) { + MinecraftServer.LOGGER.info("Saving worlds"); + // TODO: Make this disable + this.saveChunks(false); + + /* CraftBukkit start - Handled in saveChunks + for (int i = 0; i < this.worldServer.length; ++i) { + WorldServer worldserver = this.worldServer[i]; + + worldserver.saveLevel(); + } + // CraftBukkit end */ + } + + if (this.n.d()) { + this.n.e(); + } + // Spigot start + if( org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) + { + LOGGER.info("Saving usercache.json"); + this.Z.c(); + } + //Spigot end + } + } + + public String getServerIp() { + return this.serverIp; + } + + public void c(String s) { + this.serverIp = s; + } + + public boolean isRunning() { + return this.isRunning; + } + + public void safeShutdown() { + this.isRunning = false; + } + + // PaperSpigot start - Further improve tick loop + private static final int TPS = 20; + private static final long SEC_IN_NANO = 1000000000; + private static final long TICK_TIME = SEC_IN_NANO / TPS; + private static final long MAX_CATCHUP_BUFFER = TICK_TIME * TPS * 60L; + private static final int SAMPLE_INTERVAL = 20; + public final RollingAverage tps1 = new RollingAverage(60); + public final RollingAverage tps5 = new RollingAverage(60 * 5); + public final RollingAverage tps15 = new RollingAverage(60 * 15); + public double[] recentTps = new double[ 3 ]; // PaperSpigot - Fine have your darn compat with bad plugins + + public static class RollingAverage { + private final int size; + private long time; + private double total; + private int index = 0; + private final double[] samples; + private final long[] times; + + RollingAverage(int size) { + this.size = size; + this.time = size * SEC_IN_NANO; + this.total = TPS * SEC_IN_NANO * size; + this.samples = new double[size]; + this.times = new long[size]; + for (int i = 0; i < size; i++) { + this.samples[i] = TPS; + this.times[i] = SEC_IN_NANO; + } + } + + public void add(double x, long t) { + time -= times[index]; + total -= samples[index] * times[index]; + samples[index] = x; + times[index] = t; + time += t; + total += x * t; + if (++index == size) { + index = 0; + } + } + + public double getAverage() { + return total / time; + } + } + // PaperSpigot End + + public void run() { + try { + if (this.init()) { + this.ab = az(); + long i = 0L; + + this.r.setMOTD(new ChatComponentText(this.motd)); + this.r.setServerInfo(new ServerPing.ServerData("1.8.8", 47)); + this.a(this.r); + + // Spigot start + // PaperSpigot start - Further improve tick loop + Arrays.fill( recentTps, 20 ); + //long lastTick = System.nanoTime(), catchupTime = 0, curTime, wait, tickSection = lastTick; + long start = System.nanoTime(), lastTick = start - TICK_TIME, catchupTime = 0, curTime, wait, tickSection = start; + // PaperSpigot end + while (this.isRunning) { + curTime = System.nanoTime(); + // PaperSpigot start - Further improve tick loop + wait = TICK_TIME - (curTime - lastTick); + if (wait > 0) { + // TacoSpigot start - fix the tick loop improvements + if (catchupTime < 2E6) { + wait += Math.abs(catchupTime); + } else if (wait < catchupTime) { + catchupTime -= wait; + wait = 0; + } else { + if(catchupTime < 0) { // Mythic - Get tick length closer to 50ms + long limit = TimeUnit.MILLISECONDS.toNanos(MythicConfiguration.Options.Server.maxSleepMillis), + oldWait = wait; + wait = Math.min(oldWait - catchupTime, limit); + + catchupTime += Math.max(limit - oldWait, 0); + } else { + wait -= catchupTime; + catchupTime = 0; + } + } + // TacoSpigot end + } + if (wait > 0) { + if(MythicConfiguration.Options.Server.optimalPacketTick) { // Mythic - Process network queue more often + if(wait > TICK_TIME / 10){ + wait /= 3; + + TimeUnit.NANOSECONDS.sleep(wait); + + long nano = System.nanoTime(); + + processNetworkQueue(true); // Mythic - Process network queue more often + + wait -= System.nanoTime() - nano; + + if(wait > 0) { + TimeUnit.NANOSECONDS.sleep(wait); + } else { + processNetworkQueue(true); // Mythic - Process network queue more often + + wait -= System.nanoTime() - nano; + + if (wait > 0) { + TimeUnit.NANOSECONDS.sleep(wait); + } + } + } else { + TimeUnit.NANOSECONDS.sleep(wait); + } + } else { + Thread.sleep(wait / 1000000); + } + + curTime = System.nanoTime(); + wait = TICK_TIME - (curTime - lastTick); + } + + catchupTime = Math.min(MAX_CATCHUP_BUFFER, catchupTime - wait); + + if ( ++MinecraftServer.currentTick % SAMPLE_INTERVAL == 0 ) + { + final long diff = curTime - tickSection; + double currentTps = 1E9 / diff * SAMPLE_INTERVAL; + tps1.add(currentTps, diff); + tps5.add(currentTps, diff); + tps15.add(currentTps, diff); + // Backwards compat with bad plugins + recentTps[0] = tps1.getAverage(); + recentTps[1] = tps5.getAverage(); + recentTps[2] = tps15.getAverage(); + tickSection = curTime; + // PaperSpigot end + } + + processNetworkQueue(false); + + lastTick = curTime; + + this.A(); + this.Q = true; + } + // Spigot end + } else { + this.a((CrashReport) null); + } + } catch (Throwable throwable) { + MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable); + // Spigot Start + if ( throwable.getCause() != null ) + { + MinecraftServer.LOGGER.error( "\tCause of unexpected exception was", throwable.getCause() ); + } + // Spigot End + CrashReport crashreport = null; + + if (throwable instanceof ReportedException) { + crashreport = this.b(((ReportedException) throwable).a()); + } else { + crashreport = this.b(new CrashReport("Exception in server tick loop", throwable)); + } + + File file = new File(new File(this.y(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt"); + + if (crashreport.a(file)) { + MinecraftServer.LOGGER.error("This crash report has been saved to: " + file.getAbsolutePath()); + } else { + MinecraftServer.LOGGER.error("We were unable to save this crash report to disk."); + } + + this.a(crashreport); + } finally { + try { + org.spigotmc.WatchdogThread.doStop(); + this.isStopped = true; + this.stop(); + } catch (Throwable throwable1) { + MinecraftServer.LOGGER.error("Exception stopping the server", throwable1); + } finally { + // CraftBukkit start - Restore terminal to original settings + try { + reader.getTerminal().restore(); + } catch (Exception ignored) { + } + // CraftBukkit end + this.z(); + } + + } + + } + + private void a(ServerPing serverping) { + File file = this.d("server-icon.png"); + + if (file.isFile()) { + ByteBuf bytebuf = Unpooled.buffer(); + + try { + BufferedImage bufferedimage = ImageIO.read(file); + + Validate.validState(bufferedimage.getWidth() == 64, "Must be 64 pixels wide"); + Validate.validState(bufferedimage.getHeight() == 64, "Must be 64 pixels high"); + ImageIO.write(bufferedimage, "PNG", new ByteBufOutputStream(bytebuf)); + ByteBuf bytebuf1 = Base64.encode(bytebuf); + + serverping.setFavicon("data:image/png;base64," + bytebuf1.toString(Charsets.UTF_8)); + } catch (Exception exception) { + MinecraftServer.LOGGER.error("Couldn't load server icon", exception); + } finally { + bytebuf.release(); + } + } + + } + + public File y() { + return new File("."); + } + + protected void a(CrashReport crashreport) {} + + protected void z() {} + + protected void A() throws ExceptionWorldConflict { // CraftBukkit - added throws + co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Spigot + long i = System.nanoTime(); + + ++this.ticks; + if (this.T) { + this.T = false; + this.methodProfiler.a = true; + this.methodProfiler.a(); + } + + this.methodProfiler.a("root"); + this.B(); + if (i - this.X >= 5000000000L) { + this.X = i; + this.r.setPlayerSample(new ServerPing.ServerPingPlayerSample(this.J(), this.I())); + GameProfile[] agameprofile = new GameProfile[Math.min(this.I(), 12)]; + int j = MathHelper.nextInt(this.s, 0, this.I() - agameprofile.length); + + for (int k = 0; k < agameprofile.length; ++k) { + agameprofile[k] = this.v.v().get(j + k).getProfile(); + } + + Collections.shuffle(Arrays.asList(agameprofile)); + this.r.b().a(agameprofile); + } + + if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit + SpigotTimings.worldSaveTimer.startTiming(); // Spigot + this.methodProfiler.a("save"); + this.v.savePlayers(); + // Spigot Start + // We replace this with saving each individual world as this.saveChunks(...) is broken, + // and causes the main thread to sleep for random amounts of time depending on chunk activity + // Also pass flag to only save modified chunks + server.playerCommandState = true; + for (World world : worlds) { + world.getWorld().save(false); + } + server.playerCommandState = false; + // this.saveChunks(true); + // Spigot End + this.methodProfiler.b(); + SpigotTimings.worldSaveTimer.stopTiming(); // Spigot + } + this.methodProfiler.a("tallying"); + this.h[this.ticks % 100] = System.nanoTime() - i; + this.methodProfiler.b(); + this.methodProfiler.a("snooper"); + if(MythicConfiguration.Options.Server.snooper) { + if (getSnooperEnabled() && !this.n.d() && this.ticks > 100) { // Spigot + this.n.a(); + } + + if (getSnooperEnabled() && this.ticks % 6000 == 0) { // Spigot + this.n.b(); + } + } + + this.methodProfiler.b(); + this.methodProfiler.b(); + org.spigotmc.WatchdogThread.tick(); // Spigot + co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Spigot + } + + public void processNetworkQueue(boolean must) { + if(!must && !MythicConfiguration.Options.Server.optimalPacketTick) return; + + Queue queue = this.j; + + // Spigot start + FutureTask entry; + int count = this.j.size(); + while (count-- > 0 && (entry = this.j.poll()) != null) { + SystemUtils.a(entry, MinecraftServer.LOGGER); + } + } + + public void B() { + SpigotTimings.minecraftSchedulerTimer.startTiming(); // Spigot + this.methodProfiler.a("jobs"); + + // Mythic - Process pending logins at start of tick + getPlayerList().processLogins(); + + processNetworkQueue(true); // Mythic - Process network queue more often + + // Spigot end + SpigotTimings.minecraftSchedulerTimer.stopTiming(); // Spigot + + this.methodProfiler.c("levels"); + + SpigotTimings.bukkitSchedulerTimer.startTiming(); // Spigot + // CraftBukkit start + this.server.getScheduler().mainThreadHeartbeat(this.ticks); + SpigotTimings.bukkitSchedulerTimer.stopTiming(); // Spigot + + // Run tasks that are waiting on processing + SpigotTimings.processQueueTimer.startTiming(); // Spigot + while (!processQueue.isEmpty()) { + processQueue.remove().run(); + } + SpigotTimings.processQueueTimer.stopTiming(); // Spigot + + SpigotTimings.chunkIOTickTimer.startTiming(); // Spigot + org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick(); + SpigotTimings.chunkIOTickTimer.stopTiming(); // Spigot + + SpigotTimings.timeUpdateTimer.startTiming(); // Spigot + if(MythicConfiguration.Options.World.daylightCycle) { + // Send time updates to everyone, it will get the right time from the world the player is in. + if (this.ticks % 20 == 0) { + for (int i = 0; i < this.getPlayerList().players.size(); ++i) { + EntityPlayer entityplayer = this.getPlayerList().players.get(i); + entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean("doDaylightCycle"))); // Add support for per player time + } + } + } + SpigotTimings.timeUpdateTimer.stopTiming(); // Spigot + + int i; + + for (i = 0; i < this.worlds.size(); ++i) { + long j = System.nanoTime(); + + // if (i == 0 || this.getAllowNether()) { + WorldServer worldserver = this.worlds.get(i); + + this.methodProfiler.a(worldserver.getWorldData().getName()); + /* Drop global time updates + if (this.ticks % 20 == 0) { + this.methodProfiler.a("timeSync"); + this.v.a(new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.worldProvider.getDimension()); + this.methodProfiler.b(); + } + // CraftBukkit end */ + + this.methodProfiler.a("tick"); + + CrashReport crashreport; + + try { + worldserver.timings.doTick.startTiming(); // Spigot + worldserver.doTick(); + worldserver.timings.doTick.stopTiming(); // Spigot + } catch (Throwable throwable) { + // Spigot Start + try { + crashreport = CrashReport.a(throwable, "Exception ticking world"); + } catch (Throwable t){ + throw new RuntimeException("Error generating crash report", t); + } + // Spigot End + worldserver.a(crashreport); + throw new ReportedException(crashreport); + } + + processNetworkQueue(false); // Mythic - Process network queue more often + + try { + worldserver.timings.tickEntities.startTiming(); // Spigot + worldserver.tickEntities(); + worldserver.timings.tickEntities.stopTiming(); // Spigot + } catch (Throwable throwable1) { + // Spigot Start + try { + crashreport = CrashReport.a(throwable1, "Exception ticking world entities"); + } catch (Throwable t){ + throw new RuntimeException("Error generating crash report", t); + } + // Spigot End + worldserver.a(crashreport); + throw new ReportedException(crashreport); + } + + processNetworkQueue(false); // Mythic - Process network queue more often + + this.methodProfiler.b(); + this.methodProfiler.a("tracker"); + worldserver.timings.tracker.startTiming(); // Spigot + worldserver.getTracker().updatePlayers(); + worldserver.timings.tracker.stopTiming(); // Spigot + this.methodProfiler.b(); + this.methodProfiler.b(); + worldserver.explosionDensityCache.clear(); // PaperSpigot - Optimize explosions + + processNetworkQueue(false); // Mythic - Process network queue more often + // } // CraftBukkit + + // this.i[i][this.ticks % 100] = System.nanoTime() - j; // CraftBukkit + } + + this.methodProfiler.c("connection"); + SpigotTimings.connectionTimer.startTiming(); // Spigot + this.aq().c(); + SpigotTimings.connectionTimer.stopTiming(); // Spigot + this.methodProfiler.c("players"); + SpigotTimings.playerListTimer.startTiming(); // Spigot + if(MythicConfiguration.Options.Server.Players.sendLatency) { + this.v.tick(); + } + SpigotTimings.playerListTimer.stopTiming(); // Spigot + this.methodProfiler.c("tickables"); + + SpigotTimings.tickablesTimer.startTiming(); // Spigot + for (i = 0; i < this.p.size(); ++i) { + this.p.get(i).c(); + } + SpigotTimings.tickablesTimer.stopTiming(); // Spigot + + this.methodProfiler.b(); + + processNetworkQueue(false); // Mythic - Process network queue more often + } + + public boolean getAllowNether() { + return true; + } + + public void a(IUpdatePlayerListBox iupdateplayerlistbox) { + this.p.add(iupdateplayerlistbox); + } + + public static void main(final OptionSet options) { // CraftBukkit - replaces main(String[] astring) + DispenserRegistry.c(); + + try { + /* CraftBukkit start - Replace everything + boolean flag = true; + String s = null; + String s1 = "."; + String s2 = null; + boolean flag1 = false; + boolean flag2 = false; + int i = -1; + + for (int j = 0; j < astring.length; ++j) { + String s3 = astring[j]; + String s4 = j == astring.length - 1 ? null : astring[j + 1]; + boolean flag3 = false; + + if (!s3.equals("nogui") && !s3.equals("--nogui")) { + if (s3.equals("--port") && s4 != null) { + flag3 = true; + + try { + i = Integer.parseInt(s4); + } catch (NumberFormatException numberformatexception) { + ; + } + } else if (s3.equals("--singleplayer") && s4 != null) { + flag3 = true; + s = s4; + } else if (s3.equals("--universe") && s4 != null) { + flag3 = true; + s1 = s4; + } else if (s3.equals("--world") && s4 != null) { + flag3 = true; + s2 = s4; + } else if (s3.equals("--demo")) { + flag1 = true; + } else if (s3.equals("--bonusChest")) { + flag2 = true; + } + } else { + flag = false; + } + + if (flag3) { + ++j; + } + } + + final DedicatedServer dedicatedserver = new DedicatedServer(new File(s1)); + + if (s != null) { + dedicatedserver.i(s); + } + + if (s2 != null) { + dedicatedserver.setWorld(s2); + } + + if (i >= 0) { + dedicatedserver.setPort(i); + } + + if (flag1) { + dedicatedserver.b(true); + } + + if (flag2) { + dedicatedserver.c(true); + } + + if (flag && !GraphicsEnvironment.isHeadless()) { + dedicatedserver.aQ(); + } + + dedicatedserver.D(); + Runtime.getRuntime().addShutdownHook(new Thread("Server Shutdown Thread") { + public void run() { + dedicatedserver.stop(); + } + }); + */ + + DedicatedServer dedicatedserver = new DedicatedServer(options); + + if (options.has("port")) { + int port = (Integer) options.valueOf("port"); + if (port > 0) { + dedicatedserver.setPort(port); + } + } + + if (options.has("universe")) { + dedicatedserver.universe = (File) options.valueOf("universe"); + } + + if (options.has("world")) { + dedicatedserver.setWorld((String) options.valueOf("world")); + } + + dedicatedserver.primaryThread.start(); + // CraftBukkit end + } catch (Exception exception) { + MinecraftServer.LOGGER.fatal("Failed to start the minecraft server", exception); + } + + } + + public void C() { + /* CraftBukkit start - prevent abuse + this.serverThread = new Thread(this, "Server thread"); + this.serverThread.start(); + // CraftBukkit end */ + } + + public File d(String s) { + return new File(this.y(), s); + } + + public void info(String s) { + MinecraftServer.LOGGER.info(s); + } + + public void warning(String s) { + MinecraftServer.LOGGER.warn(s); + } + + public WorldServer getWorldServer(int i) { + // CraftBukkit start + for (WorldServer world : worlds) { + if (world.dimension == i) { + return world; + } + } + return worlds.get(0); + // CraftBukkit end + } + + public String E() { + return this.serverIp; + } + + public int F() { + return this.u; + } + + public String G() { + return this.motd; + } + + public String getVersion() { + return "1.8.8"; + } + + public int I() { + return this.v.getPlayerCount(); + } + + public int J() { + return this.v.getMaxPlayers(); + } + + public String[] getPlayers() { + return this.v.f(); + } + + public GameProfile[] L() { + return this.v.g(); + } + + public boolean isDebugging() { + return this.getPropertyManager().getBoolean("debug", false); // CraftBukkit - don't hardcode + } + + public void g(String s) { + MinecraftServer.LOGGER.error(s); + } + + public void h(String s) { + if (this.isDebugging()) { + MinecraftServer.LOGGER.info(s); + } + + } + + public String getServerModName() { + return "mySpigot"; // MythicSpigot - MythicSpigot - TacoSpigot - TacoSpigot // PaperSpigot - PaperSpigot > // Spigot - Spigot > // CraftBukkit - cb > vanilla! + } + + public CrashReport b(CrashReport crashreport) { + crashreport.g().a("Profiler Position", new Callable() { + public String a() throws Exception { + return MinecraftServer.this.methodProfiler.a ? MinecraftServer.this.methodProfiler.c() : "N/A (disabled)"; + } + + public Object call() throws Exception { + return this.a(); + } + }); + if (this.v != null) { + crashreport.g().a("Player Count", new Callable() { + public String a() { + return MinecraftServer.this.v.getPlayerCount() + " / " + MinecraftServer.this.v.getMaxPlayers() + "; " + MinecraftServer.this.v.v(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + } + + return crashreport; + } + + public List tabCompleteCommand(ICommandListener icommandlistener, String s, BlockPosition blockposition) { + /* CraftBukkit start - Allow tab-completion of Bukkit commands + ArrayList arraylist = Lists.newArrayList(); + + if (s.startsWith("/")) { + s = s.substring(1); + boolean flag = !s.contains(" "); + List list = this.b.a(icommandlistener, s, blockposition); + + if (list != null) { + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + String s1 = (String) iterator.next(); + + if (flag) { + arraylist.add("/" + s1); + } else { + arraylist.add(s1); + } + } + } + + return arraylist; + } else { + String[] astring = s.split(" ", -1); + String s2 = astring[astring.length - 1]; + String[] astring1 = this.v.f(); + int i = astring1.length; + + for (int j = 0; j < i; ++j) { + String s3 = astring1[j]; + + if (CommandAbstract.a(s2, s3)) { + arraylist.add(s3); + } + } + + return arraylist; + } + */ + return server.tabComplete(icommandlistener, s, blockposition); // PaperSpigot - add Location argument + // CraftBukkit end + } + + public static MinecraftServer getServer() { + return MinecraftServer.l; + } + + public boolean O() { + return true; // CraftBukkit + } + + public String getName() { + return "Server"; + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + MinecraftServer.LOGGER.info(ichatbasecomponent.c()); + } + + public boolean a(int i, String s) { + return true; + } + + public ICommandHandler getCommandHandler() { + return this.b; + } + + public KeyPair Q() { + return this.H; + } + + public int R() { + return this.u; + } + + public void setPort(int i) { + this.u = i; + } + + public String S() { + return this.I; + } + + public void i(String s) { + this.I = s; + } + + public boolean T() { + return this.I != null; + } + + public String U() { + return this.J; + } + + public void setWorld(String s) { + this.J = s; + } + + public void a(KeyPair keypair) { + this.H = keypair; + } + + public void a(EnumDifficulty enumdifficulty) { + // CraftBukkit start + for (int i = 0; i < this.worlds.size(); ++i) { + WorldServer worldserver = this.worlds.get(i); + // CraftBukkit end + + if (worldserver != null) { + if (worldserver.getWorldData().isHardcore()) { + worldserver.getWorldData().setDifficulty(EnumDifficulty.HARD); + worldserver.setSpawnFlags(true, true); + } else if (this.T()) { + worldserver.getWorldData().setDifficulty(enumdifficulty); + worldserver.setSpawnFlags(worldserver.getDifficulty() != EnumDifficulty.PEACEFUL, true); + } else { + worldserver.getWorldData().setDifficulty(enumdifficulty); + worldserver.setSpawnFlags(this.getSpawnMonsters(), this.spawnAnimals); + } + } + } + + } + + protected boolean getSpawnMonsters() { + return true; + } + + public boolean X() { + return this.demoMode; + } + + public void b(boolean flag) { + this.demoMode = flag; + } + + public void c(boolean flag) { + this.M = flag; + } + + public Convertable getConvertable() { + return this.convertable; + } + + public void aa() { + this.N = true; + this.getConvertable().d(); + + // CraftBukkit start + for (int i = 0; i < this.worlds.size(); ++i) { + WorldServer worldserver = this.worlds.get(i); + // CraftBukkit end + + if (worldserver != null) { + worldserver.saveLevel(); + } + } + + this.getConvertable().e(this.worlds.get(0).getDataManager().g()); // CraftBukkit + this.safeShutdown(); + } + + public String getResourcePack() { + return this.O; + } + + public String getResourcePackHash() { + return this.P; + } + + public void setResourcePack(String s, String s1) { + this.O = s; + this.P = s1; + } + + public void a(MojangStatisticsGenerator mojangstatisticsgenerator) { + mojangstatisticsgenerator.a("whitelist_enabled", Boolean.valueOf(false)); + mojangstatisticsgenerator.a("whitelist_count", Integer.valueOf(0)); + if (this.v != null) { + mojangstatisticsgenerator.a("players_current", Integer.valueOf(this.I())); + mojangstatisticsgenerator.a("players_max", Integer.valueOf(this.J())); + mojangstatisticsgenerator.a("players_seen", Integer.valueOf(this.v.getSeenPlayers().length)); + } + + mojangstatisticsgenerator.a("uses_auth", Boolean.valueOf(this.onlineMode)); + mojangstatisticsgenerator.a("gui_state", this.as() ? "enabled" : "disabled"); + mojangstatisticsgenerator.a("run_time", Long.valueOf((az() - mojangstatisticsgenerator.g()) / 60L * 1000L)); + mojangstatisticsgenerator.a("avg_tick_ms", Integer.valueOf((int) (MathHelper.a(this.h) * 1.0E-6D))); + int i = 0; + + if (this.worldServer != null) { + // CraftBukkit start + for (int j = 0; j < this.worlds.size(); ++j) { + WorldServer worldserver = this.worlds.get(j); + if (worldserver != null) { + // CraftBukkit end + WorldData worlddata = worldserver.getWorldData(); + + mojangstatisticsgenerator.a("world[" + i + "][dimension]", Integer.valueOf(worldserver.worldProvider.getDimension())); + mojangstatisticsgenerator.a("world[" + i + "][mode]", worlddata.getGameType()); + mojangstatisticsgenerator.a("world[" + i + "][difficulty]", worldserver.getDifficulty()); + mojangstatisticsgenerator.a("world[" + i + "][hardcore]", Boolean.valueOf(worlddata.isHardcore())); + mojangstatisticsgenerator.a("world[" + i + "][generator_name]", worlddata.getType().name()); + mojangstatisticsgenerator.a("world[" + i + "][generator_version]", Integer.valueOf(worlddata.getType().getVersion())); + mojangstatisticsgenerator.a("world[" + i + "][height]", Integer.valueOf(this.F)); + mojangstatisticsgenerator.a("world[" + i + "][chunks_loaded]", Integer.valueOf(worldserver.N().getLoadedChunks())); + ++i; + } + } + } + + mojangstatisticsgenerator.a("worlds", Integer.valueOf(i)); + } + + public void b(MojangStatisticsGenerator mojangstatisticsgenerator) { + mojangstatisticsgenerator.b("singleplayer", Boolean.valueOf(this.T())); + mojangstatisticsgenerator.b("server_brand", this.getServerModName()); + mojangstatisticsgenerator.b("gui_supported", GraphicsEnvironment.isHeadless() ? "headless" : "supported"); + mojangstatisticsgenerator.b("dedicated", Boolean.valueOf(this.ae())); + } + + public boolean getSnooperEnabled() { + return true; + } + + public abstract boolean ae(); + + public boolean getOnlineMode() { + return server.getOnlineMode(); // CraftBukkit + } + + public void setOnlineMode(boolean flag) { + this.onlineMode = flag; + } + + public boolean getSpawnAnimals() { + return this.spawnAnimals; + } + + public void setSpawnAnimals(boolean flag) { + this.spawnAnimals = flag; + } + + public boolean getSpawnNPCs() { + return this.spawnNPCs; + } + + public abstract boolean ai(); + + public void setSpawnNPCs(boolean flag) { + this.spawnNPCs = flag; + } + + public boolean getPVP() { + return this.pvpMode; + } + + public void setPVP(boolean flag) { + this.pvpMode = flag; + } + + public boolean getAllowFlight() { + return this.allowFlight; + } + + public void setAllowFlight(boolean flag) { + this.allowFlight = flag; + } + + public abstract boolean getEnableCommandBlock(); + + public String getMotd() { + return this.motd; + } + + public void setMotd(String s) { + this.motd = s; + } + + public int getMaxBuildHeight() { + return this.F; + } + + public void c(int i) { + this.F = i; + } + + public boolean isStopped() { + return this.isStopped; + } + + public PlayerList getPlayerList() { + return this.v; + } + + public void a(PlayerList playerlist) { + this.v = playerlist; + } + + public void setGamemode(WorldSettings.EnumGamemode worldsettings_enumgamemode) { + // CraftBukkit start + for (int i = 0; i < this.worlds.size(); ++i) { + getServer().worlds.get(i).getWorldData().setGameType(worldsettings_enumgamemode); + } + + } + + // Spigot Start + public ServerConnection getServerConnection() + { + return this.q; + } + // Spigot End + public ServerConnection aq() { + return this.q == null ? this.q = new ServerConnection(this) : this.q; // Spigot + } + + public boolean as() { + return false; + } + + public abstract String a(WorldSettings.EnumGamemode worldsettings_enumgamemode, boolean flag); + + public int at() { + return this.ticks; + } + + public void au() { + this.T = true; + } + + public BlockPosition getChunkCoordinates() { + return BlockPosition.ZERO; + } + + public Vec3D d() { + return new Vec3D(0.0D, 0.0D, 0.0D); + } + + public World getWorld() { + return this.worlds.get(0); // CraftBukkit + } + + public Entity f() { + return null; + } + + public int getSpawnProtection() { + return 16; + } + + public boolean a(World world, BlockPosition blockposition, EntityHuman entityhuman) { + return false; + } + + public void setForceGamemode(boolean flag) { + this.U = flag; + } + + public boolean getForceGamemode() { + return this.U; + } + + public Proxy ay() { + return this.e; + } + + public static long az() { + return System.currentTimeMillis(); + } + + public int getIdleTimeout() { + return this.G; + } + + public void setIdleTimeout(int i) { + this.G = i; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return new ChatComponentText(this.getName()); + } + + public boolean aB() { + return true; + } + + public MinecraftSessionService aD() { + return this.W; + } + + public GameProfileRepository getGameProfileRepository() { + return this.Y; + } + + public UserCache getUserCache() { + return this.Z; + } + + public ServerPing aG() { + return this.r; + } + + public void aH() { + this.X = 0L; + } + + public Entity a(UUID uuid) { + WorldServer[] aworldserver = this.worldServer; + int i = aworldserver.length; + + // CraftBukkit start + for (int j = 0; j < worlds.size(); ++j) { + WorldServer worldserver = worlds.get(j); + // CraftBukkit end + + if (worldserver != null) { + Entity entity = worldserver.getEntity(uuid); + + if (entity != null) { + return entity; + } + } + } + + return null; + } + + public boolean getSendCommandFeedback() { + return getServer().worlds.get(0).getGameRules().getBoolean("sendCommandFeedback"); + } + + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) {} + + public int aI() { + return 29999984; + } + + public ListenableFuture a(Callable callable) { + Validate.notNull(callable); + if (!this.isMainThread()) { // CraftBukkit && !this.isStopped()) { + ListenableFutureTask listenablefuturetask = ListenableFutureTask.create(callable); + Queue queue = this.j; + + // Spigot start + this.j.add(listenablefuturetask); + return listenablefuturetask; + // Spigot end + } else { + try { + return Futures.immediateFuture(callable.call()); + } catch (Exception exception) { + return Futures.immediateFailedCheckedFuture(exception); + } + } + } + + public ListenableFuture postToMainThread(Runnable runnable) { + Validate.notNull(runnable); + return this.a(Executors.callable(runnable)); + } + + public boolean isMainThread() { + return Thread.currentThread() == this.serverThread; + } + + public int aK() { + return 256; + } + + public long aL() { + return this.ab; + } + + public Thread aM() { + return this.serverThread; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffect.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffect.java new file mode 100644 index 0000000..57407a7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffect.java @@ -0,0 +1,174 @@ +package net.minecraft.server; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class MobEffect { + private static final Logger a = LogManager.getLogger(); + private int effectId; + private int duration; + private int amplification; + private boolean splash; + private boolean ambient; + private boolean particles; + + public MobEffect(int var1, int var2) { + this(var1, var2, 0); + } + + public MobEffect(int var1, int var2, int var3) { + this(var1, var2, var3, false, true); + } + + public MobEffect(int var1, int var2, int var3, boolean var4, boolean var5) { + this.effectId = var1; + this.duration = var2; + this.amplification = var3; + this.ambient = var4; + this.particles = var5; + } + + public MobEffect(MobEffect var1) { + this.effectId = var1.effectId; + this.duration = var1.duration; + this.amplification = var1.amplification; + this.ambient = var1.ambient; + this.particles = var1.particles; + } + + public void a(MobEffect var1) { + if (this.effectId != var1.effectId) { + a.warn("This method should only be called for matching effects!"); + } + + if (var1.amplification > this.amplification) { + this.amplification = var1.amplification; + this.duration = var1.duration; + } else if (var1.amplification == this.amplification && this.duration < var1.duration) { + this.duration = var1.duration; + } else if (!var1.ambient && this.ambient) { + this.ambient = var1.ambient; + } + + this.particles = var1.particles; + } + + public int getEffectId() { + return this.effectId; + } + + public int getDuration() { + return this.duration; + } + + public int getAmplifier() { + return this.amplification; + } + + public void setSplash(boolean var1) { + this.splash = var1; + } + + public boolean isAmbient() { + return this.ambient; + } + + public boolean isShowParticles() { + return this.particles; + } + + public boolean tick(EntityLiving var1) { + if (this.duration > 0) { + if (MobEffectList.byId[this.effectId].a(this.duration, this.amplification)) { + this.b(var1); + } + + this.i(); + } + + return this.duration > 0; + } + + private int i() { + return --this.duration; + } + + public void b(EntityLiving var1) { + if (this.duration > 0) { + MobEffectList.byId[this.effectId].tick(var1, this.amplification); + } + + } + + public String g() { + return MobEffectList.byId[this.effectId].a(); + } + + public int hashCode() { + return this.effectId; + } + + public String toString() { + String var1 = ""; + if (this.getAmplifier() > 0) { + var1 = this.g() + " x " + (this.getAmplifier() + 1) + ", Duration: " + this.getDuration(); + } else { + var1 = this.g() + ", Duration: " + this.getDuration(); + } + + if (this.splash) { + var1 = var1 + ", Splash: true"; + } + + if (!this.particles) { + var1 = var1 + ", Particles: false"; + } + + return MobEffectList.byId[this.effectId].j() ? "(" + var1 + ")" : var1; + } + + public boolean equals(Object var1) { + if (!(var1 instanceof MobEffect)) { + return false; + } else { + MobEffect var2 = (MobEffect)var1; + return this.effectId == var2.effectId && this.amplification == var2.amplification && this.duration == var2.duration && this.splash == var2.splash && this.ambient == var2.ambient; + } + } + + public NBTTagCompound a(NBTTagCompound var1) { + var1.setByte("Id", (byte)this.getEffectId()); + var1.setByte("Amplifier", (byte)this.getAmplifier()); + var1.setInt("Duration", this.getDuration()); + var1.setBoolean("Ambient", this.isAmbient()); + var1.setBoolean("ShowParticles", this.isShowParticles()); + return var1; + } + + public static MobEffect b(NBTTagCompound var0) { + byte var1 = var0.getByte("Id"); + if (var1 >= 0 && var1 < MobEffectList.byId.length && MobEffectList.byId[var1] != null) { + byte var2 = var0.getByte("Amplifier"); + int var3 = var0.getInt("Duration"); + boolean var4 = var0.getBoolean("Ambient"); + boolean var5 = true; + if (var0.hasKeyOfType("ShowParticles", 1)) { + var5 = var0.getBoolean("ShowParticles"); + } + + return new MobEffect(var1, var3, var2, var4, var5); + } else { + return null; + } + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public PotionEffect toBukkit() { + return new PotionEffect(PotionEffectType.getById(getEffectId()), getDuration(), getAmplifier(), isAmbient(), isShowParticles()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffectAttackDamage.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffectAttackDamage.java new file mode 100644 index 0000000..175503b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffectAttackDamage.java @@ -0,0 +1,13 @@ +package net.minecraft.server; + +public class MobEffectAttackDamage extends MobEffectList { + + protected MobEffectAttackDamage(int i, MinecraftKey minecraftkey, boolean flag, int j) { + super(i, minecraftkey, flag, j); + } + + public double a(int i, AttributeModifier attributemodifier) { + // PaperSpigot - Configurable modifiers for strength and weakness effects + return this.id == MobEffectList.WEAKNESS.id ? (double) (org.github.paperspigot.PaperSpigotConfig.weaknessEffectModifier * (float) (i + 1)) : org.github.paperspigot.PaperSpigotConfig.strengthEffectModifier * (double) (i + 1); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffectList.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffectList.java new file mode 100644 index 0000000..6e4d1dd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobEffectList.java @@ -0,0 +1,241 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.Map.Entry; + +// CraftBukkit start +import me.levansj01.mythicspigot.MythicConfiguration; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; +// CraftBukkit end + +public class MobEffectList { + + public static final MobEffectList[] byId = new MobEffectList[32]; + private static final Map I = Maps.newHashMap(); + public static final MobEffectList b = null; + public static final MobEffectList FASTER_MOVEMENT = (new MobEffectList(1, new MinecraftKey("speed"), false, 8171462)).c("potion.moveSpeed").b(0, 0).a(GenericAttributes.MOVEMENT_SPEED, "91AEAA56-376B-4498-935B-2F7F68070635", 0.20000000298023224D, 2); + public static final MobEffectList SLOWER_MOVEMENT = (new MobEffectList(2, new MinecraftKey("slowness"), true, 5926017)).c("potion.moveSlowdown").b(1, 0).a(GenericAttributes.MOVEMENT_SPEED, "7107DE5E-7CE8-4030-940E-514C1F160890", -0.15000000596046448D, 2); + public static final MobEffectList FASTER_DIG = (new MobEffectList(3, new MinecraftKey("haste"), false, 14270531)).c("potion.digSpeed").b(2, 0).a(1.5D); + public static final MobEffectList SLOWER_DIG = (new MobEffectList(4, new MinecraftKey("mining_fatigue"), true, 4866583)).c("potion.digSlowDown").b(3, 0); + public static final MobEffectList INCREASE_DAMAGE = (new MobEffectAttackDamage(5, new MinecraftKey("strength"), false, 9643043)).c("potion.damageBoost").b(4, 0).a(GenericAttributes.ATTACK_DAMAGE, "648D7064-6A60-4F59-8ABE-C2C23A6DD7A9", 2.5D, 2); + public static final MobEffectList HEAL = (new InstantMobEffect(6, new MinecraftKey("instant_health"), false, 16262179)).c("potion.heal"); + public static final MobEffectList HARM = (new InstantMobEffect(7, new MinecraftKey("instant_damage"), true, 4393481)).c("potion.harm"); + public static final MobEffectList JUMP = (new MobEffectList(8, new MinecraftKey("jump_boost"), false, 2293580)).c("potion.jump").b(2, 1); + public static final MobEffectList CONFUSION = (new MobEffectList(9, new MinecraftKey("nausea"), true, 5578058)).c("potion.confusion").b(3, 1).a(0.25D); + public static final MobEffectList REGENERATION = (new MobEffectList(10, new MinecraftKey("regeneration"), false, 13458603)).c("potion.regeneration").b(7, 0).a(0.25D); + public static final MobEffectList RESISTANCE = (new MobEffectList(11, new MinecraftKey("resistance"), false, 10044730)).c("potion.resistance").b(6, 1); + public static final MobEffectList FIRE_RESISTANCE = (new MobEffectList(12, new MinecraftKey("fire_resistance"), false, 14981690)).c("potion.fireResistance").b(7, 1); + public static final MobEffectList WATER_BREATHING = (new MobEffectList(13, new MinecraftKey("water_breathing"), false, 3035801)).c("potion.waterBreathing").b(0, 2); + public static final MobEffectList INVISIBILITY = (new MobEffectList(14, new MinecraftKey("invisibility"), false, 8356754)).c("potion.invisibility").b(0, 1); + public static final MobEffectList BLINDNESS = (new MobEffectList(15, new MinecraftKey("blindness"), true, 2039587)).c("potion.blindness").b(5, 1).a(0.25D); + public static final MobEffectList NIGHT_VISION = (new MobEffectList(16, new MinecraftKey("night_vision"), false, 2039713)).c("potion.nightVision").b(4, 1); + public static final MobEffectList HUNGER = (new MobEffectList(17, new MinecraftKey("hunger"), true, 5797459)).c("potion.hunger").b(1, 1); + public static final MobEffectList WEAKNESS = (new MobEffectAttackDamage(18, new MinecraftKey("weakness"), true, 4738376)).c("potion.weakness").b(5, 0).a(GenericAttributes.ATTACK_DAMAGE, "22653B89-116E-49DC-9B6B-9971489B5BE5", 2.0D, 0); + public static final MobEffectList POISON = (new MobEffectList(19, new MinecraftKey("poison"), true, 5149489)).c("potion.poison").b(6, 0).a(0.25D); + public static final MobEffectList WITHER = (new MobEffectList(20, new MinecraftKey("wither"), true, 3484199)).c("potion.wither").b(1, 2).a(0.25D); + public static final MobEffectList HEALTH_BOOST = (new MobEffectHealthBoost(21, new MinecraftKey("health_boost"), false, 16284963)).c("potion.healthBoost").b(2, 2).a(GenericAttributes.maxHealth, "5D6F0BA2-1186-46AC-B896-C61C5CEE99CC", 4.0D, 0); + public static final MobEffectList ABSORBTION = (new MobEffectAbsorption(22, new MinecraftKey("absorption"), false, 2445989)).c("potion.absorption").b(2, 2); + public static final MobEffectList SATURATION = (new InstantMobEffect(23, new MinecraftKey("saturation"), false, 16262179)).c("potion.saturation"); + public static final MobEffectList z = null; + public static final MobEffectList A = null; + public static final MobEffectList B = null; + public static final MobEffectList C = null; + public static final MobEffectList D = null; + public static final MobEffectList E = null; + public static final MobEffectList F = null; + public static final MobEffectList G = null; + public final int id; + private final Map J = Maps.newHashMap(); + private final boolean K; + private final int L; + private String M = ""; + private int N = -1; + private double O; + private boolean P; + + protected MobEffectList(int i, MinecraftKey minecraftkey, boolean flag, int j) { + this.id = i; + MobEffectList.byId[i] = this; + MobEffectList.I.put(minecraftkey, this); + this.K = flag; + if (flag) { + this.O = 0.5D; + } else { + this.O = 1.0D; + } + + this.L = j; + org.bukkit.potion.PotionEffectType.registerPotionEffectType(new org.bukkit.craftbukkit.potion.CraftPotionEffectType(this)); // CraftBukkit + } + + public static MobEffectList b(String s) { + return (MobEffectList) MobEffectList.I.get(new MinecraftKey(s)); + } + + public static Set c() { + return MobEffectList.I.keySet(); + } + + protected MobEffectList b(int i, int j) { + this.N = i + j * 8; + return this; + } + + public int getId() { + return this.id; + } + + public void tick(EntityLiving entityliving, int i) { + final int lastNoDamageTicks = entityliving.noDamageTicks; + if (this.id == MobEffectList.REGENERATION.id) { + if (entityliving.getHealth() < entityliving.getMaxHealth()) { + entityliving.heal(1.0F, RegainReason.MAGIC_REGEN); // CraftBukkit + } + } else if (this.id == MobEffectList.POISON.id) { + if (entityliving.getHealth() > 1.0F) { + entityliving.damageEntity(CraftEventFactory.POISON, 1.0F); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON + if (entityliving.getKBProfile().isPoison()) entityliving.noDamageTicks = lastNoDamageTicks; // fix poison + } + } else if (this.id == MobEffectList.WITHER.id) { + entityliving.damageEntity(DamageSource.WITHER, 1.0F); + if (entityliving.getKBProfile().isWither()) entityliving.noDamageTicks = lastNoDamageTicks; // fix wither + } else if (this.id == MobEffectList.HUNGER.id && entityliving instanceof EntityHuman) { + ((EntityHuman) entityliving).applyExhaustion(0.025F * (float) (i + 1)); + } else if (this.id == MobEffectList.SATURATION.id && entityliving instanceof EntityHuman) { + if (!entityliving.world.isClientSide) { + // CraftBukkit start + EntityHuman entityhuman = (EntityHuman) entityliving; + int oldFoodLevel = entityhuman.getFoodData().foodLevel; + + org.bukkit.event.entity.FoodLevelChangeEvent event = CraftEventFactory.callFoodLevelChangeEvent(entityhuman, i + 1 + oldFoodLevel); + + if (!event.isCancelled()) { + entityhuman.getFoodData().eat(event.getFoodLevel() - oldFoodLevel, 1.0F); + } + + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutUpdateHealth(((EntityPlayer) entityhuman).getBukkitEntity().getScaledHealth(), entityhuman.getFoodData().foodLevel, entityhuman.getFoodData().saturationLevel)); + // CraftBukkit end + } + } else if ((this.id != MobEffectList.HEAL.id || entityliving.bm()) && (this.id != MobEffectList.HARM.id || !entityliving.bm())) { + if (this.id == MobEffectList.HARM.id && !entityliving.bm() || this.id == MobEffectList.HEAL.id && entityliving.bm()) { + entityliving.damageEntity(DamageSource.MAGIC, (float) (6 << i)); + } + } else { + entityliving.heal((float) Math.max(4 << i, 0), RegainReason.MAGIC); // CraftBukkit + } + + } + + public void applyInstantEffect(Entity entity, Entity entity1, EntityLiving entityliving, int i, double d0) { + int j; + + if ((this.id != MobEffectList.HEAL.id || entityliving.bm()) && (this.id != MobEffectList.HARM.id || !entityliving.bm())) { + if (this.id == MobEffectList.HARM.id && !entityliving.bm() || this.id == MobEffectList.HEAL.id && entityliving.bm()) { + j = (int) (d0 * (double) (6 << i) + 0.5D); + if (entity == null) { + entityliving.damageEntity(DamageSource.MAGIC, (float) j); + } else { + entityliving.damageEntity(DamageSource.b(entity, entity1), (float) j); + } + } + } else { + j = (int) (d0 * (double) (4 << i) + 0.5D); + entityliving.heal((float) j, RegainReason.MAGIC); // CraftBukkit + } + + } + + public boolean isInstant() { + return false; + } + + public boolean a(int i, int j) { + int k; + + if (this.id == MobEffectList.REGENERATION.id) { + k = 50 >> j; + return k > 0 ? i % k == 0 : true; + } else if (this.id == MobEffectList.POISON.id) { + k = 25 >> j; + return k > 0 ? i % k == 0 : true; + } else if (this.id == MobEffectList.WITHER.id) { + k = 40 >> j; + return k > 0 ? i % k == 0 : true; + } else { + return this.id == MobEffectList.HUNGER.id; + } + } + + public MobEffectList c(String s) { + this.M = s; + return this; + } + + public String a() { + return this.M; + } + + protected MobEffectList a(double d0) { + this.O = d0; + return this; + } + + public double getDurationModifier() { + return this.O; + } + + public boolean j() { + return this.P; + } + + public int k() { + return this.L; + } + + public MobEffectList a(IAttribute iattribute, String s, double d0, int i) { + AttributeModifier attributemodifier = new AttributeModifier(UUID.fromString(s), this.a(), d0, i); + + this.J.put(iattribute, attributemodifier); + return this; + } + + public void a(EntityLiving entityliving, AttributeMapBase attributemapbase, int i) { + Iterator iterator = this.J.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + AttributeInstance attributeinstance = attributemapbase.a((IAttribute) entry.getKey()); + + if (attributeinstance != null) { + attributeinstance.c((AttributeModifier) entry.getValue()); + } + } + + } + + public void b(EntityLiving entityliving, AttributeMapBase attributemapbase, int i) { + Iterator iterator = this.J.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + AttributeInstance attributeinstance = attributemapbase.a((IAttribute) entry.getKey()); + + if (attributeinstance != null) { + AttributeModifier attributemodifier = (AttributeModifier) entry.getValue(); + + attributeinstance.c(attributemodifier); + attributeinstance.b(new AttributeModifier(attributemodifier.a(), this.a() + " " + i, this.a(i, attributemodifier), attributemodifier.c())); + } + } + + } + + public double a(int i, AttributeModifier attributemodifier) { + return attributemodifier.d() * (double) (i + 1); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobSpawnerAbstract.java new file mode 100644 index 0000000..897f8f1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/MobSpawnerAbstract.java @@ -0,0 +1,383 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; + +// CraftBukkit start +import net.techcable.tacospigot.event.entity.SpawnerPreSpawnEvent; + +import org.bukkit.Location; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.EntityType; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.SpawnerSpawnEvent; +// CraftBukkit end + +public abstract class MobSpawnerAbstract { + + public int spawnDelay = 20; + private String mobName = "Pig"; + private final List mobs = Lists.newArrayList(); + private MobSpawnerAbstract.a spawnData; + private double e; + private double f; + private int minSpawnDelay = 200; + private int maxSpawnDelay = 800; + private int spawnCount = 4; + private Entity j; + private int maxNearbyEntities = 6; + private int requiredPlayerRange = 16; + private int spawnRange = 4; + private int tickDelay = 0; // PaperSpigot + + public MobSpawnerAbstract() {} + + public String getMobName() { + if (this.i() == null) { + // CraftBukkit start - fix NPE + if (this.mobName == null) { + this.mobName = "Pig"; + } + // CraftBukkit end + if (this.mobName != null && this.mobName.equals("Minecart")) { + this.mobName = "MinecartRideable"; + } + + return this.mobName; + } else { + return this.i().d; + } + } + + public void setMobName(String s) { + this.mobName = s; + } + + private boolean g() { + BlockPosition blockposition = this.b(); + + return this.a().isPlayerNearbyWhoAffectsSpawning((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, (double) this.requiredPlayerRange); // PaperSpigot - Affects Spawning API + } + + public void c() { + // PaperSpigot start - Configurable mob spawner tick rate + if (spawnDelay > 0 && --tickDelay > 0) return; + tickDelay = this.a().paperSpigotConfig.mobSpawnerTickRate; + // PaperSpigot end + if (this.g()) { + BlockPosition blockposition = this.b(); + double d0; + + if (this.a().isClientSide) { + double d1 = (double) ((float) blockposition.getX() + this.a().random.nextFloat()); + double d2 = (double) ((float) blockposition.getY() + this.a().random.nextFloat()); + + d0 = (double) ((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]); + if (this.spawnDelay > 0) { + this.spawnDelay -= tickDelay; // PaperSpigot + } + + this.f = this.e; + this.e = (this.e + (double) (1000.0F / ((float) this.spawnDelay + 200.0F))) % 360.0D; + } else { + if (this.spawnDelay < -tickDelay) { // PaperSpigot + this.h(); + } + + if (this.spawnDelay > 0) { + this.spawnDelay -= tickDelay; // PaperSpigot + return; + } + + boolean flag = false; + + for (int i = 0; i < this.spawnCount; ++i) { + // TacoSpigot start + SpawnerPreSpawnEvent event = new SpawnerPreSpawnEvent( new Location(this.a().getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()), EntityType.fromName(this.getMobName())); + this.a().getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + flag = true; + break; + } + // TacoSpigot end + + Entity entity = EntityTypes.createEntityByName(this.getMobName(), this.a()); + + if (entity == null) { + return; + } + + int j = this.a().a(entity.getClass(), (new AxisAlignedBB((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), (double) (blockposition.getX() + 1), (double) (blockposition.getY() + 1), (double) (blockposition.getZ() + 1))).grow((double) this.spawnRange, (double) this.spawnRange, (double) this.spawnRange)).size(); + + if (j >= this.maxNearbyEntities) { + this.h(); + return; + } + + d0 = (double) blockposition.getX() + (this.a().random.nextDouble() - this.a().random.nextDouble()) * (double) this.spawnRange + 0.5D; + double d3 = (double) (blockposition.getY() + this.a().random.nextInt(3) - 1); + double d4 = (double) blockposition.getZ() + (this.a().random.nextDouble() - this.a().random.nextDouble()) * (double) this.spawnRange + 0.5D; + EntityInsentient entityinsentient = entity instanceof EntityInsentient ? (EntityInsentient) entity : null; + + entity.setPositionRotation(d0, d3, d4, this.a().random.nextFloat() * 360.0F, 0.0F); + if (entityinsentient == null || entityinsentient.bR() && entityinsentient.canSpawn()) { + this.a(entity, true); + this.a().triggerEffect(2004, blockposition, 0); + if (entityinsentient != null) { + entityinsentient.y(); + } + + flag = true; + } + } + + if (flag) { + this.h(); + } + } + + } + } + + private Entity a(Entity entity, boolean flag) { + if (this.i() != null) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + entity.d(nbttagcompound); + Iterator iterator = this.i().c.c().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + NBTBase nbtbase = this.i().c.get(s); + + nbttagcompound.set(s, nbtbase.clone()); + } + + entity.f(nbttagcompound); + if (entity.world != null && flag) { + // CraftBukkit start - call SpawnerSpawnEvent, abort if cancelled + SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b().getX(), this.b().getY(), this.b().getZ()); + if (!event.isCancelled()) { + entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + // Spigot Start + if ( entity.world.spigotConfig.nerfSpawnerMobs ) + { + entity.fromMobSpawner = true; + } + // Spigot End + } + // CraftBukkit end + } + + NBTTagCompound nbttagcompound1; + + for (Entity entity1 = entity; nbttagcompound.hasKeyOfType("Riding", 10); nbttagcompound = nbttagcompound1) { + nbttagcompound1 = nbttagcompound.getCompound("Riding"); + Entity entity2 = EntityTypes.createEntityByName(nbttagcompound1.getString("id"), entity.world); + + if (entity2 != null) { + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); + + entity2.d(nbttagcompound2); + Iterator iterator1 = nbttagcompound1.c().iterator(); + + while (iterator1.hasNext()) { + String s1 = (String) iterator1.next(); + NBTBase nbtbase1 = nbttagcompound1.get(s1); + + nbttagcompound2.set(s1, nbtbase1.clone()); + } + + entity2.f(nbttagcompound2); + entity2.setPositionRotation(entity1.locX, entity1.locY, entity1.locZ, entity1.yaw, entity1.pitch); + // CraftBukkit start - call SpawnerSpawnEvent, skip if cancelled + SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity2, this.b().getX(), this.b().getY(), this.b().getZ()); + if (event.isCancelled()) { + continue; + } + if (entity.world != null && flag) { + entity.world.addEntity(entity2, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + } + + entity1.mount(entity2); + } + + entity1 = entity2; + } + } else if (entity instanceof EntityLiving && entity.world != null && flag) { + if (entity instanceof EntityInsentient) { + ((EntityInsentient) entity).prepare(entity.world.E(new BlockPosition(entity)), (GroupDataEntity) null); + } + // Spigot start - call SpawnerSpawnEvent, abort if cancelled + SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b().getX(), this.b().getY(), this.b().getZ()); + if (!event.isCancelled()) { + entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + // Spigot Start + if ( entity.world.spigotConfig.nerfSpawnerMobs ) + { + entity.fromMobSpawner = true; + } + // Spigot End + } + // Spigot end + } + + return entity; + } + + private void h() { + if (this.maxSpawnDelay <= this.minSpawnDelay) { + this.spawnDelay = this.minSpawnDelay; + } else { + int i = this.maxSpawnDelay - this.minSpawnDelay; + + this.spawnDelay = this.minSpawnDelay + this.a().random.nextInt(i); + } + + if (this.mobs.size() > 0) { + this.a((MobSpawnerAbstract.a) WeightedRandom.a(this.a().random, this.mobs)); + } + + this.a(1); + } + + public void a(NBTTagCompound nbttagcompound) { + this.mobName = nbttagcompound.getString("EntityId"); + this.spawnDelay = nbttagcompound.getShort("Delay"); + this.mobs.clear(); + if (nbttagcompound.hasKeyOfType("SpawnPotentials", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("SpawnPotentials", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + this.mobs.add(new MobSpawnerAbstract.a(nbttaglist.get(i))); + } + } + + if (nbttagcompound.hasKeyOfType("SpawnData", 10)) { + this.a(new MobSpawnerAbstract.a(nbttagcompound.getCompound("SpawnData"), this.mobName)); + } else { + this.a((MobSpawnerAbstract.a) null); + } + + if (nbttagcompound.hasKeyOfType("MinSpawnDelay", 99)) { + this.minSpawnDelay = nbttagcompound.getShort("MinSpawnDelay"); + this.maxSpawnDelay = nbttagcompound.getShort("MaxSpawnDelay"); + this.spawnCount = nbttagcompound.getShort("SpawnCount"); + } + + if (nbttagcompound.hasKeyOfType("MaxNearbyEntities", 99)) { + this.maxNearbyEntities = nbttagcompound.getShort("MaxNearbyEntities"); + this.requiredPlayerRange = nbttagcompound.getShort("RequiredPlayerRange"); + } + + if (nbttagcompound.hasKeyOfType("SpawnRange", 99)) { + this.spawnRange = nbttagcompound.getShort("SpawnRange"); + } + + if (this.a() != null) { + this.j = null; + } + + } + + public void b(NBTTagCompound nbttagcompound) { + String s = this.getMobName(); + + if (!UtilColor.b(s)) { + nbttagcompound.setString("EntityId", s); + nbttagcompound.setShort("Delay", (short) this.spawnDelay); + nbttagcompound.setShort("MinSpawnDelay", (short) this.minSpawnDelay); + nbttagcompound.setShort("MaxSpawnDelay", (short) this.maxSpawnDelay); + nbttagcompound.setShort("SpawnCount", (short) this.spawnCount); + nbttagcompound.setShort("MaxNearbyEntities", (short) this.maxNearbyEntities); + nbttagcompound.setShort("RequiredPlayerRange", (short) this.requiredPlayerRange); + nbttagcompound.setShort("SpawnRange", (short) this.spawnRange); + if (this.i() != null) { + nbttagcompound.set("SpawnData", this.i().c.clone()); + } + + if (this.i() != null || this.mobs.size() > 0) { + NBTTagList nbttaglist = new NBTTagList(); + + if (this.mobs.size() > 0) { + Iterator iterator = this.mobs.iterator(); + + while (iterator.hasNext()) { + MobSpawnerAbstract.a mobspawnerabstract_a = (MobSpawnerAbstract.a) iterator.next(); + + nbttaglist.add(mobspawnerabstract_a.a()); + } + } else { + nbttaglist.add(this.i().a()); + } + + nbttagcompound.set("SpawnPotentials", nbttaglist); + } + + } + } + + public boolean b(int i) { + if (i == 1 && this.a().isClientSide) { + this.spawnDelay = this.minSpawnDelay; + return true; + } else { + return false; + } + } + + private MobSpawnerAbstract.a i() { + return this.spawnData; + } + + public void a(MobSpawnerAbstract.a mobspawnerabstract_a) { + this.spawnData = mobspawnerabstract_a; + } + + public abstract void a(int i); + + public abstract World a(); + + public abstract BlockPosition b(); + + public class a extends WeightedRandom.WeightedRandomChoice { + + private final NBTTagCompound c; + private final String d; + + public a(NBTTagCompound nbttagcompound) { + this(nbttagcompound.getCompound("Properties"), nbttagcompound.getString("Type"), nbttagcompound.getInt("Weight")); + } + + public a(NBTTagCompound nbttagcompound, String s) { + this(nbttagcompound, s, 1); + } + + private a(NBTTagCompound nbttagcompound, String s, int i) { + super(i); + if (s.equals("Minecart")) { + if (nbttagcompound != null) { + s = EntityMinecartAbstract.EnumMinecartType.a(nbttagcompound.getInt("Type")).b(); + } else { + s = "MinecartRideable"; + } + } + + this.c = nbttagcompound; + this.d = s; + } + + public NBTTagCompound a() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + nbttagcompound.set("Properties", this.c); + nbttagcompound.setString("Type", this.d); + nbttagcompound.setInt("Weight", this.a); + return nbttagcompound; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTBase.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTBase.java new file mode 100644 index 0000000..8756b63 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTBase.java @@ -0,0 +1,104 @@ +package net.minecraft.server; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public abstract class NBTBase { + + public static final String[] a = new String[] { "END", "BYTE", "SHORT", "INT", "LONG", "FLOAT", "DOUBLE", "BYTE[]", "STRING", "LIST", "COMPOUND", "INT[]"}; + + abstract void write(DataOutput dataoutput) throws IOException; + + abstract void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException; + + public abstract String toString(); + + public abstract byte getTypeId(); + + protected NBTBase() {} + + protected static NBTBase createTag(byte b0) { + switch (b0) { + case 0: + return new NBTTagEnd(); + + case 1: + return new NBTTagByte(); + + case 2: + return new NBTTagShort(); + + case 3: + return new NBTTagInt(); + + case 4: + return new NBTTagLong(); + + case 5: + return new NBTTagFloat(); + + case 6: + return new NBTTagDouble(); + + case 7: + return new NBTTagByteArray(); + + case 8: + return new NBTTagString(); + + case 9: + return new NBTTagList(); + + case 10: + return new NBTTagCompound(); + + case 11: + return new NBTTagIntArray(); + + default: + return null; + } + } + + public abstract NBTBase clone(); + + public boolean isEmpty() { + return false; + } + + public boolean equals(Object object) { + if (!(object instanceof NBTBase)) { + return false; + } else { + NBTBase nbtbase = (NBTBase) object; + + return this.getTypeId() == nbtbase.getTypeId(); + } + } + + public int hashCode() { + return this.getTypeId(); + } + + protected String a_() { + return this.toString(); + } + + public abstract static class NBTNumber extends NBTBase { + + protected NBTNumber() {} + + public abstract long c(); + + public abstract int d(); + + public abstract short e(); + + public abstract byte f(); + + public abstract double g(); + + public abstract float h(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java new file mode 100644 index 0000000..56db742 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTCompressedStreamTools.java @@ -0,0 +1,96 @@ +package net.minecraft.server; + +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; + +import java.io.*; +import java.util.logging.Level; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class NBTCompressedStreamTools { + + public static NBTTagCompound a(InputStream inputstream) throws IOException { + DataInputStream datainputstream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(inputstream))); + + NBTTagCompound nbttagcompound; + + try { + nbttagcompound = a(datainputstream, NBTReadLimiter.a); + } finally { + datainputstream.close(); + } + + return nbttagcompound; + } + + public static void a(NBTTagCompound nbttagcompound, OutputStream outputstream) throws IOException { + DataOutputStream dataoutputstream = new DataOutputStream(new BufferedOutputStream(new GZIPOutputStream(outputstream))); + + try { + a(nbttagcompound, (DataOutput) dataoutputstream); + } finally { + dataoutputstream.close(); + } + + } + + public static NBTTagCompound a(DataInputStream datainputstream) throws IOException { + return a(datainputstream, NBTReadLimiter.a); + } + + public static NBTTagCompound a(DataInput datainput, NBTReadLimiter nbtreadlimiter) throws IOException { + // Spigot start + if ( datainput instanceof io.netty.buffer.ByteBufInputStream ) + { + datainput = new DataInputStream(new org.spigotmc.LimitStream((InputStream) datainput, nbtreadlimiter)); + } + // Spigot end + NBTBase nbtbase = a(datainput, 0, nbtreadlimiter); + + if (nbtbase instanceof NBTTagCompound) { + return (NBTTagCompound) nbtbase; + } else { + throw new IOException("Root tag must be a named compound tag"); + } + } + + public static void a(NBTTagCompound nbttagcompound, DataOutput dataoutput) throws IOException { + a((NBTBase) nbttagcompound, dataoutput); + } + + private static void a(NBTBase nbtbase, DataOutput dataoutput) throws IOException { + dataoutput.writeByte(nbtbase.getTypeId()); + if (nbtbase.getTypeId() != 0) { + dataoutput.writeUTF(""); + nbtbase.write(dataoutput); + } + } + + private static NBTBase a(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException { + byte b0 = datainput.readByte(); + + if (b0 == 0) { + return new NBTTagEnd(); + } else { + datainput.readUTF(); + NBTBase nbtbase = NBTBase.createTag(b0); + + try { + nbtbase.load(datainput, i, nbtreadlimiter); + return nbtbase; + } catch (IOException ioexception) { + CrashReport crashreport = CrashReport.a(ioexception, "Loading NBT data"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("NBT Tag"); + + crashreportsystemdetails.a("Tag name", "[UNNAMED TAG]"); + crashreportsystemdetails.a("Tag type", Byte.valueOf(b0)); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + return nbtbase; + } + throw new ReportedException(crashreport); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagByteArray.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagByteArray.java new file mode 100644 index 0000000..13e9d0b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagByteArray.java @@ -0,0 +1,59 @@ +package net.minecraft.server; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +public class NBTTagByteArray extends NBTBase { + + private byte[] data; + + NBTTagByteArray() {} + + public NBTTagByteArray(byte[] abyte) { + this.data = abyte; + } + + void write(DataOutput dataoutput) throws IOException { + dataoutput.writeInt(this.data.length); + dataoutput.write(this.data); + } + + void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException { + nbtreadlimiter.a(192L); + int j = datainput.readInt(); + com.google.common.base.Preconditions.checkArgument( j < 1 << 24); + + nbtreadlimiter.a((long) (8 * j)); + this.data = new byte[j]; + datainput.readFully(this.data); + } + + public byte getTypeId() { + return (byte) 7; + } + + public String toString() { + return "[" + this.data.length + " bytes]"; + } + + public NBTBase clone() { + byte[] abyte = new byte[this.data.length]; + + System.arraycopy(this.data, 0, abyte, 0, this.data.length); + return new NBTTagByteArray(abyte); + } + + public boolean equals(Object object) { + return super.equals(object) ? Arrays.equals(this.data, ((NBTTagByteArray) object).data) : false; + } + + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.data); + } + + public byte[] c() { + return this.data; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagIntArray.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagIntArray.java new file mode 100644 index 0000000..e206e50 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagIntArray.java @@ -0,0 +1,77 @@ +package net.minecraft.server; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; + +public class NBTTagIntArray extends NBTBase { + + private int[] data; + + NBTTagIntArray() {} + + public NBTTagIntArray(int[] aint) { + this.data = aint; + } + + void write(DataOutput dataoutput) throws IOException { + dataoutput.writeInt(this.data.length); + + for (int i = 0; i < this.data.length; ++i) { + dataoutput.writeInt(this.data[i]); + } + + } + + void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException { + nbtreadlimiter.a(192L); + int j = datainput.readInt(); + com.google.common.base.Preconditions.checkArgument( j < 1 << 24); + + nbtreadlimiter.a((long) (32 * j)); + this.data = new int[j]; + + for (int k = 0; k < j; ++k) { + this.data[k] = datainput.readInt(); + } + + } + + public byte getTypeId() { + return (byte) 11; + } + + public String toString() { + String s = "["; + int[] aint = this.data; + int i = aint.length; + + for (int j = 0; j < i; ++j) { + int k = aint[j]; + + s = s + k + ","; + } + + return s + "]"; + } + + public NBTBase clone() { + int[] aint = new int[this.data.length]; + + System.arraycopy(this.data, 0, aint, 0, this.data.length); + return new NBTTagIntArray(aint); + } + + public boolean equals(Object object) { + return super.equals(object) ? Arrays.equals(this.data, ((NBTTagIntArray) object).data) : false; + } + + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.data); + } + + public int[] c() { + return this.data; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagList.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagList.java new file mode 100644 index 0000000..a0e6b0f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NBTTagList.java @@ -0,0 +1,213 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class NBTTagList extends NBTBase { + + private static final Logger b = LogManager.getLogger(); + private List list = Lists.newArrayList(); + private byte type = 0; + + public NBTTagList() {} + + void write(DataOutput dataoutput) throws IOException { + if (!this.list.isEmpty()) { + this.type = ((NBTBase) this.list.get(0)).getTypeId(); + } else { + this.type = 0; + } + + dataoutput.writeByte(this.type); + dataoutput.writeInt(this.list.size()); + + for (int i = 0; i < this.list.size(); ++i) { + ((NBTBase) this.list.get(i)).write(dataoutput); + } + + } + + void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException { + nbtreadlimiter.a(296L); + if (i > 512) { + throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512"); + } else { + this.type = datainput.readByte(); + int j = datainput.readInt(); + nbtreadlimiter.a(j * 8); // CraftBukkit + + if (this.type == 0 && j > 0) { + throw new RuntimeException("Missing type on ListTag"); + } else { + nbtreadlimiter.a(32L * (long) j); + this.list = Lists.newArrayListWithCapacity(j); + + for (int k = 0; k < j; ++k) { + NBTBase nbtbase = NBTBase.createTag(this.type); + + nbtbase.load(datainput, i + 1, nbtreadlimiter); + this.list.add(nbtbase); + } + + } + } + } + + public byte getTypeId() { + return (byte) 9; + } + + public String toString() { + StringBuilder stringbuilder = new StringBuilder("["); + + for (int i = 0; i < this.list.size(); ++i) { + if (i != 0) { + stringbuilder.append(','); + } + + stringbuilder.append(i).append(':').append(this.list.get(i)); + } + + return stringbuilder.append(']').toString(); + } + + public void add(NBTBase nbtbase) { + if (nbtbase.getTypeId() == 0) { + NBTTagList.b.warn("Invalid TagEnd added to ListTag"); + } else { + if (this.type == 0) { + this.type = nbtbase.getTypeId(); + } else if (this.type != nbtbase.getTypeId()) { + NBTTagList.b.warn("Adding mismatching tag types to tag list"); + return; + } + + this.list.add(nbtbase); + } + } + + public void a(int i, NBTBase nbtbase) { + if (nbtbase.getTypeId() == 0) { + NBTTagList.b.warn("Invalid TagEnd added to ListTag"); + } else if (i >= 0 && i < this.list.size()) { + if (this.type == 0) { + this.type = nbtbase.getTypeId(); + } else if (this.type != nbtbase.getTypeId()) { + NBTTagList.b.warn("Adding mismatching tag types to tag list"); + return; + } + + this.list.set(i, nbtbase); + } else { + NBTTagList.b.warn("index out of bounds to set tag in tag list"); + } + } + + public NBTBase a(int i) { + return (NBTBase) this.list.remove(i); + } + + public boolean isEmpty() { + return this.list.isEmpty(); + } + + public NBTTagCompound get(int i) { + if (i >= 0 && i < this.list.size()) { + NBTBase nbtbase = (NBTBase) this.list.get(i); + + return nbtbase.getTypeId() == 10 ? (NBTTagCompound) nbtbase : new NBTTagCompound(); + } else { + return new NBTTagCompound(); + } + } + + public int[] c(int i) { + if (i >= 0 && i < this.list.size()) { + NBTBase nbtbase = (NBTBase) this.list.get(i); + + return nbtbase.getTypeId() == 11 ? ((NBTTagIntArray) nbtbase).c() : new int[0]; + } else { + return new int[0]; + } + } + + public double d(int i) { + if (i >= 0 && i < this.list.size()) { + NBTBase nbtbase = (NBTBase) this.list.get(i); + + return nbtbase.getTypeId() == 6 ? ((NBTTagDouble) nbtbase).g() : 0.0D; + } else { + return 0.0D; + } + } + + public float e(int i) { + if (i >= 0 && i < this.list.size()) { + NBTBase nbtbase = (NBTBase) this.list.get(i); + + return nbtbase.getTypeId() == 5 ? ((NBTTagFloat) nbtbase).h() : 0.0F; + } else { + return 0.0F; + } + } + + public String getString(int i) { + if (i >= 0 && i < this.list.size()) { + NBTBase nbtbase = (NBTBase) this.list.get(i); + + return nbtbase.getTypeId() == 8 ? nbtbase.a_() : nbtbase.toString(); + } else { + return ""; + } + } + + public NBTBase g(int i) { + return (NBTBase) (i >= 0 && i < this.list.size() ? (NBTBase) this.list.get(i) : new NBTTagEnd()); + } + + public int size() { + return this.list.size(); + } + + public NBTBase clone() { + NBTTagList nbttaglist = new NBTTagList(); + + nbttaglist.type = this.type; + Iterator iterator = this.list.iterator(); + + while (iterator.hasNext()) { + NBTBase nbtbase = (NBTBase) iterator.next(); + NBTBase nbtbase1 = nbtbase.clone(); + + nbttaglist.list.add(nbtbase1); + } + + return nbttaglist; + } + + public boolean equals(Object object) { + if (super.equals(object)) { + NBTTagList nbttaglist = (NBTTagList) object; + + if (this.type == nbttaglist.type) { + return this.list.equals(nbttaglist.list); + } + } + + return false; + } + + public int hashCode() { + return super.hashCode() ^ this.list.hashCode(); + } + + public int f() { + return this.type; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NameReferencingFileConverter.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NameReferencingFileConverter.java new file mode 100644 index 0000000..d67539c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NameReferencingFileConverter.java @@ -0,0 +1,539 @@ +package net.minecraft.server; + +import com.google.common.base.Charsets; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.io.Files; +import com.mojang.authlib.Agent; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.ProfileLookupCallback; +import com.mojang.authlib.yggdrasil.ProfileNotFoundException; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class NameReferencingFileConverter { + + private static final Logger e = LogManager.getLogger(); + public static final File a = new File("banned-ips.txt"); + public static final File b = new File("banned-players.txt"); + public static final File c = new File("ops.txt"); + public static final File d = new File("white-list.txt"); + + static List a(File file, Map map) throws IOException { + List list = Files.readLines(file, Charsets.UTF_8); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + + s = s.trim(); + if (!s.startsWith("#") && s.length() >= 1) { + String[] astring = s.split("\\|"); + + map.put(astring[0].toLowerCase(Locale.ROOT), astring); + } + } + + return list; + } + + private static void a(MinecraftServer minecraftserver, Collection collection, ProfileLookupCallback profilelookupcallback) { + String[] astring = (String[]) Iterators.toArray(Iterators.filter(collection.iterator(), new Predicate() { + public boolean a(String s) { + return !UtilColor.b(s); + } + + public boolean apply(Object object) { + return this.a((String) object); + } + }), String.class); + + if (minecraftserver.getOnlineMode() || org.spigotmc.SpigotConfig.bungee) { // Spigot: bungee = online mode, for now. + minecraftserver.getGameProfileRepository().findProfilesByNames(astring, Agent.MINECRAFT, profilelookupcallback); + } else { + String[] astring1 = astring; + int i = astring.length; + + for (int j = 0; j < i; ++j) { + String s = astring1[j]; + UUID uuid = EntityHuman.a(new GameProfile((UUID) null, s)); + GameProfile gameprofile = new GameProfile(uuid, s); + + profilelookupcallback.onProfileLookupSucceeded(gameprofile); + } + } + + } + + public static boolean a(final MinecraftServer minecraftserver) { + final GameProfileBanList gameprofilebanlist = new GameProfileBanList(PlayerList.a); + + if (NameReferencingFileConverter.b.exists() && NameReferencingFileConverter.b.isFile()) { + if (gameprofilebanlist.c().exists()) { + try { + gameprofilebanlist.load(); + // CraftBukkit start - FileNotFoundException -> IOException, don't print stacetrace + } catch (IOException filenotfoundexception) { + NameReferencingFileConverter.e.warn("Could not load existing file " + gameprofilebanlist.c().getName()); + } + } + + try { + final HashMap hashmap = Maps.newHashMap(); + + a(NameReferencingFileConverter.b, (Map) hashmap); + ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { + public void onProfileLookupSucceeded(GameProfile gameprofile) { + minecraftserver.getUserCache().a(gameprofile); + String[] astring = (String[]) hashmap.get(gameprofile.getName().toLowerCase(Locale.ROOT)); + + if (astring == null) { + NameReferencingFileConverter.e.warn("Could not convert user banlist entry for " + gameprofile.getName()); + throw new NameReferencingFileConverter.FileConversionException("Profile not in the conversionlist", null); + } else { + Date date = astring.length > 1 ? NameReferencingFileConverter.b(astring[1], (Date) null) : null; + String s = astring.length > 2 ? astring[2] : null; + Date date1 = astring.length > 3 ? NameReferencingFileConverter.b(astring[3], (Date) null) : null; + String s1 = astring.length > 4 ? astring[4] : null; + + gameprofilebanlist.add(new GameProfileBanEntry(gameprofile, date, s, date1, s1)); + } + } + + public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { + NameReferencingFileConverter.e.warn("Could not lookup user banlist entry for " + gameprofile.getName(), exception); + if (!(exception instanceof ProfileNotFoundException)) { + throw new NameReferencingFileConverter.FileConversionException("Could not request user " + gameprofile.getName() + " from backend systems", exception, null); + } + } + }; + + a(minecraftserver, hashmap.keySet(), profilelookupcallback); + gameprofilebanlist.save(); + c(NameReferencingFileConverter.b); + return true; + } catch (IOException ioexception) { + NameReferencingFileConverter.e.warn("Could not read old user banlist to convert it!", ioexception); + return false; + } catch (NameReferencingFileConverter.FileConversionException namereferencingfileconverter_fileconversionexception) { + NameReferencingFileConverter.e.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); + return false; + } + } else { + return true; + } + } + + public static boolean b(MinecraftServer minecraftserver) { + IpBanList ipbanlist = new IpBanList(PlayerList.b); + + if (NameReferencingFileConverter.a.exists() && NameReferencingFileConverter.a.isFile()) { + if (ipbanlist.c().exists()) { + try { + ipbanlist.load(); + // CraftBukkit start - FileNotFoundException -> IOException, don't print stacetrace + } catch (IOException filenotfoundexception) { + NameReferencingFileConverter.e.warn("Could not load existing file " + ipbanlist.c().getName()); + } + } + + try { + HashMap hashmap = Maps.newHashMap(); + + a(NameReferencingFileConverter.a, (Map) hashmap); + Iterator iterator = hashmap.keySet().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + String[] astring = (String[]) hashmap.get(s); + Date date = astring.length > 1 ? b(astring[1], (Date) null) : null; + String s1 = astring.length > 2 ? astring[2] : null; + Date date1 = astring.length > 3 ? b(astring[3], (Date) null) : null; + String s2 = astring.length > 4 ? astring[4] : null; + + ipbanlist.add(new IpBanEntry(s, date, s1, date1, s2)); + } + + ipbanlist.save(); + c(NameReferencingFileConverter.a); + return true; + } catch (IOException ioexception) { + NameReferencingFileConverter.e.warn("Could not parse old ip banlist to convert it!", ioexception); + return false; + } + } else { + return true; + } + } + + public static boolean c(final MinecraftServer minecraftserver) { + final OpList oplist = new OpList(PlayerList.c); + + if (NameReferencingFileConverter.c.exists() && NameReferencingFileConverter.c.isFile()) { + if (oplist.c().exists()) { + try { + oplist.load(); + // CraftBukkit start - FileNotFoundException -> IOException, don't print stacetrace + } catch (IOException filenotfoundexception) { + NameReferencingFileConverter.e.warn("Could not load existing file " + oplist.c().getName()); + } + } + + try { + List list = Files.readLines(NameReferencingFileConverter.c, Charsets.UTF_8); + ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { + public void onProfileLookupSucceeded(GameProfile gameprofile) { + minecraftserver.getUserCache().a(gameprofile); + oplist.add(new OpListEntry(gameprofile, minecraftserver.p(), false)); + } + + public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { + NameReferencingFileConverter.e.warn("Could not lookup oplist entry for " + gameprofile.getName(), exception); + if (!(exception instanceof ProfileNotFoundException)) { + throw new NameReferencingFileConverter.FileConversionException("Could not request user " + gameprofile.getName() + " from backend systems", exception, null); + } + } + }; + + a(minecraftserver, list, profilelookupcallback); + oplist.save(); + c(NameReferencingFileConverter.c); + return true; + } catch (IOException ioexception) { + NameReferencingFileConverter.e.warn("Could not read old oplist to convert it!", ioexception); + return false; + } catch (NameReferencingFileConverter.FileConversionException namereferencingfileconverter_fileconversionexception) { + NameReferencingFileConverter.e.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); + return false; + } + } else { + return true; + } + } + + public static boolean d(final MinecraftServer minecraftserver) { + final WhiteList whitelist = new WhiteList(PlayerList.d); + + if (NameReferencingFileConverter.d.exists() && NameReferencingFileConverter.d.isFile()) { + if (whitelist.c().exists()) { + try { + whitelist.load(); + // CraftBukkit start - FileNotFoundException -> IOException, don't print stacetrace + } catch (IOException filenotfoundexception) { + NameReferencingFileConverter.e.warn("Could not load existing file " + whitelist.c().getName()); + } + } + + try { + List list = Files.readLines(NameReferencingFileConverter.d, Charsets.UTF_8); + ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { + public void onProfileLookupSucceeded(GameProfile gameprofile) { + minecraftserver.getUserCache().a(gameprofile); + whitelist.add(new WhiteListEntry(gameprofile)); + } + + public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { + NameReferencingFileConverter.e.warn("Could not lookup user whitelist entry for " + gameprofile.getName(), exception); + if (!(exception instanceof ProfileNotFoundException)) { + throw new NameReferencingFileConverter.FileConversionException("Could not request user " + gameprofile.getName() + " from backend systems", exception, null); + } + } + }; + + a(minecraftserver, list, profilelookupcallback); + whitelist.save(); + c(NameReferencingFileConverter.d); + return true; + } catch (IOException ioexception) { + NameReferencingFileConverter.e.warn("Could not read old whitelist to convert it!", ioexception); + return false; + } catch (NameReferencingFileConverter.FileConversionException namereferencingfileconverter_fileconversionexception) { + NameReferencingFileConverter.e.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); + return false; + } + } else { + return true; + } + } + + public static String a(String s) { + if (!UtilColor.b(s) && s.length() <= 16) { + final MinecraftServer minecraftserver = MinecraftServer.getServer(); + GameProfile gameprofile = minecraftserver.getUserCache().getProfile(s); + + if (gameprofile != null && gameprofile.getId() != null) { + return gameprofile.getId().toString(); + } else if (!minecraftserver.T() && minecraftserver.getOnlineMode()) { + final ArrayList arraylist = Lists.newArrayList(); + ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { + public void onProfileLookupSucceeded(GameProfile gameprofile) { + minecraftserver.getUserCache().a(gameprofile); + arraylist.add(gameprofile); + } + + public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { + NameReferencingFileConverter.e.warn("Could not lookup user whitelist entry for " + gameprofile.getName(), exception); + } + }; + + a(minecraftserver, Lists.newArrayList(new String[] { s}), profilelookupcallback); + return arraylist.size() > 0 && ((GameProfile) arraylist.get(0)).getId() != null ? ((GameProfile) arraylist.get(0)).getId().toString() : ""; + } else { + return EntityHuman.a(new GameProfile((UUID) null, s)).toString(); + } + } else { + return s; + } + } + + public static boolean a(final DedicatedServer dedicatedserver, PropertyManager propertymanager) { + final File file = d(propertymanager); + final File file1 = new File(file.getParentFile(), "playerdata"); + final File file2 = new File(file.getParentFile(), "unknownplayers"); + + if (file.exists() && file.isDirectory()) { + File[] afile = file.listFiles(); + ArrayList arraylist = Lists.newArrayList(); + File[] afile1 = afile; + int i = afile.length; + + for (int j = 0; j < i; ++j) { + File file3 = afile1[j]; + String s = file3.getName(); + + if (s.toLowerCase(Locale.ROOT).endsWith(".dat")) { + String s1 = s.substring(0, s.length() - ".dat".length()); + + if (s1.length() > 0) { + arraylist.add(s1); + } + } + } + + try { + final String[] astring = (String[]) arraylist.toArray(new String[arraylist.size()]); + ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { + public void onProfileLookupSucceeded(GameProfile gameprofile) { + dedicatedserver.getUserCache().a(gameprofile); + UUID uuid = gameprofile.getId(); + + if (uuid == null) { + throw new NameReferencingFileConverter.FileConversionException("Missing UUID for user profile " + gameprofile.getName(), null); + } else { + this.a(file, this.a(gameprofile), uuid.toString()); + } + } + + public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { + NameReferencingFileConverter.e.warn("Could not lookup user uuid for " + gameprofile.getName(), exception); + if (exception instanceof ProfileNotFoundException) { + String s = this.a(gameprofile); + + this.a(file, s, s); + } else { + throw new NameReferencingFileConverter.FileConversionException("Could not request user " + gameprofile.getName() + " from backend systems", exception, null); + } + } + + private void a(File file, String s, String s1) { + File file1 = new File(file2, s + ".dat"); + File file3 = new File(file, s1 + ".dat"); + + // CraftBukkit start - Use old file name to seed lastKnownName + NBTTagCompound root = null; + + try { + root = NBTCompressedStreamTools.a(new java.io.FileInputStream(file1)); + } catch (Exception exception) { + exception.printStackTrace(); + } + + if (root != null) { + if (!root.hasKey("bukkit")) { + root.set("bukkit", new NBTTagCompound()); + } + NBTTagCompound data = root.getCompound("bukkit"); + data.setString("lastKnownName", s); + + try { + NBTCompressedStreamTools.a(root, new java.io.FileOutputStream(file2)); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + // CraftBukkit end + + NameReferencingFileConverter.b(file); + if (!file1.renameTo(file3)) { + throw new NameReferencingFileConverter.FileConversionException("Could not convert file for " + s, null); + } + } + + private String a(GameProfile gameprofile) { + String s = null; + + for (int i = 0; i < astring.length; ++i) { + if (astring[i] != null && astring[i].equalsIgnoreCase(gameprofile.getName())) { + s = astring[i]; + break; + } + } + + if (s == null) { + throw new NameReferencingFileConverter.FileConversionException("Could not find the filename for " + gameprofile.getName() + " anymore", null); + } else { + return s; + } + } + }; + + a(dedicatedserver, Lists.newArrayList(astring), profilelookupcallback); + return true; + } catch (NameReferencingFileConverter.FileConversionException namereferencingfileconverter_fileconversionexception) { + NameReferencingFileConverter.e.error("Conversion failed, please try again later", namereferencingfileconverter_fileconversionexception); + return false; + } + } else { + return true; + } + } + + private static void b(File file) { + if (file.exists()) { + if (!file.isDirectory()) { + throw new NameReferencingFileConverter.FileConversionException("Can\'t create directory " + file.getName() + " in world save directory.", null); + } + } else if (!file.mkdirs()) { + throw new NameReferencingFileConverter.FileConversionException("Can\'t create directory " + file.getName() + " in world save directory.", null); + } + } + + public static boolean a(PropertyManager propertymanager) { + boolean flag = b(propertymanager); + + flag = flag && c(propertymanager); + return flag; + } + + private static boolean b(PropertyManager propertymanager) { + boolean flag = false; + + if (NameReferencingFileConverter.b.exists() && NameReferencingFileConverter.b.isFile()) { + flag = true; + } + + boolean flag1 = false; + + if (NameReferencingFileConverter.a.exists() && NameReferencingFileConverter.a.isFile()) { + flag1 = true; + } + + boolean flag2 = false; + + if (NameReferencingFileConverter.c.exists() && NameReferencingFileConverter.c.isFile()) { + flag2 = true; + } + + boolean flag3 = false; + + if (NameReferencingFileConverter.d.exists() && NameReferencingFileConverter.d.isFile()) { + flag3 = true; + } + + if (!flag && !flag1 && !flag2 && !flag3) { + return true; + } else { + NameReferencingFileConverter.e.warn("**** FAILED TO START THE SERVER AFTER ACCOUNT CONVERSION!"); + NameReferencingFileConverter.e.warn("** please remove the following files and restart the server:"); + if (flag) { + NameReferencingFileConverter.e.warn("* " + NameReferencingFileConverter.b.getName()); + } + + if (flag1) { + NameReferencingFileConverter.e.warn("* " + NameReferencingFileConverter.a.getName()); + } + + if (flag2) { + NameReferencingFileConverter.e.warn("* " + NameReferencingFileConverter.c.getName()); + } + + if (flag3) { + NameReferencingFileConverter.e.warn("* " + NameReferencingFileConverter.d.getName()); + } + + return false; + } + } + + private static boolean c(PropertyManager propertymanager) { + File file = d(propertymanager); + + if (file.exists() && file.isDirectory() && (file.list().length > 0 || !file.delete())) { + NameReferencingFileConverter.e.warn("**** DETECTED OLD PLAYER DIRECTORY IN THE WORLD SAVE"); + NameReferencingFileConverter.e.warn("**** THIS USUALLY HAPPENS WHEN THE AUTOMATIC CONVERSION FAILED IN SOME WAY"); + NameReferencingFileConverter.e.warn("** please restart the server and if the problem persists, remove the directory \'{}\'", new Object[] { file.getPath()}); + return false; + } else { + return true; + } + } + + private static File d(PropertyManager propertymanager) { + String s = propertymanager.getString("level-name", "world"); + File file = new File(MinecraftServer.getServer().server.getWorldContainer(), s); // CraftBukkit - Respect container setting + + return new File(file, "players"); + } + + private static void c(File file) { + File file1 = new File(file.getName() + ".converted"); + + file.renameTo(file1); + } + + private static Date b(String s, Date date) { + Date date1; + + try { + date1 = ExpirableListEntry.a.parse(s); + } catch (ParseException parseexception) { + date1 = date; + } + + return date1; + } + + static class FileConversionException extends RuntimeException { + + private FileConversionException(String s, Throwable throwable) { + super(s, throwable); + } + + private FileConversionException(String s) { + super(s); + } + + FileConversionException(String s, Object object) { + this(s); + } + + FileConversionException(String s, Throwable throwable, Object object) { + this(s, throwable); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NavigationAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NavigationAbstract.java new file mode 100644 index 0000000..8ebe584 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NavigationAbstract.java @@ -0,0 +1,238 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +public abstract class NavigationAbstract { + + protected EntityInsentient b; + protected World c; + protected PathEntity d; + protected double e; + private final AttributeInstance a; + private int f; + private int g; + private Vec3D h = new Vec3D(0.0D, 0.0D, 0.0D); + private float i = 1.0F; + private final Pathfinder j; + + public NavigationAbstract(EntityInsentient entityinsentient, World world) { + this.b = entityinsentient; + this.c = world; + this.a = entityinsentient.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); + this.j = this.a(); + } + + protected abstract Pathfinder a(); + + public void a(double d0) { + this.e = d0; + } + + public float i() { + return (float) this.a.getValue(); + } + + public final PathEntity a(double d0, double d1, double d2) { + return this.a(new BlockPosition(MathHelper.floor(d0), (int) d1, MathHelper.floor(d2))); + } + + public PathEntity a(BlockPosition blockposition) { + if (!this.b()) { + return null; + } else { + float f = this.i(); + + this.c.methodProfiler.a("pathfind"); + BlockPosition blockposition1 = new BlockPosition(this.b); + int i = (int) (f + 8.0F); + ChunkCache chunkcache = new ChunkCache(this.c, blockposition1.a(-i, -i, -i), blockposition1.a(i, i, i), 0); + PathEntity pathentity = this.j.a((IBlockAccess) chunkcache, (Entity) this.b, blockposition, f); + + this.c.methodProfiler.b(); + return pathentity; + } + } + + public boolean a(double d0, double d1, double d2, double d3) { + PathEntity pathentity = this.a((double) MathHelper.floor(d0), (double) ((int) d1), (double) MathHelper.floor(d2)); + + return this.a(pathentity, d3); + } + + public void a(float f) { + this.i = f; + } + + public PathEntity a(Entity entity) { + if (!this.b()) { + return null; + } else { + float f = this.i(); + + this.c.methodProfiler.a("pathfind"); + BlockPosition blockposition = (new BlockPosition(this.b)).up(); + int i = (int) (f + 16.0F); + ChunkCache chunkcache = new ChunkCache(this.c, blockposition.a(-i, -i, -i), blockposition.a(i, i, i), 0); + PathEntity pathentity = this.j.a((IBlockAccess) chunkcache, (Entity) this.b, entity, f); + + this.c.methodProfiler.b(); + return pathentity; + } + } + + public boolean a(Entity entity, double d0) { + // PaperSpigot start - Pathfinding optimizations + if (this.pathfindFailures > 10 && this.d == null && MinecraftServer.currentTick < this.lastFailure + 40) { + return false; + } + PathEntity pathentity = this.a(entity); + + if (pathentity != null && this.a(pathentity, d0)) { + this.lastFailure = 0; + this.pathfindFailures = 0; + return true; + } else { + this.pathfindFailures++; + this.lastFailure = MinecraftServer.currentTick; + return false; + } + } + private int lastFailure = 0; + private int pathfindFailures = 0; + // PaperSpigot end + + public boolean a(PathEntity pathentity, double d0) { + if (pathentity == null) { + this.d = null; + return false; + } else { + if (!pathentity.a(this.d)) { + this.d = pathentity; + } + + this.d(); + if (this.d.d() == 0) { + return false; + } else { + this.e = d0; + Vec3D vec3d = this.c(); + + this.g = this.f; + this.h = vec3d; + return true; + } + } + } + + public PathEntity j() { + return this.d; + } + + public void k() { + ++this.f; + if (!this.m()) { + Vec3D vec3d; + + if (this.b()) { + this.l(); + } else if (this.d != null && this.d.e() < this.d.d()) { + vec3d = this.c(); + Vec3D vec3d1 = this.d.a(this.b, this.d.e()); + + if (vec3d.b > vec3d1.b && !this.b.onGround && MathHelper.floor(vec3d.a) == MathHelper.floor(vec3d1.a) && MathHelper.floor(vec3d.c) == MathHelper.floor(vec3d1.c)) { + this.d.c(this.d.e() + 1); + } + } + + if (!this.m()) { + vec3d = this.d.a((Entity) this.b); + if (vec3d != null) { + AxisAlignedBB axisalignedbb = (new AxisAlignedBB(vec3d.a, vec3d.b, vec3d.c, vec3d.a, vec3d.b, vec3d.c)).grow(0.5D, 0.5D, 0.5D); + List list = this.c.getCubes(this.b, axisalignedbb.a(0.0D, -1.0D, 0.0D)); + double d0 = -1.0D; + + axisalignedbb = axisalignedbb.c(0.0D, 1.0D, 0.0D); + + AxisAlignedBB axisalignedbb1; + + for (Iterator iterator = list.iterator(); iterator.hasNext(); d0 = axisalignedbb1.b(axisalignedbb, d0)) { + axisalignedbb1 = (AxisAlignedBB) iterator.next(); + } + + this.b.getControllerMove().a(vec3d.a, vec3d.b + d0, vec3d.c, this.e); + } + } + } + } + + protected void l() { + Vec3D vec3d = this.c(); + int i = this.d.d(); + + for (int j = this.d.e(); j < this.d.d(); ++j) { + if (this.d.a(j).b != (int) vec3d.b) { + i = j; + break; + } + } + + float f = this.b.width * this.b.width * this.i; + + int k; + + for (k = this.d.e(); k < i; ++k) { + Vec3D vec3d1 = this.d.a(this.b, k); + + if (vec3d.distanceSquared(vec3d1) < (double) f) { + this.d.c(k + 1); + } + } + + k = MathHelper.f(this.b.width); + int l = (int) this.b.length + 1; + int i1 = k; + + for (int j1 = i - 1; j1 >= this.d.e(); --j1) { + if (this.a(vec3d, this.d.a(this.b, j1), k, l, i1)) { + this.d.c(j1); + break; + } + } + + this.a(vec3d); + } + + protected void a(Vec3D vec3d) { + if (this.f - this.g > 100) { + if (vec3d.distanceSquared(this.h) < 2.25D) { + this.n(); + } + + this.g = this.f; + this.h = vec3d; + } + + } + + public boolean m() { + return this.d == null || this.d.b(); + } + + public void n() { + this.pathfindFailures = 0; this.lastFailure = 0; // PaperSpigot - Pathfinding optimizations + this.d = null; + } + + protected abstract Vec3D c(); + + protected abstract boolean b(); + + protected boolean o() { + return this.b.V() || this.b.ab(); + } + + protected void d() {} + + protected abstract boolean a(Vec3D vec3d, Vec3D vec3d1, int i, int j, int k); +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NetworkManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NetworkManager.java new file mode 100644 index 0000000..9d23c6c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NetworkManager.java @@ -0,0 +1,345 @@ +package net.minecraft.server; + +import com.google.common.collect.Queues; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.epoll.EpollEventLoopGroup; +import io.netty.channel.local.LocalChannel; +import io.netty.channel.local.LocalEventLoopGroup; +import io.netty.channel.local.LocalServerChannel; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.handler.timeout.TimeoutException; +import io.netty.util.AttributeKey; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; +import java.net.SocketAddress; +import java.util.Queue; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import javax.crypto.SecretKey; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.Validate; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; + +public class NetworkManager extends SimpleChannelInboundHandler { + + private static final Logger g = LogManager.getLogger(); + public static final Marker a = MarkerManager.getMarker("NETWORK"); + public static final Marker b = MarkerManager.getMarker("NETWORK_PACKETS", NetworkManager.a); + public static final AttributeKey c = AttributeKey.valueOf("protocol"); + public static final LazyInitVar d = new LazyInitVar() { + protected NioEventLoopGroup a() { + return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Client IO #%d").setDaemon(true).build()); + } + + protected Object init() { + return this.a(); + } + }; + public static final LazyInitVar e = new LazyInitVar() { + protected EpollEventLoopGroup a() { + return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Client IO #%d").setDaemon(true).build()); + } + + protected Object init() { + return this.a(); + } + }; + public static final LazyInitVar f = new LazyInitVar() { + protected LocalEventLoopGroup a() { + return new LocalEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).build()); + } + + protected Object init() { + return this.a(); + } + }; + private final EnumProtocolDirection h; + private final Queue i = Queues.newConcurrentLinkedQueue(); + private final ReentrantReadWriteLock j = new ReentrantReadWriteLock(); + public Channel channel; + // Spigot Start // PAIL + public SocketAddress l; + public java.util.UUID spoofedUUID; + public com.mojang.authlib.properties.Property[] spoofedProfile; + public boolean preparing = true; + // Spigot End + private PacketListener m; + private IChatBaseComponent n; + private boolean o; + private boolean p; + + public NetworkManager(EnumProtocolDirection enumprotocoldirection) { + this.h = enumprotocoldirection; + } + + public void channelActive(ChannelHandlerContext channelhandlercontext) throws Exception { + super.channelActive(channelhandlercontext); + this.channel = channelhandlercontext.channel(); + this.l = this.channel.remoteAddress(); + // Spigot Start + this.preparing = false; + // Spigot End + + try { + this.a(EnumProtocol.HANDSHAKING); + } catch (Throwable throwable) { + NetworkManager.g.fatal(throwable); + } + + } + + public void a(EnumProtocol enumprotocol) { + this.channel.attr(NetworkManager.c).set(enumprotocol); + this.channel.config().setAutoRead(true); + NetworkManager.g.debug("Enabled auto read"); + } + + public void channelInactive(ChannelHandlerContext channelhandlercontext) throws Exception { + this.close(new ChatMessage("disconnect.endOfStream", new Object[0])); + } + + public void exceptionCaught(ChannelHandlerContext channelhandlercontext, Throwable throwable) throws Exception { + ChatMessage chatmessage; + + if (throwable instanceof TimeoutException) { + chatmessage = new ChatMessage("disconnect.timeout", new Object[0]); + } else { + chatmessage = new ChatMessage("disconnect.genericReason", new Object[] { "Internal Exception: " + throwable}); + } + + this.close(chatmessage); + if (MinecraftServer.getServer().isDebugging()) throwable.printStackTrace(); // Spigot + } + + protected void a(ChannelHandlerContext channelhandlercontext, Packet packet) throws Exception { + if (this.channel.isOpen()) { + try { + packet.a(this.m); + } catch (CancelledPacketHandleException cancelledpackethandleexception) { + ; + } + } + + } + + public void a(PacketListener packetlistener) { + Validate.notNull(packetlistener, "packetListener", new Object[0]); + NetworkManager.g.debug("Set listener of {} to {}", new Object[] { this, packetlistener}); + this.m = packetlistener; + } + + public void handle(Packet packet) { + if (this.g()) { + this.m(); + this.a(packet, (GenericFutureListener[]) null); + } else { + this.j.writeLock().lock(); + + try { + this.i.add(new NetworkManager.QueuedPacket(packet, (GenericFutureListener[]) null)); + } finally { + this.j.writeLock().unlock(); + } + } + + } + + public void a(Packet packet, GenericFutureListener> genericfuturelistener, GenericFutureListener>... agenericfuturelistener) { + if (this.g()) { + this.m(); + this.a(packet, (GenericFutureListener[]) ArrayUtils.add(agenericfuturelistener, 0, genericfuturelistener)); + } else { + this.j.writeLock().lock(); + + try { + this.i.add(new NetworkManager.QueuedPacket(packet, (GenericFutureListener[]) ArrayUtils.add(agenericfuturelistener, 0, genericfuturelistener))); + } finally { + this.j.writeLock().unlock(); + } + } + + } + + private void a(final Packet packet, final GenericFutureListener>[] agenericfuturelistener) { + final EnumProtocol enumprotocol = EnumProtocol.a(packet); + final EnumProtocol enumprotocol1 = (EnumProtocol) this.channel.attr(NetworkManager.c).get(); + + if (enumprotocol1 != enumprotocol) { + NetworkManager.g.debug("Disabled auto read"); + this.channel.config().setAutoRead(false); + } + + if (this.channel.eventLoop().inEventLoop()) { + if (enumprotocol != enumprotocol1) { + this.a(enumprotocol); + } + + ChannelFuture channelfuture = this.channel.writeAndFlush(packet); + + if (agenericfuturelistener != null) { + channelfuture.addListeners(agenericfuturelistener); + } + + channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); + } else { + this.channel.eventLoop().execute(new Runnable() { + public void run() { + if (enumprotocol != enumprotocol1) { + NetworkManager.this.a(enumprotocol); + } + + ChannelFuture channelfuture = NetworkManager.this.channel.writeAndFlush(packet); + + if (agenericfuturelistener != null) { + channelfuture.addListeners(agenericfuturelistener); + } + + channelfuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); + } + }); + } + + } + + private void m() { + if (this.channel != null && this.channel.isOpen()) { + this.j.readLock().lock(); + + try { + while (!this.i.isEmpty()) { + NetworkManager.QueuedPacket networkmanager_queuedpacket = (NetworkManager.QueuedPacket) this.i.poll(); + + this.a(networkmanager_queuedpacket.a, networkmanager_queuedpacket.b); + } + } finally { + this.j.readLock().unlock(); + } + + } + } + + public void a() { + this.m(); + if (this.m instanceof IUpdatePlayerListBox) { + ((IUpdatePlayerListBox) this.m).c(); + } + + this.channel.flush(); + } + + public SocketAddress getSocketAddress() { + return this.l; + } + + public void close(IChatBaseComponent ichatbasecomponent) { + // Spigot Start + this.preparing = false; + // Spigot End + if (this.channel.isOpen()) { + this.channel.close(); // We can't wait as this may be called from an event loop. + this.n = ichatbasecomponent; + } + + } + + public boolean c() { + return this.channel instanceof LocalChannel || this.channel instanceof LocalServerChannel; + } + + public void a(SecretKey secretkey) { + this.o = true; + this.channel.pipeline().addBefore("splitter", "decrypt", new PacketDecrypter(MinecraftEncryption.a(2, secretkey))); + this.channel.pipeline().addBefore("prepender", "encrypt", new PacketEncrypter(MinecraftEncryption.a(1, secretkey))); + } + + public boolean g() { + return this.channel != null && this.channel.isOpen(); + } + + public boolean h() { + return this.channel == null; + } + + public PacketListener getPacketListener() { + return this.m; + } + + public IChatBaseComponent j() { + return this.n; + } + + public void k() { + this.channel.config().setAutoRead(false); + } + + public void a(int i) { + if (i >= 0) { + if (this.channel.pipeline().get("decompress") instanceof PacketDecompressor) { + ((PacketDecompressor) this.channel.pipeline().get("decompress")).a(i); + } else { + this.channel.pipeline().addBefore("decoder", "decompress", new PacketDecompressor(i)); + } + + if (this.channel.pipeline().get("compress") instanceof PacketCompressor) { + ((PacketCompressor) this.channel.pipeline().get("decompress")).a(i); + } else { + this.channel.pipeline().addBefore("encoder", "compress", new PacketCompressor(i)); + } + } else { + if (this.channel.pipeline().get("decompress") instanceof PacketDecompressor) { + this.channel.pipeline().remove("decompress"); + } + + if (this.channel.pipeline().get("compress") instanceof PacketCompressor) { + this.channel.pipeline().remove("compress"); + } + } + + } + + public void l() { + if (this.channel != null && !this.channel.isOpen()) { + if (!this.p) { + this.p = true; + if (this.j() != null) { + this.getPacketListener().a(this.j()); + } else if (this.getPacketListener() != null) { + this.getPacketListener().a(new ChatComponentText("Disconnected")); + } + this.i.clear(); // Free up packet queue. + } else { + NetworkManager.g.warn("handleDisconnection() called twice"); + } + + } + } + + protected void channelRead0(ChannelHandlerContext channelhandlercontext, Packet object) throws Exception { // CraftBukkit - fix decompile error + this.a(channelhandlercontext, (Packet) object); + } + + static class QueuedPacket { + + private final Packet a; + private final GenericFutureListener>[] b; + + public QueuedPacket(Packet packet, GenericFutureListener>... agenericfuturelistener) { + this.a = packet; + this.b = agenericfuturelistener; + } + } + + // Spigot Start + public SocketAddress getRawAddress() + { + return this.channel.remoteAddress(); + } + // Spigot End +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NextTickListEntry.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NextTickListEntry.java new file mode 100644 index 0000000..648d255 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NextTickListEntry.java @@ -0,0 +1,56 @@ +package net.minecraft.server; + +public class NextTickListEntry implements Comparable { + + private static long d; + private final Block e; + public final BlockPosition a; + public long b; + public int c; + private long f; + + public NextTickListEntry(BlockPosition blockposition, Block block) { + this.f = (long) (NextTickListEntry.d++); + this.a = blockposition; + this.e = block; + } + + public boolean equals(Object object) { + if (!(object instanceof NextTickListEntry)) { + return false; + } else { + NextTickListEntry nextticklistentry = (NextTickListEntry) object; + + return this.a.equals(nextticklistentry.a) && Block.a(this.e, nextticklistentry.e); + } + } + + public int hashCode() { + return this.a.hashCode(); + } + + public NextTickListEntry a(long i) { + this.b = i; + return this; + } + + public void a(int i) { + this.c = i; + } + + public int a(NextTickListEntry nextticklistentry) { + return this.b < nextticklistentry.b ? -1 : (this.b > nextticklistentry.b ? 1 : (this.c != nextticklistentry.c ? this.c - nextticklistentry.c : (this.f < nextticklistentry.f ? -1 : (this.f > nextticklistentry.f ? 1 : 0)))); + } + + public String toString() { + return Block.getId(this.e) + ": " + this.a + ", " + this.b + ", " + this.c + ", " + this.f; + } + + public Block a() { + return this.e; + } + + public int compareTo(NextTickListEntry object) { + return this.a((NextTickListEntry) object); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NibbleArray.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NibbleArray.java new file mode 100644 index 0000000..9306f97 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/NibbleArray.java @@ -0,0 +1,58 @@ +package net.minecraft.server; + +public class NibbleArray { + + private final byte[] a; + + public NibbleArray() { + this.a = new byte[2048]; + } + + public NibbleArray(byte[] abyte) { + this.a = abyte; + if (abyte.length != 2048) { + throw new IllegalArgumentException("ChunkNibbleArrays should be 2048 bytes not: " + abyte.length); + } + } + + public int a(int i, int j, int k) { + return this.a(this.b(i, j, k)); + } + + public void a(int i, int j, int k, int l) { + this.a(this.b(i, j, k), l); + } + + private int b(int i, int j, int k) { + return j << 8 | k << 4 | i; + } + + public int a(int i) { + int j = this.c(i); + + return this.b(i) ? this.a[j] & 15 : this.a[j] >> 4 & 15; + } + + public void a(int i, int j) { + int k = this.c(i); + + if (this.b(i)) { + this.a[k] = (byte) (this.a[k] & 240 | j & 15); + } else { + this.a[k] = (byte) (this.a[k] & 15 | (j & 15) << 4); + } + + } + + private boolean b(int i) { + return (i & 1) == 0; + } + + private int c(int i) { + return i >> 1; + } + + public byte[] a() { + return this.a; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/OldChunkLoader.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/OldChunkLoader.java new file mode 100644 index 0000000..670d626 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/OldChunkLoader.java @@ -0,0 +1,145 @@ +package net.minecraft.server; + +public class OldChunkLoader { + + public static OldChunkLoader.OldChunk a(NBTTagCompound nbttagcompound) { + int i = nbttagcompound.getInt("xPos"); + int j = nbttagcompound.getInt("zPos"); + OldChunkLoader.OldChunk oldchunkloader_oldchunk = new OldChunkLoader.OldChunk(i, j); + + oldchunkloader_oldchunk.g = nbttagcompound.getByteArray("Blocks"); + oldchunkloader_oldchunk.f = new OldNibbleArray(nbttagcompound.getByteArray("Data"), 7); + oldchunkloader_oldchunk.e = new OldNibbleArray(nbttagcompound.getByteArray("SkyLight"), 7); + oldchunkloader_oldchunk.d = new OldNibbleArray(nbttagcompound.getByteArray("BlockLight"), 7); + oldchunkloader_oldchunk.c = nbttagcompound.getByteArray("HeightMap"); + oldchunkloader_oldchunk.b = nbttagcompound.getBoolean("TerrainPopulated"); + oldchunkloader_oldchunk.h = nbttagcompound.getList("Entities", 10); + oldchunkloader_oldchunk.i = nbttagcompound.getList("TileEntities", 10); + oldchunkloader_oldchunk.j = nbttagcompound.getList("TileTicks", 10); + + try { + oldchunkloader_oldchunk.a = nbttagcompound.getLong("LastUpdate"); + } catch (ClassCastException classcastexception) { + oldchunkloader_oldchunk.a = (long) nbttagcompound.getInt("LastUpdate"); + } + + return oldchunkloader_oldchunk; + } + + public static void a(OldChunkLoader.OldChunk oldchunkloader_oldchunk, NBTTagCompound nbttagcompound, WorldChunkManager worldchunkmanager) { + nbttagcompound.setInt("xPos", oldchunkloader_oldchunk.k); + nbttagcompound.setInt("zPos", oldchunkloader_oldchunk.l); + nbttagcompound.setLong("LastUpdate", oldchunkloader_oldchunk.a); + int[] aint = new int[oldchunkloader_oldchunk.c.length]; + + for (int i = 0; i < oldchunkloader_oldchunk.c.length; ++i) { + aint[i] = oldchunkloader_oldchunk.c[i]; + } + + nbttagcompound.setIntArray("HeightMap", aint); + nbttagcompound.setBoolean("TerrainPopulated", oldchunkloader_oldchunk.b); + NBTTagList nbttaglist = new NBTTagList(); + + int j; + int k; + + for (int l = 0; l < 8; ++l) { + boolean flag = true; + + for (j = 0; j < 16 && flag; ++j) { + k = 0; + + while (k < 16 && flag) { + int i1 = 0; + + while (true) { + if (i1 < 16) { + int j1 = j << 11 | i1 << 7 | k + (l << 4); + byte b0 = oldchunkloader_oldchunk.g[j1]; + + if (b0 == 0) { + ++i1; + continue; + } + + flag = false; + } + + ++k; + break; + } + } + } + + if (!flag) { + byte[] abyte = new byte[4096]; + NibbleArray nibblearray = new NibbleArray(); + NibbleArray nibblearray1 = new NibbleArray(); + NibbleArray nibblearray2 = new NibbleArray(); + + for (int k1 = 0; k1 < 16; ++k1) { + for (int l1 = 0; l1 < 16; ++l1) { + for (int i2 = 0; i2 < 16; ++i2) { + int j2 = k1 << 11 | i2 << 7 | l1 + (l << 4); + byte b1 = oldchunkloader_oldchunk.g[j2]; + + abyte[l1 << 8 | i2 << 4 | k1] = (byte) (b1 & 255); + nibblearray.a(k1, l1, i2, oldchunkloader_oldchunk.f.a(k1, l1 + (l << 4), i2)); + nibblearray1.a(k1, l1, i2, oldchunkloader_oldchunk.e.a(k1, l1 + (l << 4), i2)); + nibblearray2.a(k1, l1, i2, oldchunkloader_oldchunk.d.a(k1, l1 + (l << 4), i2)); + } + } + } + + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setByte("Y", (byte) (l & 255)); + nbttagcompound1.setByteArray("Blocks", abyte); + nbttagcompound1.setByteArray("Data", nibblearray.a()); + nbttagcompound1.setByteArray("SkyLight", nibblearray1.a()); + nbttagcompound1.setByteArray("BlockLight", nibblearray2.a()); + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Sections", nbttaglist); + byte[] abyte1 = new byte[256]; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (j = 0; j < 16; ++j) { + for (k = 0; k < 16; ++k) { + blockposition_mutableblockposition.c(oldchunkloader_oldchunk.k << 4 | j, 0, oldchunkloader_oldchunk.l << 4 | k); + abyte1[k << 4 | j] = (byte) (worldchunkmanager.getBiome(blockposition_mutableblockposition, BiomeBase.ad).id & 255); + } + } + + nbttagcompound.setByteArray("Biomes", abyte1); + nbttagcompound.set("Entities", oldchunkloader_oldchunk.h); + nbttagcompound.set("TileEntities", oldchunkloader_oldchunk.i); + if (oldchunkloader_oldchunk.j != null) { + nbttagcompound.set("TileTicks", oldchunkloader_oldchunk.j); + } + + } + + public static class OldChunk { + + public long a; + public boolean b; + public byte[] c; + public OldNibbleArray d; + public OldNibbleArray e; + public OldNibbleArray f; + public byte[] g; + public NBTTagList h; + public NBTTagList i; + public NBTTagList j; + public final int k; + public final int l; + + public OldChunk(int i, int j) { + this.k = i; + this.l = j; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketDataSerializer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketDataSerializer.java new file mode 100644 index 0000000..21ab829 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketDataSerializer.java @@ -0,0 +1,843 @@ +package net.minecraft.server; + +import com.google.common.base.Charsets; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.ByteBufInputStream; +import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.ByteBufProcessor; +import io.netty.handler.codec.DecoderException; +import io.netty.handler.codec.EncoderException; +import io.netty.util.ReferenceCounted; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; +import java.util.UUID; + +import org.bukkit.craftbukkit.inventory.CraftItemStack; // CraftBukkit +// TacoSpigot start +import net.techcable.tacospigot.CompatHacks; +// TacoSpigot end + +public class PacketDataSerializer extends ByteBuf { + + private final ByteBuf a; + + // TacoSpigot start + private final boolean allowLargePackets; + public PacketDataSerializer(ByteBuf bytebuf) { + /* + * By default, we limit the size of the received byte array to Short.MAX_VALUE, which is 31 KB. + * However, we make an exception when ProtocolSupport is installed, to allow 1.7 clients to work, + * and limit them to 31 MEGABYTES as they seem to need to send larger packets sometimes. + * Although a 31 MB limit leaves the server slightly vulnerable, + * it's still much better than the old system of having no limit, + * which would leave the server vulnerable to packets up to 2 GIGABYTES in size. + */ + this.allowLargePackets = CompatHacks.hasProtocolSupport(); + // TacoSpigot end + this.a = bytebuf; + } + + public static int a(int i) { + for (int j = 1; j < 5; ++j) { + if ((i & -1 << j * 7) == 0) { + return j; + } + } + + return 5; + } + + public void a(byte[] abyte) { + this.b(abyte.length); + this.writeBytes(abyte); + } + + // TacoSpigot start + private static final int DEFAULT_LIMIT = Short.MAX_VALUE; + private static final int LARGE_PACKET_LIMIT = Short.MAX_VALUE * 1024; + public byte[] a() { + // TacoSpigot start + int limit = allowLargePackets ? LARGE_PACKET_LIMIT : DEFAULT_LIMIT; + return readByteArray(limit); + } + + public byte[] readByteArray(int limit) { + int len = this.e(); + if (len > limit) throw new DecoderException("The received a byte array longer than allowed " + len + " > " + limit); + byte[] abyte = new byte[len]; + // TacoSpigot end + this.readBytes(abyte); + return abyte; + } + + public BlockPosition c() { + return BlockPosition.fromLong(this.readLong()); + } + + public void a(BlockPosition blockposition) { + this.writeLong(blockposition.asLong()); + } + + public IChatBaseComponent d() throws IOException { + return IChatBaseComponent.ChatSerializer.a(this.c(32767)); + } + + public void a(IChatBaseComponent ichatbasecomponent) throws IOException { + this.a(IChatBaseComponent.ChatSerializer.a(ichatbasecomponent)); + } + + public > T a(Class oclass) { + return ((T[]) oclass.getEnumConstants())[this.e()]; // CraftBukkit - fix decompile error + } + + public void a(Enum oenum) { + this.b(oenum.ordinal()); + } + + public int e() { + int i = 0; + int j = 0; + + byte b0; + + do { + b0 = this.readByte(); + i |= (b0 & 127) << j++ * 7; + if (j > 5) { + throw new RuntimeException("VarInt too big"); + } + } while ((b0 & 128) == 128); + + return i; + } + + public long f() { + long i = 0L; + int j = 0; + + byte b0; + + do { + b0 = this.readByte(); + i |= (long) (b0 & 127) << j++ * 7; + if (j > 10) { + throw new RuntimeException("VarLong too big"); + } + } while ((b0 & 128) == 128); + + return i; + } + + public void a(UUID uuid) { + this.writeLong(uuid.getMostSignificantBits()); + this.writeLong(uuid.getLeastSignificantBits()); + } + + public UUID g() { + return new UUID(this.readLong(), this.readLong()); + } + + public void b(int i) { + while ((i & -128) != 0) { + this.writeByte(i & 127 | 128); + i >>>= 7; + } + + this.writeByte(i); + } + + public void b(long i) { + while ((i & -128L) != 0L) { + this.writeByte((int) (i & 127L) | 128); + i >>>= 7; + } + + this.writeByte((int) i); + } + + public void a(NBTTagCompound nbttagcompound) { + if (nbttagcompound == null) { + this.writeByte(0); + } else { + try { + NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) (new ByteBufOutputStream(this))); + } catch (Exception ioexception) { // CraftBukkit - IOException -> Exception + throw new EncoderException(ioexception); + } + } + + } + + public NBTTagCompound h() throws IOException { + int i = this.readerIndex(); + byte b0 = this.readByte(); + + if (b0 == 0) { + return null; + } else { + this.readerIndex(i); + return NBTCompressedStreamTools.a((DataInput) (new ByteBufInputStream(this)), new NBTReadLimiter(2097152L)); + } + } + + public void a(ItemStack itemstack) { + if (itemstack == null || itemstack.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem() + this.writeShort(-1); + } else { + this.writeShort(Item.getId(itemstack.getItem())); + this.writeByte(itemstack.count); + this.writeShort(itemstack.getData()); + NBTTagCompound nbttagcompound = null; + + if (itemstack.getItem().usesDurability() || itemstack.getItem().p()) { + // Spigot start - filter + itemstack = itemstack.cloneItemStack(); + CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); + // Spigot end + nbttagcompound = itemstack.getTag(); + } + + this.a(nbttagcompound); + } + + } + + public ItemStack i() throws IOException { + ItemStack itemstack = null; + short short0 = this.readShort(); + + if (short0 >= 0) { + byte b0 = this.readByte(); + short short1 = this.readShort(); + + itemstack = new ItemStack(Item.getById(short0), b0, short1); + itemstack.setTag(this.h()); + // CraftBukkit start + if (itemstack.getTag() != null) { + CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); + } + // CraftBukkit end + } + + return itemstack; + } + + public String c(int i) { + int j = this.e(); + + if (j > i * 4) { + throw new DecoderException("The received encoded string buffer length is longer than maximum allowed (" + j + " > " + i * 4 + ")"); + } else if (j < 0) { + throw new DecoderException("The received encoded string buffer length is less than zero! Weird string!"); + } else { + String s = new String(this.readBytes(j).array(), Charsets.UTF_8); + + if (s.length() > i) { + throw new DecoderException("The received string length is longer than maximum allowed (" + j + " > " + i + ")"); + } else { + return s; + } + } + } + + public PacketDataSerializer a(String s) { + byte[] abyte = s.getBytes(Charsets.UTF_8); + + if (abyte.length > 32767) { + throw new EncoderException("String too big (was " + s.length() + " bytes encoded, max " + 32767 + ")"); + } else { + this.b(abyte.length); + this.writeBytes(abyte); + return this; + } + } + + public int capacity() { + return this.a.capacity(); + } + + public ByteBuf capacity(int i) { + return this.a.capacity(i); + } + + public int maxCapacity() { + return this.a.maxCapacity(); + } + + public ByteBufAllocator alloc() { + return this.a.alloc(); + } + + public ByteOrder order() { + return this.a.order(); + } + + public ByteBuf order(ByteOrder byteorder) { + return this.a.order(byteorder); + } + + public ByteBuf unwrap() { + return this.a.unwrap(); + } + + public boolean isDirect() { + return this.a.isDirect(); + } + + public int readerIndex() { + return this.a.readerIndex(); + } + + public ByteBuf readerIndex(int i) { + return this.a.readerIndex(i); + } + + public int writerIndex() { + return this.a.writerIndex(); + } + + public ByteBuf writerIndex(int i) { + return this.a.writerIndex(i); + } + + public ByteBuf setIndex(int i, int j) { + return this.a.setIndex(i, j); + } + + public int readableBytes() { + return this.a.readableBytes(); + } + + public int writableBytes() { + return this.a.writableBytes(); + } + + public int maxWritableBytes() { + return this.a.maxWritableBytes(); + } + + public boolean isReadable() { + return this.a.isReadable(); + } + + public boolean isReadable(int i) { + return this.a.isReadable(i); + } + + public boolean isWritable() { + return this.a.isWritable(); + } + + public boolean isWritable(int i) { + return this.a.isWritable(i); + } + + public ByteBuf clear() { + return this.a.clear(); + } + + public ByteBuf markReaderIndex() { + return this.a.markReaderIndex(); + } + + public ByteBuf resetReaderIndex() { + return this.a.resetReaderIndex(); + } + + public ByteBuf markWriterIndex() { + return this.a.markWriterIndex(); + } + + public ByteBuf resetWriterIndex() { + return this.a.resetWriterIndex(); + } + + public ByteBuf discardReadBytes() { + return this.a.discardReadBytes(); + } + + public ByteBuf discardSomeReadBytes() { + return this.a.discardSomeReadBytes(); + } + + public ByteBuf ensureWritable(int i) { + return this.a.ensureWritable(i); + } + + public int ensureWritable(int i, boolean flag) { + return this.a.ensureWritable(i, flag); + } + + public boolean getBoolean(int i) { + return this.a.getBoolean(i); + } + + public byte getByte(int i) { + return this.a.getByte(i); + } + + public short getUnsignedByte(int i) { + return this.a.getUnsignedByte(i); + } + + public short getShort(int i) { + return this.a.getShort(i); + } + + public int getUnsignedShort(int i) { + return this.a.getUnsignedShort(i); + } + + public int getMedium(int i) { + return this.a.getMedium(i); + } + + public int getUnsignedMedium(int i) { + return this.a.getUnsignedMedium(i); + } + + public int getInt(int i) { + return this.a.getInt(i); + } + + public long getUnsignedInt(int i) { + return this.a.getUnsignedInt(i); + } + + public long getLong(int i) { + return this.a.getLong(i); + } + + public char getChar(int i) { + return this.a.getChar(i); + } + + public float getFloat(int i) { + return this.a.getFloat(i); + } + + public double getDouble(int i) { + return this.a.getDouble(i); + } + + public ByteBuf getBytes(int i, ByteBuf bytebuf) { + return this.a.getBytes(i, bytebuf); + } + + public ByteBuf getBytes(int i, ByteBuf bytebuf, int j) { + return this.a.getBytes(i, bytebuf, j); + } + + public ByteBuf getBytes(int i, ByteBuf bytebuf, int j, int k) { + return this.a.getBytes(i, bytebuf, j, k); + } + + public ByteBuf getBytes(int i, byte[] abyte) { + return this.a.getBytes(i, abyte); + } + + public ByteBuf getBytes(int i, byte[] abyte, int j, int k) { + return this.a.getBytes(i, abyte, j, k); + } + + public ByteBuf getBytes(int i, ByteBuffer bytebuffer) { + return this.a.getBytes(i, bytebuffer); + } + + public ByteBuf getBytes(int i, OutputStream outputstream, int j) throws IOException { + return this.a.getBytes(i, outputstream, j); + } + + public int getBytes(int i, GatheringByteChannel gatheringbytechannel, int j) throws IOException { + return this.a.getBytes(i, gatheringbytechannel, j); + } + + public ByteBuf setBoolean(int i, boolean flag) { + return this.a.setBoolean(i, flag); + } + + public ByteBuf setByte(int i, int j) { + return this.a.setByte(i, j); + } + + public ByteBuf setShort(int i, int j) { + return this.a.setShort(i, j); + } + + public ByteBuf setMedium(int i, int j) { + return this.a.setMedium(i, j); + } + + public ByteBuf setInt(int i, int j) { + return this.a.setInt(i, j); + } + + public ByteBuf setLong(int i, long j) { + return this.a.setLong(i, j); + } + + public ByteBuf setChar(int i, int j) { + return this.a.setChar(i, j); + } + + public ByteBuf setFloat(int i, float f) { + return this.a.setFloat(i, f); + } + + public ByteBuf setDouble(int i, double d0) { + return this.a.setDouble(i, d0); + } + + public ByteBuf setBytes(int i, ByteBuf bytebuf) { + return this.a.setBytes(i, bytebuf); + } + + public ByteBuf setBytes(int i, ByteBuf bytebuf, int j) { + return this.a.setBytes(i, bytebuf, j); + } + + public ByteBuf setBytes(int i, ByteBuf bytebuf, int j, int k) { + return this.a.setBytes(i, bytebuf, j, k); + } + + public ByteBuf setBytes(int i, byte[] abyte) { + return this.a.setBytes(i, abyte); + } + + public ByteBuf setBytes(int i, byte[] abyte, int j, int k) { + return this.a.setBytes(i, abyte, j, k); + } + + public ByteBuf setBytes(int i, ByteBuffer bytebuffer) { + return this.a.setBytes(i, bytebuffer); + } + + public int setBytes(int i, InputStream inputstream, int j) throws IOException { + return this.a.setBytes(i, inputstream, j); + } + + public int setBytes(int i, ScatteringByteChannel scatteringbytechannel, int j) throws IOException { + return this.a.setBytes(i, scatteringbytechannel, j); + } + + public ByteBuf setZero(int i, int j) { + return this.a.setZero(i, j); + } + + public boolean readBoolean() { + return this.a.readBoolean(); + } + + public byte readByte() { + return this.a.readByte(); + } + + public short readUnsignedByte() { + return this.a.readUnsignedByte(); + } + + public short readShort() { + return this.a.readShort(); + } + + public int readUnsignedShort() { + return this.a.readUnsignedShort(); + } + + public int readMedium() { + return this.a.readMedium(); + } + + public int readUnsignedMedium() { + return this.a.readUnsignedMedium(); + } + + public int readInt() { + return this.a.readInt(); + } + + public long readUnsignedInt() { + return this.a.readUnsignedInt(); + } + + public long readLong() { + return this.a.readLong(); + } + + public char readChar() { + return this.a.readChar(); + } + + public float readFloat() { + return this.a.readFloat(); + } + + public double readDouble() { + return this.a.readDouble(); + } + + public ByteBuf readBytes(int i) { + return this.a.readBytes(i); + } + + public ByteBuf readSlice(int i) { + return this.a.readSlice(i); + } + + public ByteBuf readBytes(ByteBuf bytebuf) { + return this.a.readBytes(bytebuf); + } + + public ByteBuf readBytes(ByteBuf bytebuf, int i) { + return this.a.readBytes(bytebuf, i); + } + + public ByteBuf readBytes(ByteBuf bytebuf, int i, int j) { + return this.a.readBytes(bytebuf, i, j); + } + + public ByteBuf readBytes(byte[] abyte) { + return this.a.readBytes(abyte); + } + + public ByteBuf readBytes(byte[] abyte, int i, int j) { + return this.a.readBytes(abyte, i, j); + } + + public ByteBuf readBytes(ByteBuffer bytebuffer) { + return this.a.readBytes(bytebuffer); + } + + public ByteBuf readBytes(OutputStream outputstream, int i) throws IOException { + return this.a.readBytes(outputstream, i); + } + + public int readBytes(GatheringByteChannel gatheringbytechannel, int i) throws IOException { + return this.a.readBytes(gatheringbytechannel, i); + } + + public ByteBuf skipBytes(int i) { + return this.a.skipBytes(i); + } + + public ByteBuf writeBoolean(boolean flag) { + return this.a.writeBoolean(flag); + } + + public ByteBuf writeByte(int i) { + return this.a.writeByte(i); + } + + public ByteBuf writeShort(int i) { + return this.a.writeShort(i); + } + + public ByteBuf writeMedium(int i) { + return this.a.writeMedium(i); + } + + public ByteBuf writeInt(int i) { + return this.a.writeInt(i); + } + + public ByteBuf writeLong(long i) { + return this.a.writeLong(i); + } + + public ByteBuf writeChar(int i) { + return this.a.writeChar(i); + } + + public ByteBuf writeFloat(float f) { + return this.a.writeFloat(f); + } + + public ByteBuf writeDouble(double d0) { + return this.a.writeDouble(d0); + } + + public ByteBuf writeBytes(ByteBuf bytebuf) { + return this.a.writeBytes(bytebuf); + } + + public ByteBuf writeBytes(ByteBuf bytebuf, int i) { + return this.a.writeBytes(bytebuf, i); + } + + public ByteBuf writeBytes(ByteBuf bytebuf, int i, int j) { + return this.a.writeBytes(bytebuf, i, j); + } + + public ByteBuf writeBytes(byte[] abyte) { + return this.a.writeBytes(abyte); + } + + public ByteBuf writeBytes(byte[] abyte, int i, int j) { + return this.a.writeBytes(abyte, i, j); + } + + public ByteBuf writeBytes(ByteBuffer bytebuffer) { + return this.a.writeBytes(bytebuffer); + } + + public int writeBytes(InputStream inputstream, int i) throws IOException { + return this.a.writeBytes(inputstream, i); + } + + public int writeBytes(ScatteringByteChannel scatteringbytechannel, int i) throws IOException { + return this.a.writeBytes(scatteringbytechannel, i); + } + + public ByteBuf writeZero(int i) { + return this.a.writeZero(i); + } + + public int indexOf(int i, int j, byte b0) { + return this.a.indexOf(i, j, b0); + } + + public int bytesBefore(byte b0) { + return this.a.bytesBefore(b0); + } + + public int bytesBefore(int i, byte b0) { + return this.a.bytesBefore(i, b0); + } + + public int bytesBefore(int i, int j, byte b0) { + return this.a.bytesBefore(i, j, b0); + } + + public int forEachByte(ByteBufProcessor bytebufprocessor) { + return this.a.forEachByte(bytebufprocessor); + } + + public int forEachByte(int i, int j, ByteBufProcessor bytebufprocessor) { + return this.a.forEachByte(i, j, bytebufprocessor); + } + + public int forEachByteDesc(ByteBufProcessor bytebufprocessor) { + return this.a.forEachByteDesc(bytebufprocessor); + } + + public int forEachByteDesc(int i, int j, ByteBufProcessor bytebufprocessor) { + return this.a.forEachByteDesc(i, j, bytebufprocessor); + } + + public ByteBuf copy() { + return this.a.copy(); + } + + public ByteBuf copy(int i, int j) { + return this.a.copy(i, j); + } + + public ByteBuf slice() { + return this.a.slice(); + } + + public ByteBuf slice(int i, int j) { + return this.a.slice(i, j); + } + + public ByteBuf duplicate() { + return this.a.duplicate(); + } + + public int nioBufferCount() { + return this.a.nioBufferCount(); + } + + public ByteBuffer nioBuffer() { + return this.a.nioBuffer(); + } + + public ByteBuffer nioBuffer(int i, int j) { + return this.a.nioBuffer(i, j); + } + + public ByteBuffer internalNioBuffer(int i, int j) { + return this.a.internalNioBuffer(i, j); + } + + public ByteBuffer[] nioBuffers() { + return this.a.nioBuffers(); + } + + public ByteBuffer[] nioBuffers(int i, int j) { + return this.a.nioBuffers(i, j); + } + + public boolean hasArray() { + return this.a.hasArray(); + } + + public byte[] array() { + return this.a.array(); + } + + public int arrayOffset() { + return this.a.arrayOffset(); + } + + public boolean hasMemoryAddress() { + return this.a.hasMemoryAddress(); + } + + public long memoryAddress() { + return this.a.memoryAddress(); + } + + public String toString(Charset charset) { + return this.a.toString(charset); + } + + public String toString(int i, int j, Charset charset) { + return this.a.toString(i, j, charset); + } + + public int hashCode() { + return this.a.hashCode(); + } + + public boolean equals(Object object) { + return this.a.equals(object); + } + + public int compareTo(ByteBuf bytebuf) { + return this.a.compareTo(bytebuf); + } + + public String toString() { + return this.a.toString(); + } + + public ByteBuf retain(int i) { + return this.a.retain(i); + } + + public ByteBuf retain() { + return this.a.retain(); + } + + public int refCnt() { + return this.a.refCnt(); + } + + public boolean release() { + return this.a.release(); + } + + public boolean release(int i) { + return this.a.release(i); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java new file mode 100644 index 0000000..fba8bba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java @@ -0,0 +1,39 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketHandshakingInSetProtocol implements Packet { + + private int a; + public String hostname; + public int port; + private EnumProtocol d; + + public PacketHandshakingInSetProtocol() {} + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = packetdataserializer.e(); + this.hostname = packetdataserializer.c(Short.MAX_VALUE); // Spigot + this.port = packetdataserializer.readUnsignedShort(); + this.d = EnumProtocol.a(packetdataserializer.e()); + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.b(this.a); + packetdataserializer.a(this.hostname); + packetdataserializer.writeShort(this.port); + packetdataserializer.b(this.d.a()); + } + + public void a(PacketHandshakingInListener packethandshakinginlistener) { + packethandshakinginlistener.a(this); + } + + public EnumProtocol a() { + return this.d; + } + + public int b() { + return this.a; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketLoginInEncryptionBegin.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketLoginInEncryptionBegin.java new file mode 100644 index 0000000..2d408b5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketLoginInEncryptionBegin.java @@ -0,0 +1,45 @@ +package net.minecraft.server; + +import java.io.IOException; +import java.security.PrivateKey; +import javax.crypto.SecretKey; + +public class PacketLoginInEncryptionBegin implements Packet { + + private byte[] a = new byte[0]; + private byte[] b = new byte[0]; + + public PacketLoginInEncryptionBegin() {} + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + // TacoSpigot start - limit to 256 bytes + this.a = packetdataserializer.readByteArray(256); + this.b = packetdataserializer.readByteArray(256); + // TacoSpigot end + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.a(this.a); + packetdataserializer.a(this.b); + } + + public void a(PacketLoginInListener packetlogininlistener) { + packetlogininlistener.a(this); + } + + public SecretKey a(PrivateKey privatekey) { + return MinecraftEncryption.a(privatekey, this.a); + } + + public byte[] b(PrivateKey privatekey) { + return privatekey == null ? this.b : MinecraftEncryption.b(privatekey, this.b); + } + + // TacoSpigot start - fernflower is gud at generics + /* + public void a(PacketListener packetlistener) { + this.a((PacketLoginInListener) packetlistener); + } + */ + // TacoSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInArmAnimation.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInArmAnimation.java new file mode 100644 index 0000000..28cb5e3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInArmAnimation.java @@ -0,0 +1,20 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayInArmAnimation implements Packet { + + public long timestamp; // Spigot + + public PacketPlayInArmAnimation() {} + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + timestamp = System.currentTimeMillis(); // Spigot + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException {} + + public void a(PacketListenerPlayIn packetlistenerplayin) { + packetlistenerplayin.a(this); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java new file mode 100644 index 0000000..02d8e07 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java @@ -0,0 +1,78 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayInBlockPlace implements Packet { + + private static final BlockPosition a = new BlockPosition(-1, -1, -1); + private BlockPosition b; + private int c; + private ItemStack d; + private float e; + private float f; + private float g; + + public long timestamp; // CraftBukkit + + public PacketPlayInBlockPlace() {} + + public PacketPlayInBlockPlace(ItemStack itemstack) { + this(PacketPlayInBlockPlace.a, 255, itemstack, 0.0F, 0.0F, 0.0F); + } + + public PacketPlayInBlockPlace(BlockPosition blockposition, int i, ItemStack itemstack, float f, float f1, float f2) { + this.b = blockposition; + this.c = i; + this.d = itemstack != null ? itemstack.cloneItemStack() : null; + this.e = f; + this.f = f1; + this.g = f2; + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + timestamp = System.currentTimeMillis(); // CraftBukkit + this.b = packetdataserializer.c(); + this.c = packetdataserializer.readUnsignedByte(); + this.d = packetdataserializer.i(); + this.e = (float) packetdataserializer.readUnsignedByte() / 16.0F; + this.f = (float) packetdataserializer.readUnsignedByte() / 16.0F; + this.g = (float) packetdataserializer.readUnsignedByte() / 16.0F; + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.a(this.b); + packetdataserializer.writeByte(this.c); + packetdataserializer.a(this.d); + packetdataserializer.writeByte((int) (this.e * 16.0F)); + packetdataserializer.writeByte((int) (this.f * 16.0F)); + packetdataserializer.writeByte((int) (this.g * 16.0F)); + } + + public void a(PacketListenerPlayIn packetlistenerplayin) { + packetlistenerplayin.a(this); + } + + public BlockPosition a() { + return this.b; + } + + public int getFace() { + return this.c; + } + + public ItemStack getItemStack() { + return this.d; + } + + public float d() { + return this.e; + } + + public float e() { + return this.f; + } + + public float f() { + return this.g; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInChat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInChat.java new file mode 100644 index 0000000..18358b4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInChat.java @@ -0,0 +1,51 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayInChat implements Packet { + + private String a; + + public PacketPlayInChat() {} + + public PacketPlayInChat(String s) { + if (s.length() > 100) { + s = s.substring(0, 100); + } + + this.a = s; + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = packetdataserializer.c(100); + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.a(this.a); + } + + // Spigot Start + private static final java.util.concurrent.ExecutorService executors = java.util.concurrent.Executors.newCachedThreadPool( + new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon( true ).setNameFormat( "Async Chat Thread - #%d" ).build() ); + public void a(final PacketListenerPlayIn packetlistenerplayin) { + if ( !a.startsWith("/") ) + { + executors.submit( new Runnable() + { + + @Override + public void run() + { + packetlistenerplayin.a( PacketPlayInChat.this ); + } + } ); + return; + } + // Spigot End + packetlistenerplayin.a(this); + } + + public String a() { + return this.a; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java new file mode 100644 index 0000000..4dfb6c0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInCloseWindow.java @@ -0,0 +1,28 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayInCloseWindow implements Packet { + + private int id; + + public PacketPlayInCloseWindow() {} + + // CraftBukkit start + public PacketPlayInCloseWindow(int id) { + this.id = id; + } + // CraftBukkit end + + public void a(PacketListenerPlayIn packetlistenerplayin) { + packetlistenerplayin.a(this); + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.id = packetdataserializer.readByte(); + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.writeByte(this.id); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInResourcePackStatus.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInResourcePackStatus.java new file mode 100644 index 0000000..c5e5aa7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayInResourcePackStatus.java @@ -0,0 +1,32 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayInResourcePackStatus implements Packet { + + public String a; // TacoSpigot - make public + public PacketPlayInResourcePackStatus.EnumResourcePackStatus b; // PAIL: private -> public, rename: status + + public PacketPlayInResourcePackStatus() {} + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = packetdataserializer.c(40); + this.b = (PacketPlayInResourcePackStatus.EnumResourcePackStatus) packetdataserializer.a(PacketPlayInResourcePackStatus.EnumResourcePackStatus.class); + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.a(this.a); + packetdataserializer.a((Enum) this.b); + } + + public void a(PacketListenerPlayIn packetlistenerplayin) { + packetlistenerplayin.a(this); + } + + public static enum EnumResourcePackStatus { + + SUCCESSFULLY_LOADED, DECLINED, FAILED_DOWNLOAD, ACCEPTED; + + private EnumResourcePackStatus() {} + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutChat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutChat.java new file mode 100644 index 0000000..63bb0fc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutChat.java @@ -0,0 +1,52 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayOutChat implements Packet { + + private IChatBaseComponent a; + public net.md_5.bungee.api.chat.BaseComponent[] components; // Spigot + private byte b; + + public PacketPlayOutChat() {} + + public PacketPlayOutChat(IChatBaseComponent ichatbasecomponent) { + this(ichatbasecomponent, (byte) 1); + } + + public PacketPlayOutChat(IChatBaseComponent ichatbasecomponent, byte b0) { + this.a = ichatbasecomponent; + this.b = b0; + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = packetdataserializer.d(); + this.b = packetdataserializer.readByte(); + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + // Spigot start + if (components != null) { + //packetdataserializer.a(net.md_5.bungee.chat.ComponentSerializer.toString(components)); // Paper - comment, replaced with below + // Paper start - don't nest if we don't need to so that we can preserve formatting + if (this.components.length == 1) { + packetdataserializer.a(net.md_5.bungee.chat.ComponentSerializer.toString(this.components[0])); + } else { + packetdataserializer.a(net.md_5.bungee.chat.ComponentSerializer.toString(this.components)); + } + // Paper end + } else { + packetdataserializer.a(this.a); + } + // Spigot end + packetdataserializer.writeByte(this.b); + } + + public void a(PacketListenerPlayOut packetlistenerplayout) { + packetlistenerplayout.a(this); + } + + public boolean b() { + return this.b == 1 || this.b == 2; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java new file mode 100644 index 0000000..a0021fb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java @@ -0,0 +1,120 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +public class PacketPlayOutMapChunk implements Packet { + + private int a; + private int b; + private PacketPlayOutMapChunk.ChunkMap c; + private boolean d; + + public PacketPlayOutMapChunk() {} + + public PacketPlayOutMapChunk(Chunk chunk, boolean flag, int i) { + this.a = chunk.locX; + 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); + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = packetdataserializer.readInt(); + this.b = packetdataserializer.readInt(); + this.d = packetdataserializer.readBoolean(); + this.c = new PacketPlayOutMapChunk.ChunkMap(); + this.c.b = packetdataserializer.readShort(); + this.c.a = packetdataserializer.a(); + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.writeInt(this.a); + packetdataserializer.writeInt(this.b); + packetdataserializer.writeBoolean(this.d); + packetdataserializer.writeShort((short) (this.c.b & '\uffff')); + packetdataserializer.a(this.c.a); + } + + public void a(PacketListenerPlayOut packetlistenerplayout) { + packetlistenerplayout.a(this); + } + + protected static int a(int i, boolean flag, boolean flag1) { + int j = i * 2 * 16 * 16 * 16; + int k = i * 16 * 16 * 16 / 2; + int l = flag ? i * 16 * 16 * 16 / 2 : 0; + int i1 = flag1 ? 256 : 0; + + return j + k + l + i1; + } + + public static PacketPlayOutMapChunk.ChunkMap a(Chunk chunk, boolean flag, boolean flag1, int i) { + ChunkSection[] achunksection = chunk.getSections(); + PacketPlayOutMapChunk.ChunkMap packetplayoutmapchunk_chunkmap = new PacketPlayOutMapChunk.ChunkMap(); + ArrayList arraylist = Lists.newArrayList(); + + int j; + + for (j = 0; j < achunksection.length; ++j) { + ChunkSection chunksection = achunksection[j]; + + if (chunksection != null && (!flag || !chunksection.a()) && (i & 1 << j) != 0) { + packetplayoutmapchunk_chunkmap.b |= 1 << j; + arraylist.add(chunksection); + } + } + + packetplayoutmapchunk_chunkmap.a = new byte[a(Integer.bitCount(packetplayoutmapchunk_chunkmap.b), flag1, flag)]; + j = 0; + Iterator iterator = arraylist.iterator(); + + ChunkSection chunksection1; + + while (iterator.hasNext()) { + chunksection1 = (ChunkSection) iterator.next(); + char[] achar = chunksection1.getIdArray(); + char[] achar1 = achar; + int k = achar.length; + + for (int l = 0; l < k; ++l) { + char c0 = achar1[l]; + + packetplayoutmapchunk_chunkmap.a[j++] = (byte) (c0 & 255); + packetplayoutmapchunk_chunkmap.a[j++] = (byte) (c0 >> 8 & 255); + } + } + + for (iterator = arraylist.iterator(); iterator.hasNext(); j = a(chunksection1.getEmittedLightArray().a(), packetplayoutmapchunk_chunkmap.a, j)) { + chunksection1 = (ChunkSection) iterator.next(); + } + + if (flag1) { + for (iterator = arraylist.iterator(); iterator.hasNext(); j = a(chunksection1.getSkyLightArray().a(), packetplayoutmapchunk_chunkmap.a, j)) { + chunksection1 = (ChunkSection) iterator.next(); + } + } + + if (flag) { + a(chunk.getBiomeIndex(), packetplayoutmapchunk_chunkmap.a, j); + } + + return packetplayoutmapchunk_chunkmap; + } + + private static int a(byte[] abyte, byte[] abyte1, int i) { + System.arraycopy(abyte, 0, abyte1, i, abyte.length); + return i + abyte.length; + } + + public static class ChunkMap { + + public byte[] a; + public int b; + + public ChunkMap() {} + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java new file mode 100644 index 0000000..00c0538 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java @@ -0,0 +1,82 @@ +package net.minecraft.server; + +import java.io.IOException; +import java.util.List; + +public class PacketPlayOutMapChunkBulk implements Packet { + + private int[] a; + private int[] b; + private PacketPlayOutMapChunk.ChunkMap[] c; + private boolean d; + private World world; // Spigot + + public PacketPlayOutMapChunkBulk() {} + + public PacketPlayOutMapChunkBulk(List list) { + int i = list.size(); + + this.a = new int[i]; + this.b = new int[i]; + this.c = new PacketPlayOutMapChunk.ChunkMap[i]; + this.d = !((Chunk) list.get(0)).getWorld().worldProvider.o(); + + for (int j = 0; j < i; ++j) { + Chunk chunk = (Chunk) list.get(j); + PacketPlayOutMapChunk.ChunkMap packetplayoutmapchunk_chunkmap = chunk.getChunkMap(true, '\uffff'); // PaperSpigot + + this.a[j] = chunk.locX; + this.b[j] = chunk.locZ; + this.c[j] = packetplayoutmapchunk_chunkmap; + } + + world = ((Chunk) list.get(0)).getWorld(); // Spigot + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.d = packetdataserializer.readBoolean(); + int i = packetdataserializer.e(); + + this.a = new int[i]; + this.b = new int[i]; + this.c = new PacketPlayOutMapChunk.ChunkMap[i]; + + int j; + + for (j = 0; j < i; ++j) { + this.a[j] = packetdataserializer.readInt(); + this.b[j] = packetdataserializer.readInt(); + this.c[j] = new PacketPlayOutMapChunk.ChunkMap(); + this.c[j].b = packetdataserializer.readShort() & '\uffff'; + this.c[j].a = new byte[PacketPlayOutMapChunk.a(Integer.bitCount(this.c[j].b), this.d, true)]; + } + + for (j = 0; j < i; ++j) { + packetdataserializer.readBytes(this.c[j].a); + } + + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.writeBoolean(this.d); + packetdataserializer.b(this.c.length); + + int i; + + for (i = 0; i < this.a.length; ++i) { + packetdataserializer.writeInt(this.a[i]); + packetdataserializer.writeInt(this.b[i]); + packetdataserializer.writeShort((short) (this.c[i].b & '\uffff')); + } + + for (i = 0; i < this.a.length; ++i) { + world.spigotConfig.antiXrayInstance.obfuscate(this.a[i], this.b[i], this.c[i].b, this.c[i].a, world); // Spigot + packetdataserializer.writeBytes(this.c[i].a); + } + + } + + public void a(PacketListenerPlayOut packetlistenerplayout) { + packetlistenerplayout.a(this); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java new file mode 100644 index 0000000..c168194 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutOpenWindow.java @@ -0,0 +1,56 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayOutOpenWindow implements Packet { + + private int a; + private String b; + private IChatBaseComponent c; + private int d; + private int e; + + public PacketPlayOutOpenWindow() {} + + public PacketPlayOutOpenWindow(int i, String s, IChatBaseComponent ichatbasecomponent) { + this(i, s, ichatbasecomponent, 0); + } + + public PacketPlayOutOpenWindow(int i, String s, IChatBaseComponent ichatbasecomponent, int j) { + this.a = i; + this.b = s; + this.c = ichatbasecomponent; + this.d = j; + } + + public PacketPlayOutOpenWindow(int i, String s, IChatBaseComponent ichatbasecomponent, int j, int k) { + this(i, s, ichatbasecomponent, j); + this.e = k; + } + + public void a(PacketListenerPlayOut packetlistenerplayout) { + packetlistenerplayout.a(this); + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = packetdataserializer.readUnsignedByte(); + this.b = packetdataserializer.c(32); + this.c = packetdataserializer.d(); + this.d = packetdataserializer.readUnsignedByte(); + if (this.b.equals("EntityHorse")) { + this.e = packetdataserializer.readInt(); + } + + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.writeByte(this.a); + packetdataserializer.a(this.b); + packetdataserializer.a(this.c); + packetdataserializer.writeByte(this.d); + if (this.b.equals("EntityHorse")) { + packetdataserializer.writeInt(this.e); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutPlayerListHeaderFooter.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutPlayerListHeaderFooter.java new file mode 100644 index 0000000..795e70a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutPlayerListHeaderFooter.java @@ -0,0 +1,50 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayOutPlayerListHeaderFooter implements Packet { + + public net.md_5.bungee.api.chat.BaseComponent[] header, footer; // Paper + + private IChatBaseComponent a; + private IChatBaseComponent b; + + public PacketPlayOutPlayerListHeaderFooter() {} + + public PacketPlayOutPlayerListHeaderFooter(IChatBaseComponent ichatbasecomponent) { + this.a = ichatbasecomponent; + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = packetdataserializer.d(); + this.b = packetdataserializer.d(); + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + // Paper start + if (this.header != null) { + packetdataserializer.a(net.md_5.bungee.chat.ComponentSerializer.toString(this.header)); + } else { + packetdataserializer.a(this.a); + } + + if (this.footer != null) { + packetdataserializer.a(net.md_5.bungee.chat.ComponentSerializer.toString(this.footer)); + } else { + packetdataserializer.a(this.b); + } + // Paper end + } + + public void a(PacketListenerPlayOut packetlistenerplayout) { + packetlistenerplayout.a(this); + } + + // PaperSpigot start - fix compile error + /* + public void a(PacketListener packetlistener) { + this.a((PacketListenerPlayOut) packetlistener); + } + */ + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutTitle.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutTitle.java new file mode 100644 index 0000000..20016b5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketPlayOutTitle.java @@ -0,0 +1,125 @@ +package net.minecraft.server; + +import java.io.IOException; + +public class PacketPlayOutTitle implements Packet { + + private EnumTitleAction a; + private IChatBaseComponent b; + private int c; + private int d; + private int e; + + // Paper start + public net.md_5.bungee.api.chat.BaseComponent[] components; + + public PacketPlayOutTitle(EnumTitleAction action, net.md_5.bungee.api.chat.BaseComponent[] components, int fadeIn, int stay, int fadeOut) { + this.a = action; + this.components = components; + this.c = fadeIn; + this.d = stay; + this.e = fadeOut; + } + // Paper end + + public PacketPlayOutTitle() {} + + public PacketPlayOutTitle(EnumTitleAction packetplayouttitle_enumtitleaction, IChatBaseComponent ichatbasecomponent) { + this(packetplayouttitle_enumtitleaction, ichatbasecomponent, -1, -1, -1); + } + + public PacketPlayOutTitle(int i, int j, int k) { + this(EnumTitleAction.TIMES, (IChatBaseComponent) null, i, j, k); + } + + public PacketPlayOutTitle(EnumTitleAction packetplayouttitle_enumtitleaction, IChatBaseComponent ichatbasecomponent, int i, int j, int k) { + this.a = packetplayouttitle_enumtitleaction; + this.b = ichatbasecomponent; + this.c = i; + this.d = j; + this.e = k; + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + this.a = (EnumTitleAction) packetdataserializer.a(EnumTitleAction.class); + if (this.a == EnumTitleAction.TITLE || this.a == EnumTitleAction.SUBTITLE) { + this.b = packetdataserializer.d(); + } + + if (this.a == EnumTitleAction.TIMES) { + this.c = packetdataserializer.readInt(); + this.d = packetdataserializer.readInt(); + this.e = packetdataserializer.readInt(); + } + + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.a((Enum) this.a); + if (this.a == EnumTitleAction.TITLE || this.a == EnumTitleAction.SUBTITLE) { + // Paper start + if (this.components != null) { + packetdataserializer.a(net.md_5.bungee.chat.ComponentSerializer.toString(components)); + } else { + packetdataserializer.a(this.b); + } + // Paper end + } + + if (this.a == EnumTitleAction.TIMES) { + packetdataserializer.writeInt(this.c); + packetdataserializer.writeInt(this.d); + packetdataserializer.writeInt(this.e); + } + + } + + public void a(PacketListenerPlayOut packetlistenerplayout) { + packetlistenerplayout.a(this); + } + + // PaperSpigot start - fix compile error + /* + public void a(PacketListener packetlistener) { + this.a((PacketListenerPlayOut) packetlistener); + } + */ + // PaperSpigot end + + public static enum EnumTitleAction { + + TITLE, SUBTITLE, TIMES, CLEAR, RESET; + + private EnumTitleAction() {} + + public static EnumTitleAction a(String s) { + EnumTitleAction[] apacketplayouttitle_enumtitleaction = values(); + int i = apacketplayouttitle_enumtitleaction.length; + + for (int j = 0; j < i; ++j) { + EnumTitleAction packetplayouttitle_enumtitleaction = apacketplayouttitle_enumtitleaction[j]; + + if (packetplayouttitle_enumtitleaction.name().equalsIgnoreCase(s)) { + return packetplayouttitle_enumtitleaction; + } + } + + return EnumTitleAction.TITLE; + } + + public static String[] a() { + String[] astring = new String[values().length]; + int i = 0; + EnumTitleAction[] apacketplayouttitle_enumtitleaction = values(); + int j = apacketplayouttitle_enumtitleaction.length; + + for (int k = 0; k < j; ++k) { + EnumTitleAction packetplayouttitle_enumtitleaction = apacketplayouttitle_enumtitleaction[k]; + + astring[i++] = packetplayouttitle_enumtitleaction.name().toLowerCase(); + } + + return astring; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketStatusListener.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketStatusListener.java new file mode 100644 index 0000000..fbbfa00 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PacketStatusListener.java @@ -0,0 +1,135 @@ +package net.minecraft.server; + +// CraftBukkit start +import com.mojang.authlib.GameProfile; +import io.netty.channel.ChannelFutureListener; +import java.net.InetSocketAddress; +import java.util.Iterator; + +import net.jafama.FastMath; +import org.bukkit.craftbukkit.util.CraftIconCache; +import org.bukkit.entity.Player; + +// CraftBukkit end + +public class PacketStatusListener implements PacketStatusInListener { + + private static final IChatBaseComponent a = new ChatComponentText("Status request has been handled."); + private final MinecraftServer minecraftServer; + private final NetworkManager networkManager; + private boolean d; + + public PacketStatusListener(MinecraftServer minecraftserver, NetworkManager networkmanager) { + this.minecraftServer = minecraftserver; + this.networkManager = networkmanager; + } + + public void a(IChatBaseComponent ichatbasecomponent) {} + + public void a(PacketStatusInStart packetstatusinstart) { + if (this.d) { + this.networkManager.close(PacketStatusListener.a); + // CraftBukkit start - fire ping event + return; + } + this.d = true; + // this.networkManager.handle(new PacketStatusOutServerInfo(this.minecraftServer.aG())); + final Object[] players = minecraftServer.getPlayerList().players.toArray(); + class ServerListPingEvent extends org.bukkit.event.server.ServerListPingEvent { + CraftIconCache icon = minecraftServer.server.getServerIcon(); + + ServerListPingEvent() { + super(((InetSocketAddress) networkManager.getSocketAddress()).getAddress(), minecraftServer.getMotd(), minecraftServer.getPlayerList().getMaxPlayers()); + } + + @Override + public void setServerIcon(org.bukkit.util.CachedServerIcon icon) { + if (!(icon instanceof CraftIconCache)) { + throw new IllegalArgumentException(icon + " was not created by " + org.bukkit.craftbukkit.CraftServer.class); + } + this.icon = (CraftIconCache) icon; + } + + @Override + public Iterator iterator() throws UnsupportedOperationException { + return new Iterator() { + int i; + int ret = Integer.MIN_VALUE; + EntityPlayer player; + + @Override + public boolean hasNext() { + if (player != null) { + return true; + } + final Object[] currentPlayers = players; + for (int length = currentPlayers.length, i = this.i; i < length; i++) { + final EntityPlayer player = (EntityPlayer) currentPlayers[i]; + if (player != null) { + this.i = i + 1; + this.player = player; + return true; + } + } + return false; + } + + @Override + public Player next() { + if (!hasNext()) { + throw new java.util.NoSuchElementException(); + } + final EntityPlayer player = this.player; + this.player = null; + this.ret = this.i - 1; + return player.getBukkitEntity(); + } + + @Override + public void remove() { + final Object[] currentPlayers = players; + final int i = this.ret; + if (i < 0 || currentPlayers[i] == null) { + throw new IllegalStateException(); + } + currentPlayers[i] = null; + } + }; + } + } + + ServerListPingEvent event = new ServerListPingEvent(); + this.minecraftServer.server.getPluginManager().callEvent(event); + + java.util.List profiles = new java.util.ArrayList(players.length); + for (Object player : players) { + if (player != null) { + profiles.add(((EntityPlayer) player).getProfile()); + } + } + + ServerPing.ServerPingPlayerSample playerSample = new ServerPing.ServerPingPlayerSample(event.getMaxPlayers(), profiles.size()); + // Spigot Start + if ( !profiles.isEmpty() ) + { + java.util.Collections.shuffle( profiles ); // This sucks, its inefficient but we have no simple way of doing it differently + profiles = profiles.subList( 0, FastMath.min( profiles.size(), org.spigotmc.SpigotConfig.playerSample ) ); // Cap the sample to n (or less) displayed players, ie: Vanilla behaviour + } + // Spigot End + playerSample.a(profiles.toArray(new GameProfile[profiles.size()])); + + ServerPing ping = new ServerPing(); + ping.setFavicon(event.icon.value); + ping.setMOTD(new ChatComponentText(event.getMotd())); + ping.setPlayerSample(playerSample); + ping.setServerInfo(new ServerPing.ServerData(minecraftServer.getServerModName() + " " + minecraftServer.getVersion(), 47)); // TODO: Update when protocol changes + + this.networkManager.handle(new PacketStatusOutServerInfo(ping)); + // CraftBukkit end + } + + public void a(PacketStatusInPing packetstatusinping) { + this.networkManager.handle(new PacketStatusOutPong(packetstatusinping.a())); + this.networkManager.close(PacketStatusListener.a); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Path.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Path.java new file mode 100644 index 0000000..c976c98 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Path.java @@ -0,0 +1,129 @@ +package net.minecraft.server; + +public class Path { + + private PathPoint[] a = new PathPoint[128]; // CraftBukkit - reduce default size + private int b; + + public Path() {} + + public PathPoint a(PathPoint pathpoint) { + if (pathpoint.d >= 0) { + throw new IllegalStateException("OW KNOWS!"); + } else { + if (this.b == this.a.length) { + PathPoint[] apathpoint = new PathPoint[this.b << 1]; + + System.arraycopy(this.a, 0, apathpoint, 0, this.b); + this.a = apathpoint; + } + + this.a[this.b] = pathpoint; + pathpoint.d = this.b; + this.a(this.b++); + return pathpoint; + } + } + + public void a() { + this.b = 0; + } + + public PathPoint c() { + PathPoint pathpoint = this.a[0]; + + this.a[0] = this.a[--this.b]; + this.a[this.b] = null; + if (this.b > 0) { + this.b(0); + } + + pathpoint.d = -1; + return pathpoint; + } + + public void a(PathPoint pathpoint, float f) { + float f1 = pathpoint.g; + + pathpoint.g = f; + if (f < f1) { + this.a(pathpoint.d); + } else { + this.b(pathpoint.d); + } + + } + + private void a(int i) { + PathPoint pathpoint = this.a[i]; + + int j; + + for (float f = pathpoint.g; i > 0; i = j) { + j = i - 1 >> 1; + PathPoint pathpoint1 = this.a[j]; + + if (f >= pathpoint1.g) { + break; + } + + this.a[i] = pathpoint1; + pathpoint1.d = i; + } + + this.a[i] = pathpoint; + pathpoint.d = i; + } + + private void b(int i) { + PathPoint pathpoint = this.a[i]; + float f = pathpoint.g; + + while (true) { + int j = 1 + (i << 1); + int k = j + 1; + + if (j >= this.b) { + break; + } + + PathPoint pathpoint1 = this.a[j]; + float f1 = pathpoint1.g; + PathPoint pathpoint2; + float f2; + + if (k >= this.b) { + pathpoint2 = null; + f2 = Float.POSITIVE_INFINITY; + } else { + pathpoint2 = this.a[k]; + f2 = pathpoint2.g; + } + + if (f1 < f2) { + if (f1 >= f) { + break; + } + + this.a[i] = pathpoint1; + pathpoint1.d = i; + i = j; + } else { + if (f2 >= f) { + break; + } + + this.a[i] = pathpoint2; + pathpoint2.d = i; + i = k; + } + } + + this.a[i] = pathpoint; + pathpoint.d = i; + } + + public boolean e() { + return this.b == 0; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreakDoor.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreakDoor.java new file mode 100644 index 0000000..fdc77cb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreakDoor.java @@ -0,0 +1,78 @@ +package net.minecraft.server; + +public class PathfinderGoalBreakDoor extends PathfinderGoalDoorInteract { + + private int g; + private int h = -1; + + public PathfinderGoalBreakDoor(EntityInsentient entityinsentient) { + super(entityinsentient); + } + + public boolean a() { + if (!super.a()) { + return false; + } else if (!this.a.world.getGameRules().getBoolean("mobGriefing")) { + return false; + } else { + BlockDoor blockdoor = this.c; + + return !BlockDoor.f(this.a.world, this.b); + } + } + + public void c() { + super.c(); + this.g = 0; + } + + public boolean b() { + double d0 = this.a.b(this.b); + boolean flag; + + if (this.g <= 240) { + BlockDoor blockdoor = this.c; + + if (!BlockDoor.f(this.a.world, this.b) && d0 < 4.0D) { + flag = true; + return flag; + } + } + + flag = false; + return flag; + } + + public void d() { + super.d(); + this.a.world.c(this.a.getId(), this.b, -1); + } + + public void e() { + super.e(); + if (this.a.bc().nextInt(20) == 0) { + this.a.world.triggerEffect(1010, this.b, 0); + } + + ++this.g; + int i = (int) ((float) this.g / 240.0F * 10.0F); + + if (i != this.h) { + this.a.world.c(this.a.getId(), this.b, i); + this.h = i; + } + + if (this.g == 240 && this.a.world.getDifficulty() == EnumDifficulty.HARD) { + // CraftBukkit start + if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreakDoorEvent(this.a, this.b.getX(), this.b.getY(), this.b.getZ()).isCancelled()) { + this.c(); + return; + } + // CraftBukkit end + this.a.world.setAir(this.b); + this.a.world.triggerEffect(1012, this.b, 0); + this.a.world.triggerEffect(2001, this.b, Block.getId(this.c)); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreed.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreed.java new file mode 100644 index 0000000..cdff6d2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalBreed.java @@ -0,0 +1,117 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class PathfinderGoalBreed extends PathfinderGoal { + + private EntityAnimal d; + World a; + private EntityAnimal e; + int b; + double c; + + public PathfinderGoalBreed(EntityAnimal entityanimal, double d0) { + this.d = entityanimal; + this.a = entityanimal.world; + this.c = d0; + this.a(3); + } + + public boolean a() { + if (!this.d.isInLove()) { + return false; + } else { + this.e = this.f(); + return this.e != null; + } + } + + public boolean b() { + return this.e.isAlive() && this.e.isInLove() && this.b < 60; + } + + public void d() { + this.e = null; + this.b = 0; + } + + public void e() { + this.d.getControllerLook().a(this.e, 10.0F, (float) this.d.bQ()); + this.d.getNavigation().a((Entity) this.e, this.c); + ++this.b; + if (this.b >= 60 && this.d.h(this.e) < 9.0D) { + this.g(); + } + + } + + private EntityAnimal f() { + float f = 8.0F; + List list = this.a.a(this.d.getClass(), this.d.getBoundingBox().grow((double) f, (double) f, (double) f)); + double d0 = Double.MAX_VALUE; + EntityAnimal entityanimal = null; + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityAnimal entityanimal1 = (EntityAnimal) iterator.next(); + + if (this.d.mate(entityanimal1) && this.d.h(entityanimal1) < d0) { + entityanimal = entityanimal1; + d0 = this.d.h(entityanimal1); + } + } + + return entityanimal; + } + + private void g() { + EntityAgeable entityageable = this.d.createChild(this.e); + + if (entityageable != null) { + // CraftBukkit start - set persistence for tame animals + if (entityageable instanceof EntityTameableAnimal && ((EntityTameableAnimal) entityageable).isTamed()) { + entityageable.persistent = true; + } + // CraftBukkit end + EntityHuman entityhuman = this.d.cq(); + + if (entityhuman == null && this.e.cq() != null) { + entityhuman = this.e.cq(); + } + + if (entityhuman != null) { + entityhuman.b(StatisticList.A); + if (this.d instanceof EntityCow) { + entityhuman.b((Statistic) AchievementList.H); + } + } + + this.d.setAgeRaw(6000); + this.e.setAgeRaw(6000); + this.d.cs(); + this.e.cs(); + entityageable.setAgeRaw(-24000); + entityageable.setPositionRotation(this.d.locX, this.d.locY, this.d.locZ, 0.0F, 0.0F); + this.a.addEntity(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + Random random = this.d.bc(); + + for (int i = 0; i < 7; ++i) { + double d0 = random.nextGaussian() * 0.02D; + double d1 = random.nextGaussian() * 0.02D; + double d2 = random.nextGaussian() * 0.02D; + double d3 = random.nextDouble() * (double) this.d.width * 2.0D - (double) this.d.width; + 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]); + } + + if (this.a.getGameRules().getBoolean("doMobLoot")) { + this.a.addEntity(new EntityExperienceOrb(this.a, this.d.locX, this.d.locY, this.d.locZ, random.nextInt(7) + 1)); + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalDefendVillage.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalDefendVillage.java new file mode 100644 index 0000000..df627d3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalDefendVillage.java @@ -0,0 +1,40 @@ +package net.minecraft.server; + +public class PathfinderGoalDefendVillage extends PathfinderGoalTarget { + + EntityIronGolem a; + EntityLiving b; + + public PathfinderGoalDefendVillage(EntityIronGolem entityirongolem) { + super(entityirongolem, false, true); + this.a = entityirongolem; + this.a(1); + } + + public boolean a() { + Village village = this.a.n(); + + if (village == null) { + return false; + } else { + this.b = village.b((EntityLiving) this.a); + if (this.b instanceof EntityCreeper) { + return false; + } else if (!this.a(this.b, false)) { + if (this.e.bc().nextInt(20) == 0) { + this.b = village.c((EntityLiving) this.a); + return this.a(this.b, false); + } else { + return false; + } + } else { + return true; + } + } + } + + public void c() { + this.a.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.DEFEND_VILLAGE, true); // CraftBukkit - reason + super.c(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalEatTile.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalEatTile.java new file mode 100644 index 0000000..0582519 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalEatTile.java @@ -0,0 +1,80 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; + +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.Material; +// CraftBukkit end + +public class PathfinderGoalEatTile extends PathfinderGoal { + + private static final Predicate b = BlockStatePredicate.a((Block) Blocks.TALLGRASS).a(BlockLongGrass.TYPE, Predicates.equalTo(BlockLongGrass.EnumTallGrassType.GRASS)); + private EntityInsentient c; + private World d; + int a; + + public PathfinderGoalEatTile(EntityInsentient entityinsentient) { + this.c = entityinsentient; + this.d = entityinsentient.world; + this.a(7); + } + + public boolean a() { + if (this.c.bc().nextInt(this.c.isBaby() ? 50 : 1000) != 0) { + return false; + } else { + BlockPosition blockposition = new BlockPosition(this.c.locX, this.c.locY, this.c.locZ); + + return PathfinderGoalEatTile.b.apply(this.d.getType(blockposition)) ? true : this.d.getType(blockposition.down()).getBlock() == Blocks.GRASS; + } + } + + public void c() { + this.a = 40; + this.d.broadcastEntityEffect(this.c, (byte) 10); + this.c.getNavigation().n(); + } + + public void d() { + this.a = 0; + } + + public boolean b() { + return this.a > 0; + } + + public int f() { + return this.a; + } + + public void e() { + this.a = Math.max(0, this.a - 1); + if (this.a == 4) { + BlockPosition blockposition = new BlockPosition(this.c.locX, this.c.locY, this.c.locZ); + + if (PathfinderGoalEatTile.b.apply(this.d.getType(blockposition))) { + // CraftBukkit + if (!CraftEventFactory.callEntityChangeBlockEvent(this.c, this.c.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), Material.AIR, !this.d.getGameRules().getBoolean("mobGriefing")).isCancelled()) { + this.d.setAir(blockposition, false); + } + + this.c.v(); + } else { + BlockPosition blockposition1 = blockposition.down(); + + if (this.d.getType(blockposition1).getBlock() == Blocks.GRASS) { + // CraftBukkit + if (!CraftEventFactory.callEntityChangeBlockEvent(this.c, this.c.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), Material.AIR, !this.d.getGameRules().getBoolean("mobGriefing")).isCancelled()) { + this.d.triggerEffect(2001, blockposition1, Block.getId(Blocks.GRASS)); + this.d.setTypeAndData(blockposition1, Blocks.DIRT.getBlockData(), 2); + } + + this.c.v(); + } + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalFloat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalFloat.java new file mode 100644 index 0000000..da019c1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalFloat.java @@ -0,0 +1,24 @@ +package net.minecraft.server; + +public class PathfinderGoalFloat extends PathfinderGoal { + + private EntityInsentient a; + + public PathfinderGoalFloat(EntityInsentient entityinsentient) { + this.a = entityinsentient; + entityinsentient.goalFloat = this; // PaperSpigot + this.a(4); + ((Navigation) entityinsentient.getNavigation()).d(true); + } + + public boolean a() { + return this.a.V() || this.a.ab(); + } + + public void e() { + if (this.a.bc().nextFloat() < 0.8F) { + this.a.getControllerJump().a(); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalHurtByTarget.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalHurtByTarget.java new file mode 100644 index 0000000..bf9eda8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalHurtByTarget.java @@ -0,0 +1,63 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +public class PathfinderGoalHurtByTarget extends PathfinderGoalTarget { + + private boolean a; + private int b; + private final Class[] c; + + public PathfinderGoalHurtByTarget(EntityCreature entitycreature, boolean flag, Class... aclass) { + super(entitycreature, false); + this.a = flag; + this.c = aclass; + this.a(1); + } + + public boolean a() { + int i = this.e.be(); + + return i != this.b && this.a(this.e.getLastDamager(), false); + } + + public void c() { + this.e.setGoalTarget(this.e.getLastDamager(), org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY, true); // CraftBukkit - reason + this.b = this.e.be(); + if (this.a) { + double d0 = this.f(); + List list = this.e.world.a(this.e.getClass(), (new AxisAlignedBB(this.e.locX, this.e.locY, this.e.locZ, this.e.locX + 1.0D, this.e.locY + 1.0D, this.e.locZ + 1.0D)).grow(d0, 10.0D, d0)); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityCreature entitycreature = (EntityCreature) iterator.next(); + + if (this.e != entitycreature && entitycreature.getGoalTarget() == null && !entitycreature.c(this.e.getLastDamager())) { + boolean flag = false; + Class[] aclass = this.c; + int i = aclass.length; + + for (int j = 0; j < i; ++j) { + Class oclass = aclass[j]; + + if (entitycreature.getClass() == oclass) { + flag = true; + break; + } + } + + if (!flag) { + this.a(entitycreature, this.e.getLastDamager()); + } + } + } + } + + super.c(); + } + + protected void a(EntityCreature entitycreature, EntityLiving entityliving) { + entitycreature.setGoalTarget(entityliving, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, true); // CraftBukkit - reason + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalMakeLove.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalMakeLove.java new file mode 100644 index 0000000..d8a0204 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalMakeLove.java @@ -0,0 +1,93 @@ +package net.minecraft.server; + +public class PathfinderGoalMakeLove extends PathfinderGoal { + + private EntityVillager b; + private EntityVillager c; + private World d; + private int e; + Village a; + + public PathfinderGoalMakeLove(EntityVillager entityvillager) { + this.b = entityvillager; + this.d = entityvillager.world; + this.a(3); + } + + public boolean a() { + if (this.b.getAge() != 0) { + return false; + } else if (this.b.bc().nextInt(500) != 0) { + return false; + } else { + this.a = this.d.ae().getClosestVillage(new BlockPosition(this.b), 0); + if (this.a == null) { + return false; + } else if (this.f() && this.b.n(true)) { + Entity entity = this.d.a(EntityVillager.class, this.b.getBoundingBox().grow(8.0D, 3.0D, 8.0D), (Entity) this.b); + + if (entity == null) { + return false; + } else { + this.c = (EntityVillager) entity; + return this.c.getAge() == 0 && this.c.n(true); + } + } else { + return false; + } + } + } + + public void c() { + this.e = 300; + this.b.l(true); + } + + public void d() { + this.a = null; + this.c = null; + this.b.l(false); + } + + public boolean b() { + return this.e >= 0 && this.f() && this.b.getAge() == 0 && this.b.n(false); + } + + public void e() { + --this.e; + this.b.getControllerLook().a(this.c, 10.0F, 30.0F); + if (this.b.h(this.c) > 2.25D) { + this.b.getNavigation().a((Entity) this.c, 0.25D); + } else if (this.e == 0 && this.c.cm()) { + this.g(); + } + + if (this.b.bc().nextInt(35) == 0) { + this.d.broadcastEntityEffect(this.b, (byte) 12); + } + + } + + private boolean f() { + if (!this.a.i()) { + return false; + } else { + int i = (int) ((double) ((float) this.a.c()) * 0.35D); + + return this.a.e() < i; + } + } + + private void g() { + EntityVillager entityvillager = this.b.b((EntityAgeable) this.c); + + this.c.setAgeRaw(6000); + this.b.setAgeRaw(6000); + this.c.o(false); + this.b.o(false); + entityvillager.setAgeRaw(-24000); + entityvillager.setPositionRotation(this.b.locX, this.b.locY, this.b.locZ, 0.0F, 0.0F); + this.d.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + this.d.broadcastEntityEffect(entityvillager, (byte) 12); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java new file mode 100644 index 0000000..5cdc263 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTarget.java @@ -0,0 +1,109 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class PathfinderGoalNearestAttackableTarget extends PathfinderGoalTarget { + + protected final Class a; + private final int g; + protected final PathfinderGoalNearestAttackableTarget.DistanceComparator b; + protected Predicate c; + protected EntityLiving d; + + public PathfinderGoalNearestAttackableTarget(EntityCreature entitycreature, Class oclass, boolean flag) { + this(entitycreature, oclass, flag, false); + } + + public PathfinderGoalNearestAttackableTarget(EntityCreature entitycreature, Class oclass, boolean flag, boolean flag1) { + this(entitycreature, oclass, 10, flag, flag1, (Predicate) null); + } + + public PathfinderGoalNearestAttackableTarget(EntityCreature entitycreature, Class oclass, int i, boolean flag, boolean flag1, final Predicate predicate) { + super(entitycreature, flag, flag1); + this.a = oclass; + this.g = i; + this.b = new PathfinderGoalNearestAttackableTarget.DistanceComparator(entitycreature); + this.a(1); + this.c = new Predicate() { + public boolean a(T t0) { + if (predicate != null && !predicate.apply(t0)) { + return false; + } else { + if (t0 instanceof EntityHuman) { + double d0 = PathfinderGoalNearestAttackableTarget.this.f(); + + if (t0.isSneaking()) { + d0 *= 0.800000011920929D; + } + + if (t0.isInvisible()) { + float f = ((EntityHuman) t0).bY(); + + if (f < 0.1F) { + f = 0.1F; + } + + d0 *= (double) (0.7F * f); + } + + if ((double) t0.g(PathfinderGoalNearestAttackableTarget.this.e) > d0) { + return false; + } + } + + return PathfinderGoalNearestAttackableTarget.this.a(t0, false); + } + } + + public boolean apply(Object object) { + return this.a((T) object); // CraftBukkit - fix decompile error + } + }; + } + + public boolean a() { + if (this.g > 0 && this.e.bc().nextInt(this.g) != 0) { + return false; + } else { + double d0 = this.f(); + List list = this.e.world.a(this.a, this.e.getBoundingBox().grow(d0, 4.0D, d0), Predicates.and((Predicate) this.c, (Predicate) IEntitySelector.d)); // TacoSpigot - the eclipse compiler can't understand this, so make it generic + + Collections.sort(list, this.b); + if (list.isEmpty()) { + return false; + } else { + this.d = (EntityLiving) list.get(0); + return true; + } + } + } + + public void c() { + this.e.setGoalTarget(this.d, d instanceof EntityPlayer ? org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER : org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // Craftbukkit - reason + super.c(); + } + + public static class DistanceComparator implements Comparator { + + private final Entity a; + + public DistanceComparator(Entity entity) { + this.a = entity; + } + + public int a(Entity entity, Entity entity1) { + double d0 = this.a.h(entity); + double d1 = this.a.h(entity1); + + return d0 < d1 ? -1 : (d0 > d1 ? 1 : 0); + } + + public int compare(Entity object, Entity object1) { // CraftBukkit - fix decompile error + return this.a((Entity) object, (Entity) object1); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTargetInsentient.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTargetInsentient.java new file mode 100644 index 0000000..b0b95bd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalNearestAttackableTargetInsentient.java @@ -0,0 +1,85 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.Collections; +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class PathfinderGoalNearestAttackableTargetInsentient extends PathfinderGoal { + + private static final Logger a = LogManager.getLogger(); + private EntityInsentient b; + private final Predicate c; + private final PathfinderGoalNearestAttackableTarget.DistanceComparator d; + private EntityLiving e; + private Class f; + + public PathfinderGoalNearestAttackableTargetInsentient(EntityInsentient entityinsentient, Class oclass) { + this.b = entityinsentient; + this.f = oclass; + if (entityinsentient instanceof EntityCreature) { + PathfinderGoalNearestAttackableTargetInsentient.a.warn("Use NearestAttackableTargetGoal.class for PathfinerMob mobs!"); + } + + this.c = new Predicate() { + public boolean a(EntityLiving entityliving) { + double d0 = PathfinderGoalNearestAttackableTargetInsentient.this.f(); + + if (entityliving.isSneaking()) { + d0 *= 0.800000011920929D; + } + + return entityliving.isInvisible() ? false : ((double) entityliving.g(PathfinderGoalNearestAttackableTargetInsentient.this.b) > d0 ? false : PathfinderGoalTarget.a(PathfinderGoalNearestAttackableTargetInsentient.this.b, entityliving, false, true)); + } + + public boolean apply(Object object) { + return this.a((EntityLiving) object); + } + }; + this.d = new PathfinderGoalNearestAttackableTarget.DistanceComparator(entityinsentient); + } + + public boolean a() { + double d0 = this.f(); + List list = this.b.world.a(this.f, this.b.getBoundingBox().grow(d0, 4.0D, d0), this.c); + + Collections.sort(list, this.d); + if (list.isEmpty()) { + return false; + } else { + this.e = (EntityLiving) list.get(0); + return true; + } + } + + public boolean b() { + EntityLiving entityliving = this.b.getGoalTarget(); + + if (entityliving == null) { + return false; + } else if (!entityliving.isAlive()) { + return false; + } else { + double d0 = this.f(); + + return this.b.h(entityliving) > d0 * d0 ? false : !(entityliving instanceof EntityPlayer) || !((EntityPlayer) entityliving).playerInteractManager.isCreative(); + } + } + + public void c() { + this.b.setGoalTarget(this.e, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_ENTITY, true); // CraftBukkit - reason + super.c(); + } + + public void d() { + this.b.setGoalTarget((EntityLiving) null); + super.c(); + } + + protected double f() { + AttributeInstance attributeinstance = this.b.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); + + return attributeinstance == null ? 16.0D : attributeinstance.getValue(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java new file mode 100644 index 0000000..465cfd1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtByTarget.java @@ -0,0 +1,42 @@ +package net.minecraft.server; + +public class PathfinderGoalOwnerHurtByTarget extends PathfinderGoalTarget { + + EntityTameableAnimal a; + EntityLiving b; + private int c; + + public PathfinderGoalOwnerHurtByTarget(EntityTameableAnimal entitytameableanimal) { + super(entitytameableanimal, false); + this.a = entitytameableanimal; + this.a(1); + } + + public boolean a() { + if (!this.a.isTamed()) { + return false; + } else { + EntityLiving entityliving = this.a.getOwner(); + + if (entityliving == null) { + return false; + } else { + this.b = entityliving.getLastDamager(); + int i = entityliving.be(); + + return i != this.c && this.a(this.b, false) && this.a.a(this.b, entityliving); + } + } + } + + public void c() { + this.e.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.TARGET_ATTACKED_OWNER, true); // CraftBukkit - reason + EntityLiving entityliving = this.a.getOwner(); + + if (entityliving != null) { + this.c = entityliving.be(); + } + + super.c(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java new file mode 100644 index 0000000..7269d2f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalOwnerHurtTarget.java @@ -0,0 +1,42 @@ +package net.minecraft.server; + +public class PathfinderGoalOwnerHurtTarget extends PathfinderGoalTarget { + + EntityTameableAnimal a; + EntityLiving b; + private int c; + + public PathfinderGoalOwnerHurtTarget(EntityTameableAnimal entitytameableanimal) { + super(entitytameableanimal, false); + this.a = entitytameableanimal; + this.a(1); + } + + public boolean a() { + if (!this.a.isTamed()) { + return false; + } else { + EntityLiving entityliving = this.a.getOwner(); + + if (entityliving == null) { + return false; + } else { + this.b = entityliving.bf(); + int i = entityliving.bg(); + + return i != this.c && this.a(this.b, false) && this.a.a(this.b, entityliving); + } + } + } + + public void c() { + this.e.setGoalTarget(this.b, org.bukkit.event.entity.EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET, true); // CraftBukkit - reason + EntityLiving entityliving = this.a.getOwner(); + + if (entityliving != null) { + this.c = entityliving.bg(); + } + + super.c(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalPanic.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalPanic.java new file mode 100644 index 0000000..30907ef --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalPanic.java @@ -0,0 +1,47 @@ +package net.minecraft.server; + +public class PathfinderGoalPanic extends PathfinderGoal { + + private EntityCreature b; + protected double a; + private double c; + private double d; + private double e; + + public PathfinderGoalPanic(EntityCreature entitycreature, double d0) { + this.b = entitycreature; + this.a = d0; + this.a(1); + } + + public boolean a() { + if (this.b.getLastDamager() == null && !this.b.isBurning()) { + return false; + } else { + Vec3D vec3d = RandomPositionGenerator.a(this.b, 5, 4); + + if (vec3d == null) { + return false; + } else { + this.c = vec3d.a; + this.d = vec3d.b; + this.e = vec3d.c; + return true; + } + } + } + + public void c() { + this.b.getNavigation().a(this.c, this.d, this.e, this.a); + } + + public boolean b() { + // CraftBukkit start - introduce a temporary timeout hack until this is fixed properly + if ((this.b.ticksLived - this.b.hurtTimestamp) > 100) { + this.b.b((EntityLiving) null); + return false; + } + // CraftBukkit end + return !this.b.getNavigation().m(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSelector.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSelector.java new file mode 100644 index 0000000..4f64dea --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSelector.java @@ -0,0 +1,142 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; + +import me.levansj01.mythicspigot.MythicConfiguration; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.bukkit.craftbukkit.util.UnsafeList; // CraftBukkit + +public class PathfinderGoalSelector { + + private static final Logger a = LogManager.getLogger(); + private List b = new UnsafeList(); + private List c = new UnsafeList(); + private final MethodProfiler d; + private int e; + private int f = 3; + + public PathfinderGoalSelector(MethodProfiler methodprofiler) { + this.d = methodprofiler; + } + + public void a(int i, PathfinderGoal pathfindergoal) { + if (!MythicConfiguration.Options.Server.mobAi && !(pathfindergoal instanceof PathfinderGoalBreed)) return; + this.b.add(new PathfinderGoalSelector.PathfinderGoalSelectorItem(i, pathfindergoal)); + } + + public void a(PathfinderGoal pathfindergoal) { + Iterator iterator = this.b.iterator(); + + while (iterator.hasNext()) { + PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); + PathfinderGoal pathfindergoal1 = pathfindergoalselector_pathfindergoalselectoritem.a; + + if (pathfindergoal1 == pathfindergoal) { + if (this.c.contains(pathfindergoalselector_pathfindergoalselectoritem)) { + pathfindergoal1.d(); + this.c.remove(pathfindergoalselector_pathfindergoalselectoritem); + } + + iterator.remove(); + } + } + + } + + public void a() { + this.d.a("goalSetup"); + Iterator iterator; + PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem; + + if (this.e++ % this.f == 0) { + iterator = this.b.iterator(); + + while (iterator.hasNext()) { + pathfindergoalselector_pathfindergoalselectoritem = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); + boolean flag = this.c.contains(pathfindergoalselector_pathfindergoalselectoritem); + + if (flag) { + if (this.b(pathfindergoalselector_pathfindergoalselectoritem) && this.a(pathfindergoalselector_pathfindergoalselectoritem)) { + continue; + } + + pathfindergoalselector_pathfindergoalselectoritem.a.d(); + this.c.remove(pathfindergoalselector_pathfindergoalselectoritem); + } + + if (this.b(pathfindergoalselector_pathfindergoalselectoritem) && pathfindergoalselector_pathfindergoalselectoritem.a.a()) { + pathfindergoalselector_pathfindergoalselectoritem.a.c(); + this.c.add(pathfindergoalselector_pathfindergoalselectoritem); + } + } + } else { + iterator = this.c.iterator(); + + while (iterator.hasNext()) { + pathfindergoalselector_pathfindergoalselectoritem = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); + if (!this.a(pathfindergoalselector_pathfindergoalselectoritem)) { + pathfindergoalselector_pathfindergoalselectoritem.a.d(); + iterator.remove(); + } + } + } + + this.d.b(); + this.d.a("goalTick"); + iterator = this.c.iterator(); + + while (iterator.hasNext()) { + pathfindergoalselector_pathfindergoalselectoritem = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); + pathfindergoalselector_pathfindergoalselectoritem.a.e(); + } + + this.d.b(); + } + + private boolean a(PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem) { + boolean flag = pathfindergoalselector_pathfindergoalselectoritem.a.b(); + + return flag; + } + + private boolean b(PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem) { + Iterator iterator = this.b.iterator(); + + while (iterator.hasNext()) { + PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem1 = (PathfinderGoalSelector.PathfinderGoalSelectorItem) iterator.next(); + + if (pathfindergoalselector_pathfindergoalselectoritem1 != pathfindergoalselector_pathfindergoalselectoritem) { + if (pathfindergoalselector_pathfindergoalselectoritem.b >= pathfindergoalselector_pathfindergoalselectoritem1.b) { + if (!this.a(pathfindergoalselector_pathfindergoalselectoritem, pathfindergoalselector_pathfindergoalselectoritem1) && this.c.contains(pathfindergoalselector_pathfindergoalselectoritem1)) { + ((UnsafeList.Itr) iterator).valid = false; // CraftBukkit - mark iterator for reuse + return false; + } + } else if (!pathfindergoalselector_pathfindergoalselectoritem1.a.i() && this.c.contains(pathfindergoalselector_pathfindergoalselectoritem1)) { + ((UnsafeList.Itr) iterator).valid = false; // CraftBukkit - mark iterator for reuse + return false; + } + } + } + + return true; + } + + private boolean a(PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem, PathfinderGoalSelector.PathfinderGoalSelectorItem pathfindergoalselector_pathfindergoalselectoritem1) { + return (pathfindergoalselector_pathfindergoalselectoritem.a.j() & pathfindergoalselector_pathfindergoalselectoritem1.a.j()) == 0; + } + + class PathfinderGoalSelectorItem { + + public PathfinderGoal a; + public int b; + + public PathfinderGoalSelectorItem(int i, PathfinderGoal pathfindergoal) { + this.b = i; + this.a = pathfindergoal; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSit.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSit.java new file mode 100644 index 0000000..5081b4f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSit.java @@ -0,0 +1,39 @@ +package net.minecraft.server; + +public class PathfinderGoalSit extends PathfinderGoal { + + private EntityTameableAnimal entity; + private boolean willSit; + + public PathfinderGoalSit(EntityTameableAnimal entitytameableanimal) { + this.entity = entitytameableanimal; + this.a(5); + } + + public boolean a() { + if (!this.entity.isTamed()) { + return this.willSit && this.entity.getGoalTarget() == null; // CraftBukkit - Allow sitting for wild animals + } else if (this.entity.V()) { + return false; + } else if (!this.entity.onGround) { + return false; + } else { + EntityLiving entityliving = this.entity.getOwner(); + + return entityliving == null ? true : (this.entity.h(entityliving) < 144.0D && entityliving.getLastDamager() != null ? false : this.willSit); + } + } + + public void c() { + this.entity.getNavigation().n(); + this.entity.setSitting(true); + } + + public void d() { + this.entity.setSitting(false); + } + + public void setSitting(boolean flag) { + this.willSit = flag; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSwell.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSwell.java new file mode 100644 index 0000000..c8eebf8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalSwell.java @@ -0,0 +1,39 @@ +package net.minecraft.server; + +public class PathfinderGoalSwell extends PathfinderGoal { + + EntityCreeper a; + EntityLiving b; + + public PathfinderGoalSwell(EntityCreeper entitycreeper) { + this.a = entitycreeper; + this.a(1); + } + + public boolean a() { + EntityLiving entityliving = this.a.getGoalTarget(); + + return this.a.cm() > 0 || entityliving != null && this.a.h(entityliving) < 9.0D; + } + + public void c() { + this.a.getNavigation().n(); + this.b = this.a.getGoalTarget(); + } + + public void d() { + this.b = null; + } + + public void e() { + if (this.b == null) { + this.a.a(-1); + } else if (this.a.h(this.b) > 49.0D) { + this.a.a(-1); + } else if (!this.a.getEntitySenses().a(this.b)) { + this.a.a(-1); + } else { + this.a.a(1); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalTame.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalTame.java new file mode 100644 index 0000000..123e657 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalTame.java @@ -0,0 +1,73 @@ +package net.minecraft.server; + +public class PathfinderGoalTame extends PathfinderGoal { + + private EntityHorse entity; + private double b; + private double c; + private double d; + private double e; + + public PathfinderGoalTame(EntityHorse entityhorse, double d0) { + this.entity = entityhorse; + this.b = d0; + this.a(1); + } + + public boolean a() { + if (!this.entity.isTame() && this.entity.passenger != null) { + Vec3D vec3d = RandomPositionGenerator.a(this.entity, 5, 4); + + if (vec3d == null) { + return false; + } else { + this.c = vec3d.a; + this.d = vec3d.b; + this.e = vec3d.c; + return true; + } + } else { + return false; + } + } + + public void c() { + this.entity.getNavigation().a(this.c, this.d, this.e, this.b); + } + + public boolean b() { + return !this.entity.getNavigation().m() && this.entity.passenger != null; + } + + public void e() { + if (this.entity.bc().nextInt(50) == 0) { + if (this.entity.passenger instanceof EntityHuman) { + int i = this.entity.getTemper(); + int j = this.entity.getMaxDomestication(); + + // CraftBukkit - fire EntityTameEvent + if (j > 0 && this.entity.bc().nextInt(j) < i && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this.entity, (EntityHuman) this.entity.passenger).isCancelled() && this.entity.passenger instanceof EntityHuman) { + this.entity.h((EntityHuman) this.entity.passenger); + this.entity.world.broadcastEntityEffect(this.entity, (byte) 7); + return; + } + + this.entity.u(5); + } + + // CraftBukkit start - Handle dismounting to account for VehicleExitEvent being fired. + if (this.entity.passenger != null) { + this.entity.passenger.mount((Entity) null); + // If the entity still has a passenger, then a plugin cancelled the event. + if (this.entity.passenger != null) { + return; + } + } + // this.entity.passenger = null; + // CraftBukkit end + this.entity.cW(); + this.entity.world.broadcastEntityEffect(this.entity, (byte) 6); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalTargetNearestPlayer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalTargetNearestPlayer.java new file mode 100644 index 0000000..4c1f168 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderGoalTargetNearestPlayer.java @@ -0,0 +1,108 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import java.util.Collections; +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class PathfinderGoalTargetNearestPlayer extends PathfinderGoal { + + private static final Logger a = LogManager.getLogger(); + private EntityInsentient b; + private final Predicate c; + private final PathfinderGoalNearestAttackableTarget.DistanceComparator d; + private EntityLiving e; + + public PathfinderGoalTargetNearestPlayer(EntityInsentient entityinsentient) { + this.b = entityinsentient; + if (entityinsentient instanceof EntityCreature) { + PathfinderGoalTargetNearestPlayer.a.warn("Use NearestAttackableTargetGoal.class for PathfinerMob mobs!"); + } + + this.c = new Predicate() { + public boolean a(Entity entity) { + if (!(entity instanceof EntityHuman)) { + return false; + } else if (((EntityHuman) entity).abilities.isInvulnerable) { + return false; + } else { + double d0 = PathfinderGoalTargetNearestPlayer.this.f(); + + if (entity.isSneaking()) { + d0 *= 0.800000011920929D; + } + + if (entity.isInvisible()) { + float f = ((EntityHuman) entity).bY(); + + if (f < 0.1F) { + f = 0.1F; + } + + d0 *= (double) (0.7F * f); + } + + return (double) entity.g(PathfinderGoalTargetNearestPlayer.this.b) > d0 ? false : PathfinderGoalTarget.a(PathfinderGoalTargetNearestPlayer.this.b, (EntityLiving) entity, false, true); + } + } + + public boolean apply(Object object) { + return this.a((Entity) object); + } + }; + this.d = new PathfinderGoalNearestAttackableTarget.DistanceComparator(entityinsentient); + } + + public boolean a() { + double d0 = this.f(); + List list = this.b.world.a(EntityHuman.class, this.b.getBoundingBox().grow(d0, 4.0D, d0), this.c); + + Collections.sort(list, this.d); + if (list.isEmpty()) { + return false; + } else { + this.e = (EntityLiving) list.get(0); + return true; + } + } + + public boolean b() { + EntityLiving entityliving = this.b.getGoalTarget(); + + if (entityliving == null) { + return false; + } else if (!entityliving.isAlive()) { + return false; + } else if (entityliving instanceof EntityHuman && ((EntityHuman) entityliving).abilities.isInvulnerable) { + return false; + } else { + ScoreboardTeamBase scoreboardteambase = this.b.getScoreboardTeam(); + ScoreboardTeamBase scoreboardteambase1 = entityliving.getScoreboardTeam(); + + if (scoreboardteambase != null && scoreboardteambase1 == scoreboardteambase) { + return false; + } else { + double d0 = this.f(); + + return this.b.h(entityliving) > d0 * d0 ? false : !(entityliving instanceof EntityPlayer) || !((EntityPlayer) entityliving).playerInteractManager.isCreative(); + } + } + } + + public void c() { + this.b.setGoalTarget(this.e, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit - added reason + super.c(); + } + + public void d() { + this.b.setGoalTarget((EntityLiving) null); + super.c(); + } + + protected double f() { + AttributeInstance attributeinstance = this.b.getAttributeInstance(GenericAttributes.FOLLOW_RANGE); + + return attributeinstance == null ? 16.0D : attributeinstance.getValue(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderNormal.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderNormal.java new file mode 100644 index 0000000..629aa16 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PathfinderNormal.java @@ -0,0 +1,219 @@ +package net.minecraft.server; + +public class PathfinderNormal extends PathfinderAbstract { + + private boolean f; + private boolean g; + private boolean h; + private boolean i; + private boolean j; + + public PathfinderNormal() {} + + public void a(IBlockAccess iblockaccess, Entity entity) { + super.a(iblockaccess, entity); + this.j = this.h; + } + + public void a() { + super.a(); + this.h = this.j; + } + + public PathPoint a(Entity entity) { + int i; + + if (this.i && entity.V()) { + i = (int) entity.getBoundingBox().b; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(MathHelper.floor(entity.locX), i, MathHelper.floor(entity.locZ)); + + for (Block block = this.a.getType(blockposition_mutableblockposition).getBlock(); block == Blocks.FLOWING_WATER || block == Blocks.WATER; block = this.a.getType(blockposition_mutableblockposition).getBlock()) { + ++i; + blockposition_mutableblockposition.c(MathHelper.floor(entity.locX), i, MathHelper.floor(entity.locZ)); + } + + this.h = false; + } else { + i = MathHelper.floor(entity.getBoundingBox().b + 0.5D); + } + + return this.a(MathHelper.floor(entity.getBoundingBox().a), i, MathHelper.floor(entity.getBoundingBox().c)); + } + + public PathPoint a(Entity entity, double d0, double d1, double d2) { + return this.a(MathHelper.floor(d0 - (double) (entity.width / 2.0F)), MathHelper.floor(d1), MathHelper.floor(d2 - (double) (entity.width / 2.0F))); + } + + public int a(PathPoint[] apathpoint, Entity entity, PathPoint pathpoint, PathPoint pathpoint1, float f) { + int i = 0; + byte b0 = 0; + + if (this.a(entity, pathpoint.a, pathpoint.b + 1, pathpoint.c) == 1) { + b0 = 1; + } + + PathPoint pathpoint2 = this.a(entity, pathpoint.a, pathpoint.b, pathpoint.c + 1, b0); + PathPoint pathpoint3 = this.a(entity, pathpoint.a - 1, pathpoint.b, pathpoint.c, b0); + PathPoint pathpoint4 = this.a(entity, pathpoint.a + 1, pathpoint.b, pathpoint.c, b0); + PathPoint pathpoint5 = this.a(entity, pathpoint.a, pathpoint.b, pathpoint.c - 1, b0); + + if (pathpoint2 != null && !pathpoint2.i && pathpoint2.a(pathpoint1) < f) { + apathpoint[i++] = pathpoint2; + } + + if (pathpoint3 != null && !pathpoint3.i && pathpoint3.a(pathpoint1) < f) { + apathpoint[i++] = pathpoint3; + } + + if (pathpoint4 != null && !pathpoint4.i && pathpoint4.a(pathpoint1) < f) { + apathpoint[i++] = pathpoint4; + } + + if (pathpoint5 != null && !pathpoint5.i && pathpoint5.a(pathpoint1) < f) { + apathpoint[i++] = pathpoint5; + } + + return i; + } + + private PathPoint a(Entity entity, int i, int j, int k, int l) { + PathPoint pathpoint = null; + int i1 = this.a(entity, i, j, k); + + if (i1 == 2) { + return this.a(i, j, k); + } else { + if (i1 == 1) { + pathpoint = this.a(i, j, k); + } + + if (pathpoint == null && l > 0 && i1 != -3 && i1 != -4 && this.a(entity, i, j + l, k) == 1) { + pathpoint = this.a(i, j + l, k); + j += l; + } + + if (pathpoint != null) { + int j1 = 0; + + int k1; + + for (k1 = 0; j > 0; pathpoint = this.a(i, j, k)) { + k1 = this.a(entity, i, j - 1, k); + if (this.h && k1 == -1) { + return null; + } + + if (k1 != 1) { + break; + } + + if (j1++ >= entity.aE()) { + return null; + } + + --j; + if (j <= 0) { + return null; + } + } + + if (k1 == -2) { + return null; + } + } + + return pathpoint; + } + } + + private int a(Entity entity, int i, int j, int k) { + return a(this.a, entity, i, j, k, this.c, this.d, this.e, this.h, this.g, this.f); + } + + public static int a(IBlockAccess iblockaccess, Entity entity, int i, int j, int k, int l, int i1, int j1, boolean flag, boolean flag1, boolean flag2) { + boolean flag3 = false; + BlockPosition blockposition = new BlockPosition(entity); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k1 = i; k1 < i + l; ++k1) { + for (int l1 = j; l1 < j + i1; ++l1) { + for (int i2 = k; i2 < k + j1; ++i2) { + blockposition_mutableblockposition.c(k1, l1, i2); + Block block = iblockaccess.getType(blockposition_mutableblockposition).getBlock(); + + if (block.getMaterial() != Material.AIR) { + if (block != Blocks.TRAPDOOR && block != Blocks.IRON_TRAPDOOR) { + if (block != Blocks.FLOWING_WATER && block != Blocks.WATER) { + if (!flag2 && block instanceof BlockDoor && block.getMaterial() == Material.WOOD) { + return 0; + } + } else { + if (flag) { + return -1; + } + + flag3 = true; + } + } else { + flag3 = true; + } + + if (block instanceof BlockMinecartTrackAbstract) { // PaperSpigot - Pathfinder optimizations + if (!(iblockaccess.getType(blockposition).getBlock() instanceof BlockMinecartTrackAbstract) && !(iblockaccess.getType(blockposition.down()).getBlock() instanceof BlockMinecartTrackAbstract)) { // PaperSpigot - Pathfinder optimizations + return -3; + } + } else if (!block.b(iblockaccess, blockposition_mutableblockposition) && (!flag1 || !(block instanceof BlockDoor) || block.getMaterial() != Material.WOOD)) { + if (block instanceof BlockFence || block instanceof BlockFenceGate || block instanceof BlockCobbleWall) { + return -3; + } + + if (block == Blocks.TRAPDOOR || block == Blocks.IRON_TRAPDOOR) { + return -4; + } + + Material material = block.getMaterial(); + + if (material != Material.LAVA) { + return 0; + } + + if (!entity.ab()) { + return -2; + } + } + } + } + } + } + + return flag3 ? 2 : 1; + } + + public void a(boolean flag) { + this.f = flag; + } + + public void b(boolean flag) { + this.g = flag; + } + + public void c(boolean flag) { + this.h = flag; + } + + public void d(boolean flag) { + this.i = flag; + } + + public boolean b() { + return this.f; + } + + public boolean d() { + return this.i; + } + + public boolean e() { + return this.h; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PersistentCollection.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PersistentCollection.java new file mode 100644 index 0000000..451f481 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PersistentCollection.java @@ -0,0 +1,184 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.io.DataInputStream; +import java.io.DataOutput; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class PersistentCollection { + + private IDataManager b; + protected Map a = Maps.newHashMap(); + public List c = Lists.newArrayList(); // Spigot + private Map d = Maps.newHashMap(); + + public PersistentCollection(IDataManager idatamanager) { + this.b = idatamanager; + this.b(); + } + + public PersistentBase get(Class oclass, String s) { + PersistentBase persistentbase = (PersistentBase) this.a.get(s); + + if (persistentbase != null) { + return persistentbase; + } else { + if (this.b != null) { + try { + File file = this.b.getDataFile(s); + + if (file != null && file.exists()) { + try { + persistentbase = (PersistentBase) oclass.getConstructor(new Class[] { String.class}).newInstance(new Object[] { s}); + } catch (Exception exception) { + throw new RuntimeException("Failed to instantiate " + oclass.toString(), exception); + } + + FileInputStream fileinputstream = new FileInputStream(file); + NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a((InputStream) fileinputstream); + + fileinputstream.close(); + persistentbase.a(nbttagcompound.getCompound("data")); + } + } catch (Exception exception1) { + exception1.printStackTrace(); + } + } + + if (persistentbase != null) { + this.a.put(s, persistentbase); + this.c.add(persistentbase); + } + + return persistentbase; + } + } + + public void a(String s, PersistentBase persistentbase) { + if (this.a.containsKey(s)) { + this.c.remove(this.a.remove(s)); + } + + this.a.put(s, persistentbase); + this.c.add(persistentbase); + } + + public void a() { + for (int i = 0; i < this.c.size(); ++i) { + PersistentBase persistentbase = (PersistentBase) this.c.get(i); + + if (persistentbase.d()) { + this.a(persistentbase); + persistentbase.a(false); + } + } + + } + + private void a(PersistentBase persistentbase) { + if (this.b != null) { + try { + File file = this.b.getDataFile(persistentbase.id); + + if (file != null) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + persistentbase.b(nbttagcompound); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.set("data", nbttagcompound); + FileOutputStream fileoutputstream = new FileOutputStream(file); + + NBTCompressedStreamTools.a(nbttagcompound1, (OutputStream) fileoutputstream); + fileoutputstream.close(); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + + } + } + + private void b() { + try { + this.d.clear(); + if (this.b == null) { + return; + } + + File file = this.b.getDataFile("idcounts"); + + if (file != null && file.exists()) { + DataInputStream datainputstream = new DataInputStream(new FileInputStream(file)); + NBTTagCompound nbttagcompound = NBTCompressedStreamTools.a(datainputstream); + + datainputstream.close(); + Iterator iterator = nbttagcompound.c().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + NBTBase nbtbase = nbttagcompound.get(s); + + if (nbtbase instanceof NBTTagShort) { + NBTTagShort nbttagshort = (NBTTagShort) nbtbase; + short short0 = nbttagshort.e(); + + this.d.put(s, Short.valueOf(short0)); + } + } + } + } catch (Exception exception) { + exception.printStackTrace(); + } + + } + + public int a(String s) { + Short oshort = (Short) this.d.get(s); + + if (oshort == null) { + oshort = Short.valueOf((short) 0); + } else { + oshort = Short.valueOf((short) (oshort.shortValue() + 1)); + } + + this.d.put(s, oshort); + if (this.b == null) { + return oshort.shortValue(); + } else { + try { + File file = this.b.getDataFile("idcounts"); + + if (file != null) { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + Iterator iterator = this.d.keySet().iterator(); + + while (iterator.hasNext()) { + String s1 = (String) iterator.next(); + short short0 = ((Short) this.d.get(s1)).shortValue(); + + nbttagcompound.setShort(s1, short0); + } + + DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(file)); + + NBTCompressedStreamTools.a(nbttagcompound, (DataOutput) dataoutputstream); + dataoutputstream.close(); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + + return oshort.shortValue(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerChunkMap.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerChunkMap.java new file mode 100644 index 0000000..38586aa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerChunkMap.java @@ -0,0 +1,596 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +// CraftBukkit start +import java.util.Collections; +import java.util.Queue; +import java.util.LinkedList; +import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; +import java.util.HashMap; +// CraftBukkit end + +public class PlayerChunkMap { + + private static final Logger a = LogManager.getLogger(); + private final WorldServer world; + private final List managedPlayers = Lists.newArrayList(); + private final LongHashMap d = new LongHashMap(); + private final Queue e = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue + private final Queue f = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue + private int g; + private long h; + private final int[][] i = new int[][] { { 1, 0}, { 0, 1}, { -1, 0}, { 0, -1}}; + private boolean wasNotEmpty; // CraftBukkit - add field + + public PlayerChunkMap(WorldServer worldserver, int viewDistance /* Spigot */) { + this.world = worldserver; + this.a(viewDistance); // Spigot + } + + public WorldServer a() { + return this.world; + } + + public void flush() { + long i = this.world.getTime(); + int j; + PlayerChunkMap.PlayerChunk playerchunkmap_playerchunk; + + if (i - this.h > 8000L) { + this.h = i; + + // CraftBukkit start - Use iterator + java.util.Iterator iterator = this.f.iterator(); + while (iterator.hasNext()) { + playerchunkmap_playerchunk = (PlayerChunk) iterator.next(); + playerchunkmap_playerchunk.b(); + playerchunkmap_playerchunk.a(); + } + } else { + java.util.Iterator iterator = this.e.iterator(); + while (iterator.hasNext()) { + playerchunkmap_playerchunk = (PlayerChunk) iterator.next(); + playerchunkmap_playerchunk.b(); + iterator.remove(); + // CraftBukkit end + } + } + + // this.e.clear(); //CraftBukkit - Removals are already covered + if (this.managedPlayers.isEmpty()) { + if (!wasNotEmpty) return; // CraftBukkit - Only do unload when we go from non-empty to empty + WorldProvider worldprovider = this.world.worldProvider; + + if (!worldprovider.e()) { + this.world.chunkProviderServer.b(); + } + // CraftBukkit start + wasNotEmpty = false; + } else { + wasNotEmpty = true; + } + // CraftBukkit end + + } + + public boolean a(int i, int j) { + long k = (long) i + 2147483647L | (long) j + 2147483647L << 32; + + return this.d.getEntry(k) != null; + } + + private PlayerChunkMap.PlayerChunk a(int i, int j, boolean flag) { + long k = (long) i + 2147483647L | (long) j + 2147483647L << 32; + PlayerChunkMap.PlayerChunk playerchunkmap_playerchunk = (PlayerChunkMap.PlayerChunk) this.d.getEntry(k); + + if (playerchunkmap_playerchunk == null && flag) { + playerchunkmap_playerchunk = new PlayerChunkMap.PlayerChunk(i, j); + this.d.put(k, playerchunkmap_playerchunk); + this.f.add(playerchunkmap_playerchunk); + } + + return playerchunkmap_playerchunk; + } + + // CraftBukkit start - add method + public final boolean isChunkInUse(int x, int z) { + PlayerChunk pi = a(x, z, false); + if (pi != null) { + return (pi.b.size() > 0); + } + return false; + } + // CraftBukkit end + + public void flagDirty(BlockPosition blockposition) { + int i = blockposition.getX() >> 4; + int j = blockposition.getZ() >> 4; + PlayerChunkMap.PlayerChunk playerchunkmap_playerchunk = this.a(i, j, false); + + if (playerchunkmap_playerchunk != null) { + playerchunkmap_playerchunk.a(blockposition.getX() & 15, blockposition.getY(), blockposition.getZ() & 15); + } + + } + + public void addPlayer(EntityPlayer entityplayer) { + int i = (int) entityplayer.locX >> 4; + int j = (int) entityplayer.locZ >> 4; + + entityplayer.d = entityplayer.locX; + entityplayer.e = entityplayer.locZ; + + // CraftBukkit start - Load nearby chunks first + List chunkList = new LinkedList(); + + // PaperSpigot start - Player view distance API + for (int k = i - entityplayer.viewDistance; k <= i + entityplayer.viewDistance; ++k) { + for (int l = j - entityplayer.viewDistance; l <= j + entityplayer.viewDistance; ++l) { + // PaperSpigot end + chunkList.add(new ChunkCoordIntPair(k, l)); + } + } + + Collections.sort(chunkList, new ChunkCoordComparator(entityplayer)); + for (ChunkCoordIntPair pair : chunkList) { + this.a(pair.x, pair.z, true).a(entityplayer); + } + // CraftBukkit end + + this.managedPlayers.add(entityplayer); + this.b(entityplayer); + } + + public void b(EntityPlayer entityplayer) { + ArrayList arraylist = Lists.newArrayList(entityplayer.chunkCoordIntPairQueue); + int i = 0; + int j = entityplayer.viewDistance; // PaperSpigot - Player view distance API + int k = (int) entityplayer.locX >> 4; + int l = (int) entityplayer.locZ >> 4; + int i1 = 0; + int j1 = 0; + ChunkCoordIntPair chunkcoordintpair = this.a(k, l, true).location; + + entityplayer.chunkCoordIntPairQueue.clear(); + if (arraylist.contains(chunkcoordintpair)) { + entityplayer.chunkCoordIntPairQueue.add(chunkcoordintpair); + } + + int k1; + + for (k1 = 1; k1 <= j * 2; ++k1) { + for (int l1 = 0; l1 < 2; ++l1) { + int[] aint = this.i[i++ % 4]; + + for (int i2 = 0; i2 < k1; ++i2) { + i1 += aint[0]; + j1 += aint[1]; + chunkcoordintpair = this.a(k + i1, l + j1, true).location; + if (arraylist.contains(chunkcoordintpair)) { + entityplayer.chunkCoordIntPairQueue.add(chunkcoordintpair); + } + } + } + } + + i %= 4; + + for (k1 = 0; k1 < j * 2; ++k1) { + i1 += this.i[i][0]; + j1 += this.i[i][1]; + chunkcoordintpair = this.a(k + i1, l + j1, true).location; + if (arraylist.contains(chunkcoordintpair)) { + entityplayer.chunkCoordIntPairQueue.add(chunkcoordintpair); + } + } + + } + + public void removePlayer(EntityPlayer entityplayer) { + int i = (int) entityplayer.d >> 4; + int j = (int) entityplayer.e >> 4; + + // PaperSpigot start - Player view distance API + for (int k = i - entityplayer.viewDistance; k <= i + entityplayer.viewDistance; ++k) { + for (int l = j - entityplayer.viewDistance; l <= j + entityplayer.viewDistance; ++l) { + // PaperSpigot end + PlayerChunkMap.PlayerChunk playerchunkmap_playerchunk = this.a(k, l, false); + + if (playerchunkmap_playerchunk != null) { + playerchunkmap_playerchunk.b(entityplayer); + } + } + } + + this.managedPlayers.remove(entityplayer); + } + + private boolean a(int i, int j, int k, int l, int i1) { + int j1 = i - k; + int k1 = j - l; + + return j1 >= -i1 && j1 <= i1 ? k1 >= -i1 && k1 <= i1 : false; + } + + public void movePlayer(EntityPlayer entityplayer) { + int i = (int) entityplayer.locX >> 4; + int j = (int) entityplayer.locZ >> 4; + double d0 = entityplayer.d - entityplayer.locX; + double d1 = entityplayer.e - entityplayer.locZ; + double d2 = d0 * d0 + d1 * d1; + + if (d2 >= 64.0D) { + int k = (int) entityplayer.d >> 4; + int l = (int) entityplayer.e >> 4; + int i1 = entityplayer.viewDistance; // PaperSpigot - Player view distance API + int j1 = i - k; + int k1 = j - l; + List chunksToLoad = new LinkedList(); // CraftBukkit + + if (j1 != 0 || k1 != 0) { + for (int l1 = i - i1; l1 <= i + i1; ++l1) { + for (int i2 = j - i1; i2 <= j + i1; ++i2) { + if (!this.a(l1, i2, k, l, i1)) { + chunksToLoad.add(new ChunkCoordIntPair(l1, i2)); // CraftBukkit + } + + if (!this.a(l1 - j1, i2 - k1, i, j, i1)) { + PlayerChunkMap.PlayerChunk playerchunkmap_playerchunk = this.a(l1 - j1, i2 - k1, false); + + if (playerchunkmap_playerchunk != null) { + playerchunkmap_playerchunk.b(entityplayer); + } + } + } + } + + this.b(entityplayer); + entityplayer.d = entityplayer.locX; + entityplayer.e = entityplayer.locZ; + + // CraftBukkit start - send nearest chunks first + Collections.sort(chunksToLoad, new ChunkCoordComparator(entityplayer)); + for (ChunkCoordIntPair pair : chunksToLoad) { + this.a(pair.x, pair.z, true).a(entityplayer); + } + + if (j1 > 1 || j1 < -1 || k1 > 1 || k1 < -1) { + Collections.sort(entityplayer.chunkCoordIntPairQueue, new ChunkCoordComparator(entityplayer)); + } + // CraftBukkit end + } + } + } + + public boolean a(EntityPlayer entityplayer, int i, int j) { + PlayerChunkMap.PlayerChunk playerchunkmap_playerchunk = this.a(i, j, false); + + return playerchunkmap_playerchunk != null && playerchunkmap_playerchunk.b.contains(entityplayer) && !entityplayer.chunkCoordIntPairQueue.contains(playerchunkmap_playerchunk.location); + } + + public void a(int i) { + i = MathHelper.clamp(i, 3, 32); + if (i != this.g) { + int j = i - this.g; + ArrayList arraylist = Lists.newArrayList(this.managedPlayers); + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + int k = (int) entityplayer.locX >> 4; + int l = (int) entityplayer.locZ >> 4; + int i1; + int j1; + + if (j > 0) { + for (i1 = k - i; i1 <= k + i; ++i1) { + for (j1 = l - i; j1 <= l + i; ++j1) { + PlayerChunkMap.PlayerChunk playerchunkmap_playerchunk = this.a(i1, j1, true); + + if (!playerchunkmap_playerchunk.b.contains(entityplayer)) { + playerchunkmap_playerchunk.a(entityplayer); + } + } + } + } else { + for (i1 = k - this.g; i1 <= k + this.g; ++i1) { + for (j1 = l - this.g; j1 <= l + this.g; ++j1) { + if (!this.a(i1, j1, k, l, i)) { + this.a(i1, j1, true).b(entityplayer); + } + } + } + } + } + + this.g = i; + } + } + + // PaperSpigot start - Player view distance API + public void updateViewDistance(EntityPlayer player, int viewDistance) { + viewDistance = MathHelper.clamp(viewDistance, 3, 32); + if (viewDistance != player.viewDistance) { + int cx = (int) player.locX >> 4; + int cz = (int) player.locZ >> 4; + + if (viewDistance - player.viewDistance > 0) { + for (int x = cx - viewDistance; x <= cx + viewDistance; ++x) { + for (int z = cz - viewDistance; z <= cz + viewDistance; ++z) { + PlayerChunkMap.PlayerChunk playerchunkmap_playerchunk = this.a(x, z, true); + + if (!playerchunkmap_playerchunk.b.contains(player)) { + playerchunkmap_playerchunk.a(player); + } + } + } + } else { + for (int x = cx - player.viewDistance; x <= cx + player.viewDistance; ++x) { + for (int z = cz - player.viewDistance; z <= cz + player.viewDistance; ++z) { + if (!this.a(x, z, cx, cz, viewDistance)) { + this.a(x, z, true).b(player); + } + } + } + } + + player.viewDistance = viewDistance; + } + } + // PaperSpigot end + + public static int getFurthestViewableBlock(int i) { + return i * 16 - 16; + } + + class PlayerChunk { + + private final List b = Lists.newArrayList(); + private final ChunkCoordIntPair location; + private short[] dirtyBlocks = new short[64]; + private int dirtyCount; + private int f; + private long g; + + // CraftBukkit start - add fields + private final HashMap players = new HashMap(); + private boolean loaded = false; + private Runnable loadedRunnable = new Runnable() { + public void run() { + PlayerChunk.this.loaded = true; + } + }; + // CraftBukkit end + + public PlayerChunk(int i, int j) { + this.location = new ChunkCoordIntPair(i, j); + PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(i, j, loadedRunnable); // CraftBukkit + } + + public void a(final EntityPlayer entityplayer) { // CraftBukkit - added final to argument + if (this.b.contains(entityplayer)) { + PlayerChunkMap.a.debug("Failed to add player. {} already is in chunk {}, {}", new Object[] { entityplayer, Integer.valueOf(this.location.x), Integer.valueOf(this.location.z)}); + } else { + if (this.b.isEmpty()) { + this.g = PlayerChunkMap.this.world.getTime(); + } + + this.b.add(entityplayer); + // CraftBukkit start - use async chunk io + Runnable playerRunnable; + if (this.loaded) { + playerRunnable = null; + entityplayer.chunkCoordIntPairQueue.add(this.location); + } else { + playerRunnable = new Runnable() { + public void run() { + entityplayer.chunkCoordIntPairQueue.add(PlayerChunk.this.location); + } + }; + PlayerChunkMap.this.a().chunkProviderServer.getChunkAt(this.location.x, this.location.z, playerRunnable); + } + + this.players.put(entityplayer, playerRunnable); + // CraftBukkit end + } + } + + public void b(EntityPlayer entityplayer) { + if (this.b.contains(entityplayer)) { + // CraftBukkit start - If we haven't loaded yet don't load the chunk just so we can clean it up + if (!this.loaded) { + ChunkIOExecutor.dropQueuedChunkLoad(PlayerChunkMap.this.a(), this.location.x, this.location.z, this.players.get(entityplayer)); + this.b.remove(entityplayer); + this.players.remove(entityplayer); + + if (this.b.isEmpty()) { + ChunkIOExecutor.dropQueuedChunkLoad(PlayerChunkMap.this.a(), this.location.x, this.location.z, this.loadedRunnable); + long i = (long) this.location.x + 2147483647L | (long) this.location.z + 2147483647L << 32; + PlayerChunkMap.this.d.remove(i); + PlayerChunkMap.this.f.remove(this); + } + + return; + } + // CraftBukkit end + Chunk chunk = PlayerChunkMap.this.world.getChunkAt(this.location.x, this.location.z); + + if (chunk.isReady()) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(chunk, true, 0)); + } + + this.players.remove(entityplayer); // CraftBukkit + this.b.remove(entityplayer); + entityplayer.chunkCoordIntPairQueue.remove(this.location); + if (this.b.isEmpty()) { + long i = (long) this.location.x + 2147483647L | (long) this.location.z + 2147483647L << 32; + + this.a(chunk); + PlayerChunkMap.this.d.remove(i); + PlayerChunkMap.this.f.remove(this); + if (this.dirtyCount > 0) { + PlayerChunkMap.this.e.remove(this); + } + + PlayerChunkMap.this.a().chunkProviderServer.queueUnload(this.location.x, this.location.z); + } + + } + } + + public void a() { + this.a(PlayerChunkMap.this.world.getChunkAt(this.location.x, this.location.z)); + } + + private void a(Chunk chunk) { + chunk.c(chunk.w() + PlayerChunkMap.this.world.getTime() - this.g); + this.g = PlayerChunkMap.this.world.getTime(); + } + + public void a(int i, int j, int k) { + if (this.dirtyCount == 0) { + PlayerChunkMap.this.e.add(this); + } + + this.f |= 1 << (j >> 4); + if (this.dirtyCount < 64) { + short short0 = (short) (i << 12 | k << 8 | j); + + for (int l = 0; l < this.dirtyCount; ++l) { + if (this.dirtyBlocks[l] == short0) { + return; + } + } + + this.dirtyBlocks[this.dirtyCount++] = short0; + } + + } + + public void a(Packet packet) { + for (int i = 0; i < this.b.size(); ++i) { + EntityPlayer entityplayer = (EntityPlayer) this.b.get(i); + + if (!entityplayer.chunkCoordIntPairQueue.contains(this.location)) { + entityplayer.playerConnection.sendPacket(packet); + } + } + + } + + public void b() { + if (this.dirtyCount != 0) { + int i; + int j; + int k; + + if (this.dirtyCount == 1) { + i = (this.dirtyBlocks[0] >> 12 & 15) + this.location.x * 16; + j = this.dirtyBlocks[0] & 255; + k = (this.dirtyBlocks[0] >> 8 & 15) + this.location.z * 16; + BlockPosition blockposition = new BlockPosition(i, j, k); + + this.a((Packet) (new PacketPlayOutBlockChange(PlayerChunkMap.this.world, blockposition))); + if (PlayerChunkMap.this.world.getType(blockposition).getBlock().isTileEntity()) { + this.a(PlayerChunkMap.this.world.getTileEntity(blockposition)); + } + } else { + int l; + + if (this.dirtyCount == 64) { + i = this.location.x * 16; + j = this.location.z * 16; + this.a((Packet) (new PacketPlayOutMapChunk(PlayerChunkMap.this.world.getChunkAt(this.location.x, this.location.z), false, this.f))); + + for (k = 0; k < 16; ++k) { + if ((this.f & 1 << k) != 0) { + l = k << 4; + List list = PlayerChunkMap.this.world.getTileEntities(i, l, j, i + 16, l + 16, j + 16); + + for (int i1 = 0; i1 < list.size(); ++i1) { + this.a((TileEntity) list.get(i1)); + } + } + } + } else { + this.a((Packet) (new PacketPlayOutMultiBlockChange(this.dirtyCount, this.dirtyBlocks, PlayerChunkMap.this.world.getChunkAt(this.location.x, this.location.z)))); + + for (i = 0; i < this.dirtyCount; ++i) { + j = (this.dirtyBlocks[i] >> 12 & 15) + this.location.x * 16; + k = this.dirtyBlocks[i] & 255; + l = (this.dirtyBlocks[i] >> 8 & 15) + this.location.z * 16; + BlockPosition blockposition1 = new BlockPosition(j, k, l); + + if (PlayerChunkMap.this.world.getType(blockposition1).getBlock().isTileEntity()) { + this.a(PlayerChunkMap.this.world.getTileEntity(blockposition1)); + } + } + } + } + + this.dirtyCount = 0; + this.f = 0; + } + } + + private void a(TileEntity tileentity) { + if (tileentity != null) { + Packet packet = tileentity.getUpdatePacket(); + + if (packet != null) { + this.a(packet); + } + } + + } + } + + // CraftBukkit start - Sorter to load nearby chunks first + private static class ChunkCoordComparator implements java.util.Comparator { + private int x; + private int z; + + public ChunkCoordComparator (EntityPlayer entityplayer) { + x = (int) entityplayer.locX >> 4; + z = (int) entityplayer.locZ >> 4; + } + + public int compare(ChunkCoordIntPair a, ChunkCoordIntPair b) { + if (a.equals(b)) { + return 0; + } + + // Subtract current position to set center point + int ax = a.x - this.x; + int az = a.z - this.z; + int bx = b.x - this.x; + int bz = b.z - this.z; + + int result = ((ax - bx) * (ax + bx)) + ((az - bz) * (az + bz)); + if (result != 0) { + return result; + } + + if (ax < 0) { + if (bx < 0) { + return bz - az; + } else { + return -1; + } + } else { + if (bx < 0) { + return 1; + } else { + return az - bz; + } + } + } + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerConnection.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerConnection.java new file mode 100644 index 0000000..02cafc0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerConnection.java @@ -0,0 +1,2274 @@ +package net.minecraft.server; + +import co.aikar.timings.SpigotTimings; +import com.google.common.collect.Lists; +import com.google.common.primitives.Doubles; +import com.google.common.primitives.Floats; +import io.netty.buffer.Unpooled; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import me.levansj01.mythicspigot.limiter.TickLimiter; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Location; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.craftbukkit.util.LazyPlayerSet; +import org.bukkit.craftbukkit.util.Waitable; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.inventory.*; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.event.player.*; +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.util.NumberConversions; +import org.github.paperspigot.PaperSpigotConfig; + +import java.io.IOException; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.logging.Level; + +// CraftBukkit start +// CraftBukkit end + +public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerListBox { + + private static final Logger c = LogManager.getLogger(); + public final NetworkManager networkManager; + private final MinecraftServer minecraftServer; + public EntityPlayer player; + private int e; + private int f; + private int g; + private boolean h; + private int i; + private long j; + private long k; + // CraftBukkit start - multithreaded fields + private volatile int chatThrottle; + private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(PlayerConnection.class, "chatThrottle"); + // CraftBukkit end + private int m; + private IntHashMap n = new IntHashMap(); + private double o; + private double p; + private double q; + private boolean checkMovement = true; + private boolean processedDisconnect; // CraftBukkit - added + + public PlayerConnection(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) { + this.minecraftServer = minecraftserver; + this.networkManager = networkmanager; + networkmanager.a(this); + this.player = entityplayer; + entityplayer.playerConnection = this; + + // CraftBukkit start - add fields and methods + this.server = minecraftserver.server; + } + + private final org.bukkit.craftbukkit.CraftServer server; + private int lastTick = MinecraftServer.currentTick; + private int lastDropTick = MinecraftServer.currentTick; + private int dropCount = 0; + private static final int SURVIVAL_PLACE_DISTANCE_SQUARED = 6 * 6; + private static final int CREATIVE_PLACE_DISTANCE_SQUARED = 7 * 7; + + // Get position of last block hit for BlockDamageLevel.STOPPED + private double lastPosX = Double.MAX_VALUE; + private double lastPosY = Double.MAX_VALUE; + private double lastPosZ = Double.MAX_VALUE; + private float lastPitch = Float.MAX_VALUE; + private float lastYaw = Float.MAX_VALUE; + private boolean justTeleported = false; + private boolean hasMoved; // Spigot + + public CraftPlayer getPlayer() { + return (this.player == null) ? null : this.player.getBukkitEntity(); + } + private final static HashSet invalidItems = new HashSet(java.util.Arrays.asList(8, 9, 10, 11, 26, 34, 36, 43, 51, 52, 55, 59, 60, 62, 63, 64, 68, 71, 74, 75, 83, 90, 92, 93, 94, 104, 105, 115, 117, 118, 119, 125, 127, 132, 140, 141, 142, 144)); // TODO: Check after every update. + // CraftBukkit end + + public void c() { + this.h = false; + ++this.e; + this.minecraftServer.methodProfiler.a("keepAlive"); + if ((long) this.e - this.k > 40L) { + this.k = this.e; + this.j = this.d(); + this.i = (int) this.j; + this.sendPacket(new PacketPlayOutKeepAlive(this.i)); + } + + this.minecraftServer.methodProfiler.b(); + // CraftBukkit start + for (int spam; (spam = this.chatThrottle) > 0 && !chatSpamField.compareAndSet(this, spam, spam - 1); ) ; + /* Use thread-safe field access instead + if (this.chatThrottle > 0) { + --this.chatThrottle; + } + */ + // CraftBukkit end + + if (this.m > 0) { + --this.m; + } + + if (this.player.D() > 0L && this.minecraftServer.getIdleTimeout() > 0 && MinecraftServer.az() - this.player.D() > (long) (this.minecraftServer.getIdleTimeout() * 1000 * 60)) { + this.player.resetIdleTimer(); // CraftBukkit - SPIGOT-854 + this.disconnect("You have been idle for too long!"); + } + + } + + public NetworkManager a() { + return this.networkManager; + } + + public void disconnect(String s) { + // CraftBukkit start - fire PlayerKickEvent + + // MythicSpigot - Set the leave message to null + PlayerKickEvent event = new PlayerKickEvent(this.server.getPlayer(this.player), s, null); + + if (this.server.getServer().isRunning()) { + this.server.getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + // Do not kick the player + return; + } + // Send the possibly modified leave message + s = event.getReason(); + // CraftBukkit end + final ChatComponentText chatcomponenttext = new ChatComponentText(s); + + this.networkManager.a(new PacketPlayOutKickDisconnect(chatcomponenttext), new GenericFutureListener() { + public void operationComplete(Future future) throws Exception { // CraftBukkit - fix decompile error + PlayerConnection.this.networkManager.close(chatcomponenttext); + } + }); + this.a(chatcomponenttext); // CraftBukkit - fire quit instantly + this.networkManager.k(); + // CraftBukkit - Don't wait + this.minecraftServer.postToMainThread(new Runnable() { + public void run() { + PlayerConnection.this.networkManager.l(); + } + }); + } + + public void a(PacketPlayInSteerVehicle packetplayinsteervehicle) { + PlayerConnectionUtils.ensureMainThread(packetplayinsteervehicle, this, this.player.u()); + this.player.a(packetplayinsteervehicle.a(), packetplayinsteervehicle.b(), packetplayinsteervehicle.c(), packetplayinsteervehicle.d()); + } + + private boolean b(PacketPlayInFlying packetplayinflying) { + return !Doubles.isFinite(packetplayinflying.a()) || !Doubles.isFinite(packetplayinflying.b()) || !Doubles.isFinite(packetplayinflying.c()) || !Floats.isFinite(packetplayinflying.e()) || !Floats.isFinite(packetplayinflying.d()); + } + + public void a(PacketPlayInFlying packetplayinflying) { + PlayerConnectionUtils.ensureMainThread(packetplayinflying, this, this.player.u()); + if (this.b(packetplayinflying)) { + this.disconnect("Invalid move packet received"); + } else { + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); + + this.h = true; + if (!this.player.viewingCredits) { + double d0 = this.player.locX; + double d1 = this.player.locY; + double d2 = this.player.locZ; + double d3 = 0.0D; + double d4 = packetplayinflying.a() - this.o; + double d5 = packetplayinflying.b() - this.p; + double d6 = packetplayinflying.c() - this.q; + + if (packetplayinflying.g()) { + d3 = d4 * d4 + d5 * d5 + d6 * d6; + if (!this.checkMovement && d3 < 0.25D) { + this.checkMovement = true; + } + } + // CraftBukkit start - fire PlayerMoveEvent + Player player = this.getPlayer(); + // Spigot Start + if ( !hasMoved ) + { + Location curPos = player.getLocation(); + lastPosX = curPos.getX(); + lastPosY = curPos.getY(); + lastPosZ = curPos.getZ(); + lastYaw = curPos.getYaw(); + lastPitch = curPos.getPitch(); + hasMoved = true; + } + // Spigot End + Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. + Location to = player.getLocation().clone(); // Start off the To location as the Players current location. + + // If the packet contains movement information then we update the To location with the correct XYZ. + if (packetplayinflying.hasPos && !(packetplayinflying.hasPos && packetplayinflying.y == -999.0D)) { + to.setX(packetplayinflying.x); + to.setY(packetplayinflying.y); + to.setZ(packetplayinflying.z); + } + + // If the packet contains look information then we update the To location with the correct Yaw & Pitch. + if (packetplayinflying.hasLook) { + to.setYaw(packetplayinflying.yaw); + to.setPitch(packetplayinflying.pitch); + } + + // Prevent 40 event-calls for less than a single pixel of movement >.> + double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2); + float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch()); + + int lastBlockX = (int) Math.floor(lastPosX), lastBlockY = (int) Math.floor(lastPosY), lastBlockZ = (int) Math.floor(lastPosZ); + + if ((delta > 1f / 256 || deltaAngle > 10f) && (this.checkMovement && !this.player.dead) + && (!MythicConfiguration.Options.PacketProcessing.Flying.reduceMoveEvent || (lastBlockX != to.getBlockX() || lastBlockY != to.getBlockY() || lastBlockZ != to.getBlockZ()))) { // Mythic - Reduce move event + this.lastPosX = to.getX(); + this.lastPosY = to.getY(); + this.lastPosZ = to.getZ(); + this.lastYaw = to.getYaw(); + this.lastPitch = to.getPitch(); + + // Skip the first time we do this + if (true) { // Spigot - don't skip any move events + Location oldTo = to.clone(); + PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); + if(MythicConfiguration.Options.PacketProcessing.Flying.moveEvent) this.server.getPluginManager().callEvent(event); + + // If the event is cancelled we move the player back to their old location. + if (event.isCancelled()) { + this.player.playerConnection.sendPacket(new PacketPlayOutPosition(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet())); + return; + } + + /* If a Plugin has changed the To destination then we teleport the Player + there to avoid any 'Moved wrongly' or 'Moved too quickly' errors. + We only do this if the Event was not cancelled. */ + if (!oldTo.equals(event.getTo()) && !event.isCancelled()) { + this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.UNKNOWN); + return; + } + + /* Check to see if the Players Location has some how changed during the call of the event. + This can happen due to a plugin teleporting the player instead of using .setTo() */ + if (!from.equals(this.getPlayer().getLocation()) && this.justTeleported) { + this.justTeleported = false; + return; + } + } + } + + if (this.checkMovement && !this.player.dead) { + // CraftBukkit end + this.f = this.e; + double d7; + double d8; + double d9; + + if (this.player.vehicle != null) { + float f = this.player.yaw; + float f1 = this.player.pitch; + + this.player.vehicle.al(); + d7 = this.player.locX; + d8 = this.player.locY; + d9 = this.player.locZ; + if (packetplayinflying.h()) { + f = packetplayinflying.d(); + f1 = packetplayinflying.e(); + } + + this.player.onGround = packetplayinflying.f(); + this.player.l(); + this.player.setLocation(d7, d8, d9, f, f1); + if (this.player.vehicle != null) { + this.player.vehicle.al(); + } + + this.minecraftServer.getPlayerList().d(this.player); + if (this.player.vehicle != null) { + this.player.vehicle.ai = true; // CraftBukkit - moved from below + if (d3 > 4.0D) { + Entity entity = this.player.vehicle; + + this.player.playerConnection.sendPacket(new PacketPlayOutEntityTeleport(entity)); + this.a(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch); + } + + // this.player.vehicle.ai = true; // CraftBukkit - moved up + } + + if (this.checkMovement) { + this.o = this.player.locX; + this.p = this.player.locY; + this.q = this.player.locZ; + } + + worldserver.g(this.player); + return; + } + + if (this.player.isSleeping()) { + this.player.l(); + this.player.setLocation(this.o, this.p, this.q, this.player.yaw, this.player.pitch); + worldserver.g(this.player); + return; + } + + double d10 = this.player.locY; + + this.o = this.player.locX; + this.p = this.player.locY; + this.q = this.player.locZ; + d7 = this.player.locX; + d8 = this.player.locY; + d9 = this.player.locZ; + float f2 = this.player.yaw; + float f3 = this.player.pitch; + + if (packetplayinflying.g() && packetplayinflying.b() == -999.0D) { + packetplayinflying.a(false); + } + + if (packetplayinflying.g()) { + d7 = packetplayinflying.a(); + d8 = packetplayinflying.b(); + d9 = packetplayinflying.c(); + if (Math.abs(packetplayinflying.a()) > 3.0E7D || Math.abs(packetplayinflying.c()) > 3.0E7D) { + this.disconnect("Illegal position"); + return; + } + } + + if (packetplayinflying.h()) { + f2 = packetplayinflying.d(); + f3 = packetplayinflying.e(); + } + + this.player.l(); + this.player.setLocation(this.o, this.p, this.q, f2, f3); + if (!this.checkMovement) { + return; + } + + double d11 = d7 - this.player.locX; + double d12 = d8 - this.player.locY; + double d13 = d9 - this.player.locZ; + double d14 = this.player.motX * this.player.motX + this.player.motY * this.player.motY + this.player.motZ * this.player.motZ; + double d15 = d11 * d11 + d12 * d12 + d13 * d13; + + + // Spigot: make "moved too quickly" limit configurable + if (d15 - d14 > org.spigotmc.SpigotConfig.movedTooQuicklyThreshold && this.checkMovement && (!this.minecraftServer.T() || !this.minecraftServer.S().equals(this.player.getName()))) { // CraftBukkit - Added this.checkMovement condition to solve this check being triggered by teleports + PlayerConnection.c.warn(this.player.getName() + " moved too quickly! " + d11 + "," + d12 + "," + d13 + " (" + d11 + ", " + d12 + ", " + d13 + ")"); + this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch); + return; + } + + float f4 = 0.0625F; + boolean flag = worldserver.getCubes(this.player, this.player.getBoundingBox().shrink(f4, f4, f4)).isEmpty(); // Mythic - + + if (this.player.onGround && !packetplayinflying.f() && d12 > 0.0D) { + this.player.bF(); + } + + this.player.move(d11, d12, d13); + this.player.onGround = packetplayinflying.f(); + double d16 = d12; + + d11 = d7 - this.player.locX; + d12 = d8 - this.player.locY; + if (d12 > -0.5D || d12 < 0.5D) { + d12 = 0.0D; + } + + d13 = d9 - this.player.locZ; + d15 = d11 * d11 + d12 * d12 + d13 * d13; + boolean flag1 = false; + + // Spigot: make "moved wrongly" limit configurable + if (d15 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.playerInteractManager.isCreative()) { + flag1 = true; // Mythic - Movement was invalid + PlayerConnection.c.warn(this.player.getName() + " moved wrongly!"); + } + + this.player.setLocation(d7, d8, d9, f2, f3); + this.player.checkMovement(this.player.locX - d0, this.player.locY - d1, this.player.locZ - d2); + if (!this.player.noclip && !this.player.isSleeping()) { + boolean flag2 = worldserver.getCubes(this.player, this.player.getBoundingBox().shrink(f4, f4, f4)).isEmpty(); // Mythic - Location towards is passable + if(MythicConfiguration.Options.AntiPhase.enabled && flag && (flag2 || flag1)){ // Mythic - AntiPhase + MovingObjectPosition rayTrace = worldserver.rayTrace(new Vec3D(d0, d1 + 1, d2), new Vec3D(d7, d8 + 1, d9), false, true, false); + if(rayTrace != null) { + IBlockData data = worldserver.getType(new BlockPosition(rayTrace.pos.a, rayTrace.pos.b, rayTrace.pos.c)); + Block block = data.getBlock(); + if(block != Blocks.END_PORTAL) { + this.a(this.o, this.p, this.q, f2, f3); + return; + } + } + } + + if (flag && (flag1 || !flag2)) { + this.a(this.o, this.p, this.q, f2, f3); + return; + } + } + + AxisAlignedBB axisalignedbb = this.player.getBoundingBox().grow(f4, f4, f4).a(0.0D, -0.55D, 0.0D); + + if (!this.minecraftServer.getAllowFlight() && !this.player.abilities.canFly && !worldserver.c(axisalignedbb)) { + if (d16 >= -0.03125D) { + ++this.g; + if (this.g > 80) { + PlayerConnection.c.warn(this.player.getName() + " was kicked for floating too long!"); + this.disconnect("Flying is not enabled on this server"); + return; + } + } + } else { + this.g = 0; + } + + this.player.onGround = packetplayinflying.f(); + this.minecraftServer.getPlayerList().d(this.player); + this.player.a(this.player.locY - d10, packetplayinflying.f()); + } else if (this.e - this.f > 20) { + this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch); + } + } + + } + } + + public void a(double d0, double d1, double d2, float f, float f1) { + this.a(d0, d1, d2, f, f1, Collections.emptySet()); // CraftBukkit fix decompile errors + } + + public void a(double d0, double d1, double d2, float f, float f1, Set set) { + // CraftBukkit start - Delegate to teleport(Location) + Player player = this.getPlayer(); + Location from = player.getLocation(); + + double x = d0; + double y = d1; + double z = d2; + float yaw = f; + float pitch = f1; + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X)) { + x += from.getX(); + } + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y)) { + y += from.getY(); + } + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z)) { + z += from.getZ(); + } + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y_ROT)) { + yaw += from.getYaw(); + } + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X_ROT)) { + pitch += from.getPitch(); + } + + + Location to = new Location(this.getPlayer().getWorld(), x, y, z, yaw, pitch); + PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), PlayerTeleportEvent.TeleportCause.UNKNOWN); + this.server.getPluginManager().callEvent(event); + + if (event.isCancelled() || to.equals(event.getTo())) { + set.clear(); // Can't relative teleport + to = event.isCancelled() ? event.getFrom() : event.getTo(); + d0 = to.getX(); + d1 = to.getY(); + d2 = to.getZ(); + f = to.getYaw(); + f1 = to.getPitch(); + } + + this.internalTeleport(d0, d1, d2, f, f1, set); + } + + public void teleport(Location dest) { + internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.emptySet()); + } + + private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set set) { + if (Float.isNaN(f)) { + f = 0; + } + + if (Float.isNaN(f1)) { + f1 = 0; + } + this.justTeleported = true; + // CraftBukkit end + this.checkMovement = false; + this.o = d0; + this.p = d1; + this.q = d2; + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X)) { + this.o += this.player.locX; + } + + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y)) { + this.p += this.player.locY; + } + + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z)) { + this.q += this.player.locZ; + } + + float f2 = f; + float f3 = f1; + + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y_ROT)) { + f2 = f + this.player.yaw; + } + + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X_ROT)) { + f3 = f1 + this.player.pitch; + } + + // CraftBukkit start - update last location + this.lastPosX = this.o; + this.lastPosY = this.p; + this.lastPosZ = this.q; + this.lastYaw = f2; + this.lastPitch = f3; + // CraftBukkit end + + this.player.setLocation(this.o, this.p, this.q, f2, f3); + this.player.playerConnection.sendPacket(new PacketPlayOutPosition(d0, d1, d2, f, f1, set)); + } + + public void a(PacketPlayInBlockDig packetplayinblockdig) { + PlayerConnectionUtils.ensureMainThread(packetplayinblockdig, this, this.player.u()); + if (this.player.dead) return; // CraftBukkit + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); + BlockPosition blockposition = packetplayinblockdig.a(); + + this.player.resetIdleTimer(); + // CraftBukkit start + switch (PlayerConnection.SyntheticClass_1.a[packetplayinblockdig.c().ordinal()]) { + case 1: // DROP_ITEM + if (!this.player.isSpectator()) { + // limit how quickly items can be dropped + // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick. + if (this.lastDropTick != MinecraftServer.currentTick) { + this.dropCount = 0; + this.lastDropTick = MinecraftServer.currentTick; + } else { + // Else we increment the drop count and check the amount. + this.dropCount++; + if (this.dropCount >= 20) { + c.warn(this.player.getName() + " dropped their items too quickly!"); + this.disconnect("You dropped your items too quickly (Hacking?)"); + return; + } + } + // CraftBukkit end + this.player.a(false); + } + + return; + + case 2: // DROP_ALL_ITEMS + if (!this.player.isSpectator()) { + this.player.a(true); + } + + return; + + case 3: // RELEASE_USE_ITEM + this.player.bU(); + return; + + case 4: // START_DESTROY_BLOCK + case 5: // ABORT_DESTROY_BLOCK + case 6: // STOP_DESTROY_BLOCK + double d0 = this.player.locX - ((double) blockposition.getX() + 0.5D); + double d1 = this.player.locY - ((double) blockposition.getY() + 0.5D) + 1.5D; + double d2 = this.player.locZ - ((double) blockposition.getZ() + 0.5D); + double d3 = d0 * d0 + d1 * d1 + d2 * d2; + + if (d3 > 36.0D) { + return; + } else if (blockposition.getY() >= this.minecraftServer.getMaxBuildHeight()) { + return; + } else { + if (packetplayinblockdig.c() == PacketPlayInBlockDig.EnumPlayerDigType.START_DESTROY_BLOCK) { + if (!this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { + this.player.playerInteractManager.a(blockposition, packetplayinblockdig.b()); + } else { + // CraftBukkit start - fire PlayerInteractEvent + CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, packetplayinblockdig.b(), this.player.inventory.getItemInHand()); + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); + // Update any tile entity data for this block + TileEntity tileentity = worldserver.getTileEntity(blockposition); + if (tileentity != null) { + this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); + } + // CraftBukkit end + } + } else { + if (packetplayinblockdig.c() == PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { + this.player.playerInteractManager.a(blockposition); + } else if (packetplayinblockdig.c() == PacketPlayInBlockDig.EnumPlayerDigType.ABORT_DESTROY_BLOCK) { + this.player.playerInteractManager.e(); + } + + if (worldserver.getType(blockposition).getBlock().getMaterial() != Material.AIR) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); + } + } + + return; + } + + default: + throw new IllegalArgumentException("Invalid player action"); + } + // CraftBukkit end + } + + // Spigot start - limit place/interactions + private long lastPlace = -1; + private int packets = 0; + + public void a(PacketPlayInBlockPlace packetplayinblockplace) { + PlayerConnectionUtils.ensureMainThread(packetplayinblockplace, this, this.player.u()); + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); + boolean throttled = false; + // PaperSpigot - Allow disabling the player interaction limiter + if (org.github.paperspigot.PaperSpigotConfig.interactLimitEnabled && lastPlace != -1 && packetplayinblockplace.timestamp - lastPlace < 30 && packets++ >= 4) { + throttled = true; + } else if ( packetplayinblockplace.timestamp - lastPlace >= 30 || lastPlace == -1 ) + { + lastPlace = packetplayinblockplace.timestamp; + packets = 0; + } + // Spigot end + + // CraftBukkit start + if (this.player.dead) return; + + // CraftBukkit - if rightclick decremented the item, always send the update packet. */ + // this is not here for CraftBukkit's own functionality; rather it is to fix + // a notch bug where the item doesn't update correctly. + boolean always = false; + // CraftBukkit end + + ItemStack itemstack = this.player.inventory.getItemInHand(); + boolean flag = false; + BlockPosition blockposition = packetplayinblockplace.a(); + EnumDirection enumdirection = EnumDirection.fromType1(packetplayinblockplace.getFace()); + + this.player.resetIdleTimer(); + if (packetplayinblockplace.getFace() == 255) { + if (itemstack == null) { + return; + } + + // CraftBukkit start + int itemstackAmount = itemstack.count; + // Spigot start - skip the event if throttled + if (!throttled) { + // Raytrace to look for 'rogue armswings' + float f1 = this.player.pitch; + float f2 = this.player.yaw; + double d0 = this.player.locX; + double d1 = this.player.locY + (double) this.player.getHeadHeight(); + double d2 = this.player.locZ; + Vec3D vec3d = new Vec3D(d0, d1, d2); + + float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); + float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); + float f5 = -MathHelper.cos(-f1 * 0.017453292F); + float f6 = MathHelper.sin(-f1 * 0.017453292F); + float f7 = f4 * f5; + float f8 = f3 * f5; + double d3 = player.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.CREATIVE ? 5.0D : 4.5D; + Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); + MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, false); + + boolean cancelled = false; + if (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK) { + org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack); + cancelled = event.useItemInHand() == Event.Result.DENY; + } else { + if (player.playerInteractManager.firedInteract) { + player.playerInteractManager.firedInteract = false; + cancelled = player.playerInteractManager.interactResult; + } else { + org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectposition.a(), movingobjectposition.direction, itemstack, true); + cancelled = event.useItemInHand() == Event.Result.DENY; + } + } + + if (!cancelled) { + this.player.playerInteractManager.useItem(this.player, this.player.world, itemstack); + } + } + // Spigot end + + // CraftBukkit - notch decrements the counter by 1 in the above method with food, + // snowballs and so forth, but he does it in a place that doesn't cause the + // inventory update packet to get sent + always = (itemstack.count != itemstackAmount) || itemstack.getItem() == Item.getItemOf(Blocks.WATERLILY); + // CraftBukkit end + } else if (blockposition.getY() >= this.minecraftServer.getMaxBuildHeight() - 1 && (enumdirection == EnumDirection.UP || blockposition.getY() >= this.minecraftServer.getMaxBuildHeight())) { + ChatMessage chatmessage = new ChatMessage("build.tooHigh", Integer.valueOf(this.minecraftServer.getMaxBuildHeight())); + + chatmessage.getChatModifier().setColor(EnumChatFormat.RED); + this.player.playerConnection.sendPacket(new PacketPlayOutChat(chatmessage)); + flag = true; + } else { + // CraftBukkit start - Check if we can actually do something over this large a distance + Location eyeLoc = this.getPlayer().getEyeLocation(); + double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ()); + if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) { + return; + } + + if (!worldserver.getWorldBorder().a(blockposition)) { + return; + } + + if (this.checkMovement && this.player.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && !this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { + always = throttled || !this.player.playerInteractManager.interact(this.player, worldserver, itemstack, blockposition, enumdirection, packetplayinblockplace.d(), packetplayinblockplace.e(), packetplayinblockplace.f()); + } + + flag = true; + } + + if (flag) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition.shift(enumdirection))); + } + + itemstack = this.player.inventory.getItemInHand(); + if (itemstack != null && itemstack.count == 0) { + this.player.inventory.items[this.player.inventory.itemInHandIndex] = null; + itemstack = null; + } + + if (itemstack == null || itemstack.l() == 0) { + this.player.g = true; + this.player.inventory.items[this.player.inventory.itemInHandIndex] = ItemStack.b(this.player.inventory.items[this.player.inventory.itemInHandIndex]); + Slot slot = this.player.activeContainer.getSlot(this.player.inventory, this.player.inventory.itemInHandIndex); + + this.player.activeContainer.b(); + this.player.g = false; + // CraftBukkit - TODO CHECK IF NEEDED -- new if structure might not need 'always'. Kept it in for now, but may be able to remove in future + if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack()) || always) { + this.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, slot.rawSlotIndex, this.player.inventory.getItemInHand())); + } + } + + } + + public void a(PacketPlayInSpectate packetplayinspectate) { + PlayerConnectionUtils.ensureMainThread(packetplayinspectate, this, this.player.u()); + if (this.player.isSpectator()) { + Entity entity = null; + WorldServer[] aworldserver = this.minecraftServer.worldServer; + int i = aworldserver.length; + + // CraftBukkit - use the worlds array list + for (WorldServer worldserver : minecraftServer.worlds) { + + if (worldserver != null) { + entity = packetplayinspectate.a(worldserver); + if (entity != null) { + break; + } + } + } + + if (entity != null) { + this.player.setSpectatorTarget(this.player); + this.player.mount(null); + + /* CraftBukkit start - replace with bukkit handling for multi-world + if (entity.world != this.player.world) { + WorldServer worldserver1 = this.player.u(); + WorldServer worldserver2 = (WorldServer) entity.world; + + this.player.dimension = entity.dimension; + this.sendPacket(new PacketPlayOutRespawn(this.player.dimension, worldserver1.getDifficulty(), worldserver1.getWorldData().getType(), this.player.playerInteractManager.getGameMode())); + worldserver1.removeEntity(this.player); + this.player.dead = false; + this.player.setPositionRotation(entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch); + if (this.player.isAlive()) { + worldserver1.entityJoinedWorld(this.player, false); + worldserver2.addEntity(this.player); + worldserver2.entityJoinedWorld(this.player, false); + } + + this.player.spawnIn(worldserver2); + this.minecraftServer.getPlayerList().a(this.player, worldserver1); + this.player.enderTeleportTo(entity.locX, entity.locY, entity.locZ); + this.player.playerInteractManager.a(worldserver2); + this.minecraftServer.getPlayerList().b(this.player, worldserver2); + this.minecraftServer.getPlayerList().updateClient(this.player); + } else { + this.player.enderTeleportTo(entity.locX, entity.locY, entity.locZ); + } + */ + this.player.getBukkitEntity().teleport(entity.getBukkitEntity(), PlayerTeleportEvent.TeleportCause.SPECTATE); + // CraftBukkit end + } + } + + } + + // CraftBukkit start + public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) { + // TacoSpigot start + PlayerConnectionUtils.ensureMainThread(packetplayinresourcepackstatus, this, this.player.u()); + PlayerResourcePackStatusEvent.Status status = PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.b.ordinal()]; + this.getPlayer().setResourcePackStatus(status, packetplayinresourcepackstatus.a); + this.server.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getPlayer(), status, packetplayinresourcepackstatus.a)); + // TacoSpigot end + } + // CraftBukkit end + + public void a(IChatBaseComponent ichatbasecomponent) { + // CraftBukkit start - Rarely it would send a disconnect line twice + if (this.processedDisconnect) { + return; + } else { + this.processedDisconnect = true; + } + // CraftBukkit end + PlayerConnection.c.info(this.player.getName() + " lost connection: " + ichatbasecomponent.c()); // CraftBukkit: Don't toString(). // PAIL: Rename + // CraftBukkit start - Replace vanilla quit message handling with our own. + /* + this.minecraftServer.aH(); + ChatMessage chatmessage = new ChatMessage("multiplayer.player.left", new Object[] { this.player.getScoreboardDisplayName()}); + + chatmessage.getChatModifier().setColor(EnumChatFormat.YELLOW); + this.minecraftServer.getPlayerList().sendMessage(chatmessage); + */ + + this.player.q(); + String quitMessage = this.minecraftServer.getPlayerList().disconnect(this.player); + if ((quitMessage != null) && (quitMessage.length() > 0)) { + this.minecraftServer.getPlayerList().sendMessage(CraftChatMessage.fromString(quitMessage)); + } + // CraftBukkit end + if (this.minecraftServer.T() && this.player.getName().equals(this.minecraftServer.S())) { + PlayerConnection.c.info("Stopping singleplayer server as player logged out"); + this.minecraftServer.safeShutdown(); + } + + } + + public void sendPacket(final Packet packet) { + if (packet instanceof PacketPlayOutChat) { + PacketPlayOutChat packetplayoutchat = (PacketPlayOutChat) packet; + EntityHuman.EnumChatVisibility entityhuman_enumchatvisibility = this.player.getChatFlags(); + + if (entityhuman_enumchatvisibility == EntityHuman.EnumChatVisibility.HIDDEN) { + return; + } + + if (entityhuman_enumchatvisibility == EntityHuman.EnumChatVisibility.SYSTEM && !packetplayoutchat.b()) { + return; + } + } + + // CraftBukkit start + if (packet == null || this.processedDisconnect) { // Spigot + return; + } else if (packet instanceof PacketPlayOutSpawnPosition) { + PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet; + this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); + } + // CraftBukkit end + + try { + this.networkManager.handle(packet); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Sending packet"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Packet being sent"); + + crashreportsystemdetails.a("Packet class", new Callable() { + public String a() throws Exception { + return packet.getClass().getCanonicalName(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + + public void a(PacketPlayInHeldItemSlot packetplayinhelditemslot) { + // CraftBukkit start + if (this.player.dead) return; + PlayerConnectionUtils.ensureMainThread(packetplayinhelditemslot, this, this.player.u()); + if (packetplayinhelditemslot.a() >= 0 && packetplayinhelditemslot.a() < PlayerInventory.getHotbarSize()) { + PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayer(), this.player.inventory.itemInHandIndex, packetplayinhelditemslot.a()); + this.server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + this.sendPacket(new PacketPlayOutHeldItemSlot(this.player.inventory.itemInHandIndex)); + this.player.resetIdleTimer(); + return; + } + // CraftBukkit end + this.player.inventory.itemInHandIndex = packetplayinhelditemslot.a(); + this.player.resetIdleTimer(); + } else { + PlayerConnection.c.warn(this.player.getName() + " tried to set an invalid carried item"); + this.disconnect("Invalid hotbar selection (Hacking?)"); // CraftBukkit //Spigot "Nope" -> Descriptive reason + } + } + + public void a(PacketPlayInChat packetplayinchat) { + // CraftBukkit start - async chat + boolean isSync = packetplayinchat.a().startsWith("/"); + if (packetplayinchat.a().startsWith("/")) { + PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.u()); + } + // CraftBukkit end + if (this.player.dead || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales + ChatMessage chatmessage = new ChatMessage("chat.cannotSend"); + + chatmessage.getChatModifier().setColor(EnumChatFormat.RED); + this.sendPacket(new PacketPlayOutChat(chatmessage)); + } else { + this.player.resetIdleTimer(); + String s = packetplayinchat.a(); + + s = StringUtils.normalizeSpace(s); + + for (int i = 0; i < s.length(); ++i) { + if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) { + // CraftBukkit start - threadsafety + if (!isSync) { + Waitable waitable = new Waitable() { + @Override + protected Object evaluate() { + PlayerConnection.this.disconnect("Illegal characters in chat"); + return null; + } + }; + + this.minecraftServer.processQueue.add(waitable); + + try { + waitable.get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } else { + this.disconnect("Illegal characters in chat"); + } + // CraftBukkit end + return; + } + } + + // CraftBukkit start + if (isSync) { + try { + this.minecraftServer.server.playerCommandState = true; + this.handleCommand(s); + } finally { + this.minecraftServer.server.playerCommandState = false; + } + } else if (s.isEmpty()) { + c.warn(this.player.getName() + " tried to send an empty message"); + } else if (getPlayer().isConversing()) { + // Spigot start + final String message = s; + this.minecraftServer.processQueue.add( new Waitable() + { + @Override + protected Object evaluate() + { + getPlayer().acceptConversationInput( message ); + return null; + } + } ); + // Spigot end + } else if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.SYSTEM) { // Re-add "Command Only" flag check + ChatMessage chatmessage = new ChatMessage("chat.cannotSend"); + + chatmessage.getChatModifier().setColor(EnumChatFormat.RED); + this.sendPacket(new PacketPlayOutChat(chatmessage)); + } else if (true) { + this.chat(s, true); + // CraftBukkit end - the below is for reference. :) + } else { + ChatMessage chatmessage1 = new ChatMessage("chat.type.text", this.player.getScoreboardDisplayName(), s); + + this.minecraftServer.getPlayerList().sendMessage(chatmessage1, false); + } + + // Spigot start - spam exclusions + boolean counted = true; + for ( String exclude : org.spigotmc.SpigotConfig.spamExclusions ) + { + if ( exclude != null && s.startsWith( exclude ) ) + { + counted = false; + break; + } + } + // Spigot end + // CraftBukkit start - replaced with thread safe throttle + // this.chatThrottle += 20; + if (counted && chatSpamField.addAndGet(this, 20) > 200 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { // Spigot + if (!isSync) { + Waitable waitable = new Waitable() { + @Override + protected Object evaluate() { + // PlayerConnection.this.disconnect("disconnect.spam"); + return null; + } + }; + + this.minecraftServer.processQueue.add(waitable); + + try { + waitable.get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } else { + // this.disconnect("disconnect.spam"); + } + // CraftBukkit end + } + + } + } + + // CraftBukkit start - add method + public void chat(String s, boolean async) { + if (s.isEmpty() || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { + return; + } + + if (!async && s.startsWith("/")) { + // PaperSpigot Start + if (!org.bukkit.Bukkit.isPrimaryThread()) { + final String fCommandLine = s; + MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Command Dispatched Async: " + fCommandLine); + MinecraftServer.LOGGER.log(org.apache.logging.log4j.Level.ERROR, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable()); + Waitable wait = new Waitable() { + @Override + protected Object evaluate() { + chat(fCommandLine, false); + return null; + } + }; + minecraftServer.processQueue.add(wait); + try { + wait.get(); + return; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on! + } catch (Exception e) { + throw new RuntimeException("Exception processing chat command", e.getCause()); + } + } + // PaperSpigot End + this.handleCommand(s); + } else if (this.player.getChatFlags() == EntityHuman.EnumChatVisibility.SYSTEM) { + // Do nothing, this is coming from a plugin + } else { + Player player = this.getPlayer(); + AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet()); + this.server.getPluginManager().callEvent(event); + + if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) { + // Evil plugins still listening to deprecated event + final PlayerChatEvent queueEvent = new PlayerChatEvent(player, event.getMessage(), event.getFormat(), event.getRecipients()); + queueEvent.setCancelled(event.isCancelled()); + Waitable waitable = new Waitable() { + @Override + protected Object evaluate() { + org.bukkit.Bukkit.getPluginManager().callEvent(queueEvent); + + if (queueEvent.isCancelled()) { + return null; + } + + String message = String.format(queueEvent.getFormat(), queueEvent.getPlayer().getDisplayName(), queueEvent.getMessage()); + PlayerConnection.this.minecraftServer.console.sendMessage(message); + if (((LazyPlayerSet) queueEvent.getRecipients()).isLazy()) { + for (Object player : PlayerConnection.this.minecraftServer.getPlayerList().players) { + ((EntityPlayer) player).sendMessage(CraftChatMessage.fromString(message)); + } + } else { + for (Player player : queueEvent.getRecipients()) { + player.sendMessage(message); + } + } + return null; + }}; + if (async) { + minecraftServer.processQueue.add(waitable); + } else { + waitable.run(); + } + try { + waitable.get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on! + } catch (ExecutionException e) { + throw new RuntimeException("Exception processing chat event", e.getCause()); + } + } else { + if (event.isCancelled()) { + return; + } + + s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage()); + minecraftServer.console.sendMessage(s); + if (((LazyPlayerSet) event.getRecipients()).isLazy()) { + for (Object recipient : minecraftServer.getPlayerList().players) { + ((EntityPlayer) recipient).sendMessage(CraftChatMessage.fromString(s)); + } + } else { + for (Player recipient : event.getRecipients()) { + recipient.sendMessage(s); + } + } + } + } + } + // CraftBukkit end + + private void handleCommand(String s) { + SpigotTimings.playerCommandTimer.startTiming(); // Spigot + // CraftBukkit start - whole method + if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot + c.info(this.player.getName() + " issued server command: " + s); + + CraftPlayer player = this.getPlayer(); + + PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, s, new LazyPlayerSet()); + this.server.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + return; + } + + try { + if (this.server.dispatchCommand(event.getPlayer(), event.getMessage().substring(1))) { + SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + return; + } + } catch (org.bukkit.command.CommandException ex) { + player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); + java.util.logging.Logger.getLogger(PlayerConnection.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + return; + } + SpigotTimings.playerCommandTimer.stopTiming(); // Spigot + // this.minecraftServer.getCommandHandler().a(this.player, s); + // CraftBukkit end + } + + private final TickLimiter armAnimationEvents = new TickLimiter(() -> MythicConfiguration.Options.PacketProcessing.ArmAnimation.ticksPerEvent, () -> 1), + armAnimationAnimations = new TickLimiter(() -> MythicConfiguration.Options.PacketProcessing.ArmAnimation.ticksPerAnimation, () -> 1); + + public void a(PacketPlayInArmAnimation packetplayinarmanimation) { + if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinarmanimation, this, this.player.u()); + + this.player.resetIdleTimer(); + + if(armAnimationEvents.test()) { // Mythic - Limit number of interact events + // CraftBukkit start - Raytrace to look for 'rogue armswings' + float f1 = this.player.pitch; + float f2 = this.player.yaw; + double d0 = this.player.locX; + double d1 = this.player.locY + (double) this.player.getHeadHeight(); + double d2 = this.player.locZ; + Vec3D vec3d = new Vec3D(d0, d1, d2); + + float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); + float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); + float f5 = -MathHelper.cos(-f1 * 0.017453292F); + float f6 = MathHelper.sin(-f1 * 0.017453292F); + float f7 = f4 * f5; + float f8 = f3 * f5; + double d3 = player.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.CREATIVE ? 5.0D : 4.5D; + Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); + MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, false); + + if (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK) { + CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.inventory.getItemInHand()); + } + } + + if(armAnimationAnimations.test()) { // Mythic - Limit number of swing animations + // Arm swing animation + PlayerAnimationEvent event = new PlayerAnimationEvent(this.getPlayer()); + this.server.getPluginManager().callEvent(event); + + if (event.isCancelled()) return; + // CraftBukkit end + this.player.bw(); + } + } + + public void a(PacketPlayInEntityAction packetplayinentityaction) { + PlayerConnectionUtils.ensureMainThread(packetplayinentityaction, this, this.player.u()); + // CraftBukkit start + if (this.player.dead) return; + switch (packetplayinentityaction.b()) { + case START_SNEAKING: + case STOP_SNEAKING: + PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getPlayer(), packetplayinentityaction.b() == PacketPlayInEntityAction.EnumPlayerAction.START_SNEAKING); + this.server.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + break; + case START_SPRINTING: + case STOP_SPRINTING: + PlayerToggleSprintEvent e2 = new PlayerToggleSprintEvent(this.getPlayer(), packetplayinentityaction.b() == PacketPlayInEntityAction.EnumPlayerAction.START_SPRINTING); + this.server.getPluginManager().callEvent(e2); + + if (e2.isCancelled()) { + return; + } + break; + } + // CraftBukkit end + this.player.resetIdleTimer(); + switch (PlayerConnection.SyntheticClass_1.b[packetplayinentityaction.b().ordinal()]) { + case 1: + this.player.setSneaking(true); + break; + + case 2: + this.player.setSneaking(false); + break; + + case 3: + this.player.setSprinting(true); + break; + + case 4: + this.player.setSprinting(false); + break; + + case 5: + this.player.a(false, true, true); + // this.checkMovement = false; // CraftBukkit - this is handled in teleport + break; + + case 6: + if (this.player.vehicle instanceof EntityHorse) { + ((EntityHorse) this.player.vehicle).v(packetplayinentityaction.c()); + } + break; + + case 7: + if (this.player.vehicle instanceof EntityHorse) { + ((EntityHorse) this.player.vehicle).g(this.player); + } + break; + + default: + throw new IllegalArgumentException("Invalid client command!"); + } + + } + + public void a(PacketPlayInUseEntity packetplayinuseentity) { + if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinuseentity, this, this.player.u()); + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); + Entity entity = packetplayinuseentity.a(worldserver); + // Spigot Start + if ( entity == player && !player.isSpectator() ) + { + disconnect( "Cannot interact with self!" ); + return; + } + // Spigot End + + this.player.resetIdleTimer(); + if (entity != null) { + boolean flag = this.player.hasLineOfSight(entity); + double d0 = 36.0D; + + if (!flag) { + d0 = 9.0D; + } + + if (this.player.h(entity) < d0) { + ItemStack itemInHand = this.player.inventory.getItemInHand(); // CraftBukkit + + if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT + || packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) { + // CraftBukkit start + boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof EntityInsentient; + Item origItem = this.player.inventory.getItemInHand() == null ? null : this.player.inventory.getItemInHand().getItem(); + PlayerInteractEntityEvent event; + if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT) { + event = new PlayerInteractEntityEvent(this.getPlayer(), entity.getBukkitEntity()); + } else { + Vec3D target = packetplayinuseentity.b(); + event = new PlayerInteractAtEntityEvent(this.getPlayer(), entity.getBukkitEntity(), new org.bukkit.util.Vector(target.a, target.b, target.c)); + } + this.server.getPluginManager().callEvent(event); + + if (triggerLeashUpdate && (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != Items.LEAD)) { + // Refresh the current leash state + this.sendPacket(new PacketPlayOutAttachEntity(1, entity, ((EntityInsentient) entity).getLeashHolder())); + } + + if (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != origItem) { + // Refresh the current entity metadata + this.sendPacket(new PacketPlayOutEntityMetadata(entity.getId(), entity.datawatcher, true)); + } + + if (event.isCancelled()) { + return; + } + // CraftBukkit end + } + if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT) { + this.player.u(entity); + + // CraftBukkit start + if (itemInHand != null && itemInHand.count <= -1) { + this.player.updateInventory(this.player.activeContainer); + } + // CraftBukkit end + } else if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) { + entity.a(this.player, packetplayinuseentity.b()); + + // CraftBukkit start + if (itemInHand != null && itemInHand.count <= -1) { + this.player.updateInventory(this.player.activeContainer); + } + // CraftBukkit end + } else if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.ATTACK) { + if (entity instanceof EntityItem || entity instanceof EntityExperienceOrb || entity instanceof EntityArrow || (entity == this.player && !player.isSpectator())) { // CraftBukkit + this.disconnect("Attempting to attack an invalid entity"); + this.minecraftServer.warning("Player " + this.player.getName() + " tried to attack an invalid entity"); + return; + } + + this.player.attack(entity); + + // CraftBukkit start + if (itemInHand != null && itemInHand.count <= -1) { + this.player.updateInventory(this.player.activeContainer); + } + // CraftBukkit end + } + } + } + + } + + public void a(PacketPlayInClientCommand packetplayinclientcommand) { + PlayerConnectionUtils.ensureMainThread(packetplayinclientcommand, this, this.player.u()); + this.player.resetIdleTimer(); + PacketPlayInClientCommand.EnumClientCommand packetplayinclientcommand_enumclientcommand = packetplayinclientcommand.a(); + + switch (PlayerConnection.SyntheticClass_1.c[packetplayinclientcommand_enumclientcommand.ordinal()]) { + case 1: + if (this.player.viewingCredits) { + // this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true); + this.minecraftServer.getPlayerList().changeDimension(this.player, 0, PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management + } else if (this.player.u().getWorldData().isHardcore()) { + if (this.minecraftServer.T() && this.player.getName().equals(this.minecraftServer.S())) { + this.player.playerConnection.disconnect("You have died. Game over, man, it's game over!"); + this.minecraftServer.aa(); + } else { + GameProfileBanEntry gameprofilebanentry = new GameProfileBanEntry(this.player.getProfile(), null, "(You just lost the game)", null, "Death in Hardcore"); + + this.minecraftServer.getPlayerList().getProfileBans().add(gameprofilebanentry); + this.player.playerConnection.disconnect("You have died. Game over, man, it's game over!"); + } + } else { + if (this.player.getHealth() > 0.0F) { + return; + } + + this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, false); + } + break; + + case 2: + this.player.getStatisticManager().a(this.player); + break; + + case 3: + this.player.b(AchievementList.f); + } + + } + + public void a(PacketPlayInCloseWindow packetplayinclosewindow) { + if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinclosewindow, this, this.player.u()); + + CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit + + this.player.p(); + } + + public void a(PacketPlayInWindowClick packetplayinwindowclick) { + if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinwindowclick, this, this.player.u()); + this.player.resetIdleTimer(); + if (this.player.activeContainer.windowId == packetplayinwindowclick.a() && this.player.activeContainer.c(this.player)) { + boolean cancelled = this.player.isSpectator(); // CraftBukkit - see below if + if (false) { // this.player.isSpectator()) { + ArrayList arraylist = Lists.newArrayList(); + + for (int i = 0; i < this.player.activeContainer.c.size(); ++i) { + arraylist.add(this.player.activeContainer.c.get(i).getItem()); + } + + this.player.a(this.player.activeContainer, arraylist); + } else { + // ItemStack itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); + // CraftBukkit start - Call InventoryClickEvent + if (packetplayinwindowclick.b() < -1 && packetplayinwindowclick.b() != -999) { + return; + } + + InventoryView inventory = this.player.activeContainer.getBukkitView(); + SlotType type = CraftInventoryView.getSlotType(inventory, packetplayinwindowclick.b()); + + InventoryClickEvent event = null; + ClickType click = ClickType.UNKNOWN; + InventoryAction action = InventoryAction.UNKNOWN; + + ItemStack itemstack = null; + + if (packetplayinwindowclick.b() == -1) { + type = SlotType.OUTSIDE; // override + click = packetplayinwindowclick.c() == 0 ? ClickType.WINDOW_BORDER_LEFT : ClickType.WINDOW_BORDER_RIGHT; + action = InventoryAction.NOTHING; + } else if (packetplayinwindowclick.f() == 0) { + if (packetplayinwindowclick.c() == 0) { + click = ClickType.LEFT; + } else if (packetplayinwindowclick.c() == 1) { + click = ClickType.RIGHT; + } + if (packetplayinwindowclick.c() == 0 || packetplayinwindowclick.c() == 1) { + action = InventoryAction.NOTHING; // Don't want to repeat ourselves + if (packetplayinwindowclick.b() == -999) { + if (player.inventory.getCarried() != null) { + action = packetplayinwindowclick.c() == 0 ? InventoryAction.DROP_ALL_CURSOR : InventoryAction.DROP_ONE_CURSOR; + } + } else { + Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); + if (slot != null) { + ItemStack clickedItem = slot.getItem(); + ItemStack cursor = player.inventory.getCarried(); + if (clickedItem == null) { + if (cursor != null) { + action = packetplayinwindowclick.c() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; + } + } else if (slot.isAllowed(player)) { + if (cursor == null) { + action = packetplayinwindowclick.c() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; + } else if (slot.isAllowed(cursor)) { + if (clickedItem.doMaterialsMatch(cursor) && ItemStack.equals(clickedItem, cursor)) { + int toPlace = packetplayinwindowclick.c() == 0 ? cursor.count : 1; + toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.count); + toPlace = Math.min(toPlace, slot.inventory.getMaxStackSize() - clickedItem.count); + if (toPlace == 1) { + action = InventoryAction.PLACE_ONE; + } else if (toPlace == cursor.count) { + action = InventoryAction.PLACE_ALL; + } else if (toPlace < 0) { + action = toPlace != -1 ? InventoryAction.PICKUP_SOME : InventoryAction.PICKUP_ONE; // this happens with oversized stacks + } else if (toPlace != 0) { + action = InventoryAction.PLACE_SOME; + } + } else if (cursor.count <= slot.getMaxStackSize()) { + action = InventoryAction.SWAP_WITH_CURSOR; + } + } else if (cursor.getItem() == clickedItem.getItem() && (!cursor.usesData() || cursor.getData() == clickedItem.getData()) && ItemStack.equals(cursor, clickedItem)) { + if (clickedItem.count >= 0) { + if (clickedItem.count + cursor.count <= cursor.getMaxStackSize()) { + // As of 1.5, this is result slots only + action = InventoryAction.PICKUP_ALL; + } + } + } + } + } + } + } + } else if (packetplayinwindowclick.f() == 1) { + if (packetplayinwindowclick.c() == 0) { + click = ClickType.SHIFT_LEFT; + } else if (packetplayinwindowclick.c() == 1) { + click = ClickType.SHIFT_RIGHT; + } + if (packetplayinwindowclick.c() == 0 || packetplayinwindowclick.c() == 1) { + if (packetplayinwindowclick.b() < 0) { + action = InventoryAction.NOTHING; + } else { + Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); + if (slot != null && slot.isAllowed(this.player) && slot.hasItem()) { + action = InventoryAction.MOVE_TO_OTHER_INVENTORY; + } else { + action = InventoryAction.NOTHING; + } + } + } + } else if (packetplayinwindowclick.f() == 2) { + if (packetplayinwindowclick.c() >= 0 && packetplayinwindowclick.c() < 9) { + click = ClickType.NUMBER_KEY; + Slot clickedSlot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); + if (clickedSlot.isAllowed(player)) { + ItemStack hotbar = this.player.inventory.getItem(packetplayinwindowclick.c()); + boolean canCleanSwap = hotbar == null || (clickedSlot.inventory == player.inventory && clickedSlot.isAllowed(hotbar)); // the slot will accept the hotbar item + if (clickedSlot.hasItem()) { + if (canCleanSwap) { + action = InventoryAction.HOTBAR_SWAP; + } else { + int firstEmptySlot = player.inventory.getFirstEmptySlotIndex(); + if (firstEmptySlot > -1) { + action = InventoryAction.HOTBAR_MOVE_AND_READD; + } else { + action = InventoryAction.NOTHING; // This is not sane! Mojang: You should test for other slots of same type + } + } + } else if (!clickedSlot.hasItem() && hotbar != null && clickedSlot.isAllowed(hotbar)) { + action = InventoryAction.HOTBAR_SWAP; + } else { + action = InventoryAction.NOTHING; + } + } else { + action = InventoryAction.NOTHING; + } + // Special constructor for number key + event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c()); + } + } else if (packetplayinwindowclick.f() == 3) { + if (packetplayinwindowclick.c() == 2) { + click = ClickType.MIDDLE; + if (packetplayinwindowclick.b() == -999) { + action = InventoryAction.NOTHING; + } else { + Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); + if (slot != null && slot.hasItem() && player.abilities.canInstantlyBuild && player.inventory.getCarried() == null) { + action = InventoryAction.CLONE_STACK; + } else { + action = InventoryAction.NOTHING; + } + } + } else { + click = ClickType.UNKNOWN; + action = InventoryAction.UNKNOWN; + } + } else if (packetplayinwindowclick.f() == 4) { + if (packetplayinwindowclick.b() >= 0) { + if (packetplayinwindowclick.c() == 0) { + click = ClickType.DROP; + Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); + if (slot != null && slot.hasItem() && slot.isAllowed(player) && slot.getItem() != null && slot.getItem().getItem() != Item.getItemOf(Blocks.AIR)) { + action = InventoryAction.DROP_ONE_SLOT; + } else { + action = InventoryAction.NOTHING; + } + } else if (packetplayinwindowclick.c() == 1) { + click = ClickType.CONTROL_DROP; + Slot slot = this.player.activeContainer.getSlot(packetplayinwindowclick.b()); + if (slot != null && slot.hasItem() && slot.isAllowed(player) && slot.getItem() != null && slot.getItem().getItem() != Item.getItemOf(Blocks.AIR)) { + action = InventoryAction.DROP_ALL_SLOT; + } else { + action = InventoryAction.NOTHING; + } + } + } else { + // Sane default (because this happens when they are holding nothing. Don't ask why.) + click = ClickType.LEFT; + if (packetplayinwindowclick.c() == 1) { + click = ClickType.RIGHT; + } + action = InventoryAction.NOTHING; + } + } else if (packetplayinwindowclick.f() == 5) { + itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), 5, this.player); + } else if (packetplayinwindowclick.f() == 6) { + click = ClickType.DOUBLE_CLICK; + action = InventoryAction.NOTHING; + if (packetplayinwindowclick.b() >= 0 && this.player.inventory.getCarried() != null) { + ItemStack cursor = this.player.inventory.getCarried(); + action = InventoryAction.NOTHING; + // Quick check for if we have any of the item + if (inventory.getTopInventory().contains(org.bukkit.Material.getMaterial(Item.getId(cursor.getItem()))) || inventory.getBottomInventory().contains(org.bukkit.Material.getMaterial(Item.getId(cursor.getItem())))) { + action = InventoryAction.COLLECT_TO_CURSOR; + } + } + } + // TODO check on updates + + if (packetplayinwindowclick.f() != 5) { + if (click == ClickType.NUMBER_KEY) { + event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c()); + } else { + event = new InventoryClickEvent(inventory, type, packetplayinwindowclick.b(), click, action); + } + + org.bukkit.inventory.Inventory top = inventory.getTopInventory(); + if (packetplayinwindowclick.b() == 0 && top instanceof CraftingInventory) { + org.bukkit.inventory.Recipe recipe = ((CraftingInventory) top).getRecipe(); + if (recipe != null) { + if (click == ClickType.NUMBER_KEY) { + event = new CraftItemEvent(recipe, inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c()); + } else { + event = new CraftItemEvent(recipe, inventory, type, packetplayinwindowclick.b(), click, action); + } + } + } + + event.setCancelled(cancelled); + server.getPluginManager().callEvent(event); + + switch (event.getResult()) { + case ALLOW: + case DEFAULT: + itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); + // PaperSpigot start - Stackable Buckets + if (itemstack != null && + ((itemstack.getItem() == Items.LAVA_BUCKET && PaperSpigotConfig.stackableLavaBuckets) || + (itemstack.getItem() == Items.WATER_BUCKET && PaperSpigotConfig.stackableWaterBuckets) || + (itemstack.getItem() == Items.MILK_BUCKET && PaperSpigotConfig.stackableMilkBuckets))) { + if (action == InventoryAction.MOVE_TO_OTHER_INVENTORY) { + this.player.updateInventory(this.player.activeContainer); + } else { + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.player.inventory.getCarried())); + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, packetplayinwindowclick.b(), this.player.activeContainer.getSlot(packetplayinwindowclick.b()).getItem())); + } + } + // PaperSpigot end + break; + case DENY: + /* Needs enum constructor in InventoryAction + if (action.modifiesOtherSlots()) { + + } else { + if (action.modifiesCursor()) { + this.player.playerConnection.sendPacket(new Packet103SetSlot(-1, -1, this.player.inventory.getCarried())); + } + if (action.modifiesClicked()) { + this.player.playerConnection.sendPacket(new Packet103SetSlot(this.player.activeContainer.windowId, packet102windowclick.slot, this.player.activeContainer.getSlot(packet102windowclick.slot).getItem())); + } + }*/ + switch (action) { + // Modified other slots + case PICKUP_ALL: + case MOVE_TO_OTHER_INVENTORY: + case HOTBAR_MOVE_AND_READD: + case HOTBAR_SWAP: + case COLLECT_TO_CURSOR: + case UNKNOWN: + this.player.updateInventory(this.player.activeContainer); + break; + // Modified cursor and clicked + case PICKUP_SOME: + case PICKUP_HALF: + case PICKUP_ONE: + case PLACE_ALL: + case PLACE_SOME: + case PLACE_ONE: + case SWAP_WITH_CURSOR: + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.player.inventory.getCarried())); + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, packetplayinwindowclick.b(), this.player.activeContainer.getSlot(packetplayinwindowclick.b()).getItem())); + break; + // Modified clicked only + case DROP_ALL_SLOT: + case DROP_ONE_SLOT: + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, packetplayinwindowclick.b(), this.player.activeContainer.getSlot(packetplayinwindowclick.b()).getItem())); + break; + // Modified cursor only + case DROP_ALL_CURSOR: + case DROP_ONE_CURSOR: + case CLONE_STACK: + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.player.inventory.getCarried())); + break; + // Nothing + case NOTHING: + break; + } + return; + } + + if (event instanceof CraftItemEvent) { + // Need to update the inventory on crafting to + // correctly support custom recipes + player.updateInventory(player.activeContainer); + } + } + // CraftBukkit end + + if (ItemStack.matches(packetplayinwindowclick.e(), itemstack)) { + this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.a(), packetplayinwindowclick.d(), true)); + this.player.g = true; + this.player.activeContainer.b(); + this.player.broadcastCarriedItem(); + this.player.g = false; + } else { + this.n.a(this.player.activeContainer.windowId, Short.valueOf(packetplayinwindowclick.d())); + this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.a(), packetplayinwindowclick.d(), false)); + this.player.activeContainer.a(this.player, false); + ArrayList arraylist1 = Lists.newArrayList(); + + for (int j = 0; j < this.player.activeContainer.c.size(); ++j) { + arraylist1.add(this.player.activeContainer.c.get(j).getItem()); + } + + this.player.a(this.player.activeContainer, arraylist1); + } + } + } + + } + + public void a(PacketPlayInEnchantItem packetplayinenchantitem) { + PlayerConnectionUtils.ensureMainThread(packetplayinenchantitem, this, this.player.u()); + this.player.resetIdleTimer(); + if (this.player.activeContainer.windowId == packetplayinenchantitem.a() && this.player.activeContainer.c(this.player) && !this.player.isSpectator()) { + this.player.activeContainer.a(this.player, packetplayinenchantitem.b()); + this.player.activeContainer.b(); + } + + } + + public void a(PacketPlayInSetCreativeSlot packetplayinsetcreativeslot) { + PlayerConnectionUtils.ensureMainThread(packetplayinsetcreativeslot, this, this.player.u()); + if (this.player.playerInteractManager.isCreative()) { + boolean flag = packetplayinsetcreativeslot.a() < 0; + ItemStack itemstack = packetplayinsetcreativeslot.getItemStack(); + + if (itemstack != null && itemstack.hasTag() && itemstack.getTag().hasKeyOfType("BlockEntityTag", 10)) { + NBTTagCompound nbttagcompound = itemstack.getTag().getCompound("BlockEntityTag"); + + if (nbttagcompound.hasKey("x") && nbttagcompound.hasKey("y") && nbttagcompound.hasKey("z")) { + BlockPosition blockposition = new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")); + TileEntity tileentity = this.player.world.getTileEntity(blockposition); + + if (tileentity != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + tileentity.b(nbttagcompound1); + nbttagcompound1.remove("x"); + nbttagcompound1.remove("y"); + nbttagcompound1.remove("z"); + itemstack.a("BlockEntityTag", nbttagcompound1); + } + } + } + + boolean flag1 = packetplayinsetcreativeslot.a() >= 1 && packetplayinsetcreativeslot.a() < 36 + PlayerInventory.getHotbarSize(); + // CraftBukkit - Add invalidItems check + boolean flag2 = itemstack == null || itemstack.getItem() != null && (!invalidItems.contains(Item.getId(itemstack.getItem())) || !org.spigotmc.SpigotConfig.filterCreativeItems); // Spigot + boolean flag3 = itemstack == null || itemstack.getData() >= 0 && itemstack.count <= 64 && itemstack.count > 0; + // CraftBukkit start - Call click event + if (flag || (flag1 && !ItemStack.matches(this.player.defaultContainer.getSlot(packetplayinsetcreativeslot.a()).getItem(), packetplayinsetcreativeslot.getItemStack()))) { // Insist on valid slot + + org.bukkit.entity.HumanEntity player = this.player.getBukkitEntity(); + InventoryView inventory = new CraftInventoryView(player, player.getInventory(), this.player.defaultContainer); + org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(packetplayinsetcreativeslot.getItemStack()); + + SlotType type = SlotType.QUICKBAR; + if (flag) { + type = SlotType.OUTSIDE; + } else if (packetplayinsetcreativeslot.a() < 36) { + if (packetplayinsetcreativeslot.a() >= 5 && packetplayinsetcreativeslot.a() < 9) { + type = SlotType.ARMOR; + } else { + type = SlotType.CONTAINER; + } + } + InventoryCreativeEvent event = new InventoryCreativeEvent(inventory, type, flag ? -999 : packetplayinsetcreativeslot.a(), item); + server.getPluginManager().callEvent(event); + + itemstack = CraftItemStack.asNMSCopy(event.getCursor()); + + switch (event.getResult()) { + case ALLOW: + // Plugin cleared the id / stacksize checks + flag2 = flag3 = true; + break; + case DEFAULT: + break; + case DENY: + // Reset the slot + if (packetplayinsetcreativeslot.a() >= 0) { + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.defaultContainer.windowId, packetplayinsetcreativeslot.a(), this.player.defaultContainer.getSlot(packetplayinsetcreativeslot.a()).getItem())); + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, null)); + } + return; + } + } + // CraftBukkit end + + if (flag1 && flag2 && flag3) { + if (itemstack == null) { + this.player.defaultContainer.setItem(packetplayinsetcreativeslot.a(), null); + } else { + this.player.defaultContainer.setItem(packetplayinsetcreativeslot.a(), itemstack); + } + + this.player.defaultContainer.a(this.player, true); + } else if (flag && flag2 && flag3 && this.m < 200) { + this.m += 20; + EntityItem entityitem = this.player.drop(itemstack, true); + + if (entityitem != null) { + entityitem.j(); + } + } + } + + } + + public void a(PacketPlayInTransaction packetplayintransaction) { + if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayintransaction, this, this.player.u()); + Short oshort = this.n.get(this.player.activeContainer.windowId); + + if (oshort != null && packetplayintransaction.b() == oshort.shortValue() && this.player.activeContainer.windowId == packetplayintransaction.a() && !this.player.activeContainer.c(this.player) && !this.player.isSpectator()) { + this.player.activeContainer.a(this.player, true); + } + + } + + public void a(PacketPlayInUpdateSign packetplayinupdatesign) { + if (this.player.dead) return; // CraftBukkit + PlayerConnectionUtils.ensureMainThread(packetplayinupdatesign, this, this.player.u()); + this.player.resetIdleTimer(); + WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); + BlockPosition blockposition = packetplayinupdatesign.a(); + + if (worldserver.isLoaded(blockposition)) { + TileEntity tileentity = worldserver.getTileEntity(blockposition); + + if (!(tileentity instanceof TileEntitySign)) { + return; + } + + TileEntitySign tileentitysign = (TileEntitySign) tileentity; + + if (!tileentitysign.b() || tileentitysign.c() != this.player) { + this.minecraftServer.warning("Player " + this.player.getName() + " just tried to change non-editable sign"); + this.sendPacket(new PacketPlayOutUpdateSign(tileentity.world, packetplayinupdatesign.a(), tileentitysign.lines)); // CraftBukkit + return; + } + + IChatBaseComponent[] aichatbasecomponent = packetplayinupdatesign.b(); + + // CraftBukkit start + Player player = this.server.getPlayer(this.player); + int x = packetplayinupdatesign.a().getX(); + int y = packetplayinupdatesign.a().getY(); + int z = packetplayinupdatesign.a().getZ(); + String[] lines = new String[4]; + + for (int i = 0; i < aichatbasecomponent.length; ++i) { + lines[i] = EnumChatFormat.a(aichatbasecomponent[i].c()); + } + SignChangeEvent event = new SignChangeEvent(player.getWorld().getBlockAt(x, y, z), this.server.getPlayer(this.player), lines); + this.server.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + System.arraycopy(org.bukkit.craftbukkit.block.CraftSign.sanitizeLines(event.getLines()), 0, tileentitysign.lines, 0, 4); + tileentitysign.isEditable = false; + } + // CraftBukkit end + + tileentitysign.update(); + worldserver.notify(blockposition); + } + + } + + public void a(PacketPlayInKeepAlive packetplayinkeepalive) { + if (packetplayinkeepalive.a() == this.i) { + int i = (int) (this.d() - this.j); + + this.player.ping = (this.player.ping * 3 + i) / 4; + } + + } + + private long d() { + return System.nanoTime() / 1000000L; + } + + public void a(PacketPlayInAbilities packetplayinabilities) { + PlayerConnectionUtils.ensureMainThread(packetplayinabilities, this, this.player.u()); + // CraftBukkit start + if (this.player.abilities.canFly && this.player.abilities.isFlying != packetplayinabilities.isFlying()) { + PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.server.getPlayer(this.player), packetplayinabilities.isFlying()); + this.server.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + this.player.abilities.isFlying = packetplayinabilities.isFlying(); // Actually set the player's flying status + } else { + this.player.updateAbilities(); // Tell the player their ability was reverted + } + } + // CraftBukkit end + } + + public void a(PacketPlayInTabComplete packetplayintabcomplete) { + PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.u()); + // CraftBukkit start + if (chatSpamField.addAndGet(this, 10) > 500 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { + this.disconnect("disconnect.spam"); + return; + } + // CraftBukkit end + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = this.minecraftServer.tabCompleteCommand(this.player, packetplayintabcomplete.a(), packetplayintabcomplete.b()).iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + + arraylist.add(s); + } + + this.player.playerConnection.sendPacket(new PacketPlayOutTabComplete((String[]) arraylist.toArray(new String[arraylist.size()]))); + } + + public void a(PacketPlayInSettings packetplayinsettings) { + PlayerConnectionUtils.ensureMainThread(packetplayinsettings, this, this.player.u()); + this.player.a(packetplayinsettings); + } + + public void a(PacketPlayInCustomPayload packetplayincustompayload) { + PlayerConnectionUtils.ensureMainThread(packetplayincustompayload, this, this.player.u()); + PacketDataSerializer packetdataserializer; + ItemStack itemstack; + ItemStack itemstack1; + + try { // CraftBukkit + if ("MC|BEdit".equals(packetplayincustompayload.a())) { + packetdataserializer = new PacketDataSerializer(Unpooled.wrappedBuffer(packetplayincustompayload.b())); + + try { + itemstack = packetdataserializer.i(); + if (itemstack == null) { + return; + } + + if (!ItemBookAndQuill.b(itemstack.getTag())) { + throw new IOException("Invalid book tag!"); + } + + itemstack1 = this.player.inventory.getItemInHand(); + if (itemstack1 != null) { + if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack.getItem() == itemstack1.getItem()) { + itemstack1 = new ItemStack(Items.WRITABLE_BOOK); // CraftBukkit + itemstack1.a("pages", itemstack.getTag().getList("pages", 8)); + CraftEventFactory.handleEditBookEvent(player, itemstack1); // CraftBukkit + } + + return; + } + } catch (Exception exception) { + PlayerConnection.c.error("Couldn't handle book info", exception); + this.disconnect("Invalid book data!"); // CraftBukkit + return; + } finally { + packetdataserializer.release(); + } + + return; + } else if ("MC|BSign".equals(packetplayincustompayload.a())) { + packetdataserializer = new PacketDataSerializer(Unpooled.wrappedBuffer(packetplayincustompayload.b())); + + try { + itemstack = packetdataserializer.i(); + if (itemstack == null) { + return; + } + + if (!ItemWrittenBook.b(itemstack.getTag())) { + throw new IOException("Invalid book tag!"); + } + + itemstack1 = this.player.inventory.getItemInHand(); + if (itemstack1 != null) { + if (itemstack.getItem() == Items.WRITTEN_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) { + // CraftBukkit start + itemstack1 = new ItemStack(Items.WRITTEN_BOOK); + itemstack1.a("author", new NBTTagString(this.player.getName())); + itemstack1.a("title", new NBTTagString(itemstack.getTag().getString("title"))); + itemstack1.a("pages", itemstack.getTag().getList("pages", 8)); + itemstack1.setItem(Items.WRITTEN_BOOK); + CraftEventFactory.handleEditBookEvent(player, itemstack1); + // CraftBukkit end + } + + return; + } + } catch (Exception exception1) { + PlayerConnection.c.error("Couldn't sign book", exception1); + this.disconnect("Invalid book data!"); // CraftBukkit + return; + } finally { + packetdataserializer.release(); + } + + return; + } else if ("MC|TrSel".equals(packetplayincustompayload.a())) { + try { + int i = packetplayincustompayload.b().readInt(); + Container container = this.player.activeContainer; + + if (container instanceof ContainerMerchant) { + ((ContainerMerchant) container).d(i); + } + } catch (Exception exception2) { + PlayerConnection.c.error("Couldn't select trade", exception2); + this.disconnect("Invalid trade data!"); // CraftBukkit + } + } else if ("MC|AdvCdm".equals(packetplayincustompayload.a())) { + if (!this.minecraftServer.getEnableCommandBlock()) { + this.player.sendMessage(new ChatMessage("advMode.notEnabled")); + } else if (this.player.getBukkitEntity().isOp() && this.player.abilities.canInstantlyBuild) { // CraftBukkit - Change to Bukkit OP versus Vanilla OP + packetdataserializer = packetplayincustompayload.b(); + + try { + byte b0 = packetdataserializer.readByte(); + CommandBlockListenerAbstract commandblocklistenerabstract = null; + + if (b0 == 0) { + TileEntity tileentity = this.player.world.getTileEntity(new BlockPosition(packetdataserializer.readInt(), packetdataserializer.readInt(), packetdataserializer.readInt())); + + if (tileentity instanceof TileEntityCommand) { + commandblocklistenerabstract = ((TileEntityCommand) tileentity).getCommandBlock(); + } + } else if (b0 == 1) { + Entity entity = this.player.world.a(packetdataserializer.readInt()); + + if (entity instanceof EntityMinecartCommandBlock) { + commandblocklistenerabstract = ((EntityMinecartCommandBlock) entity).getCommandBlock(); + } + } + + String s = packetdataserializer.c(packetdataserializer.readableBytes()); + boolean flag = packetdataserializer.readBoolean(); + + if (commandblocklistenerabstract != null) { + commandblocklistenerabstract.setCommand(s); + commandblocklistenerabstract.a(flag); + if (!flag) { + commandblocklistenerabstract.b((IChatBaseComponent) null); + } + + commandblocklistenerabstract.h(); + this.player.sendMessage(new ChatMessage("advMode.setCommand.success", s)); + } + } catch (Exception exception3) { + PlayerConnection.c.error("Couldn't set command block", exception3); + this.disconnect("Invalid CommandBlock data!"); // CraftBukkit + } finally { + packetdataserializer.release(); + } + } else { + this.player.sendMessage(new ChatMessage("advMode.notAllowed")); + } + } else if ("MC|Beacon".equals(packetplayincustompayload.a())) { + if (this.player.activeContainer instanceof ContainerBeacon) { + try { + packetdataserializer = packetplayincustompayload.b(); + int j = packetdataserializer.readInt(); + int k = packetdataserializer.readInt(); + ContainerBeacon containerbeacon = (ContainerBeacon) this.player.activeContainer; + Slot slot = containerbeacon.getSlot(0); + + if (slot.hasItem()) { + slot.a(1); + IInventory iinventory = containerbeacon.e(); + + iinventory.b(1, j); + iinventory.b(2, k); + iinventory.update(); + } + } catch (Exception exception4) { + PlayerConnection.c.error("Couldn't set beacon", exception4); + this.disconnect("Invalid beacon data!"); // CraftBukkit + } + } + } else if ("MC|ItemName".equals(packetplayincustompayload.a()) && this.player.activeContainer instanceof ContainerAnvil) { + ContainerAnvil containeranvil = (ContainerAnvil) this.player.activeContainer; + + if (packetplayincustompayload.b() != null && packetplayincustompayload.b().readableBytes() >= 1) { + String s1 = SharedConstants.a(packetplayincustompayload.b().c(32767)); + + if (s1.length() <= 30) { + containeranvil.a(s1); + } + } else { + containeranvil.a(""); + } + } + // CraftBukkit start + else if (packetplayincustompayload.a().equals("REGISTER")) { + String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8); + for (String channel : channels.split("\0")) { + getPlayer().addChannel(channel); + } + } else if (packetplayincustompayload.a().equals("UNREGISTER")) { + String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8); + for (String channel : channels.split("\0")) { + getPlayer().removeChannel(channel); + } + } else { + byte[] data = new byte[packetplayincustompayload.b().readableBytes()]; + packetplayincustompayload.b().readBytes(data); + server.getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), packetplayincustompayload.a(), data); + } + // CraftBukkit end + // CraftBukkit start + } finally { + if (packetplayincustompayload.b().refCnt() > 0) { + packetplayincustompayload.b().release(); + } + } + // CraftBukkit end + } + + // CraftBukkit start - Add "isDisconnected" method + public boolean isDisconnected() { // Spigot + return !this.player.joining && !this.networkManager.channel.config().isAutoRead(); + } + + static class SyntheticClass_1 { + + static final int[] a; + static final int[] b; + static final int[] c = new int[PacketPlayInClientCommand.EnumClientCommand.values().length]; + + static { + try { + PlayerConnection.SyntheticClass_1.c[PacketPlayInClientCommand.EnumClientCommand.PERFORM_RESPAWN.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + } + + try { + PlayerConnection.SyntheticClass_1.c[PacketPlayInClientCommand.EnumClientCommand.REQUEST_STATS.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + } + + try { + PlayerConnection.SyntheticClass_1.c[PacketPlayInClientCommand.EnumClientCommand.OPEN_INVENTORY_ACHIEVEMENT.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + } + + b = new int[PacketPlayInEntityAction.EnumPlayerAction.values().length]; + + try { + PlayerConnection.SyntheticClass_1.b[PacketPlayInEntityAction.EnumPlayerAction.START_SNEAKING.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror3) { + } + + try { + PlayerConnection.SyntheticClass_1.b[PacketPlayInEntityAction.EnumPlayerAction.STOP_SNEAKING.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror4) { + } + + try { + PlayerConnection.SyntheticClass_1.b[PacketPlayInEntityAction.EnumPlayerAction.START_SPRINTING.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror5) { + } + + try { + PlayerConnection.SyntheticClass_1.b[PacketPlayInEntityAction.EnumPlayerAction.STOP_SPRINTING.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror6) { + } + + try { + PlayerConnection.SyntheticClass_1.b[PacketPlayInEntityAction.EnumPlayerAction.STOP_SLEEPING.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror7) { + } + + try { + PlayerConnection.SyntheticClass_1.b[PacketPlayInEntityAction.EnumPlayerAction.RIDING_JUMP.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror8) { + } + + try { + PlayerConnection.SyntheticClass_1.b[PacketPlayInEntityAction.EnumPlayerAction.OPEN_INVENTORY.ordinal()] = 7; + } catch (NoSuchFieldError nosuchfielderror9) { + } + + a = new int[PacketPlayInBlockDig.EnumPlayerDigType.values().length]; + + try { + PlayerConnection.SyntheticClass_1.a[PacketPlayInBlockDig.EnumPlayerDigType.DROP_ITEM.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror10) { + } + + try { + PlayerConnection.SyntheticClass_1.a[PacketPlayInBlockDig.EnumPlayerDigType.DROP_ALL_ITEMS.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror11) { + } + + try { + PlayerConnection.SyntheticClass_1.a[PacketPlayInBlockDig.EnumPlayerDigType.RELEASE_USE_ITEM.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror12) { + } + + try { + PlayerConnection.SyntheticClass_1.a[PacketPlayInBlockDig.EnumPlayerDigType.START_DESTROY_BLOCK.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror13) { + } + + try { + PlayerConnection.SyntheticClass_1.a[PacketPlayInBlockDig.EnumPlayerDigType.ABORT_DESTROY_BLOCK.ordinal()] = 5; + } catch (NoSuchFieldError nosuchfielderror14) { + } + + try { + PlayerConnection.SyntheticClass_1.a[PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK.ordinal()] = 6; + } catch (NoSuchFieldError nosuchfielderror15) { + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerInteractManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerInteractManager.java new file mode 100644 index 0000000..33a0a09 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerInteractManager.java @@ -0,0 +1,519 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.Event; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +// CraftBukkit end + +public class PlayerInteractManager { + + public World world; + public EntityPlayer player; + private WorldSettings.EnumGamemode gamemode; + private boolean d; + private int lastDigTick; + private BlockPosition f; + private int currentTick; + private boolean h; + private BlockPosition i; + private int j; + private int k; + + public PlayerInteractManager(World world) { + this.gamemode = WorldSettings.EnumGamemode.NOT_SET; + this.f = BlockPosition.ZERO; + this.i = BlockPosition.ZERO; + this.k = -1; + this.world = world; + } + + public void setGameMode(WorldSettings.EnumGamemode worldsettings_enumgamemode) { + this.gamemode = worldsettings_enumgamemode; + worldsettings_enumgamemode.a(this.player.abilities); + this.player.updateAbilities(); + this.player.server.getPlayerList().sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_GAME_MODE, new EntityPlayer[] { this.player}), this.player); // CraftBukkit + } + + public WorldSettings.EnumGamemode getGameMode() { + return this.gamemode; + } + + public boolean c() { + return this.gamemode.e(); + } + + public boolean isCreative() { + return this.gamemode.d(); + } + + public void b(WorldSettings.EnumGamemode worldsettings_enumgamemode) { + if (this.gamemode == WorldSettings.EnumGamemode.NOT_SET) { + this.gamemode = worldsettings_enumgamemode; + } + + this.setGameMode(this.gamemode); + } + + public void a() { + this.currentTick = MinecraftServer.currentTick; // CraftBukkit; + float f; + int i; + + if (this.h) { + int j = this.currentTick - this.j; + Block block = this.world.getType(this.i).getBlock(); + + if (block.getMaterial() == Material.AIR) { + this.h = false; + } else { + f = block.getDamage(this.player, this.player.world, this.i) * (float) (j + 1); + i = (int) (f * 10.0F); + if (i != this.k) { + this.world.c(this.player.getId(), this.i, i); + this.k = i; + } + + if (f >= 1.0F) { + this.h = false; + this.breakBlock(this.i); + } + } + } else if (this.d) { + Block block1 = this.world.getType(this.f).getBlock(); + + if (block1.getMaterial() == Material.AIR) { + this.world.c(this.player.getId(), this.f, -1); + this.k = -1; + this.d = false; + } else { + int k = this.currentTick - this.lastDigTick; + + f = block1.getDamage(this.player, this.player.world, this.i) * (float) (k + 1); + i = (int) (f * 10.0F); + if (i != this.k) { + this.world.c(this.player.getId(), this.f, i); + this.k = i; + } + } + } + + } + + public void a(BlockPosition blockposition, EnumDirection enumdirection) { + // CraftBukkit start + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, enumdirection, this.player.inventory.getItemInHand()); + if (event.isCancelled()) { + // Let the client know the block still exists + ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + // Update any tile entity data for this block + TileEntity tileentity = this.world.getTileEntity(blockposition); + if (tileentity != null) { + this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); + } + return; + } + // CraftBukkit end + if (this.isCreative()) { + if (!this.world.douseFire((EntityHuman) null, blockposition, enumdirection)) { + this.breakBlock(blockposition); + } + + } else { + Block block = this.world.getType(blockposition).getBlock(); + + if (this.gamemode.c()) { + if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { + return; + } + + if (!this.player.cn()) { + ItemStack itemstack = this.player.bZ(); + + if (itemstack == null) { + return; + } + + if (!itemstack.c(block)) { + return; + } + } + } + + // this.world.douseFire((EntityHuman) null, blockposition, enumdirection); // CraftBukkit - Moved down + this.lastDigTick = this.currentTick; + float f = 1.0F; + + // CraftBukkit start - Swings at air do *NOT* exist. + if (event.useInteractedBlock() == Event.Result.DENY) { + // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. + IBlockData data = this.world.getType(blockposition); + if (block == Blocks.WOODEN_DOOR) { + // For some reason *BOTH* the bottom/top part have to be marked updated. + boolean bottom = data.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER; + ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, bottom ? blockposition.up() : blockposition.down())); + } else if (block == Blocks.TRAPDOOR) { + ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + } + } else if (block.getMaterial() != Material.AIR) { + block.attack(this.world, blockposition, this.player); + f = block.getDamage(this.player, this.player.world, blockposition); + // Allow fire punching to be blocked + this.world.douseFire((EntityHuman) null, blockposition, enumdirection); + } + + if (event.useItemInHand() == Event.Result.DENY) { + // If we 'insta destroyed' then the client needs to be informed. + if (f > 1.0f) { + ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + } + return; + } + org.bukkit.event.block.BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.player, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.player.inventory.getItemInHand(), f >= 1.0f); + + if (blockEvent.isCancelled()) { + // Let the client know the block still exists + ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + return; + } + + if (blockEvent.getInstaBreak()) { + f = 2.0f; + } + // CraftBukkit end + + if (block.getMaterial() != Material.AIR && f >= 1.0F) { + this.breakBlock(blockposition); + } else { + this.d = true; + this.f = blockposition; + int i = (int) (f * 10.0F); + + this.world.c(this.player.getId(), blockposition, i); + this.k = i; + } + + } + world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, blockposition); // Spigot + } + + public void a(BlockPosition blockposition) { + if (blockposition.equals(this.f)) { + this.currentTick = MinecraftServer.currentTick; // CraftBukkit + int i = this.currentTick - this.lastDigTick; + Block block = this.world.getType(blockposition).getBlock(); + + if (block.getMaterial() != Material.AIR) { + float f = block.getDamage(this.player, this.player.world, blockposition) * (float) (i + 1); + + if (f >= 0.7F) { + this.d = false; + this.world.c(this.player.getId(), blockposition, -1); + this.breakBlock(blockposition); + } else if (!this.h) { + this.d = false; + this.h = true; + this.i = blockposition; + this.j = this.lastDigTick; + } + } + // CraftBukkit start - Force block reset to client + } else { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + // CraftBukkit end + } + + } + + public void e() { + this.d = false; + this.world.c(this.player.getId(), this.f, -1); + } + + private boolean c(BlockPosition blockposition) { + IBlockData iblockdata = this.world.getType(blockposition); + + iblockdata.getBlock().a(this.world, blockposition, iblockdata, (EntityHuman) this.player); + boolean flag = this.world.setAir(blockposition); + + if (flag) { + iblockdata.getBlock().postBreak(this.world, blockposition, iblockdata); + } + + return flag; + } + + public boolean breakBlock(BlockPosition blockposition) { + // CraftBukkit start - fire BlockBreakEvent + BlockBreakEvent event = null; + + if (this.player instanceof EntityPlayer) { + org.bukkit.block.Block block = this.world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + + // Sword + Creative mode pre-cancel + boolean isSwordNoBreak = this.gamemode.d() && this.player.bA() != null && this.player.bA().getItem() instanceof ItemSword; + + // Tell client the block is gone immediately then process events + // Don't tell the client if its a creative sword break because its not broken! + if (world.getTileEntity(blockposition) == null && !isSwordNoBreak) { + PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, blockposition); + packet.block = Blocks.AIR.getBlockData(); + ((EntityPlayer) this.player).playerConnection.sendPacket(packet); + } + + event = new BlockBreakEvent(block, this.player.getBukkitEntity()); + + // Sword + Creative mode pre-cancel + event.setCancelled(isSwordNoBreak); + + // Calculate default block experience + IBlockData nmsData = this.world.getType(blockposition); + Block nmsBlock = nmsData.getBlock(); + + if (nmsBlock != null && !event.isCancelled() && !this.isCreative() && this.player.b(nmsBlock)) { + // Copied from block.a(World world, EntityHuman entityhuman, BlockPosition blockposition, IBlockData iblockdata, TileEntity tileentity) + if (!(nmsBlock.I() && EnchantmentManager.hasSilkTouchEnchantment(this.player))) { + int data = block.getData(); + int bonusLevel = EnchantmentManager.getBonusBlockLootEnchantmentLevel(this.player); + + event.setExpToDrop(nmsBlock.getExpDrop(this.world, nmsData, bonusLevel)); + } + } + + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + if (isSwordNoBreak) { + return false; + } + // Let the client know the block still exists + ((EntityPlayer) this.player).playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + // Update any tile entity data for this block + TileEntity tileentity = this.world.getTileEntity(blockposition); + if (tileentity != null) { + this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); + } + return false; + } + } + if (false && this.gamemode.d() && this.player.bA() != null && this.player.bA().getItem() instanceof ItemSword) { + return false; + } else { + IBlockData iblockdata = this.world.getType(blockposition); + if (iblockdata.getBlock() == Blocks.AIR) return false; // CraftBukkit - A plugin set block to air without cancelling + TileEntity tileentity = this.world.getTileEntity(blockposition); + + // CraftBukkit start - Special case skulls, their item data comes from a tile entity + if (iblockdata.getBlock() == Blocks.SKULL && !this.isCreative()) { + iblockdata.getBlock().dropNaturally(world, blockposition, iblockdata, 1.0F, 0); + return this.c(blockposition); + } + // CraftBukkit end + + if (this.gamemode.c()) { + if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { + return false; + } + + if (!this.player.cn()) { + ItemStack itemstack = this.player.bZ(); + + if (itemstack == null) { + return false; + } + + if (!itemstack.c(iblockdata.getBlock())) { + return false; + } + } + } + + this.world.a(this.player, 2001, blockposition, Block.getCombinedId(iblockdata)); + boolean flag = this.c(blockposition); + + if (this.isCreative()) { + this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(this.world, blockposition)); + } else { + ItemStack itemstack1 = this.player.bZ(); + boolean flag1 = this.player.b(iblockdata.getBlock()); + + if (itemstack1 != null) { + itemstack1.a(this.world, iblockdata.getBlock(), blockposition, this.player); + if (itemstack1.count == 0) { + this.player.ca(); + } + } + + if (flag && flag1) { + iblockdata.getBlock().a(this.world, this.player, blockposition, iblockdata, tileentity); + } + } + + // CraftBukkit start - Drop event experience + if (flag && event != null) { + iblockdata.getBlock().dropExperience(this.world, blockposition, event.getExpToDrop()); + } + // CraftBukkit end + + return flag; + } + } + + public boolean useItem(EntityHuman entityhuman, World world, ItemStack itemstack) { + if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { + return false; + } else { + int i = itemstack.count; + int j = itemstack.getData(); + ItemStack itemstack1 = itemstack.a(world, entityhuman); + + if (itemstack1 == itemstack && (itemstack1 == null || itemstack1.count == i && itemstack1.l() <= 0 && itemstack1.getData() == j)) { + return false; + } else { + entityhuman.inventory.items[entityhuman.inventory.itemInHandIndex] = itemstack1; + if (this.isCreative()) { + itemstack1.count = i; + if (itemstack1.e()) { + itemstack1.setData(j); + } + } + + if (itemstack1.count == 0) { + entityhuman.inventory.items[entityhuman.inventory.itemInHandIndex] = null; + } + + if (!entityhuman.bS()) { + ((EntityPlayer) entityhuman).updateInventory(entityhuman.defaultContainer); + } + + return true; + } + } + } + + // CraftBukkit start + public boolean interactResult = false; + public boolean firedInteract = false; + // CraftBukkit end + + public boolean interact(EntityHuman entityhuman, World world, ItemStack itemstack, BlockPosition blockposition, EnumDirection enumdirection, float f, float f1, float f2) { + /* CraftBukkit start - whole method + if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof ITileInventory) { + Block block = world.getType(blockposition).getBlock(); + ITileInventory itileinventory = (ITileInventory) tileentity; + + if (itileinventory instanceof TileEntityChest && block instanceof BlockChest) { + itileinventory = ((BlockChest) block).f(world, blockposition); + } + + if (itileinventory != null) { + entityhuman.openContainer(itileinventory); + return true; + } + } else if (tileentity instanceof IInventory) { + entityhuman.openContainer((IInventory) tileentity); + return true; + } + + return false; + } else { + if (!entityhuman.isSneaking() || entityhuman.bA() == null) { + IBlockData iblockdata = world.getType(blockposition); + + if (iblockdata.getBlock().interact(world, blockposition, iblockdata, entityhuman, enumdirection, f, f1, f2)) { + return true; + } + } + + if (itemstack == null) { + return false; + } else if (this.isCreative()) { + int i = itemstack.getData(); + int j = itemstack.count; + boolean flag = itemstack.placeItem(entityhuman, world, blockposition, enumdirection, f, f1, f2); + + itemstack.setData(i); + itemstack.count = j; + return flag; + } else { + return itemstack.placeItem(entityhuman, world, blockposition, enumdirection, f, f1, f2); + } + } + // Interract event */ + IBlockData blockdata = world.getType(blockposition); + boolean result = false; + if (blockdata.getBlock() != Blocks.AIR) { + boolean cancelledBlock = false; + + if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { + TileEntity tileentity = world.getTileEntity(blockposition); + cancelledBlock = !(tileentity instanceof ITileInventory || tileentity instanceof IInventory); + } + + if (!entityhuman.getBukkitEntity().isOp() && itemstack != null && Block.asBlock(itemstack.getItem()) instanceof BlockCommand) { + cancelledBlock = true; + } + + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(entityhuman, Action.RIGHT_CLICK_BLOCK, blockposition, enumdirection, itemstack, cancelledBlock); + firedInteract = true; + interactResult = event.useItemInHand() == Event.Result.DENY; + + if (event.useInteractedBlock() == Event.Result.DENY) { + // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. + if (blockdata.getBlock() instanceof BlockDoor) { + boolean bottom = blockdata.get(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER; + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, bottom ? blockposition.up() : blockposition.down())); + } + result = (event.useItemInHand() != Event.Result.ALLOW); + } else if (this.gamemode == WorldSettings.EnumGamemode.SPECTATOR) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof ITileInventory) { + Block block = world.getType(blockposition).getBlock(); + ITileInventory itileinventory = (ITileInventory) tileentity; + + if (itileinventory instanceof TileEntityChest && block instanceof BlockChest) { + itileinventory = ((BlockChest) block).f(world, blockposition); + } + + if (itileinventory != null) { + entityhuman.openContainer(itileinventory); + return true; + } + } else if (tileentity instanceof IInventory) { + entityhuman.openContainer((IInventory) tileentity); + return true; + } + + return false; + } else if (!entityhuman.isSneaking() || itemstack == null) { + result = blockdata.getBlock().interact(world, blockposition, blockdata, entityhuman, enumdirection, f, f1, f2); + } + + if (itemstack != null && !result && !interactResult) { // add !interactResult SPIGOT-764 + int j1 = itemstack.getData(); + int k1 = itemstack.count; + + result = itemstack.placeItem(entityhuman, world, blockposition, enumdirection, f, f1, f2); + + // The item count should not decrement in Creative mode. + if (this.isCreative()) { + itemstack.setData(j1); + itemstack.count = k1; + } + } + } + return result; + // CraftBukkit end + } + + public void a(WorldServer worldserver) { + this.world = worldserver; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerInventory.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerInventory.java new file mode 100644 index 0000000..e5aba9a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerInventory.java @@ -0,0 +1,619 @@ +package net.minecraft.server; + +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; + +import java.util.List; +import java.util.concurrent.Callable; +import java.util.logging.Level; + +// CraftBukkit start +// CraftBukkit end + +public class PlayerInventory implements IInventory { + + public ItemStack[] items = new ItemStack[36]; + public ItemStack[] armor = new ItemStack[4]; + public int itemInHandIndex; + public EntityHuman player; + private ItemStack f; + public boolean e; + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public ItemStack[] getArmorContents() { + return this.armor; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public org.bukkit.inventory.InventoryHolder getOwner() { + return this.player.getBukkitEntity(); + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public PlayerInventory(EntityHuman entityhuman) { + this.player = entityhuman; + } + + public ItemStack getItemInHand() { + return this.itemInHandIndex < 9 && this.itemInHandIndex >= 0 ? this.items[this.itemInHandIndex] : null; + } + + public static int getHotbarSize() { + return 9; + } + + private int c(Item item) { + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null && this.items[i].getItem() == item) { + return i; + } + } + + return -1; + } + + private int firstPartial(ItemStack itemstack) { + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null && this.items[i].getItem() == itemstack.getItem() && this.items[i].isStackable() && this.items[i].count < this.items[i].getMaxStackSize() && this.items[i].count < this.getMaxStackSize() && (!this.items[i].usesData() || this.items[i].getData() == itemstack.getData()) && ItemStack.equals(this.items[i], itemstack)) { + return i; + } + } + + return -1; + } + + // CraftBukkit start - Watch method above! :D + public int canHold(ItemStack itemstack) { + int remains = itemstack.count; + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] == null) return itemstack.count; + + // Taken from firstPartial(ItemStack) + if (this.items[i] != null && this.items[i].getItem() == itemstack.getItem() && this.items[i].isStackable() && this.items[i].count < this.items[i].getMaxStackSize() && this.items[i].count < this.getMaxStackSize() && (!this.items[i].usesData() || this.items[i].getData() == itemstack.getData()) && ItemStack.equals(this.items[i], itemstack)) { + remains -= (this.items[i].getMaxStackSize() < this.getMaxStackSize() ? this.items[i].getMaxStackSize() : this.getMaxStackSize()) - this.items[i].count; + } + if (remains <= 0) return itemstack.count; + } + return itemstack.count - remains; + } + // CraftBukkit end + + public int getFirstEmptySlotIndex() { + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] == null) { + return i; + } + } + + return -1; + } + + public int a(Item item, int i, int j, NBTTagCompound nbttagcompound) { + int k = 0; + + int l; + ItemStack itemstack; + int i1; + + for (l = 0; l < this.items.length; ++l) { + itemstack = this.items[l]; + if (itemstack != null && (item == null || itemstack.getItem() == item) && (i <= -1 || itemstack.getData() == i) && (nbttagcompound == null || GameProfileSerializer.a(nbttagcompound, itemstack.getTag(), true))) { + i1 = j <= 0 ? itemstack.count : Math.min(j - k, itemstack.count); + k += i1; + if (j != 0) { + this.items[l].count -= i1; + if (this.items[l].count == 0) { + this.items[l] = null; + } + + if (j > 0 && k >= j) { + return k; + } + } + } + } + + for (l = 0; l < this.armor.length; ++l) { + itemstack = this.armor[l]; + if (itemstack != null && (item == null || itemstack.getItem() == item) && (i <= -1 || itemstack.getData() == i) && (nbttagcompound == null || GameProfileSerializer.a(nbttagcompound, itemstack.getTag(), false))) { + i1 = j <= 0 ? itemstack.count : Math.min(j - k, itemstack.count); + k += i1; + if (j != 0) { + this.armor[l].count -= i1; + if (this.armor[l].count == 0) { + this.player.setEquipment(l, null); + } + + if (j > 0 && k >= j) { + return k; + } + } + } + } + + if (this.f != null) { + if (item != null && this.f.getItem() != item) { + return k; + } + + if (i > -1 && this.f.getData() != i) { + return k; + } + + if (nbttagcompound != null && !GameProfileSerializer.a(nbttagcompound, this.f.getTag(), false)) { + return k; + } + + l = j <= 0 ? this.f.count : Math.min(j - k, this.f.count); + k += l; + if (j != 0) { + this.f.count -= l; + if (this.f.count == 0) { + this.f = null; + } + + if (j > 0 && k >= j) { + return k; + } + } + } + + return k; + } + + private int e(ItemStack itemstack) { + Item item = itemstack.getItem(); + int i = itemstack.count; + int j = this.firstPartial(itemstack); + + if (j < 0) { + j = this.getFirstEmptySlotIndex(); + } + + if (j < 0) { + return i; + } else { + if (this.items[j] == null) { + this.items[j] = new ItemStack(item, 0, itemstack.getData()); + if (itemstack.hasTag()) { + this.items[j].setTag((NBTTagCompound) itemstack.getTag().clone()); + } + } + + int k = i; + + if (i > this.items[j].getMaxStackSize() - this.items[j].count) { + k = this.items[j].getMaxStackSize() - this.items[j].count; + } + + if (k > this.getMaxStackSize() - this.items[j].count) { + k = this.getMaxStackSize() - this.items[j].count; + } + + if (k == 0) { + return i; + } else { + i -= k; + this.items[j].count += k; + this.items[j].c = 5; + return i; + } + } + } + + public void k() { + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + this.items[i].a(this.player.world, this.player, i, this.itemInHandIndex == i); + } + } + + } + + public boolean a(Item item) { + int i = this.c(item); + + if (i < 0) { + return false; + } else { + if (--this.items[i].count <= 0) { + this.items[i] = null; + } + + return true; + } + } + + public boolean b(Item item) { + int i = this.c(item); + + return i >= 0; + } + + public boolean pickup(final ItemStack itemstack) { + if (itemstack != null && itemstack.count != 0 && itemstack.getItem() != null) { + try { + int i; + + if (itemstack.g()) { + i = this.getFirstEmptySlotIndex(); + if (i >= 0) { + this.items[i] = ItemStack.b(itemstack); + this.items[i].c = 5; + itemstack.count = 0; + return true; + } else if (this.player.abilities.canInstantlyBuild) { + itemstack.count = 0; + return true; + } else { + return false; + } + } else { + do { + i = itemstack.count; + itemstack.count = this.e(itemstack); + } while (itemstack.count > 0 && itemstack.count < i); + + if (itemstack.count == i && this.player.abilities.canInstantlyBuild) { + itemstack.count = 0; + return true; + } else { + return itemstack.count < i; + } + } + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Adding item to inventory"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Item being added"); + + crashreportsystemdetails.a("Item ID", Integer.valueOf(Item.getId(itemstack.getItem()))); + crashreportsystemdetails.a("Item data", Integer.valueOf(itemstack.getData())); + crashreportsystemdetails.a("Item name", new Callable() { + public String a() throws Exception { + return itemstack.getName(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + return false; + } + throw new ReportedException(crashreport); + } + } else { + return false; + } + } + + public ItemStack splitStack(int i, int j) { + ItemStack[] aitemstack = this.items; + + boolean settingArmour = i >= this.items.length; + if (settingArmour) { + aitemstack = this.armor; + i -= this.items.length; + } + + if (aitemstack[i] != null) { + ItemStack itemstack; + + if (aitemstack[i].count <= j) { + itemstack = aitemstack[i]; + if (settingArmour) { + player.setEquipment(i, null); + } else { + aitemstack[i] = null; + } + } else { + itemstack = aitemstack[i].cloneAndSubtract(j); + if (aitemstack[i].count == 0) { + if (settingArmour) { + player.setEquipment(i, null); + } else { + aitemstack[i] = null; + } + } + + } + return itemstack; + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + ItemStack[] aitemstack = this.items; + + boolean settingArmour = i >= this.items.length; + if (settingArmour) { + aitemstack = this.armor; + i -= this.items.length; + } + + if (aitemstack[i] != null) { + ItemStack itemstack = aitemstack[i]; + + if (settingArmour) { + player.setEquipment(i, null); + } else { + aitemstack[i] = null; + } + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + ItemStack[] aitemstack = this.items; + + if (i >= aitemstack.length) { + i -= aitemstack.length; + player.setEquipment(i, itemstack); + } else { + aitemstack[i] = itemstack; + } + } + + public float a(Block block) { + float f = 1.0F; + + if (this.items[this.itemInHandIndex] != null) { + f *= this.items[this.itemInHandIndex].a(block); + } + + return f; + } + + public NBTTagList a(NBTTagList nbttaglist) { + int i; + NBTTagCompound nbttagcompound; + + for (i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + nbttagcompound = new NBTTagCompound(); + nbttagcompound.setByte("Slot", (byte) i); + this.items[i].save(nbttagcompound); + nbttaglist.add(nbttagcompound); + } + } + + for (i = 0; i < this.armor.length; ++i) { + if (this.armor[i] != null) { + nbttagcompound = new NBTTagCompound(); + nbttagcompound.setByte("Slot", (byte) (i + 100)); + this.armor[i].save(nbttagcompound); + nbttaglist.add(nbttagcompound); + } + } + + return nbttaglist; + } + + public void b(NBTTagList nbttaglist) { + this.items = new ItemStack[36]; + this.armor = new ItemStack[4]; + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound = nbttaglist.get(i); + int j = nbttagcompound.getByte("Slot") & 255; + ItemStack itemstack = ItemStack.createStack(nbttagcompound); + + if (itemstack != null) { + if (j >= 0 && j < this.items.length) { + this.items[j] = itemstack; + } + + if (j >= 100 && j < this.armor.length + 100) { + this.player.setEquipment(j - 100, itemstack); + } + } + } + + } + + public int getSize() { + return this.items.length + 4; + } + + public ItemStack getItem(int i) { + ItemStack[] aitemstack = this.items; + + if (i >= aitemstack.length) { + i -= aitemstack.length; + aitemstack = this.armor; + } + + return aitemstack[i]; + } + + public String getName() { + return "container.inventory"; + } + + public boolean hasCustomName() { + return false; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return this.hasCustomName() ? new ChatComponentText(this.getName()) : new ChatMessage(this.getName(), new Object[0]); + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public boolean b(Block block) { + if (block.getMaterial().isAlwaysDestroyable()) { + return true; + } else { + ItemStack itemstack = this.getItem(this.itemInHandIndex); + + return itemstack != null && itemstack.b(block); + } + } + + public ItemStack e(int i) { + return this.armor[i]; + } + + public int m() { + int i = 0; + + for (int j = 0; j < this.armor.length; ++j) { + if (this.armor[j] != null && this.armor[j].getItem() instanceof ItemArmor) { + int k = ((ItemArmor) this.armor[j].getItem()).c; + + i += k; + } + } + + return i; + } + + public void a(float f) { + f /= 4.0F; + if (f < 1.0F) { + f = 1.0F; + } + + for (int i = 0; i < this.armor.length; ++i) { + if (this.armor[i] != null && this.armor[i].getItem() instanceof ItemArmor) { + this.armor[i].damage((int) f, this.player); + if (this.armor[i].count == 0) { + this.player.setEquipment(i, null); + } + } + } + + } + + public void n() { + int i; + + for (i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + this.player.a(this.items[i], true, false); + this.items[i] = null; + } + } + + for (i = 0; i < this.armor.length; ++i) { + if (this.armor[i] != null) { + this.player.a(this.armor[i], true, false); + this.player.setEquipment(i, null); + } + } + + } + + public void update() { + this.e = true; + } + + public void setCarried(ItemStack itemstack) { + this.f = itemstack; + } + + public ItemStack getCarried() { + // CraftBukkit start + if (this.f != null && this.f.count == 0) { + this.setCarried(null); + } + // CraftBukkit end + return this.f; + } + + public boolean a(EntityHuman entityhuman) { + return !this.player.dead && entityhuman.h(this.player) <= 64.0D; + } + + public boolean c(ItemStack itemstack) { + int i; + + for (i = 0; i < this.armor.length; ++i) { + if (this.armor[i] != null && this.armor[i].doMaterialsMatch(itemstack)) { + return true; + } + } + + for (i = 0; i < this.items.length; ++i) { + if (this.items[i] != null && this.items[i].doMaterialsMatch(itemstack)) { + return true; + } + } + + return false; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public void b(PlayerInventory playerinventory) { + int i; + + for (i = 0; i < this.items.length; ++i) { + this.items[i] = ItemStack.b(playerinventory.items[i]); + } + + for (i = 0; i < this.armor.length; ++i) { + this.player.setEquipment(i, ItemStack.b(playerinventory.armor[i])); + } + + this.itemInHandIndex = playerinventory.itemInHandIndex; + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public void l() { + int i; + + for (i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + for (i = 0; i < this.armor.length; ++i) { + this.armor[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerList.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerList.java new file mode 100644 index 0000000..2680d74 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PlayerList.java @@ -0,0 +1,1316 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Queues; +import com.google.common.collect.Sets; +import com.mojang.authlib.GameProfile; +import io.netty.buffer.Unpooled; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.login.Login; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.TravelAgent; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor; +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.entity.Player; +import org.bukkit.event.player.*; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.util.Vector; +import org.spigotmc.event.player.PlayerSpawnLocationEvent; + +import java.io.File; +import java.net.SocketAddress; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; + +// CraftBukkit start +// CraftBukkit end + +public abstract class PlayerList { + + public static final File a = new File("banned-players.json"); + public static final File b = new File("banned-ips.json"); + public static final File c = new File("ops.json"); + public static final File d = new File("whitelist.json"); + private static final Logger f = LogManager.getLogger(); + private static final SimpleDateFormat g = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); + private final MinecraftServer server; + public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety + private final Map j = Maps.newHashMap(); + private final GameProfileBanList k; + private final IpBanList l; + private final OpList operators; + private final WhiteList whitelist; + private final Map o; + public IPlayerFileData playerFileData; + private boolean hasWhitelist; + protected int maxPlayers; + private int r; + private WorldSettings.EnumGamemode s; + private boolean t; + private int u; + + // CraftBukkit start + private CraftServer cserver; + private final Map playersByName = new org.spigotmc.CaseInsensitiveMap(); + + public PlayerList(MinecraftServer minecraftserver) { + this.cserver = minecraftserver.server = new CraftServer(minecraftserver, this); + minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance(); + minecraftserver.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(minecraftserver.server)); + // CraftBukkit end + + this.k = new GameProfileBanList(PlayerList.a); + this.l = new IpBanList(PlayerList.b); + this.operators = new OpList(PlayerList.c); + this.whitelist = new WhiteList(PlayerList.d); + this.o = Maps.newHashMap(); + this.server = minecraftserver; + this.k.a(false); + this.l.a(false); + this.maxPlayers = 8; + } + + private final ConcurrentLinkedQueue loginQueue = Queues.newConcurrentLinkedQueue(); + private int lastLoginTick, logins; + + // Mythic - Process logins + public void processLogins() { + logins = 0; + + Login login; + for(int i = 0; i < MythicConfiguration.Options.Server.loginsPerTick; i++) { + login = loginQueue.poll(); + if(login == null) break; + + _a(login.getNetworkManager(), login.getEntityPlayer()); + } + } + + // Mythic - Limit logins per tick + public void a(NetworkManager manager, EntityPlayer player) { + if(lastLoginTick == MinecraftServer.currentTick && logins >= MythicConfiguration.Options.Server.loginsPerTick) { + loginQueue.add(new Login(manager, player)); + } else _a(manager, player); + } + + // Mythic - a -> _a for limiting logins per tick + private void _a(NetworkManager networkmanager, EntityPlayer entityplayer) { + lastLoginTick = MinecraftServer.currentTick; + logins++; + + GameProfile gameprofile = entityplayer.getProfile(); + UserCache usercache = this.server.getUserCache(); + GameProfile gameprofile1 = usercache.a(gameprofile.getId()); + String s = gameprofile1 == null ? gameprofile.getName() : gameprofile1.getName(); + + usercache.a(gameprofile); + NBTTagCompound nbttagcompound = this.a(entityplayer); + // CraftBukkit start - Better rename detection + if (nbttagcompound != null && nbttagcompound.hasKey("bukkit")) { + NBTTagCompound bukkit = nbttagcompound.getCompound("bukkit"); + s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s; + } + // CraftBukkit end + + // PaperSpigot start - support PlayerInitialSpawnEvent + Location originalLoc = new Location(entityplayer.world.getWorld(), entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch); + org.bukkit.event.player.PlayerInitialSpawnEvent event = new org.bukkit.event.player.PlayerInitialSpawnEvent(entityplayer.getBukkitEntity(), originalLoc); + this.server.server.getPluginManager().callEvent(event); + + Location newLoc = event.getSpawnLocation(); + entityplayer.world = ((CraftWorld) newLoc.getWorld()).getHandle(); + entityplayer.locX = newLoc.getX(); + entityplayer.locY = newLoc.getY(); + entityplayer.locZ = newLoc.getZ(); + entityplayer.yaw = newLoc.getYaw(); + entityplayer.pitch = newLoc.getPitch(); + entityplayer.dimension = ((CraftWorld) newLoc.getWorld()).getHandle().dimension; + entityplayer.spawnWorld = entityplayer.world.worldData.getName(); + // PaperSpigot end + + entityplayer.spawnIn(this.server.getWorldServer(entityplayer.dimension)); + entityplayer.playerInteractManager.a((WorldServer) entityplayer.world); + String s1 = "local"; + + if (networkmanager.getSocketAddress() != null) { + s1 = networkmanager.getSocketAddress().toString(); + } + + // Spigot start - spawn location event + Player bukkitPlayer = entityplayer.getBukkitEntity(); + PlayerSpawnLocationEvent ev = new PlayerSpawnLocationEvent(bukkitPlayer, bukkitPlayer.getLocation()); + Bukkit.getPluginManager().callEvent(ev); + + Location loc = ev.getSpawnLocation(); + WorldServer world = ((CraftWorld) loc.getWorld()).getHandle(); + + entityplayer.spawnIn(world); + entityplayer.setPosition(loc.getX(), loc.getY(), loc.getZ()); + entityplayer.setYawPitch(loc.getYaw(), loc.getPitch()); + // Spigot end + + // CraftBukkit - Moved message to after join + // PlayerList.f.info(entityplayer.getName() + "[" + s1 + "] logged in with entity id " + entityplayer.getId() + " at (" + entityplayer.locX + ", " + entityplayer.locY + ", " + entityplayer.locZ + ")"); + WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); + WorldData worlddata = worldserver.getWorldData(); + BlockPosition blockposition = worldserver.getSpawn(); + + this.a(entityplayer, null, worldserver); + PlayerConnection playerconnection = new PlayerConnection(this.server, networkmanager, entityplayer); + + playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), worlddata.isHardcore(), worldserver.worldProvider.getDimension(), worldserver.getDifficulty(), Math.min(this.getMaxPlayers(), 60), worlddata.getType(), worldserver.getGameRules().getBoolean("reducedDebugInfo"))); // CraftBukkit - cap player list to 60 + entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit + playerconnection.sendPacket(new PacketPlayOutCustomPayload("MC|Brand", (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName()))); + playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + playerconnection.sendPacket(new PacketPlayOutSpawnPosition(blockposition)); + playerconnection.sendPacket(new PacketPlayOutAbilities(entityplayer.abilities)); + playerconnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex)); + entityplayer.getStatisticManager().d(); + entityplayer.getStatisticManager().updateStatistics(entityplayer); + this.sendScoreboard((ScoreboardServer) worldserver.getScoreboard(), entityplayer); + this.server.aH(); + // CraftBukkit start - login message is handled in the event + // ChatMessage chatmessage; + + String joinMessage; + if (!entityplayer.getName().equalsIgnoreCase(s)) { + // chatmessage = new ChatMessage("multiplayer.player.joined.renamed", new Object[] { entityplayer.getScoreboardDisplayName(), s}); + joinMessage = "\u00A7e" + LocaleI18n.a("multiplayer.player.joined.renamed", entityplayer.getName(), s); + } else { + // chatmessage = new ChatMessage("multiplayer.player.joined", new Object[] { entityplayer.getScoreboardDisplayName()}); + joinMessage = "\u00A7e" + LocaleI18n.a("multiplayer.player.joined", entityplayer.getName()); + } + + // chatmessage.getChatModifier().setColor(EnumChatFormat.YELLOW); + // this.sendMessage(chatmessage); + this.onPlayerJoin(entityplayer, joinMessage); + // CraftBukkit end + worldserver = server.getWorldServer(entityplayer.dimension); // CraftBukkit - Update in case join event changed it + playerconnection.a(entityplayer.locX, entityplayer.locY, entityplayer.locZ, entityplayer.yaw, entityplayer.pitch); + this.b(entityplayer, worldserver); + if (this.server.getResourcePack().length() > 0) { + entityplayer.setResourcePack(this.server.getResourcePack(), this.server.getResourcePackHash()); + } + + Iterator iterator = entityplayer.getEffects().iterator(); + + while (iterator.hasNext()) { + MobEffect mobeffect = (MobEffect) iterator.next(); + + playerconnection.sendPacket(new PacketPlayOutEntityEffect(entityplayer.getId(), mobeffect)); + } + + entityplayer.syncInventory(); + if (nbttagcompound != null && nbttagcompound.hasKeyOfType("Riding", 10)) { + Entity entity = EntityTypes.a(nbttagcompound.getCompound("Riding"), worldserver); + + if (entity != null) { + entity.attachedToPlayer = true; + worldserver.addEntity(entity); + entityplayer.mount(entity); + entity.attachedToPlayer = false; + } + } + + // CraftBukkit - Moved from above, added world + PlayerList.f.info(entityplayer.getName() + "[" + s1 + "] logged in with entity id " + entityplayer.getId() + " at ([" + entityplayer.world.worldData.getName() + "]" + entityplayer.locX + ", " + entityplayer.locY + ", " + entityplayer.locZ + ")"); + } + + public void sendScoreboard(ScoreboardServer scoreboardserver, EntityPlayer entityplayer) { + HashSet hashset = Sets.newHashSet(); + Iterator iterator = scoreboardserver.getTeams().iterator(); + + while (iterator.hasNext()) { + ScoreboardTeam scoreboardteam = (ScoreboardTeam) iterator.next(); + + entityplayer.playerConnection.sendPacket(new PacketPlayOutScoreboardTeam(scoreboardteam, 0)); + } + + for (int i = 0; i < 19; ++i) { + ScoreboardObjective scoreboardobjective = scoreboardserver.getObjectiveForSlot(i); + + if (scoreboardobjective != null && !hashset.contains(scoreboardobjective)) { + List list = scoreboardserver.getScoreboardScorePacketsForObjective(scoreboardobjective); + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { + Packet packet = (Packet) iterator1.next(); + + entityplayer.playerConnection.sendPacket(packet); + } + + hashset.add(scoreboardobjective); + } + } + + } + + public void setPlayerFileData(WorldServer[] aworldserver) { + if (playerFileData != null) return; // CraftBukkit + this.playerFileData = aworldserver[0].getDataManager().getPlayerFileData(); + aworldserver[0].getWorldBorder().a(new IWorldBorderListener() { + public void a(WorldBorder worldborder, double d0) { + PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_SIZE)); + } + + public void a(WorldBorder worldborder, double d0, double d1, long i) { + PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.LERP_SIZE)); + } + + public void a(WorldBorder worldborder, double d0, double d1) { + PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_CENTER)); + } + + public void a(WorldBorder worldborder, int i) { + PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_WARNING_TIME)); + } + + public void b(WorldBorder worldborder, int i) { + PlayerList.this.sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_WARNING_BLOCKS)); + } + + public void b(WorldBorder worldborder, double d0) {} + + public void c(WorldBorder worldborder, double d0) {} + }); + } + + public void a(EntityPlayer entityplayer, WorldServer worldserver) { + WorldServer worldserver1 = entityplayer.u(); + + if (worldserver != null) { + worldserver.getPlayerChunkMap().removePlayer(entityplayer); + } + + worldserver1.getPlayerChunkMap().addPlayer(entityplayer); + worldserver1.chunkProviderServer.getChunkAt((int) entityplayer.locX >> 4, (int) entityplayer.locZ >> 4); + } + + public int d() { + return PlayerChunkMap.getFurthestViewableBlock(this.s()); + } + + public NBTTagCompound a(EntityPlayer entityplayer) { + NBTTagCompound nbttagcompound = this.server.worlds.get(0).getWorldData().i(); // CraftBukkit + NBTTagCompound nbttagcompound1; + + if (entityplayer.getName().equals(this.server.S()) && nbttagcompound != null) { + entityplayer.f(nbttagcompound); + nbttagcompound1 = nbttagcompound; + PlayerList.f.debug("loading single player"); + } else { + nbttagcompound1 = this.playerFileData.load(entityplayer); + } + + return nbttagcompound1; + } + + protected void savePlayerFile(EntityPlayer entityplayer) { + if(!MythicConfiguration.Options.Server.Players.save) return; + + this.playerFileData.save(entityplayer); + ServerStatisticManager serverstatisticmanager = this.o.get(entityplayer.getUniqueID()); + + if (serverstatisticmanager != null) { + serverstatisticmanager.b(); + } + + } + + public void onPlayerJoin(EntityPlayer entityplayer, String joinMessage) { // CraftBukkit added param + this.players.add(entityplayer); + this.playersByName.put(entityplayer.getName(), entityplayer); // Spigot + this.j.put(entityplayer.getUniqueID(), entityplayer); + // this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, new EntityPlayer[] { entityplayer})); // CraftBukkit - replaced with loop below + WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); + + // CraftBukkit start + PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage); + cserver.getPluginManager().callEvent(playerJoinEvent); + + joinMessage = playerJoinEvent.getJoinMessage(); + + if (joinMessage != null && joinMessage.length() > 0) { + for (IChatBaseComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) { + server.getPlayerList().sendAll(new PacketPlayOutChat(line)); + } + } + + ChunkIOExecutor.adjustPoolSize(getPlayerCount()); + // CraftBukkit end + + // CraftBukkit start - sendAll above replaced with this loop + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, entityplayer); + + for (int i = 0; i < this.players.size(); ++i) { + EntityPlayer entityplayer1 = this.players.get(i); + + if (entityplayer1.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { + entityplayer1.playerConnection.sendPacket(packet); + } + + if (!entityplayer.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) { + continue; + } + + entityplayer.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, entityplayer1)); + } + // CraftBukkit end + + // CraftBukkit start - Only add if the player wasn't moved in the event + if (entityplayer.world == worldserver && !worldserver.players.contains(entityplayer)) { + worldserver.addEntity(entityplayer); + this.a(entityplayer, (WorldServer) null); + } + // CraftBukkit end + } + + public void d(EntityPlayer entityplayer) { + entityplayer.u().getPlayerChunkMap().movePlayer(entityplayer); + } + + public String disconnect(EntityPlayer entityplayer) { // CraftBukkit - return string + entityplayer.b(StatisticList.f); + + // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it + org.bukkit.craftbukkit.event.CraftEventFactory.handleInventoryCloseEvent(entityplayer); + + PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(entityplayer), null); + cserver.getPluginManager().callEvent(playerQuitEvent); + entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); + // CraftBukkit end + + this.savePlayerFile(entityplayer); + WorldServer worldserver = entityplayer.u(); + + if (entityplayer.vehicle != null && !(entityplayer.vehicle instanceof EntityPlayer)) { // CraftBukkit - Don't remove players + worldserver.removeEntity(entityplayer.vehicle); + PlayerList.f.debug("removing player mount"); + } + + worldserver.kill(entityplayer); + worldserver.getPlayerChunkMap().removePlayer(entityplayer); + this.players.remove(entityplayer); + this.playersByName.remove(entityplayer.getName()); // Spigot + UUID uuid = entityplayer.getUniqueID(); + EntityPlayer entityplayer1 = this.j.get(uuid); + + if (entityplayer1 == entityplayer) { + this.j.remove(uuid); + this.o.remove(uuid); + } + + // CraftBukkit start + // this.sendAll(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[] { entityplayer})); + PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, entityplayer); + for (int i = 0; i < players.size(); i++) { + EntityPlayer entityplayer2 = this.players.get(i); + + if (entityplayer2.getBukkitEntity().canSee(entityplayer.getBukkitEntity())) { + entityplayer2.playerConnection.sendPacket(packet); + } else { + entityplayer2.getBukkitEntity().removeDisconnectingPlayer(entityplayer.getBukkitEntity()); + } + } + // This removes the scoreboard (and player reference) for the specific player in the manager + cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity()); + // CraftBukkit end + + ChunkIOExecutor.adjustPoolSize(this.getPlayerCount()); // CraftBukkit + + return playerQuitEvent.getQuitMessage(); // CraftBukkit + } + + // CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer + public EntityPlayer attemptLogin(LoginListener loginlistener, GameProfile gameprofile, String hostname) { + // Moved from processLogin + UUID uuid = EntityHuman.a(gameprofile); + ArrayList arraylist = Lists.newArrayList(); + + EntityPlayer entityplayer; + + for (int i = 0; i < this.players.size(); ++i) { + entityplayer = this.players.get(i); + if (entityplayer.getUniqueID().equals(uuid)) { + arraylist.add(entityplayer); + } + } + + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + entityplayer = (EntityPlayer) iterator.next(); + savePlayerFile(entityplayer); // CraftBukkit - Force the player's inventory to be saved + entityplayer.playerConnection.disconnect("You logged in from another location"); + } + + // Instead of kicking then returning, we need to store the kick reason + // in the event, check with plugins to see if it's ok, and THEN kick + // depending on the outcome. + SocketAddress socketaddress = loginlistener.networkManager.getSocketAddress(); + + EntityPlayer entity = new EntityPlayer(server, server.getWorldServer(0), gameprofile, new PlayerInteractManager(server.getWorldServer(0))); + Player player = entity.getBukkitEntity(); + PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress()); + String s; + + if (getProfileBans().isBanned(gameprofile) && !getProfileBans().get(gameprofile).hasExpired()) { + GameProfileBanEntry gameprofilebanentry = this.k.get(gameprofile); + + s = "You are banned from this server!\nReason: " + gameprofilebanentry.getReason(); + if (gameprofilebanentry.getExpires() != null) { + s = s + "\nYour ban will be removed on " + PlayerList.g.format(gameprofilebanentry.getExpires()); + } + + // return s; + if (!gameprofilebanentry.hasExpired()) event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s); // Spigot + } else if (!this.isWhitelisted(gameprofile)) { + // return "You are not white-listed on this server!"; + event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot + } else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) { + IpBanEntry ipbanentry = this.l.get(socketaddress); + + s = "Your IP address is banned from this server!\nReason: " + ipbanentry.getReason(); + if (ipbanentry.getExpires() != null) { + s = s + "\nYour ban will be removed on " + PlayerList.g.format(ipbanentry.getExpires()); + } + + // return s; + event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s); + } else { + // return this.players.size() >= this.maxPlayers && !this.f(gameprofile) ? "The server is full!" : null; + if (this.players.size() >= this.maxPlayers && !this.f(gameprofile)) { + event.disallow(PlayerLoginEvent.Result.KICK_FULL, org.spigotmc.SpigotConfig.serverFullMessage); // Spigot + } + } + + cserver.getPluginManager().callEvent(event); + if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { + loginlistener.disconnect(event.getKickMessage()); + return null; + } + return entity; + } + + public EntityPlayer processLogin(GameProfile gameprofile, EntityPlayer player) { // CraftBukkit - added EntityPlayer + /* CraftBukkit startMoved up + UUID uuid = EntityHuman.a(gameprofile); + ArrayList arraylist = Lists.newArrayList(); + + for (int i = 0; i < this.players.size(); ++i) { + EntityPlayer entityplayer = (EntityPlayer) this.players.get(i); + + if (entityplayer.getUniqueID().equals(uuid)) { + arraylist.add(entityplayer); + } + } + + EntityPlayer entityplayer1 = (EntityPlayer) this.j.get(gameprofile.getId()); + + if (entityplayer1 != null && !arraylist.contains(entityplayer1)) { + arraylist.add(entityplayer1); + } + + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer2 = (EntityPlayer) iterator.next(); + + entityplayer2.playerConnection.disconnect("You logged in from another location"); + } + + Object object; + + if (this.server.X()) { + object = new DemoPlayerInteractManager(this.server.getWorldServer(0)); + } else { + object = new PlayerInteractManager(this.server.getWorldServer(0)); + } + + return new EntityPlayer(this.server, this.server.getWorldServer(0), gameprofile, (PlayerInteractManager) object); + */ + return player; + // CraftBukkit end + } + + // CraftBukkit start + public EntityPlayer moveToWorld(EntityPlayer entityplayer, int i, boolean flag) { + return this.moveToWorld(entityplayer, i, flag, null, true); + } + public EntityPlayer moveToWorld(EntityPlayer entityplayer, int i, boolean flag, Location location, boolean avoidSuffocation) { + entityplayer.u().getTracker().untrackPlayer(entityplayer); + // entityplayer.u().getTracker().untrackEntity(entityplayer); // CraftBukkit + entityplayer.u().getPlayerChunkMap().removePlayer(entityplayer); + this.players.remove(entityplayer); + this.playersByName.remove(entityplayer.getName()); // Spigot + this.server.getWorldServer(entityplayer.dimension).removeEntity(entityplayer); + BlockPosition blockposition = entityplayer.getBed(); + boolean flag1 = entityplayer.isRespawnForced(); + + /* CraftBukkit start + entityplayer.dimension = i; + Object object; + + if (this.server.X()) { + object = new DemoPlayerInteractManager(this.server.getWorldServer(entityplayer.dimension)); + } else { + object = new PlayerInteractManager(this.server.getWorldServer(entityplayer.dimension)); + } + + EntityPlayer entityplayer1 = new EntityPlayer(this.server, this.server.getWorldServer(entityplayer.dimension), entityplayer.getProfile(), (PlayerInteractManager) object); + // */ + EntityPlayer entityplayer1 = entityplayer; + org.bukkit.World fromWorld = entityplayer.getBukkitEntity().getWorld(); + entityplayer.viewingCredits = false; + // CraftBukkit end + + entityplayer1.playerConnection = entityplayer.playerConnection; + entityplayer1.copyTo(entityplayer, flag); + entityplayer1.d(entityplayer.getId()); + entityplayer1.o(entityplayer); + // WorldServer worldserver = this.server.getWorldServer(entityplayer.dimension); // CraftBukkit - handled later + + // this.a(entityplayer1, entityplayer, worldserver); // CraftBukkit - removed + BlockPosition blockposition1; + + // CraftBukkit start - fire PlayerRespawnEvent + if (location == null) { + boolean isBedSpawn = false; + CraftWorld cworld = (CraftWorld) this.server.server.getWorld(entityplayer.spawnWorld); + if (cworld != null && blockposition != null) { + blockposition1 = EntityHuman.getBed(cworld.getHandle(), blockposition, flag1); + if (blockposition1 != null) { + isBedSpawn = true; + location = new Location(cworld, blockposition1.getX() + 0.5, blockposition1.getY(), blockposition1.getZ() + 0.5); + } else { + entityplayer1.setRespawnPosition(null, true); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutGameStateChange(0, 0.0F)); + } + } + + if (location == null) { + cworld = (CraftWorld) this.server.server.getWorlds().get(0); + blockposition = cworld.getHandle().getSpawn(); + location = new Location(cworld, blockposition.getX() + 0.5, blockposition.getY(), blockposition.getZ() + 0.5); + } + + Player respawnPlayer = cserver.getPlayer(entityplayer1); + PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn); + cserver.getPluginManager().callEvent(respawnEvent); + // Spigot Start + if (entityplayer.playerConnection.isDisconnected()) { + return entityplayer; + } + // Spigot End + + location = respawnEvent.getRespawnLocation(); + entityplayer.reset(); + } else { + location.setWorld(server.getWorldServer(i).getWorld()); + } + WorldServer worldserver = ((CraftWorld) location.getWorld()).getHandle(); + entityplayer1.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + // CraftBukkit end + + worldserver.chunkProviderServer.getChunkAt((int) entityplayer1.locX >> 4, (int) entityplayer1.locZ >> 4); + + while (avoidSuffocation && !worldserver.getCubes(entityplayer1, entityplayer1.getBoundingBox()).isEmpty() && entityplayer1.locY < 256.0D) { + entityplayer1.setPosition(entityplayer1.locX, entityplayer1.locY + 1.0D, entityplayer1.locZ); + } + // CraftBukkit start + byte actualDimension = (byte) (worldserver.getWorld().getEnvironment().getId()); + // Force the client to refresh their chunk cache + if (fromWorld.getEnvironment() == worldserver.getWorld().getEnvironment()) { + entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn((byte) (actualDimension >= 0 ? -1 : 0), worldserver.getDifficulty(), worldserver.getWorldData().getType(), entityplayer.playerInteractManager.getGameMode())); + } + entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(actualDimension, worldserver.getDifficulty(), worldserver.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode())); + entityplayer1.spawnIn(worldserver); + entityplayer1.dead = false; + entityplayer1.playerConnection.teleport(new Location(worldserver.getWorld(), entityplayer1.locX, entityplayer1.locY, entityplayer1.locZ, entityplayer1.yaw, entityplayer1.pitch)); + entityplayer1.setSneaking(false); + blockposition1 = worldserver.getSpawn(); + // entityplayer1.playerConnection.a(entityplayer1.locX, entityplayer1.locY, entityplayer1.locZ, entityplayer1.yaw, entityplayer1.pitch); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutSpawnPosition(blockposition1)); + entityplayer1.playerConnection.sendPacket(new PacketPlayOutExperience(entityplayer1.exp, entityplayer1.expTotal, entityplayer1.expLevel)); + this.b(entityplayer1, worldserver); + + if (!entityplayer.playerConnection.isDisconnected()) { + worldserver.getPlayerChunkMap().addPlayer(entityplayer1); + worldserver.addEntity(entityplayer1); + this.players.add(entityplayer1); + this.playersByName.put(entityplayer1.getName(), entityplayer1); // Spigot + this.j.put(entityplayer1.getUniqueID(), entityplayer1); + } + // Added from changeDimension + updateClient(entityplayer); // Update health, etc... + entityplayer.updateAbilities(); + for (Object o1 : entityplayer.getEffects()) { + MobEffect mobEffect = (MobEffect) o1; + entityplayer.playerConnection.sendPacket(new PacketPlayOutEntityEffect(entityplayer.getId(), mobEffect)); + } + // entityplayer1.syncInventory(); + // CraftBukkit end + entityplayer1.setHealth(entityplayer1.getHealth()); + + // CraftBukkit start + // Don't fire on respawn + if (fromWorld != location.getWorld()) { + PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(entityplayer.getBukkitEntity(), fromWorld); + server.server.getPluginManager().callEvent(event); + } + + // Save player file again if they were disconnected + if (entityplayer.playerConnection.isDisconnected()) { + this.savePlayerFile(entityplayer); + } + // CraftBukkit end + return entityplayer1; + } + + // CraftBukkit start - Replaced the standard handling of portals with a more customised method. + public void changeDimension(EntityPlayer entityplayer, int i, TeleportCause cause) { + WorldServer exitWorld = null; + if (entityplayer.dimension < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // plugins must specify exit from custom Bukkit worlds + // only target existing worlds (compensate for allow-nether/allow-end as false) + for (WorldServer world : this.server.worlds) { + if (world.dimension == i) { + exitWorld = world; + } + } + } + + Location enter = entityplayer.getBukkitEntity().getLocation(); + Location exit = null; + boolean useTravelAgent = false; // don't use agent for custom worlds or return from THE_END + if (exitWorld != null) { + if ((cause == TeleportCause.END_PORTAL) && (i == 0)) { + // THE_END -> NORMAL; use bed if available, otherwise default spawn + exit = entityplayer.getBukkitEntity().getBedSpawnLocation(); + if (exit == null || ((CraftWorld) exit.getWorld()).getHandle().dimension != 0) { + exit = exitWorld.getWorld().getSpawnLocation(); + } + } else { + // NORMAL <-> NETHER or NORMAL -> THE_END + exit = this.calculateTarget(enter, exitWorld); + useTravelAgent = true; + } + } + + TravelAgent agent = exit != null ? (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().getTravelAgent() : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins + agent.setCanCreatePortal(cause != TeleportCause.END_PORTAL); // PaperSpigot - Configurable end credits, don't allow End Portals to create portals + + PlayerPortalEvent event = new PlayerPortalEvent(entityplayer.getBukkitEntity(), enter, exit, agent, cause); + event.useTravelAgent(useTravelAgent); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled() || event.getTo() == null) { + return; + } + + // PaperSpigot - Configurable end credits, if a plugin sets to use a travel agent even if the cause is an end portal, ignore it + exit = cause != TeleportCause.END_PORTAL && event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo(); + if (exit == null) { + return; + } + exitWorld = ((CraftWorld) exit.getWorld()).getHandle(); + + org.bukkit.event.player.PlayerTeleportEvent tpEvent = new org.bukkit.event.player.PlayerTeleportEvent(entityplayer.getBukkitEntity(), enter, exit, cause); + Bukkit.getServer().getPluginManager().callEvent(tpEvent); + if (tpEvent.isCancelled() || tpEvent.getTo() == null) { + return; + } + + Vector velocity = entityplayer.getBukkitEntity().getVelocity(); + boolean before = exitWorld.chunkProviderServer.forceChunkLoad; + exitWorld.chunkProviderServer.forceChunkLoad = true; + exitWorld.getTravelAgent().adjustExit(entityplayer, exit, velocity); + exitWorld.chunkProviderServer.forceChunkLoad = before; + + this.moveToWorld(entityplayer, exitWorld.dimension, true, exit, false); // Vanilla doesn't check for suffocation when handling portals, so neither should we + if (entityplayer.motX != velocity.getX() || entityplayer.motY != velocity.getY() || entityplayer.motZ != velocity.getZ()) { + entityplayer.getBukkitEntity().setVelocity(velocity); + } + } + + public void changeWorld(Entity entity, int i, WorldServer worldserver, WorldServer worldserver1) { + // CraftBukkit start - Split into modular functions + Location exit = calculateTarget(entity.getBukkitEntity().getLocation(), worldserver1); + repositionEntity(entity, exit, true); + } + + // Copy of original changeWorld(Entity, int, WorldServer, WorldServer) method with only location calculation logic + public Location calculateTarget(Location enter, World target) { + WorldServer worldserver = ((CraftWorld) enter.getWorld()).getHandle(); + WorldServer worldserver1 = target.getWorld().getHandle(); + int i = worldserver.dimension; + + double y = enter.getY(); + float yaw = enter.getYaw(); + float pitch = enter.getPitch(); + double d0 = enter.getX(); + double d1 = enter.getZ(); + double d2 = 8.0D; + /* + double d0 = entity.locX; + double d1 = entity.locZ; + double d2 = 8.0D; + float f = entity.yaw; + + worldserver.methodProfiler.a("moving"); + */ + if (worldserver1.dimension == -1) { + d0 = MathHelper.a(d0 / d2, worldserver1.getWorldBorder().b()+ 16.0D, worldserver1.getWorldBorder().d() - 16.0D); + d1 = MathHelper.a(d1 / d2, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); + /* + entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + */ + } else if (worldserver1.dimension == 0) { + d0 = MathHelper.a(d0 * d2, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); + d1 = MathHelper.a(d1 * d2, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); + /* + entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + */ + } else { + BlockPosition blockposition; + + if (i == 1) { + // use default NORMAL world spawn instead of target + worldserver1 = this.server.worlds.get(0); + blockposition = worldserver1.getSpawn(); + } else { + blockposition = worldserver1.getDimensionSpawn(); + } + + d0 = blockposition.getX(); + y = blockposition.getY(); + d1 = blockposition.getZ(); + /* + entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + */ + } + + // worldserver.methodProfiler.b(); + if (i != 1) { + worldserver.methodProfiler.a("placing"); + d0 = MathHelper.clamp((int) d0, -29999872, 29999872); + d1 = MathHelper.clamp((int) d1, -29999872, 29999872); + /* + if (entity.isAlive()) { + entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + worldserver1.getTravelAgent().a(entity, f); + worldserver1.addEntity(entity); + worldserver1.entityJoinedWorld(entity, false); + } + + worldserver.methodProfiler.b(); + */ + } + + // entity.spawnIn(worldserver1); + return new Location(worldserver1.getWorld(), d0, y, d1, yaw, pitch); + } + + // copy of original a(Entity, int, WorldServer, WorldServer) method with only entity repositioning logic + public void repositionEntity(Entity entity, Location exit, boolean portal) { + WorldServer worldserver = (WorldServer) entity.world; + WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); + int i = worldserver.dimension; + + /* + double d0 = entity.locX; + double d1 = entity.locZ; + double d2 = 8.0D; + float f = entity.yaw; + + worldserver.methodProfiler.a("moving"); + */ + entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + /* + if (entity.dimension == -1) { + d0 = MathHelper.a(d0 / d2, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); + d1 = MathHelper.a(d1 / d2, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); + entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + } else if (entity.dimension == 0) { + d0 = MathHelper.a(d0 * d2, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D); + d1 = MathHelper.a(d1 * d2, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D); + entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + } else { + BlockPosition blockposition; + + if (i == 1) { + // use default NORMAL world spawn instead of target + worldserver1 = this.server.worlds.get(0); + blockposition = worldserver1.getSpawn(); + } else { + blockposition = worldserver1.getDimensionSpawn(); + } + + d0 = (double) blockposition.getX(); + entity.locY = (double) blockposition.getY(); + d1 = (double) blockposition.getZ(); + entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F); + if (entity.isAlive()) { + worldserver.entityJoinedWorld(entity, false); + } + } + */ + + worldserver.methodProfiler.b(); + if (i != 1) { + worldserver.methodProfiler.a("placing"); + /* + d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872); + d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872); + */ + if (entity.isAlive()) { + // entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); + // worldserver1.getTravelAgent().a(entity, f); + if (portal) { + Vector velocity = entity.getBukkitEntity().getVelocity(); + worldserver1.getTravelAgent().adjustExit(entity, exit, velocity); + entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); + if (entity.motX != velocity.getX() || entity.motY != velocity.getY() || entity.motZ != velocity.getZ()) { + entity.getBukkitEntity().setVelocity(velocity); + } + } + worldserver1.addEntity(entity); + worldserver1.entityJoinedWorld(entity, false); + } + + worldserver.methodProfiler.b(); + } + + entity.spawnIn(worldserver1); + // CraftBukkit end + } + + public void tick() { + if (++this.u > 600) { + this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_LATENCY, this.players)); + this.u = 0; + } + + } + + public void sendAll(Packet packet) { + for (int i = 0; i < this.players.size(); ++i) { + this.players.get(i).playerConnection.sendPacket(packet); + } + + } + + // CraftBukkit start - add a world/entity limited version + public void sendAll(Packet packet, EntityHuman entityhuman) { + for (int i = 0; i < this.players.size(); ++i) { + EntityPlayer entityplayer = this.players.get(i); + if (entityhuman != null && entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { + continue; + } + this.players.get(i).playerConnection.sendPacket(packet); + } + } + + public void sendAll(Packet packet, World world) { + for (int i = 0; i < world.players.size(); ++i) { + ((EntityPlayer) world.players.get(i)).playerConnection.sendPacket(packet); + } + + } + // CraftBukkit end + + public void a(Packet packet, int i) { + for (int j = 0; j < this.players.size(); ++j) { + EntityPlayer entityplayer = this.players.get(j); + + if (entityplayer.dimension == i) { + entityplayer.playerConnection.sendPacket(packet); + } + } + + } + + public void a(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent) { + ScoreboardTeamBase scoreboardteambase = entityhuman.getScoreboardTeam(); + + if (scoreboardteambase != null) { + Collection collection = scoreboardteambase.getPlayerNameSet(); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + EntityPlayer entityplayer = this.getPlayer(s); + + if (entityplayer != null && entityplayer != entityhuman) { + entityplayer.sendMessage(ichatbasecomponent); + } + } + + } + } + + public void b(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent) { + ScoreboardTeamBase scoreboardteambase = entityhuman.getScoreboardTeam(); + + if (scoreboardteambase == null) { + this.sendMessage(ichatbasecomponent); + } else { + for (int i = 0; i < this.players.size(); ++i) { + EntityPlayer entityplayer = this.players.get(i); + + if (entityplayer.getScoreboardTeam() != scoreboardteambase) { + entityplayer.sendMessage(ichatbasecomponent); + } + } + + } + } + + public String b(boolean flag) { + String s = ""; + ArrayList arraylist = Lists.newArrayList(this.players); + + for (int i = 0; i < arraylist.size(); ++i) { + if (i > 0) { + s = s + ", "; + } + + s = s + ((EntityPlayer) arraylist.get(i)).getName(); + if (flag) { + s = s + " (" + ((EntityPlayer) arraylist.get(i)).getUniqueID().toString() + ")"; + } + } + + return s; + } + + public String[] f() { + String[] astring = new String[this.players.size()]; + + for (int i = 0; i < this.players.size(); ++i) { + astring[i] = this.players.get(i).getName(); + } + + return astring; + } + + public GameProfile[] g() { + GameProfile[] agameprofile = new GameProfile[this.players.size()]; + + for (int i = 0; i < this.players.size(); ++i) { + agameprofile[i] = this.players.get(i).getProfile(); + } + + return agameprofile; + } + + public GameProfileBanList getProfileBans() { + return this.k; + } + + public IpBanList getIPBans() { + return this.l; + } + + public void addOp(GameProfile gameprofile) { + this.operators.add(new OpListEntry(gameprofile, this.server.p(), this.operators.b(gameprofile))); + + // CraftBukkit start + Player player = server.server.getPlayer(gameprofile.getId()); + if (player != null) { + player.recalculatePermissions(); + } + // CraftBukkit end + } + + public void removeOp(GameProfile gameprofile) { + this.operators.remove(gameprofile); + + // CraftBukkit start + Player player = server.server.getPlayer(gameprofile.getId()); + if (player != null) { + player.recalculatePermissions(); + } + // CraftBukkit end + } + + public boolean isWhitelisted(GameProfile gameprofile) { + return !this.hasWhitelist || this.operators.d(gameprofile) || 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 + } + + public EntityPlayer getPlayer(String s) { + return this.playersByName.get(s); // Spigot + } + + public void sendPacketNearby(double d0, double d1, double d2, double d3, int i, Packet packet) { + this.sendPacketNearby(null, d0, d1, d2, d3, i, packet); + } + + public void sendPacketNearbyIncludingSelf(EntityHuman entityhuman, double d0, double d1, double d2, double d3, int i, Packet packet) { // RageSpigot + for (int j = 0; j < this.players.size(); ++j) { + EntityPlayer entityplayer = this.players.get(j); + + if (entityhuman != null && (!entityplayer.getBukkitEntity().canSeeEntity(entityhuman.getBukkitEntity()) || !((EntityPlayer) entityhuman).getBukkitEntity().canSeeEntity(entityplayer.getBukkitEntity()))) { + continue; + } + + if (entityplayer.dimension == i) { + double d4 = d0 - entityplayer.locX; + double d5 = d1 - entityplayer.locY; + double d6 = d2 - entityplayer.locZ; + + if (d4 * d4 + d5 * d5 + d6 * d6 < d3 * d3) { + entityplayer.playerConnection.sendPacket(packet); + } + } + } + } + + // Mythic - move CraftPlayer#canSee down + public void sendPacketNearby(EntityHuman entityhuman, double d0, double d1, double d2, double d3, int i, Packet packet) { + for (int j = 0; j < this.players.size(); ++j) { + EntityPlayer entityplayer = this.players.get(j); + + if (entityplayer != entityhuman && entityplayer.dimension == i) { + double d4 = d0 - entityplayer.locX; + double d5 = d1 - entityplayer.locY; + double d6 = d2 - entityplayer.locZ; + + if (d4 * d4 + d5 * d5 + d6 * d6 < d3 * d3) { + // CraftBukkit start - Test if player receiving packet can see the source of the packet + if (entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { + continue; + } + // CraftBukkit end + + entityplayer.playerConnection.sendPacket(packet); + } + } + } + + } + + public void savePlayers() { + for (int i = 0; i < this.players.size(); ++i) { + this.savePlayerFile(this.players.get(i)); + } + + } + + public void addWhitelist(GameProfile gameprofile) { + this.whitelist.add(new WhiteListEntry(gameprofile)); + } + + public void removeWhitelist(GameProfile gameprofile) { + this.whitelist.remove(gameprofile); + } + + public WhiteList getWhitelist() { + return this.whitelist; + } + + public String[] getWhitelisted() { + return this.whitelist.getEntries(); + } + + public OpList getOPs() { + return this.operators; + } + + public String[] n() { + return this.operators.getEntries(); + } + + public void reloadWhitelist() {} + + public void b(EntityPlayer entityplayer, WorldServer worldserver) { + WorldBorder worldborder = entityplayer.world.getWorldBorder(); // CraftBukkit + + entityplayer.playerConnection.sendPacket(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.INITIALIZE)); + entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(worldserver.getTime(), worldserver.getDayTime(), worldserver.getGameRules().getBoolean("doDaylightCycle"))); + if (worldserver.S()) { + // CraftBukkit start - handle player weather + // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(1, 0.0F)); + // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, worldserver.j(1.0F))); + // entityplayer.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, worldserver.h(1.0F))); + entityplayer.setPlayerWeather(org.bukkit.WeatherType.DOWNFALL, false); + entityplayer.updateWeather(-worldserver.p, worldserver.p, -worldserver.r, worldserver.r); + // CraftBukkit end + } + + } + + public void updateClient(EntityPlayer entityplayer) { + entityplayer.updateInventory(entityplayer.defaultContainer); + // entityplayer.triggerHealthUpdate(); + entityplayer.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange + entityplayer.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(entityplayer.inventory.itemInHandIndex)); + } + + public int getPlayerCount() { + return this.players.size(); + } + + public int getMaxPlayers() { + return this.maxPlayers; + } + + public String[] getSeenPlayers() { + return this.server.worlds.get(0).getDataManager().getPlayerFileData().getSeenPlayers(); // CraftBukkit + } + + public boolean getHasWhitelist() { + return this.hasWhitelist; + } + + public void setHasWhitelist(boolean flag) { + this.hasWhitelist = flag; + } + + public List b(String s) { + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = this.players.iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + if (entityplayer.w().equals(s)) { + arraylist.add(entityplayer); + } + } + + return arraylist; + } + + public int s() { + return this.r; + } + + public MinecraftServer getServer() { + return this.server; + } + + public NBTTagCompound t() { + return null; + } + + private void a(EntityPlayer entityplayer, EntityPlayer entityplayer1, World world) { + if (entityplayer1 != null) { + entityplayer.playerInteractManager.setGameMode(entityplayer1.playerInteractManager.getGameMode()); + } else if (this.s != null) { + entityplayer.playerInteractManager.setGameMode(this.s); + } + + entityplayer.playerInteractManager.b(world.getWorldData().getGameType()); + } + + public void u() { + for (int i = 0; i < this.players.size(); ++i) { + this.players.get(i).playerConnection.disconnect(this.server.server.getShutdownMessage()); // CraftBukkit - add custom shutdown message + } + + } + + // CraftBukkit start + public void sendMessage(IChatBaseComponent[] iChatBaseComponents) { + for (IChatBaseComponent component : iChatBaseComponents) { + sendMessage(component, true); + } + } + // CraftBukkit end + + public void sendMessage(IChatBaseComponent ichatbasecomponent, boolean flag) { + this.server.sendMessage(ichatbasecomponent); + int i = flag ? 1 : 0; + + // CraftBukkit start - we run this through our processor first so we can get web links etc + this.sendAll(new PacketPlayOutChat(CraftChatMessage.fixComponent(ichatbasecomponent), (byte) i)); + // CraftBukkit end + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + this.sendMessage(ichatbasecomponent, true); + } + + public ServerStatisticManager a(EntityHuman entityhuman) { + UUID uuid = entityhuman.getUniqueID(); + ServerStatisticManager serverstatisticmanager = uuid == null ? null : this.o.get(uuid); + + if (serverstatisticmanager == null) { + File file = new File(this.server.getWorldServer(0).getDataManager().getDirectory(), "stats"); + File file1 = new File(file, uuid.toString() + ".json"); + + if (!file1.exists()) { + File file2 = new File(file, entityhuman.getName() + ".json"); + + if (file2.exists() && file2.isFile()) { + file2.renameTo(file1); + } + } + + serverstatisticmanager = new ServerStatisticManager(this.server, file1); + serverstatisticmanager.a(); + this.o.put(uuid, serverstatisticmanager); + } + + return serverstatisticmanager; + } + + public void a(int i) { + this.r = i; + if (this.server.worldServer != null) { + WorldServer[] aworldserver = this.server.worldServer; + int j = aworldserver.length; + + // CraftBukkit start + for (int k = 0; k < server.worlds.size(); ++k) { + WorldServer worldserver = server.worlds.get(0); + // CraftBukkit end + + if (worldserver != null) { + worldserver.getPlayerChunkMap().a(i); + } + } + + } + } + + public List v() { + return this.players; + } + + public EntityPlayer a(UUID uuid) { + return this.j.get(uuid); + } + + public boolean f(GameProfile gameprofile) { + return false; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PortalTravelAgent.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PortalTravelAgent.java new file mode 100644 index 0000000..05b65bd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PortalTravelAgent.java @@ -0,0 +1,485 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import org.bukkit.Location; +import org.bukkit.event.entity.EntityPortalExitEvent; +import org.bukkit.util.Vector; + +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +// CraftBukkit start +// CraftBukkit end + +public class PortalTravelAgent { + + private final WorldServer a; + private final Random b; + private final LongHashMap c = new LongHashMap(); + private final List d = Lists.newArrayList(); + + public PortalTravelAgent(WorldServer worldserver) { + this.a = worldserver; + this.b = new Random(worldserver.getSeed()); + } + + public void a(Entity entity, float f) { + if (this.a.worldProvider.getDimension() != 1) { + if (!this.b(entity, f)) { + this.a(entity); + this.b(entity, f); + } + } else { + int i = MathHelper.floor(entity.locX); + int j = MathHelper.floor(entity.locY) - 1; + int k = MathHelper.floor(entity.locZ); + // CraftBukkit start - Modularize end portal creation + BlockPosition created = this.createEndPortal(entity.locX, entity.locY, entity.locZ); + entity.setPositionRotation(created.getX(), created.getY(), created.getZ(), entity.yaw, 0.0F); + entity.motX = entity.motY = entity.motZ = 0.0D; + } + } + + // Split out from original a(Entity, double, double, double, float) method in order to enable being called from createPortal + private BlockPosition createEndPortal(double x, double y, double z) { + int i = MathHelper.floor(x); + int j = MathHelper.floor(y) - 1; + int k = MathHelper.floor(z); + // CraftBukkit end + byte b0 = 1; + byte b1 = 0; + + for (int l = -2; l <= 2; ++l) { + for (int i1 = -2; i1 <= 2; ++i1) { + for (int j1 = -1; j1 < 3; ++j1) { + int k1 = i + i1 * b0 + l * b1; + int l1 = j + j1; + int i2 = k + i1 * b1 - l * b0; + boolean flag = j1 < 0; + + this.a.setTypeUpdate(new BlockPosition(k1, l1, i2), flag ? Blocks.OBSIDIAN.getBlockData() : Blocks.AIR.getBlockData()); + } + } + } + + // CraftBukkit start + return new BlockPosition(i, k, k); + } + + // use logic based on creation to verify end portal + private BlockPosition findEndPortal(BlockPosition portal) { + int i = portal.getX(); + int j = portal.getY() - 1; + int k = portal.getZ(); + byte b0 = 1; + byte b1 = 0; + + for (int l = -2; l <= 2; ++l) { + for (int i1 = -2; i1 <= 2; ++i1) { + for (int j1 = -1; j1 < 3; ++j1) { + int k1 = i + i1 * b0 + l * b1; + int l1 = j + j1; + int i2 = k + i1 * b1 - l * b0; + boolean flag = j1 < 0; + + if (this.a.getType(k1, l1, i2).getBlock() != (flag ? Blocks.OBSIDIAN : Blocks.AIR)) { + return null; + } + } + } + } + return new BlockPosition(i, j, k); + } + // CraftBukkit end + + public boolean b(Entity entity, float f) { + // CraftBukkit start - Modularize portal search process and entity teleportation + BlockPosition found = this.findPortal(entity.locX, entity.locY, entity.locZ, 128); + if (found == null) { + return false; + } + + Location exit = new Location(this.a.getWorld(), found.getX(), found.getY(), found.getZ(), f, entity.pitch); + Vector velocity = entity.getBukkitEntity().getVelocity(); + this.adjustExit(entity, exit, velocity); + entity.setPositionRotation(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); + if (entity.motX != velocity.getX() || entity.motY != velocity.getY() || entity.motZ != velocity.getZ()) { + entity.getBukkitEntity().setVelocity(velocity); + } + return true; + } + + public BlockPosition findPortal(double x, double y, double z, int searchRadius) { // Paper - actually use search radius + if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { + return this.findEndPortal(this.a.worldProvider.h()); + } + // CraftBukkit end + double d0 = -1.0D; + // CraftBukkit start + int i = MathHelper.floor(x); + int j = MathHelper.floor(z); + // CraftBukkit end + boolean flag1 = true; + Object object = BlockPosition.ZERO; + long k = ChunkCoordIntPair.a(i, j); + + if (this.c.contains(k)) { + PortalTravelAgent.ChunkCoordinatesPortal portaltravelagent_chunkcoordinatesportal = this.c.getEntry(k); + + d0 = 0.0D; + object = portaltravelagent_chunkcoordinatesportal; + portaltravelagent_chunkcoordinatesportal.c = this.a.getTime(); + flag1 = false; + } else { + BlockPosition blockposition = new BlockPosition(x, y, z); + + for (int l = -searchRadius; l <= searchRadius; ++l) { // Paper - actually use search radius + BlockPosition blockposition1; + + for (int i1 = -searchRadius; i1 <= searchRadius; ++i1) { // Paper - actually use search radius + for (BlockPosition blockposition2 = blockposition.a(l, this.a.V() - 1 - blockposition.getY(), i1); blockposition2.getY() >= 0; blockposition2 = blockposition1) { + blockposition1 = blockposition2.down(); + if (this.a.getType(blockposition2).getBlock() == Blocks.PORTAL) { + while (this.a.getType(blockposition1 = blockposition2.down()).getBlock() == Blocks.PORTAL) { + blockposition2 = blockposition1; + } + + double d1 = blockposition2.i(blockposition); + + if (d0 < 0.0D || d1 < d0) { + d0 = d1; + object = blockposition2; + } + } + } + } + } + } + + if (d0 >= 0.0D) { + if (flag1) { + this.c.put(k, new PortalTravelAgent.ChunkCoordinatesPortal((BlockPosition) object, this.a.getTime())); + this.d.add(Long.valueOf(k)); + } + // CraftBukkit start - Move entity teleportation logic into exit + return (BlockPosition) object; + } else { + return null; + } + } + + // Entity repositioning logic split out from original b method and combined with repositioning logic for The End from original a method + public void adjustExit(Entity entity, Location position, Vector velocity) { + Location from = position.clone(); + Vector before = velocity.clone(); + BlockPosition object = new BlockPosition(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + float f = position.getYaw(); + + if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END || entity.getBukkitEntity().getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END || entity.aG() == null) { + // entity.setPositionRotation((double) i, (double) j, (double) k, entity.yaw, 0.0F); + // entity.motX = entity.motY = entity.motZ = 0.0D; + position.setPitch(0.0F); + velocity.setX(0); + velocity.setY(0); + velocity.setZ(0); + } else { + // CraftBukkit end + + double d2 = (double) object.getX() + 0.5D; + double d3 = (double) object.getY() + 0.5D; + double d4 = (double) object.getZ() + 0.5D; + ShapeDetector.ShapeDetectorCollection shapedetector_shapedetectorcollection = Blocks.PORTAL.f(this.a, object); + boolean flag2 = shapedetector_shapedetectorcollection.b().e().c() == EnumDirection.EnumAxisDirection.NEGATIVE; + double d5 = shapedetector_shapedetectorcollection.b().k() == EnumDirection.EnumAxis.X ? (double) shapedetector_shapedetectorcollection.a().getZ() : (double) shapedetector_shapedetectorcollection.a().getX(); + + d3 = (double) (shapedetector_shapedetectorcollection.a().getY() + 1) - entity.aG().b * (double) shapedetector_shapedetectorcollection.e(); + if (flag2) { + ++d5; + } + + if (shapedetector_shapedetectorcollection.b().k() == EnumDirection.EnumAxis.X) { + d4 = d5 + (1.0D - entity.aG().a) * (double) shapedetector_shapedetectorcollection.d() * (double) shapedetector_shapedetectorcollection.b().e().c().a(); + } else { + d2 = d5 + (1.0D - entity.aG().a) * (double) shapedetector_shapedetectorcollection.d() * (double) shapedetector_shapedetectorcollection.b().e().c().a(); + } + + float f1 = 0.0F; + float f2 = 0.0F; + float f3 = 0.0F; + float f4 = 0.0F; + + if (shapedetector_shapedetectorcollection.b().opposite() == entity.aH()) { + f1 = 1.0F; + f2 = 1.0F; + } else if (shapedetector_shapedetectorcollection.b().opposite() == entity.aH().opposite()) { + f1 = -1.0F; + f2 = -1.0F; + } else if (shapedetector_shapedetectorcollection.b().opposite() == entity.aH().e()) { + f3 = 1.0F; + f4 = -1.0F; + } else { + f3 = -1.0F; + f4 = 1.0F; + } + + // CraftBukkit start + double d6 = velocity.getX(); + double d7 = velocity.getZ(); + // CraftBukkit end + + // CraftBukkit start - Adjust position and velocity instances instead of entity + velocity.setX(d6 * (double) f1 + d7 * (double) f4); + velocity.setZ(d6 * (double) f3 + d7 * (double) f2); + f = f - (float) (entity.aH().opposite().b() * 90) + (float) (shapedetector_shapedetectorcollection.b().b() * 90); + // entity.setPositionRotation(d2, d3, d4, entity.yaw, entity.pitch); + position.setX(d2); + position.setY(d3); + position.setZ(d4); + position.setYaw(f); + } + EntityPortalExitEvent event = new EntityPortalExitEvent(entity.getBukkitEntity(), from, position, before, velocity); + this.a.getServer().getPluginManager().callEvent(event); + Location to = event.getTo(); + if (event.isCancelled() || to == null || !entity.isAlive()) { + position.setX(from.getX()); + position.setY(from.getY()); + position.setZ(from.getZ()); + position.setYaw(from.getYaw()); + position.setPitch(from.getPitch()); + velocity.copy(before); + } else { + position.setX(to.getX()); + position.setY(to.getY()); + position.setZ(to.getZ()); + position.setYaw(to.getYaw()); + position.setPitch(to.getPitch()); + velocity.copy(event.getAfter()); // event.getAfter() will never be null, as setAfter() will cause an NPE if null is passed in + } + // CraftBukkit end + } + + public boolean a(Entity entity) { + // CraftBukkit start - Allow for portal creation to be based on coordinates instead of entity + return this.createPortal(entity.locX, entity.locY, entity.locZ, 16); + } + + public boolean createPortal(double x, double y, double z, int b0) { + if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { + createEndPortal(x, y, z); + return true; + } + // CraftBukkit end + double d0 = -1.0D; + // CraftBukkit start + int i = MathHelper.floor(x); + int j = MathHelper.floor(y); + int k = MathHelper.floor(z); + // CraftBukkit end + int l = i; + int i1 = j; + int j1 = k; + int k1 = 0; + int l1 = this.b.nextInt(4); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + int i2; + double d1; + int j2; + double d2; + int k2; + int l2; + int i3; + int j3; + int k3; + int l3; + int i4; + int j4; + int k4; + double d3; + double d4; + + for (i2 = i - b0; i2 <= i + b0; ++i2) { + d1 = (double) i2 + 0.5D - x; // CraftBukkit + + for (j2 = k - b0; j2 <= k + b0; ++j2) { + d2 = (double) j2 + 0.5D - z; // CraftBukkit + + label271: + for (k2 = this.a.V() - 1; k2 >= 0; --k2) { + if (this.a.isEmpty(blockposition_mutableblockposition.c(i2, k2, j2))) { + while (k2 > 0 && this.a.isEmpty(blockposition_mutableblockposition.c(i2, k2 - 1, j2))) { + --k2; + } + + for (l2 = l1; l2 < l1 + 4; ++l2) { + i3 = l2 % 2; + j3 = 1 - i3; + if (l2 % 4 >= 2) { + i3 = -i3; + j3 = -j3; + } + + for (k3 = 0; k3 < 3; ++k3) { + for (l3 = 0; l3 < 4; ++l3) { + for (i4 = -1; i4 < 4; ++i4) { + j4 = i2 + (l3 - 1) * i3 + k3 * j3; + k4 = k2 + i4; + int l4 = j2 + (l3 - 1) * j3 - k3 * i3; + + blockposition_mutableblockposition.c(j4, k4, l4); + if (i4 < 0 && !this.a.getType(blockposition_mutableblockposition).getBlock().getMaterial().isBuildable() || i4 >= 0 && !this.a.isEmpty(blockposition_mutableblockposition)) { + continue label271; + } + } + } + } + + d3 = (double) k2 + 0.5D - y; // CraftBukkit + d4 = d1 * d1 + d3 * d3 + d2 * d2; + if (d0 < 0.0D || d4 < d0) { + d0 = d4; + l = i2; + i1 = k2; + j1 = j2; + k1 = l2 % 4; + } + } + } + } + } + } + + if (d0 < 0.0D) { + for (i2 = i - b0; i2 <= i + b0; ++i2) { + d1 = (double) i2 + 0.5D - x; // CraftBukkit + + for (j2 = k - b0; j2 <= k + b0; ++j2) { + d2 = (double) j2 + 0.5D - z; // CraftBukkit + + label219: + for (k2 = this.a.V() - 1; k2 >= 0; --k2) { + if (this.a.isEmpty(blockposition_mutableblockposition.c(i2, k2, j2))) { + while (k2 > 0 && this.a.isEmpty(blockposition_mutableblockposition.c(i2, k2 - 1, j2))) { + --k2; + } + + for (l2 = l1; l2 < l1 + 2; ++l2) { + i3 = l2 % 2; + j3 = 1 - i3; + + for (k3 = 0; k3 < 4; ++k3) { + for (l3 = -1; l3 < 4; ++l3) { + i4 = i2 + (k3 - 1) * i3; + j4 = k2 + l3; + k4 = j2 + (k3 - 1) * j3; + blockposition_mutableblockposition.c(i4, j4, k4); + if (l3 < 0 && !this.a.getType(blockposition_mutableblockposition).getBlock().getMaterial().isBuildable() || l3 >= 0 && !this.a.isEmpty(blockposition_mutableblockposition)) { + continue label219; + } + } + } + + d3 = (double) k2 + 0.5D - y; // CraftBukkit + d4 = d1 * d1 + d3 * d3 + d2 * d2; + if (d0 < 0.0D || d4 < d0) { + d0 = d4; + l = i2; + i1 = k2; + j1 = j2; + k1 = l2 % 2; + } + } + } + } + } + } + } + + int i5 = l; + int j5 = i1; + + j2 = j1; + int k5 = k1 % 2; + int l5 = 1 - k5; + + if (k1 % 4 >= 2) { + k5 = -k5; + l5 = -l5; + } + + if (d0 < 0.0D) { + i1 = MathHelper.clamp(i1, 70, this.a.V() - 10); + j5 = i1; + + for (k2 = -1; k2 <= 1; ++k2) { + for (l2 = 1; l2 < 3; ++l2) { + for (i3 = -1; i3 < 3; ++i3) { + j3 = i5 + (l2 - 1) * k5 + k2 * l5; + k3 = j5 + i3; + l3 = j2 + (l2 - 1) * l5 - k2 * k5; + boolean flag = i3 < 0; + + this.a.setTypeUpdate(new BlockPosition(j3, k3, l3), flag ? Blocks.OBSIDIAN.getBlockData() : Blocks.AIR.getBlockData()); + } + } + } + } + + IBlockData iblockdata = Blocks.PORTAL.getBlockData().set(BlockPortal.AXIS, k5 != 0 ? EnumDirection.EnumAxis.X : EnumDirection.EnumAxis.Z); + + for (l2 = 0; l2 < 4; ++l2) { + for (i3 = 0; i3 < 4; ++i3) { + for (j3 = -1; j3 < 4; ++j3) { + k3 = i5 + (i3 - 1) * k5; + l3 = j5 + j3; + i4 = j2 + (i3 - 1) * l5; + boolean flag1 = i3 == 0 || i3 == 3 || j3 == -1 || j3 == 3; + + this.a.setTypeAndData(new BlockPosition(k3, l3, i4), flag1 ? Blocks.OBSIDIAN.getBlockData() : iblockdata, 2); + } + } + + for (i3 = 0; i3 < 4; ++i3) { + for (j3 = -1; j3 < 4; ++j3) { + k3 = i5 + (i3 - 1) * k5; + l3 = j5 + j3; + i4 = j2 + (i3 - 1) * l5; + BlockPosition blockposition = new BlockPosition(k3, l3, i4); + + this.a.applyPhysics(blockposition, this.a.getType(blockposition).getBlock()); + } + } + } + + return true; + } + + public void a(long i) { + if (i % 100L == 0L) { + Iterator iterator = this.d.iterator(); + long j = i - 300L; + + while (iterator.hasNext()) { + Long olong = (Long) iterator.next(); + PortalTravelAgent.ChunkCoordinatesPortal portaltravelagent_chunkcoordinatesportal = this.c.getEntry(olong.longValue()); + + if (portaltravelagent_chunkcoordinatesportal == null || portaltravelagent_chunkcoordinatesportal.c < j) { + iterator.remove(); + this.c.remove(olong.longValue()); + } + } + } + + } + + public class ChunkCoordinatesPortal extends BlockPosition { + + public long c; + + public ChunkCoordinatesPortal(BlockPosition blockposition, long i) { + super(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + this.c = i; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PropertyManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PropertyManager.java new file mode 100644 index 0000000..0ee7fe8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/PropertyManager.java @@ -0,0 +1,145 @@ +package net.minecraft.server; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import joptsimple.OptionSet; // CraftBukkit + +public class PropertyManager { + + private static final Logger a = LogManager.getLogger(); + public final Properties properties = new Properties(); + private final File file; + + public PropertyManager(File file) { + this.file = file; + if (file.exists()) { + FileInputStream fileinputstream = null; + + try { + fileinputstream = new FileInputStream(file); + this.properties.load(fileinputstream); + } catch (Exception exception) { + PropertyManager.a.warn("Failed to load " + file, exception); + this.a(); + } finally { + if (fileinputstream != null) { + try { + fileinputstream.close(); + } catch (IOException ioexception) { + ; + } + } + + } + } else { + PropertyManager.a.warn(file + " does not exist"); + this.a(); + } + + } + + // CraftBukkit start + private OptionSet options = null; + + public PropertyManager(final OptionSet options) { + this((File) options.valueOf("config")); + + this.options = options; + } + + private T getOverride(String name, T value) { + if ((this.options != null) && (this.options.has(name)) && !name.equals( "online-mode")) { // Spigot + return (T) this.options.valueOf(name); + } + + return value; + } + // CraftBukkit end + + public void a() { + PropertyManager.a.info("Generating new properties file"); + this.savePropertiesFile(); + } + + public void savePropertiesFile() { + FileOutputStream fileoutputstream = null; + + try { + // CraftBukkit start - Don't attempt writing to file if it's read only + if (this.file.exists() && !this.file.canWrite()) { + return; + } + // CraftBukkit end + + fileoutputstream = new FileOutputStream(this.file); + this.properties.store(fileoutputstream, "Minecraft server properties"); + } catch (Exception exception) { + PropertyManager.a.warn("Failed to save " + this.file, exception); + this.a(); + } finally { + if (fileoutputstream != null) { + try { + fileoutputstream.close(); + } catch (IOException ioexception) { + ; + } + } + + } + + } + + public File c() { + return this.file; + } + + public String getString(String s, String s1) { + if (!this.properties.containsKey(s)) { + this.properties.setProperty(s, s1); + this.savePropertiesFile(); + this.savePropertiesFile(); + } + + return getOverride(s, this.properties.getProperty(s, s1)); // CraftBukkit + } + + public int getInt(String s, int i) { + try { + return getOverride(s, Integer.parseInt(this.getString(s, "" + i))); // CraftBukkit + } catch (Exception exception) { + this.properties.setProperty(s, "" + i); + this.savePropertiesFile(); + return getOverride(s, i); // CraftBukkit + } + } + + public long getLong(String s, long i) { + try { + return getOverride(s, Long.parseLong(this.getString(s, "" + i))); // CraftBukkit + } catch (Exception exception) { + this.properties.setProperty(s, "" + i); + this.savePropertiesFile(); + return getOverride(s, i); // CraftBukkit + } + } + + public boolean getBoolean(String s, boolean flag) { + try { + return getOverride(s, Boolean.parseBoolean(this.getString(s, "" + flag))); //CraftBukkit + } catch (Exception exception) { + this.properties.setProperty(s, "" + flag); + this.savePropertiesFile(); + return getOverride(s, flag); // CraftBukkit + } + } + + public void setProperty(String s, Object object) { + this.properties.setProperty(s, "" + object); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeArmorDye.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeArmorDye.java new file mode 100644 index 0000000..eb8eeb6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeArmorDye.java @@ -0,0 +1,141 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import net.jafama.FastMath; + +import java.util.ArrayList; + +public class RecipeArmorDye extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + + // CraftBukkit start - Delegate to new parent class with bogus info + public RecipeArmorDye() { + super(new ItemStack(Items.LEATHER_HELMET, 0, 0), java.util.Arrays.asList(new ItemStack(Items.DYE, 0, 5))); + } + // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + ItemStack itemstack = null; + ArrayList arraylist = Lists.newArrayList(); + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); + + if (itemstack1 != null) { + if (itemstack1.getItem() instanceof ItemArmor) { + ItemArmor itemarmor = (ItemArmor) itemstack1.getItem(); + + if (itemarmor.x_() != ItemArmor.EnumArmorMaterial.LEATHER || itemstack != null) { + return false; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != Items.DYE) { + return false; + } + + arraylist.add(itemstack1); + } + } + } + + return itemstack != null && !arraylist.isEmpty(); + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + ItemStack itemstack = null; + int[] aint = new int[3]; + int i = 0; + int j = 0; + ItemArmor itemarmor = null; + + int k; + int l; + float f; + float f1; + int i1; + + for (k = 0; k < inventorycrafting.getSize(); ++k) { + ItemStack itemstack1 = inventorycrafting.getItem(k); + + if (itemstack1 != null) { + if (itemstack1.getItem() instanceof ItemArmor) { + itemarmor = (ItemArmor) itemstack1.getItem(); + if (itemarmor.x_() != ItemArmor.EnumArmorMaterial.LEATHER || itemstack != null) { + return null; + } + + itemstack = itemstack1.cloneItemStack(); + itemstack.count = 1; + if (itemarmor.d_(itemstack1)) { + l = itemarmor.b(itemstack); + f = (float) (l >> 16 & 255) / 255.0F; + f1 = (float) (l >> 8 & 255) / 255.0F; + float f2 = (float) (l & 255) / 255.0F; + + i = (int) ((float) i + FastMath.max(f, FastMath.max(f1, f2)) * 255.0F); + aint[0] = (int) ((float) aint[0] + f * 255.0F); + aint[1] = (int) ((float) aint[1] + f1 * 255.0F); + aint[2] = (int) ((float) aint[2] + f2 * 255.0F); + ++j; + } + } else { + if (itemstack1.getItem() != Items.DYE) { + return null; + } + + float[] afloat = EntitySheep.a(EnumColor.fromInvColorIndex(itemstack1.getData())); + int j1 = (int) (afloat[0] * 255.0F); + int k1 = (int) (afloat[1] * 255.0F); + + i1 = (int) (afloat[2] * 255.0F); + i += FastMath.max(j1, FastMath.max(k1, i1)); + aint[0] += j1; + aint[1] += k1; + aint[2] += i1; + ++j; + } + } + } + + if (itemarmor == null) { + return null; + } else { + k = aint[0] / j; + int l1 = aint[1] / j; + + l = aint[2] / j; + f = (float) i / (float) j; + f1 = (float) FastMath.max(k, FastMath.max(l1, l)); + k = (int) ((float) k * f / f1); + l1 = (int) ((float) l1 * f / f1); + l = (int) ((float) l * f / f1); + i1 = (k << 8) + l1; + i1 = (i1 << 8) + l; + itemarmor.b(itemstack, i1); + return itemstack; + } + } + + public int a() { + return 10; + } + + public ItemStack b() { + return null; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem().r()) { + aitemstack[i] = new ItemStack(itemstack.getItem().q()); + } + } + + return aitemstack; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeBookClone.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeBookClone.java new file mode 100644 index 0000000..264019d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeBookClone.java @@ -0,0 +1,99 @@ +package net.minecraft.server; + +public class RecipeBookClone extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + + // CraftBukkit start - Delegate to new parent class + public RecipeBookClone() { + super(new ItemStack(Items.WRITTEN_BOOK, 0, -1), java.util.Arrays.asList(new ItemStack(Items.WRITABLE_BOOK, 0, 0))); + } + // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + int i = 0; + ItemStack itemstack = null; + + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); + + if (itemstack1 != null) { + if (itemstack1.getItem() == Items.WRITTEN_BOOK) { + if (itemstack != null) { + return false; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != Items.WRITABLE_BOOK) { + return false; + } + + ++i; + } + } + } + + return itemstack != null && i > 0; + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + int i = 0; + ItemStack itemstack = null; + + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); + + if (itemstack1 != null) { + if (itemstack1.getItem() == Items.WRITTEN_BOOK) { + if (itemstack != null) { + return null; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != Items.WRITABLE_BOOK) { + return null; + } + + ++i; + } + } + } + + if (itemstack != null && i >= 1 && ItemWrittenBook.h(itemstack) < 2) { + ItemStack itemstack2 = new ItemStack(Items.WRITTEN_BOOK, i); + + itemstack2.setTag((NBTTagCompound) itemstack.getTag().clone()); + itemstack2.getTag().setInt("generation", ItemWrittenBook.h(itemstack) + 1); + if (itemstack.hasName()) { + itemstack2.c(itemstack.getName()); + } + + return itemstack2; + } else { + return null; + } + } + + public int a() { + return 9; + } + + public ItemStack b() { + return null; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem() instanceof ItemWrittenBook) { + aitemstack[i] = itemstack; + break; + } + } + + return aitemstack; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeFireworks.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeFireworks.java new file mode 100644 index 0000000..ba9ce61 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeFireworks.java @@ -0,0 +1,191 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.ArrayList; + +public class RecipeFireworks extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + + private ItemStack a; + + // CraftBukkit start - Delegate to new parent class with bogus info + public RecipeFireworks() { + super(new ItemStack(Items.FIREWORKS, 0, 0), java.util.Arrays.asList(new ItemStack(Items.GUNPOWDER, 0, 5))); + } + // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + this.a = null; + int i = 0; + int j = 0; + int k = 0; + int l = 0; + int i1 = 0; + int j1 = 0; + + for (int k1 = 0; k1 < inventorycrafting.getSize(); ++k1) { + ItemStack itemstack = inventorycrafting.getItem(k1); + + if (itemstack != null) { + if (itemstack.getItem() == Items.GUNPOWDER) { + ++j; + } else if (itemstack.getItem() == Items.FIREWORK_CHARGE) { + ++l; + } else if (itemstack.getItem() == Items.DYE) { + ++k; + } else if (itemstack.getItem() == Items.PAPER) { + ++i; + } else if (itemstack.getItem() == Items.GLOWSTONE_DUST) { + ++i1; + } else if (itemstack.getItem() == Items.DIAMOND) { + ++i1; + } else if (itemstack.getItem() == Items.FIRE_CHARGE) { + ++j1; + } else if (itemstack.getItem() == Items.FEATHER) { + ++j1; + } else if (itemstack.getItem() == Items.GOLD_NUGGET) { + ++j1; + } else { + if (itemstack.getItem() != Items.SKULL) { + return false; + } + + ++j1; + } + } + } + + i1 += k + j1; + if (j <= 3 && i <= 1) { + NBTTagCompound nbttagcompound; + NBTTagCompound nbttagcompound1; + + if (j >= 1 && i == 1 && i1 == 0) { + this.a = new ItemStack(Items.FIREWORKS); + if (l > 0) { + nbttagcompound = new NBTTagCompound(); + nbttagcompound1 = new NBTTagCompound(); + NBTTagList nbttaglist = new NBTTagList(); + + for (int l1 = 0; l1 < inventorycrafting.getSize(); ++l1) { + ItemStack itemstack1 = inventorycrafting.getItem(l1); + + if (itemstack1 != null && itemstack1.getItem() == Items.FIREWORK_CHARGE && itemstack1.hasTag() && itemstack1.getTag().hasKeyOfType("Explosion", 10)) { + nbttaglist.add(itemstack1.getTag().getCompound("Explosion")); + } + } + + nbttagcompound1.set("Explosions", nbttaglist); + nbttagcompound1.setByte("Flight", (byte) j); + nbttagcompound.set("Fireworks", nbttagcompound1); + this.a.setTag(nbttagcompound); + } + + return true; + } else if (j == 1 && i == 0 && l == 0 && k > 0 && j1 <= 1) { + this.a = new ItemStack(Items.FIREWORK_CHARGE); + nbttagcompound = new NBTTagCompound(); + nbttagcompound1 = new NBTTagCompound(); + byte b0 = 0; + ArrayList arraylist = Lists.newArrayList(); + + for (int i2 = 0; i2 < inventorycrafting.getSize(); ++i2) { + ItemStack itemstack2 = inventorycrafting.getItem(i2); + + if (itemstack2 != null) { + if (itemstack2.getItem() == Items.DYE) { + arraylist.add(Integer.valueOf(ItemDye.a[itemstack2.getData() & 15])); + } else if (itemstack2.getItem() == Items.GLOWSTONE_DUST) { + nbttagcompound1.setBoolean("Flicker", true); + } else if (itemstack2.getItem() == Items.DIAMOND) { + nbttagcompound1.setBoolean("Trail", true); + } else if (itemstack2.getItem() == Items.FIRE_CHARGE) { + b0 = 1; + } else if (itemstack2.getItem() == Items.FEATHER) { + b0 = 4; + } else if (itemstack2.getItem() == Items.GOLD_NUGGET) { + b0 = 2; + } else if (itemstack2.getItem() == Items.SKULL) { + b0 = 3; + } + } + } + + int[] aint = new int[arraylist.size()]; + + for (int j2 = 0; j2 < aint.length; ++j2) { + aint[j2] = ((Integer) arraylist.get(j2)).intValue(); + } + + nbttagcompound1.setIntArray("Colors", aint); + nbttagcompound1.setByte("Type", b0); + nbttagcompound.set("Explosion", nbttagcompound1); + this.a.setTag(nbttagcompound); + return true; + } else if (j == 0 && i == 0 && l == 1 && k > 0 && k == i1) { + ArrayList arraylist1 = Lists.newArrayList(); + + for (int k2 = 0; k2 < inventorycrafting.getSize(); ++k2) { + ItemStack itemstack3 = inventorycrafting.getItem(k2); + + if (itemstack3 != null) { + if (itemstack3.getItem() == Items.DYE) { + arraylist1.add(Integer.valueOf(ItemDye.a[itemstack3.getData() & 15])); + } else if (itemstack3.getItem() == Items.FIREWORK_CHARGE) { + this.a = itemstack3.cloneItemStack(); + this.a.count = 1; + } + } + } + + int[] aint1 = new int[arraylist1.size()]; + + for (int l2 = 0; l2 < aint1.length; ++l2) { + aint1[l2] = ((Integer) arraylist1.get(l2)).intValue(); + } + + if (this.a != null && this.a.hasTag()) { + NBTTagCompound nbttagcompound2 = this.a.getTag().getCompound("Explosion"); + + if (nbttagcompound2 == null) { + return false; + } else { + nbttagcompound2.setIntArray("FadeColors", aint1); + return true; + } + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + return this.a.cloneItemStack(); + } + + public int a() { + return 10; + } + + public ItemStack b() { + return this.a; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem().r()) { + aitemstack[i] = new ItemStack(itemstack.getItem().q()); + } + } + + return aitemstack; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeMapClone.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeMapClone.java new file mode 100644 index 0000000..579f6d1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeMapClone.java @@ -0,0 +1,96 @@ +package net.minecraft.server; + +public class RecipeMapClone extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + + // CraftBukkit start - Delegate to new parent class + public RecipeMapClone() { + super(new ItemStack(Items.MAP, 0, -1), java.util.Arrays.asList(new ItemStack(Items.MAP, 0, 0))); + } + // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + int i = 0; + ItemStack itemstack = null; + + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); + + if (itemstack1 != null) { + if (itemstack1.getItem() == Items.FILLED_MAP) { + if (itemstack != null) { + return false; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != Items.MAP) { + return false; + } + + ++i; + } + } + } + + return itemstack != null && i > 0; + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + int i = 0; + ItemStack itemstack = null; + + for (int j = 0; j < inventorycrafting.getSize(); ++j) { + ItemStack itemstack1 = inventorycrafting.getItem(j); + + if (itemstack1 != null) { + if (itemstack1.getItem() == Items.FILLED_MAP) { + if (itemstack != null) { + return null; + } + + itemstack = itemstack1; + } else { + if (itemstack1.getItem() != Items.MAP) { + return null; + } + + ++i; + } + } + } + + if (itemstack != null && i >= 1) { + ItemStack itemstack2 = new ItemStack(Items.FILLED_MAP, i + 1, itemstack.getData()); + + if (itemstack.hasName()) { + itemstack2.c(itemstack.getName()); + } + + return itemstack2; + } else { + return null; + } + } + + public int a() { + return 9; + } + + public ItemStack b() { + return null; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem().r()) { + aitemstack[i] = new ItemStack(itemstack.getItem().q()); + } + } + + return aitemstack; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeRepair.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeRepair.java new file mode 100644 index 0000000..187e59a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipeRepair.java @@ -0,0 +1,107 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.ArrayList; + +public class RecipeRepair extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + + // CraftBukkit start - Delegate to new parent class + public RecipeRepair() { + super(new ItemStack(Items.LEATHER_HELMET), java.util.Arrays.asList(new ItemStack(Items.LEATHER_HELMET))); + } + // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + ArrayList arraylist = Lists.newArrayList(); + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null) { + arraylist.add(itemstack); + if (arraylist.size() > 1) { + ItemStack itemstack1 = (ItemStack) arraylist.get(0); + + if (itemstack.getItem() != itemstack1.getItem() || itemstack1.count != 1 || itemstack.count != 1 || !itemstack1.getItem().usesDurability()) { + return false; + } + } + } + } + + return arraylist.size() == 2; + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + ArrayList arraylist = Lists.newArrayList(); + + ItemStack itemstack; + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + itemstack = inventorycrafting.getItem(i); + if (itemstack != null) { + arraylist.add(itemstack); + if (arraylist.size() > 1) { + ItemStack itemstack1 = (ItemStack) arraylist.get(0); + + if (itemstack.getItem() != itemstack1.getItem() || itemstack1.count != 1 || itemstack.count != 1 || !itemstack1.getItem().usesDurability()) { + return null; + } + } + } + } + + if (arraylist.size() == 2) { + ItemStack itemstack2 = (ItemStack) arraylist.get(0); + + itemstack = (ItemStack) arraylist.get(1); + if (itemstack2.getItem() == itemstack.getItem() && itemstack2.count == 1 && itemstack.count == 1 && itemstack2.getItem().usesDurability()) { + Item item = itemstack2.getItem(); + int j = item.getMaxDurability() - itemstack2.h(); + int k = item.getMaxDurability() - itemstack.h(); + int l = j + k + item.getMaxDurability() * 5 / 100; + int i1 = item.getMaxDurability() - l; + + if (i1 < 0) { + i1 = 0; + } + + // CraftBukkit start - Construct a dummy repair recipe + ItemStack result = new ItemStack(itemstack.getItem(), 1, i1); + java.util.List ingredients = new ArrayList(); + ingredients.add(itemstack2.cloneItemStack()); + ingredients.add(itemstack.cloneItemStack()); + ShapelessRecipes recipe = new ShapelessRecipes(result.cloneItemStack(), ingredients); + inventorycrafting.currentRecipe = recipe; + result = org.bukkit.craftbukkit.event.CraftEventFactory.callPreCraftEvent(inventorycrafting, result, CraftingManager.getInstance().lastCraftView, true); + return result; + // return new ItemStack(itemstack2.getItem(), 1, i1); + // CraftBukkit end + } + } + + return null; + } + + public int a() { + return 4; + } + + public ItemStack b() { + return null; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem().r()) { + aitemstack[i] = new ItemStack(itemstack.getItem().q()); + } + } + + return aitemstack; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipesBanner.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipesBanner.java new file mode 100644 index 0000000..4a77c77 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipesBanner.java @@ -0,0 +1,321 @@ +package net.minecraft.server; + +public class RecipesBanner { + + public RecipesBanner() {} + + void a(CraftingManager craftingmanager) { + EnumColor[] aenumcolor = EnumColor.values(); + int i = aenumcolor.length; + + for (int j = 0; j < i; ++j) { + EnumColor enumcolor = aenumcolor[j]; + + craftingmanager.registerShapedRecipe(new ItemStack(Items.BANNER, 1, enumcolor.getInvColorIndex()), new Object[] { "###", "###", " | ", Character.valueOf('#'), new ItemStack(Blocks.WOOL, 1, enumcolor.getColorIndex()), Character.valueOf('|'), Items.STICK}); + } + + craftingmanager.a(new RecipesBanner.DuplicateRecipe((RecipesBanner.SyntheticClass_1) null)); + craftingmanager.a(new RecipesBanner.AddRecipe((RecipesBanner.SyntheticClass_1) null)); + } + + static class SyntheticClass_1 { } + + static class AddRecipe extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + + // CraftBukkit start - Delegate to new parent class with bogus info + private AddRecipe() { + super(new ItemStack(Items.BANNER, 0, 0), java.util.Arrays.asList(new ItemStack(Items.BANNER))); + } + // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + boolean flag = false; + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem() == Items.BANNER) { + if (flag) { + return false; + } + + if (TileEntityBanner.c(itemstack) >= 6) { + return false; + } + + flag = true; + } + } + + if (!flag) { + return false; + } else { + return this.c(inventorycrafting) != null; + } + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + ItemStack itemstack = null; + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); + + if (itemstack1 != null && itemstack1.getItem() == Items.BANNER) { + itemstack = itemstack1.cloneItemStack(); + itemstack.count = 1; + break; + } + } + + TileEntityBanner.EnumBannerPatternType tileentitybanner_enumbannerpatterntype = this.c(inventorycrafting); + + if (tileentitybanner_enumbannerpatterntype != null) { + int j = 0; + + ItemStack itemstack2; + + for (int k = 0; k < inventorycrafting.getSize(); ++k) { + itemstack2 = inventorycrafting.getItem(k); + if (itemstack2 != null && itemstack2.getItem() == Items.DYE) { + j = itemstack2.getData(); + break; + } + } + + NBTTagCompound nbttagcompound = itemstack.a("BlockEntityTag", true); + + itemstack2 = null; + NBTTagList nbttaglist; + + if (nbttagcompound.hasKeyOfType("Patterns", 9)) { + nbttaglist = nbttagcompound.getList("Patterns", 10); + } else { + nbttaglist = new NBTTagList(); + nbttagcompound.set("Patterns", nbttaglist); + } + + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setString("Pattern", tileentitybanner_enumbannerpatterntype.b()); + nbttagcompound1.setInt("Color", j); + nbttaglist.add(nbttagcompound1); + } + + return itemstack; + } + + public int a() { + return 10; + } + + public ItemStack b() { + return null; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem().r()) { + aitemstack[i] = new ItemStack(itemstack.getItem().q()); + } + } + + return aitemstack; + } + + private TileEntityBanner.EnumBannerPatternType c(InventoryCrafting inventorycrafting) { + TileEntityBanner.EnumBannerPatternType[] atileentitybanner_enumbannerpatterntype = TileEntityBanner.EnumBannerPatternType.values(); + int i = atileentitybanner_enumbannerpatterntype.length; + + for (int j = 0; j < i; ++j) { + TileEntityBanner.EnumBannerPatternType tileentitybanner_enumbannerpatterntype = atileentitybanner_enumbannerpatterntype[j]; + + if (tileentitybanner_enumbannerpatterntype.d()) { + boolean flag = true; + int k; + + if (tileentitybanner_enumbannerpatterntype.e()) { + boolean flag1 = false; + boolean flag2 = false; + + for (k = 0; k < inventorycrafting.getSize() && flag; ++k) { + ItemStack itemstack = inventorycrafting.getItem(k); + + if (itemstack != null && itemstack.getItem() != Items.BANNER) { + if (itemstack.getItem() == Items.DYE) { + if (flag2) { + flag = false; + break; + } + + flag2 = true; + } else { + if (flag1 || !itemstack.doMaterialsMatch(tileentitybanner_enumbannerpatterntype.f())) { + flag = false; + break; + } + + flag1 = true; + } + } + } + + if (!flag1) { + flag = false; + } + } else if (inventorycrafting.getSize() != tileentitybanner_enumbannerpatterntype.c().length * tileentitybanner_enumbannerpatterntype.c()[0].length()) { + flag = false; + } else { + int l = -1; + + for (int i1 = 0; i1 < inventorycrafting.getSize() && flag; ++i1) { + k = i1 / 3; + int j1 = i1 % 3; + ItemStack itemstack1 = inventorycrafting.getItem(i1); + + if (itemstack1 != null && itemstack1.getItem() != Items.BANNER) { + if (itemstack1.getItem() != Items.DYE) { + flag = false; + break; + } + + if (l != -1 && l != itemstack1.getData()) { + flag = false; + break; + } + + if (tileentitybanner_enumbannerpatterntype.c()[k].charAt(j1) == 32) { + flag = false; + break; + } + + l = itemstack1.getData(); + } else if (tileentitybanner_enumbannerpatterntype.c()[k].charAt(j1) != 32) { + flag = false; + break; + } + } + } + + if (flag) { + return tileentitybanner_enumbannerpatterntype; + } + } + } + + return null; + } + + AddRecipe(RecipesBanner.SyntheticClass_1 recipesbanner_syntheticclass_1) { + this(); + } + } + + static class DuplicateRecipe extends ShapelessRecipes implements IRecipe { // CraftBukkit - added extends + + // CraftBukkit start - Delegate to new parent class with bogus info + private DuplicateRecipe() { + super(new ItemStack(Items.BANNER, 0, 0), java.util.Arrays.asList(new ItemStack(Items.DYE, 0, 5))); + } + // CraftBukkit end + + public boolean a(InventoryCrafting inventorycrafting, World world) { + ItemStack itemstack = null; + ItemStack itemstack1 = null; + + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack2 = inventorycrafting.getItem(i); + + if (itemstack2 != null) { + if (itemstack2.getItem() != Items.BANNER) { + return false; + } + + if (itemstack != null && itemstack1 != null) { + return false; + } + + int j = TileEntityBanner.b(itemstack2); + boolean flag = TileEntityBanner.c(itemstack2) > 0; + + if (itemstack != null) { + if (flag) { + return false; + } + + if (j != TileEntityBanner.b(itemstack)) { + return false; + } + + itemstack1 = itemstack2; + } else if (itemstack1 != null) { + if (!flag) { + return false; + } + + if (j != TileEntityBanner.b(itemstack1)) { + return false; + } + + itemstack = itemstack2; + } else if (flag) { + itemstack = itemstack2; + } else { + itemstack1 = itemstack2; + } + } + } + + return itemstack != null && itemstack1 != null; + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && TileEntityBanner.c(itemstack) > 0) { + ItemStack itemstack1 = itemstack.cloneItemStack(); + + itemstack1.count = 1; + return itemstack1; + } + } + + return null; + } + + public int a() { + return 2; + } + + public ItemStack b() { + return null; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null) { + if (itemstack.getItem().r()) { + aitemstack[i] = new ItemStack(itemstack.getItem().q()); + } else if (itemstack.hasTag() && TileEntityBanner.c(itemstack) > 0) { + aitemstack[i] = itemstack.cloneItemStack(); + aitemstack[i].count = 1; + } + } + } + + return aitemstack; + } + + DuplicateRecipe(RecipesBanner.SyntheticClass_1 recipesbanner_syntheticclass_1) { + this(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipesFurnace.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipesFurnace.java new file mode 100644 index 0000000..d16fa9e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RecipesFurnace.java @@ -0,0 +1,125 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class RecipesFurnace { + + private static final RecipesFurnace a = new RecipesFurnace(); + public Map recipes = Maps.newHashMap(); + private Map c = Maps.newHashMap(); + public Map customRecipes = Maps.newHashMap(); // CraftBukkit - add field + + public static RecipesFurnace getInstance() { + return RecipesFurnace.a; + } + + public RecipesFurnace() { // PAIL: Public + this.registerRecipe(Blocks.IRON_ORE, new ItemStack(Items.IRON_INGOT), 0.7F); + this.registerRecipe(Blocks.GOLD_ORE, new ItemStack(Items.GOLD_INGOT), 1.0F); + this.registerRecipe(Blocks.DIAMOND_ORE, new ItemStack(Items.DIAMOND), 1.0F); + this.registerRecipe(Blocks.SAND, new ItemStack(Blocks.GLASS), 0.1F); + this.a(Items.PORKCHOP, new ItemStack(Items.COOKED_PORKCHOP), 0.35F); + this.a(Items.BEEF, new ItemStack(Items.COOKED_BEEF), 0.35F); + this.a(Items.CHICKEN, new ItemStack(Items.COOKED_CHICKEN), 0.35F); + this.a(Items.RABBIT, new ItemStack(Items.COOKED_RABBIT), 0.35F); + this.a(Items.MUTTON, new ItemStack(Items.COOKED_MUTTON), 0.35F); + this.registerRecipe(Blocks.COBBLESTONE, new ItemStack(Blocks.STONE), 0.1F); + this.a(new ItemStack(Blocks.STONEBRICK, 1, BlockSmoothBrick.b), new ItemStack(Blocks.STONEBRICK, 1, BlockSmoothBrick.O), 0.1F); + this.a(Items.CLAY_BALL, new ItemStack(Items.BRICK), 0.3F); + this.registerRecipe(Blocks.CLAY, new ItemStack(Blocks.HARDENED_CLAY), 0.35F); + this.registerRecipe(Blocks.CACTUS, new ItemStack(Items.DYE, 1, EnumColor.GREEN.getInvColorIndex()), 0.2F); + this.registerRecipe(Blocks.LOG, new ItemStack(Items.COAL, 1, 1), 0.15F); + this.registerRecipe(Blocks.LOG2, new ItemStack(Items.COAL, 1, 1), 0.15F); + this.registerRecipe(Blocks.EMERALD_ORE, new ItemStack(Items.EMERALD), 1.0F); + this.a(Items.POTATO, new ItemStack(Items.BAKED_POTATO), 0.35F); + this.registerRecipe(Blocks.NETHERRACK, new ItemStack(Items.NETHERBRICK), 0.1F); + this.a(new ItemStack(Blocks.SPONGE, 1, 1), new ItemStack(Blocks.SPONGE, 1, 0), 0.15F); + ItemFish.EnumFish[] aitemfish_enumfish = ItemFish.EnumFish.values(); + int i = aitemfish_enumfish.length; + + for (int j = 0; j < i; ++j) { + ItemFish.EnumFish itemfish_enumfish = aitemfish_enumfish[j]; + + if (itemfish_enumfish.g()) { + this.a(new ItemStack(Items.FISH, 1, itemfish_enumfish.a()), new ItemStack(Items.COOKED_FISH, 1, itemfish_enumfish.a()), 0.35F); + } + } + + this.registerRecipe(Blocks.COAL_ORE, new ItemStack(Items.COAL), 0.1F); + this.registerRecipe(Blocks.REDSTONE_ORE, new ItemStack(Items.REDSTONE), 0.7F); + this.registerRecipe(Blocks.LAPIS_ORE, new ItemStack(Items.DYE, 1, EnumColor.BLUE.getInvColorIndex()), 0.2F); + this.registerRecipe(Blocks.QUARTZ_ORE, new ItemStack(Items.QUARTZ), 0.2F); + } + + // CraftBukkit start - add method + public void registerRecipe(ItemStack itemstack, ItemStack itemstack1) { + this.customRecipes.put(itemstack, itemstack1); + } + // CraftBukkit end + + public void registerRecipe(Block block, ItemStack itemstack, float f) { + this.a(Item.getItemOf(block), itemstack, f); + } + + public void a(Item item, ItemStack itemstack, float f) { + this.a(new ItemStack(item, 1, 32767), itemstack, f); + } + + public void a(ItemStack itemstack, ItemStack itemstack1, float f) { + this.recipes.put(itemstack, itemstack1); + this.c.put(itemstack1, Float.valueOf(f)); + } + + public ItemStack getResult(ItemStack itemstack) { + // CraftBukkit start - initialize to customRecipes + boolean vanilla = false; + Iterator iterator = this.customRecipes.entrySet().iterator(); + // CraftBukkit end + + Entry entry; + + do { + if (!iterator.hasNext()) { + // CraftBukkit start - fall back to vanilla recipes + if (!vanilla && !recipes.isEmpty()) { + iterator = this.recipes.entrySet().iterator(); + vanilla = true; + } else { + return null; + } + // CraftBukkit end + } + + entry = (Entry) iterator.next(); + } while (!this.a(itemstack, (ItemStack) entry.getKey())); + + return (ItemStack) entry.getValue(); + } + + private boolean a(ItemStack itemstack, ItemStack itemstack1) { + return itemstack1.getItem() == itemstack.getItem() && (itemstack1.getData() == 32767 || itemstack1.getData() == itemstack.getData()); + } + + public Map getRecipes() { + return this.recipes; + } + + public float b(ItemStack itemstack) { + Iterator iterator = this.c.entrySet().iterator(); + + Entry entry; + + do { + if (!iterator.hasNext()) { + return 0.0F; + } + + entry = (Entry) iterator.next(); + } while (!this.a(itemstack, (ItemStack) entry.getKey())); + + return ((Float) entry.getValue()).floatValue(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RegionFile.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RegionFile.java new file mode 100644 index 0000000..348706f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RegionFile.java @@ -0,0 +1,307 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.util.List; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.InflaterInputStream; + +public class RegionFile { + + private static final byte[] a = new byte[4096]; // Spigot - note: if this ever changes to not be 4096 bytes, update constructor! // PAIL: empty 4k block + private final File b; + private RandomAccessFile c; + private final int[] d = new int[1024]; + private final int[] e = new int[1024]; + private List f; + private int g; + private long h; + + public RegionFile(File file) { + this.b = file; + this.g = 0; + + try { + if (file.exists()) { + this.h = file.lastModified(); + } + + this.c = new RandomAccessFile(file, "rw"); + int i; + + if (this.c.length() < 4096L) { + // Spigot - more effecient chunk zero'ing + this.c.write(RegionFile.a); // Spigot + this.c.write(RegionFile.a); // Spigot + + this.g += 8192; + } + + if ((this.c.length() & 4095L) != 0L) { + for (i = 0; (long) i < (this.c.length() & 4095L); ++i) { + this.c.write(0); + } + } + + i = (int) this.c.length() / 4096; + this.f = Lists.newArrayListWithCapacity(i); + + int j; + + for (j = 0; j < i; ++j) { + this.f.add(Boolean.valueOf(true)); + } + + this.f.set(0, Boolean.valueOf(false)); + this.f.set(1, Boolean.valueOf(false)); + this.c.seek(0L); + + int k; + + for (j = 0; j < 1024; ++j) { + k = this.c.readInt(); + this.d[j] = k; + if (k != 0 && (k >> 8) + (k & 255) <= this.f.size()) { + for (int l = 0; l < (k & 255); ++l) { + this.f.set((k >> 8) + l, Boolean.valueOf(false)); + } + } + } + + for (j = 0; j < 1024; ++j) { + k = this.c.readInt(); + this.e[j] = k; + } + } catch (IOException ioexception) { + ioexception.printStackTrace(); + } + + } + + // CraftBukkit start - This is a copy (sort of) of the method below it, make sure they stay in sync + public synchronized boolean chunkExists(int i, int j) { + if (this.d(i, j)) { + return false; + } else { + try { + int k = this.e(i, j); + + if (k == 0) { + return false; + } else { + int l = k >> 8; + int i1 = k & 255; + + if (l + i1 > this.f.size()) { + return false; + } + + this.c.seek((long) (l * 4096)); + int j1 = this.c.readInt(); + + if (j1 > 4096 * i1 || j1 <= 0) { + return false; + } + + byte b0 = this.c.readByte(); + if (b0 == 1 || b0 == 2) { + return true; + } + } + } catch (IOException ioexception) { + return false; + } + } + + return false; + } + // CraftBukkit end + + public synchronized DataInputStream a(int i, int j) { + if (this.d(i, j)) { + return null; + } else { + try { + int k = this.e(i, j); + + if (k == 0) { + return null; + } else { + int l = k >> 8; + int i1 = k & 255; + + if (l + i1 > this.f.size()) { + return null; + } else { + this.c.seek((long) (l * 4096)); + int j1 = this.c.readInt(); + + if (j1 > 4096 * i1) { + return null; + } else if (j1 <= 0) { + return null; + } else { + byte b0 = this.c.readByte(); + byte[] abyte; + + if (b0 == 1) { + abyte = new byte[j1 - 1]; + this.c.read(abyte); + return new DataInputStream(new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(abyte)))); + } else if (b0 == 2) { + abyte = new byte[j1 - 1]; + this.c.read(abyte); + return new DataInputStream(new BufferedInputStream(new InflaterInputStream(new ByteArrayInputStream(abyte)))); + } else { + return null; + } + } + } + } + } catch (IOException ioexception) { + return null; + } + } + } + + public DataOutputStream b(int i, int j) { // PAIL: getChunkOutputStream + // PAIL: isInvalidRegion + return this.d(i, j) ? null : new DataOutputStream(new java.io.BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(i, j)))); // Spigot - use a BufferedOutputStream to greatly improve file write performance + } + + protected synchronized void a(int i, int j, byte[] abyte, int k) { + try { + int l = this.e(i, j); + int i1 = l >> 8; + int j1 = l & 255; + int k1 = (k + 5) / 4096 + 1; + + if (k1 >= 256) { + return; + } + + if (i1 != 0 && j1 == k1) { + this.a(i1, abyte, k); + } else { + int l1; + + for (l1 = 0; l1 < j1; ++l1) { + this.f.set(i1 + l1, Boolean.valueOf(true)); + } + + l1 = this.f.indexOf(Boolean.valueOf(true)); + int i2 = 0; + int j2; + + if (l1 != -1) { + for (j2 = l1; j2 < this.f.size(); ++j2) { + if (i2 != 0) { + if (((Boolean) this.f.get(j2)).booleanValue()) { + ++i2; + } else { + i2 = 0; + } + } else if (((Boolean) this.f.get(j2)).booleanValue()) { + l1 = j2; + i2 = 1; + } + + if (i2 >= k1) { + break; + } + } + } + + if (i2 >= k1) { + i1 = l1; + this.a(i, j, l1 << 8 | k1); + + for (j2 = 0; j2 < k1; ++j2) { + this.f.set(i1 + j2, Boolean.valueOf(false)); + } + + this.a(i1, abyte, k); + } else { + this.c.seek(this.c.length()); + i1 = this.f.size(); + + for (j2 = 0; j2 < k1; ++j2) { + this.c.write(RegionFile.a); + this.f.add(Boolean.valueOf(false)); + } + + this.g += 4096 * k1; + this.a(i1, abyte, k); + this.a(i, j, i1 << 8 | k1); + } + } + + this.b(i, j, (int) (MinecraftServer.az() / 1000L)); + } catch (IOException ioexception) { + ioexception.printStackTrace(); + } + + } + + private void a(int i, byte[] abyte, int j) throws IOException { + this.c.seek((long) (i * 4096)); + this.c.writeInt(j + 1); + this.c.writeByte(2); + this.c.write(abyte, 0, j); + } + + private boolean d(int i, int j) { + return i < 0 || i >= 32 || j < 0 || j >= 32; + } + + private int e(int i, int j) { + return this.d[i + j * 32]; + } + + public boolean c(int i, int j) { + return this.e(i, j) != 0; + } + + private void a(int i, int j, int k) throws IOException { + this.d[i + j * 32] = k; + this.c.seek((long) ((i + j * 32) * 4)); + this.c.writeInt(k); + } + + private void b(int i, int j, int k) throws IOException { + this.e[i + j * 32] = k; + this.c.seek((long) (4096 + (i + j * 32) * 4)); + this.c.writeInt(k); + } + + public void c() throws IOException { + if (this.c != null) { + this.c.close(); + } + + } + + class ChunkBuffer extends ByteArrayOutputStream { + + private int b; + private int c; + + public ChunkBuffer(int i, int j) { + super(8096); + this.b = i; + this.c = j; + } + + public void close() { + RegionFile.this.a(this.b, this.c, this.buf, this.count); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RegionFileCache.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RegionFileCache.java new file mode 100644 index 0000000..5b000c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RegionFileCache.java @@ -0,0 +1,73 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; + +public class RegionFileCache { + + public static final Map a = Maps.newHashMap(); // Spigot - private -> public + + // PaperSpigot start + public static synchronized RegionFile a(File file, int i, int j) { + return a(file, i, j, true); + } + public static synchronized RegionFile a(File file, int i, int j, boolean create) { + // PaperSpigot end + File file1 = new File(file, "region"); + File file2 = new File(file1, "r." + (i >> 5) + "." + (j >> 5) + ".mca"); + RegionFile regionfile = (RegionFile) RegionFileCache.a.get(file2); + + if (regionfile != null) { + return regionfile; + } else { + if (!create && !file2.exists()) { return null; } // PaperSpigot + if (!file1.exists()) { + file1.mkdirs(); + } + + if (RegionFileCache.a.size() >= 256) { + a(); + } + + RegionFile regionfile1 = new RegionFile(file2); + + RegionFileCache.a.put(file2, regionfile1); + return regionfile1; + } + } + + public static synchronized void a() { + Iterator iterator = RegionFileCache.a.values().iterator(); + + while (iterator.hasNext()) { + RegionFile regionfile = (RegionFile) iterator.next(); + + try { + if (regionfile != null) { + regionfile.c(); + } + } catch (IOException ioexception) { + ioexception.printStackTrace(); + } + } + + RegionFileCache.a.clear(); + } + + public static DataInputStream c(File file, int i, int j) { + RegionFile regionfile = a(file, i, j); + + return regionfile.a(i & 31, j & 31); + } + + public static DataOutputStream d(File file, int i, int j) { + RegionFile regionfile = a(file, i, j); + + return regionfile.b(i & 31, j & 31); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RemoteControlCommandListener.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RemoteControlCommandListener.java new file mode 100644 index 0000000..a63cf82 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/RemoteControlCommandListener.java @@ -0,0 +1,65 @@ +package net.minecraft.server; + +public class RemoteControlCommandListener implements ICommandListener { + + private static final RemoteControlCommandListener instance = new RemoteControlCommandListener(); + private StringBuffer b = new StringBuffer(); + + public RemoteControlCommandListener() {} + + public static RemoteControlCommandListener getInstance() { + return RemoteControlCommandListener.instance; + } + + public void i() { + this.b.setLength(0); + } + + public String j() { + return this.b.toString(); + } + + public String getName() { + return "Rcon"; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return new ChatComponentText(this.getName()); + } + + // CraftBukkit start - Send a String + public void sendMessage(String message) { + this.b.append(message); + } + // CraftBukkit end + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + this.b.append(ichatbasecomponent.c()); + } + + public boolean a(int i, String s) { + return true; + } + + public BlockPosition getChunkCoordinates() { + return new BlockPosition(0, 0, 0); + } + + public Vec3D d() { + return new Vec3D(0.0D, 0.0D, 0.0D); + } + + public World getWorld() { + return MinecraftServer.getServer().getWorld(); + } + + public Entity f() { + return null; + } + + public boolean getSendCommandFeedback() { + return true; + } + + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ScoreboardServer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ScoreboardServer.java new file mode 100644 index 0000000..1fe9d93 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ScoreboardServer.java @@ -0,0 +1,230 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class ScoreboardServer extends Scoreboard { + + private final MinecraftServer a; + private final Set b = Sets.newHashSet(); + private PersistentScoreboard c; + + public ScoreboardServer(MinecraftServer minecraftserver) { + this.a = minecraftserver; + } + + public void handleScoreChanged(ScoreboardScore scoreboardscore) { + super.handleScoreChanged(scoreboardscore); + if (this.b.contains(scoreboardscore.getObjective())) { + this.sendAll(new PacketPlayOutScoreboardScore(scoreboardscore)); + } + + this.b(); + } + + public void handlePlayerRemoved(String s) { + super.handlePlayerRemoved(s); + this.sendAll(new PacketPlayOutScoreboardScore(s)); + this.b(); + } + + public void a(String s, ScoreboardObjective scoreboardobjective) { + super.a(s, scoreboardobjective); + this.sendAll(new PacketPlayOutScoreboardScore(s, scoreboardobjective)); + this.b(); + } + + public void setDisplaySlot(int i, ScoreboardObjective scoreboardobjective) { + ScoreboardObjective scoreboardobjective1 = this.getObjectiveForSlot(i); + + super.setDisplaySlot(i, scoreboardobjective); + if (scoreboardobjective1 != scoreboardobjective && scoreboardobjective1 != null) { + if (this.h(scoreboardobjective1) > 0) { + this.sendAll(new PacketPlayOutScoreboardDisplayObjective(i, scoreboardobjective)); + } else { + this.g(scoreboardobjective1); + } + } + + if (scoreboardobjective != null) { + if (this.b.contains(scoreboardobjective)) { + this.sendAll(new PacketPlayOutScoreboardDisplayObjective(i, scoreboardobjective)); + } else { + this.e(scoreboardobjective); + } + } + + this.b(); + } + + public boolean addPlayerToTeam(String s, String s1) { + if (super.addPlayerToTeam(s, s1)) { + ScoreboardTeam scoreboardteam = this.getTeam(s1); + + this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 3)); + this.b(); + return true; + } else { + return false; + } + } + + public void removePlayerFromTeam(String s, ScoreboardTeam scoreboardteam) { + super.removePlayerFromTeam(s, scoreboardteam); + this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, Arrays.asList(new String[] { s}), 4)); + this.b(); + } + + public void handleObjectiveAdded(ScoreboardObjective scoreboardobjective) { + super.handleObjectiveAdded(scoreboardobjective); + this.b(); + } + + public void handleObjectiveChanged(ScoreboardObjective scoreboardobjective) { + super.handleObjectiveChanged(scoreboardobjective); + if (this.b.contains(scoreboardobjective)) { + this.sendAll(new PacketPlayOutScoreboardObjective(scoreboardobjective, 2)); + } + + this.b(); + } + + public void handleObjectiveRemoved(ScoreboardObjective scoreboardobjective) { + super.handleObjectiveRemoved(scoreboardobjective); + if (this.b.contains(scoreboardobjective)) { + this.g(scoreboardobjective); + } + + this.b(); + } + + public void handleTeamAdded(ScoreboardTeam scoreboardteam) { + super.handleTeamAdded(scoreboardteam); + this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 0)); + this.b(); + } + + public void handleTeamChanged(ScoreboardTeam scoreboardteam) { + super.handleTeamChanged(scoreboardteam); + this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 2)); + this.b(); + } + + public void handleTeamRemoved(ScoreboardTeam scoreboardteam) { + super.handleTeamRemoved(scoreboardteam); + this.sendAll(new PacketPlayOutScoreboardTeam(scoreboardteam, 1)); + this.b(); + } + + public void a(PersistentScoreboard persistentscoreboard) { + this.c = persistentscoreboard; + } + + protected void b() { + if (this.c != null) { + this.c.c(); + } + + } + + public List getScoreboardScorePacketsForObjective(ScoreboardObjective scoreboardobjective) { + ArrayList arraylist = Lists.newArrayList(); + + arraylist.add(new PacketPlayOutScoreboardObjective(scoreboardobjective, 0)); + + for (int i = 0; i < 19; ++i) { + if (this.getObjectiveForSlot(i) == scoreboardobjective) { + arraylist.add(new PacketPlayOutScoreboardDisplayObjective(i, scoreboardobjective)); + } + } + + Iterator iterator = this.getScoresForObjective(scoreboardobjective).iterator(); + + while (iterator.hasNext()) { + ScoreboardScore scoreboardscore = (ScoreboardScore) iterator.next(); + + arraylist.add(new PacketPlayOutScoreboardScore(scoreboardscore)); + } + + return arraylist; + } + + public void e(ScoreboardObjective scoreboardobjective) { + List list = this.getScoreboardScorePacketsForObjective(scoreboardobjective); + Iterator iterator = this.a.getPlayerList().v().iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + if (entityplayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { + Packet packet = (Packet) iterator1.next(); + + entityplayer.playerConnection.sendPacket(packet); + } + } + + this.b.add(scoreboardobjective); + } + + public List f(ScoreboardObjective scoreboardobjective) { + ArrayList arraylist = Lists.newArrayList(); + + arraylist.add(new PacketPlayOutScoreboardObjective(scoreboardobjective, 1)); + + for (int i = 0; i < 19; ++i) { + if (this.getObjectiveForSlot(i) == scoreboardobjective) { + arraylist.add(new PacketPlayOutScoreboardDisplayObjective(i, scoreboardobjective)); + } + } + + return arraylist; + } + + public void g(ScoreboardObjective scoreboardobjective) { + List list = this.f(scoreboardobjective); + Iterator iterator = this.a.getPlayerList().v().iterator(); + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + if (entityplayer.getBukkitEntity().getScoreboard().getHandle() != this) continue; // CraftBukkit - Only players on this board + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { + Packet packet = (Packet) iterator1.next(); + + entityplayer.playerConnection.sendPacket(packet); + } + } + + this.b.remove(scoreboardobjective); + } + + public int h(ScoreboardObjective scoreboardobjective) { + int i = 0; + + for (int j = 0; j < 19; ++j) { + if (this.getObjectiveForSlot(j) == scoreboardobjective) { + ++i; + } + } + + return i; + } + + // CraftBukkit start - Send to players + private void sendAll(Packet packet) { + for (EntityPlayer entityplayer : (List) this.a.getPlayerList().players) { + if (entityplayer.getBukkitEntity().getScoreboard().getHandle() == this) { + entityplayer.playerConnection.sendPacket(packet); + } + } + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SecondaryWorldServer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SecondaryWorldServer.java new file mode 100644 index 0000000..209eb01 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SecondaryWorldServer.java @@ -0,0 +1,63 @@ +package net.minecraft.server; + +public class SecondaryWorldServer extends WorldServer { + + private WorldServer a; + + // CraftBukkit start - Add WorldData, Environment and ChunkGenerator arguments + public SecondaryWorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, int i, WorldServer worldserver, MethodProfiler methodprofiler, WorldData worldData, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(minecraftserver, idatamanager, worldData, i, methodprofiler, env, gen); + // CraftBukkit end + this.a = worldserver; + /* CraftBukkit start + worldserver.getWorldBorder().a(new IWorldBorderListener() { + public void a(WorldBorder worldborder, double d0) { + SecondaryWorldServer.this.getWorldBorder().setSize(d0); + } + + public void a(WorldBorder worldborder, double d0, double d1, long i) { + SecondaryWorldServer.this.getWorldBorder().transitionSizeBetween(d0, d1, i); + } + + public void a(WorldBorder worldborder, double d0, double d1) { + SecondaryWorldServer.this.getWorldBorder().setCenter(d0, d1); + } + + public void a(WorldBorder worldborder, int i) { + SecondaryWorldServer.this.getWorldBorder().setWarningTime(i); + } + + public void b(WorldBorder worldborder, int i) { + SecondaryWorldServer.this.getWorldBorder().setWarningDistance(i); + } + + public void b(WorldBorder worldborder, double d0) { + SecondaryWorldServer.this.getWorldBorder().setDamageAmount(d0); + } + + public void c(WorldBorder worldborder, double d0) { + SecondaryWorldServer.this.getWorldBorder().setDamageBuffer(d0); + } + }); + // CraftBukkit end */ + } + + // protected void a() {} // CraftBukkit + + public World b() { + this.worldMaps = this.a.T(); + // this.scoreboard = this.a.getScoreboard(); // CraftBukkit + String s = PersistentVillage.a(this.worldProvider); + PersistentVillage persistentvillage = (PersistentVillage) this.worldMaps.get(PersistentVillage.class, s); + + if (persistentvillage == null) { + this.villages = new PersistentVillage(this); + this.worldMaps.a(s, this.villages); + } else { + this.villages = persistentvillage; + this.villages.a((World) this); + } + + return super.b(); // CraftBukkit + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ServerConnection.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ServerConnection.java new file mode 100644 index 0000000..1dab9bb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ServerConnection.java @@ -0,0 +1,187 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.channel.epoll.Epoll; +import io.netty.channel.epoll.EpollEventLoopGroup; +import io.netty.channel.epoll.EpollServerSocketChannel; +import io.netty.channel.local.LocalEventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.timeout.ReadTimeoutHandler; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.net.InetAddress; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.logging.Level; + +public class ServerConnection { + + private static final Logger e = LogManager.getLogger(); + public static final LazyInitVar a = new LazyInitVar() { + protected NioEventLoopGroup a() { + return new NioEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Server IO #%d").setDaemon(true).build()); + } + + protected Object init() { + return this.a(); + } + }; + public static final LazyInitVar b = new LazyInitVar() { + protected EpollEventLoopGroup a() { + return new EpollEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Epoll Server IO #%d").setDaemon(true).build()); + } + + protected Object init() { + return this.a(); + } + }; + public static final LazyInitVar c = new LazyInitVar() { + protected LocalEventLoopGroup a() { + return new LocalEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Server IO #%d").setDaemon(true).build()); + } + + protected Object init() { + return this.a(); + } + }; + private final MinecraftServer f; + public volatile boolean d; + private final List g = Collections.synchronizedList(Lists.newArrayList()); + private final List h = Collections.synchronizedList(Lists.newArrayList()); + + public ServerConnection(MinecraftServer minecraftserver) { + this.f = minecraftserver; + this.d = true; + } + + public void a(InetAddress inetaddress, int i) throws IOException { + List list = this.g; + + synchronized (this.g) { + Class oclass; + LazyInitVar lazyinitvar; + + if (Epoll.isAvailable() && this.f.ai()) { + oclass = EpollServerSocketChannel.class; + lazyinitvar = ServerConnection.b; + ServerConnection.e.info("Using epoll channel type"); + } else { + oclass = NioServerSocketChannel.class; + lazyinitvar = ServerConnection.a; + ServerConnection.e.info("Using default channel type"); + } + + 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.valueOf(true)); + } catch (ChannelException channelexception) { + } + + channel.pipeline().addLast("timeout", new ReadTimeoutHandler(30)).addLast("legacy_query", new LegacyPingHandler(ServerConnection.this)).addLast("splitter", new PacketSplitter()).addLast("decoder", new PacketDecoder(EnumProtocolDirection.SERVERBOUND)).addLast("prepender", new PacketPrepender()).addLast("encoder", new PacketEncoder(EnumProtocolDirection.CLIENTBOUND)); + NetworkManager networkmanager = new NetworkManager(EnumProtocolDirection.SERVERBOUND); + + ServerConnection.this.h.add(networkmanager); + channel.pipeline().addLast("packet_handler", networkmanager); + networkmanager.a(new HandshakeListener(ServerConnection.this.f, networkmanager)); + } + }).group((EventLoopGroup) lazyinitvar.c()).localAddress(inetaddress, i).bind().syncUninterruptibly()); + } + } + + public void b() { + this.d = false; + Iterator iterator = this.g.iterator(); + + while (iterator.hasNext()) { + ChannelFuture channelfuture = (ChannelFuture) iterator.next(); + + try { + channelfuture.channel().close().sync(); + } catch (InterruptedException interruptedexception) { + ServerConnection.e.error("Interrupted whilst closing channel"); + } + } + + } + + public void c() { + List list = this.h; + + synchronized (this.h) { + // Spigot Start + // This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order + if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0 ) + { + Collections.shuffle( this.h ); + } + // Spigot End + Iterator iterator = this.h.iterator(); + + while (iterator.hasNext()) { + final NetworkManager networkmanager = (NetworkManager) iterator.next(); + + if (!networkmanager.h()) { + if (!networkmanager.g()) { + // Spigot Start + // Fix a race condition where a NetworkManager could be unregistered just before connection. + if (networkmanager.preparing) continue; + // Spigot End + iterator.remove(); + networkmanager.l(); + } else { + try { + networkmanager.a(); + } catch (Exception exception) { + if (networkmanager.c()) { + CrashReport crashreport = CrashReport.a(exception, "Ticking memory connection"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Ticking connection"); + + crashreportsystemdetails.a("Connection", new Callable() { + public String a() throws Exception { + return networkmanager.toString(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + + ServerConnection.e.warn("Failed to handle packet for " + networkmanager.getSocketAddress(), exception); + final ChatComponentText chatcomponenttext = new ChatComponentText("Internal server error"); + + networkmanager.a(new PacketPlayOutKickDisconnect(chatcomponenttext), new GenericFutureListener() { + public void operationComplete(Future future) throws Exception { + networkmanager.close(chatcomponenttext); + } + }); + networkmanager.k(); + } + } + } + } + + } + } + + public MinecraftServer d() { + return this.f; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ServerStatisticManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ServerStatisticManager.java new file mode 100644 index 0000000..22c2ffd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ServerStatisticManager.java @@ -0,0 +1,222 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ServerStatisticManager extends StatisticManager { + + private static final Logger b = LogManager.getLogger(); + private final MinecraftServer c; + private final File d; + private final Set e = Sets.newHashSet(); + private int f = -300; + private boolean g = false; + + public ServerStatisticManager(MinecraftServer minecraftserver, File file) { + this.c = minecraftserver; + this.d = file; + // Spigot start + for ( String name : org.spigotmc.SpigotConfig.forcedStats.keySet() ) + { + StatisticWrapper wrapper = new StatisticWrapper(); + wrapper.a( org.spigotmc.SpigotConfig.forcedStats.get( name ) ); + a.put( StatisticList.getStatistic( name ), wrapper ); + } + // Spigot end + } + + public void a() { + if (this.d.isFile()) { + try { + this.a.clear(); + this.a.putAll(this.a(FileUtils.readFileToString(this.d))); + } catch (IOException ioexception) { + ServerStatisticManager.b.error("Couldn\'t read statistics file " + this.d, ioexception); + } catch (JsonParseException jsonparseexception) { + ServerStatisticManager.b.error("Couldn\'t parse statistics file " + this.d, jsonparseexception); + } + } + + } + + public void b() { + if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot + try { + FileUtils.writeStringToFile(this.d, a(this.a)); + } catch (IOException ioexception) { + ServerStatisticManager.b.error("Couldn\'t save stats", ioexception); + } + + } + + public void setStatistic(EntityHuman entityhuman, Statistic statistic, int i) { + if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot + int j = statistic.d() ? this.getStatisticValue(statistic) : 0; + + super.setStatistic(entityhuman, statistic, i); + this.e.add(statistic); + if (statistic.d() && j == 0 && i > 0) { + this.g = true; + if (this.c.aB()) { + this.c.getPlayerList().sendMessage(new ChatMessage("chat.type.achievement", new Object[] { entityhuman.getScoreboardDisplayName(), statistic.j()})); + } + } + + if (statistic.d() && j > 0 && i == 0) { + this.g = true; + if (this.c.aB()) { + this.c.getPlayerList().sendMessage(new ChatMessage("chat.type.achievement.taken", new Object[] { entityhuman.getScoreboardDisplayName(), statistic.j()})); + } + } + + } + + public Set c() { + HashSet hashset = Sets.newHashSet(this.e); + + this.e.clear(); + this.g = false; + return hashset; + } + + public Map a(String s) { + JsonElement jsonelement = (new JsonParser()).parse(s); + + if (!jsonelement.isJsonObject()) { + return Maps.newHashMap(); + } else { + JsonObject jsonobject = jsonelement.getAsJsonObject(); + HashMap hashmap = Maps.newHashMap(); + Iterator iterator = jsonobject.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + Statistic statistic = StatisticList.getStatistic((String) entry.getKey()); + + if (statistic != null) { + StatisticWrapper statisticwrapper = new StatisticWrapper(); + + if (((JsonElement) entry.getValue()).isJsonPrimitive() && ((JsonElement) entry.getValue()).getAsJsonPrimitive().isNumber()) { + statisticwrapper.a(((JsonElement) entry.getValue()).getAsInt()); + } else if (((JsonElement) entry.getValue()).isJsonObject()) { + JsonObject jsonobject1 = ((JsonElement) entry.getValue()).getAsJsonObject(); + + if (jsonobject1.has("value") && jsonobject1.get("value").isJsonPrimitive() && jsonobject1.get("value").getAsJsonPrimitive().isNumber()) { + statisticwrapper.a(jsonobject1.getAsJsonPrimitive("value").getAsInt()); + } + + if (jsonobject1.has("progress") && statistic.l() != null) { + try { + Constructor constructor = statistic.l().getConstructor(new Class[0]); + IJsonStatistic ijsonstatistic = (IJsonStatistic) constructor.newInstance(new Object[0]); + + ijsonstatistic.a(jsonobject1.get("progress")); + statisticwrapper.a(ijsonstatistic); + } catch (Throwable throwable) { + ServerStatisticManager.b.warn("Invalid statistic progress in " + this.d, throwable); + } + } + } + + hashmap.put(statistic, statisticwrapper); + } else { + ServerStatisticManager.b.warn("Invalid statistic in " + this.d + ": Don\'t know what " + (String) entry.getKey() + " is"); + } + } + + return hashmap; + } + } + + public static String a(Map map) { + JsonObject jsonobject = new JsonObject(); + Iterator iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + + if (((StatisticWrapper) entry.getValue()).b() != null) { + JsonObject jsonobject1 = new JsonObject(); + + jsonobject1.addProperty("value", Integer.valueOf(((StatisticWrapper) entry.getValue()).a())); + + try { + jsonobject1.add("progress", ((StatisticWrapper) entry.getValue()).b().a()); + } catch (Throwable throwable) { + ServerStatisticManager.b.warn("Couldn\'t save statistic " + ((Statistic) entry.getKey()).e() + ": error serializing progress", throwable); + } + + jsonobject.add(((Statistic) entry.getKey()).name, jsonobject1); + } else { + jsonobject.addProperty(((Statistic) entry.getKey()).name, Integer.valueOf(((StatisticWrapper) entry.getValue()).a())); + } + } + + return jsonobject.toString(); + } + + public void d() { + Iterator iterator = this.a.keySet().iterator(); + + while (iterator.hasNext()) { + Statistic statistic = (Statistic) iterator.next(); + + this.e.add(statistic); + } + + } + + public void a(EntityPlayer entityplayer) { + int i = this.c.at(); + HashMap hashmap = Maps.newHashMap(); + + if (this.g || i - this.f > 300) { + this.f = i; + Iterator iterator = this.c().iterator(); + + while (iterator.hasNext()) { + Statistic statistic = (Statistic) iterator.next(); + + hashmap.put(statistic, Integer.valueOf(this.getStatisticValue(statistic))); + } + } + + entityplayer.playerConnection.sendPacket(new PacketPlayOutStatistic(hashmap)); + } + + public void updateStatistics(EntityPlayer entityplayer) { + HashMap hashmap = Maps.newHashMap(); + Iterator iterator = AchievementList.e.iterator(); + + while (iterator.hasNext()) { + Achievement achievement = (Achievement) iterator.next(); + + if (this.hasAchievement(achievement)) { + hashmap.put(achievement, Integer.valueOf(this.getStatisticValue(achievement))); + this.e.remove(achievement); + } + } + + entityplayer.playerConnection.sendPacket(new PacketPlayOutStatistic(hashmap)); + } + + public boolean e() { + return this.g; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ShapedRecipes.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ShapedRecipes.java new file mode 100644 index 0000000..cac2e78 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ShapedRecipes.java @@ -0,0 +1,175 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; +// CraftBukkit end + +public class ShapedRecipes implements IRecipe { + + private final int width; + private final int height; + private final ItemStack[] items; + public ItemStack result; // Spigot + private boolean e; + + public ShapedRecipes(int i, int j, ItemStack[] aitemstack, ItemStack itemstack) { + this.width = i; + this.height = j; + this.items = aitemstack; + this.result = itemstack; + } + + // CraftBukkit start + public org.bukkit.inventory.ShapedRecipe toBukkitRecipe() { + CraftItemStack result = CraftItemStack.asCraftMirror(this.result); + CraftShapedRecipe recipe = new CraftShapedRecipe(result, this); + switch (this.height) { + case 1: + switch (this.width) { + case 1: + recipe.shape("a"); + break; + case 2: + recipe.shape("ab"); + break; + case 3: + recipe.shape("abc"); + break; + } + break; + case 2: + switch (this.width) { + case 1: + recipe.shape("a","b"); + break; + case 2: + recipe.shape("ab","cd"); + break; + case 3: + recipe.shape("abc","def"); + break; + } + break; + case 3: + switch (this.width) { + case 1: + recipe.shape("a","b","c"); + break; + case 2: + recipe.shape("ab","cd","ef"); + break; + case 3: + recipe.shape("abc","def","ghi"); + break; + } + break; + } + char c = 'a'; + for (ItemStack stack : this.items) { + if (stack != null) { + recipe.setIngredient(c, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), stack.getData()); + } + c++; + } + return recipe; + } + // CraftBukkit end + + public ItemStack b() { + return this.result; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem().r()) { + aitemstack[i] = new ItemStack(itemstack.getItem().q()); + } + } + + return aitemstack; + } + + public boolean a(InventoryCrafting inventorycrafting, World world) { + for (int i = 0; i <= 3 - this.width; ++i) { + for (int j = 0; j <= 3 - this.height; ++j) { + if (this.a(inventorycrafting, i, j, true)) { + return true; + } + + if (this.a(inventorycrafting, i, j, false)) { + return true; + } + } + } + + return false; + } + + private boolean a(InventoryCrafting inventorycrafting, int i, int j, boolean flag) { + for (int k = 0; k < 3; ++k) { + for (int l = 0; l < 3; ++l) { + int i1 = k - i; + int j1 = l - j; + ItemStack itemstack = null; + + if (i1 >= 0 && j1 >= 0 && i1 < this.width && j1 < this.height) { + if (flag) { + itemstack = this.items[this.width - i1 - 1 + j1 * this.width]; + } else { + itemstack = this.items[i1 + j1 * this.width]; + } + } + + ItemStack itemstack1 = inventorycrafting.c(k, l); + + if (itemstack1 != null || itemstack != null) { + if (itemstack1 == null && itemstack != null || itemstack1 != null && itemstack == null) { + return false; + } + + if (itemstack.getItem() != itemstack1.getItem()) { + return false; + } + + if (itemstack.getData() != 32767 && itemstack.getData() != itemstack1.getData()) { + return false; + } + } + } + } + + return true; + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + ItemStack itemstack = this.b().cloneItemStack(); + + if (this.e) { + for (int i = 0; i < inventorycrafting.getSize(); ++i) { + ItemStack itemstack1 = inventorycrafting.getItem(i); + + if (itemstack1 != null && itemstack1.hasTag()) { + itemstack.setTag((NBTTagCompound) itemstack1.getTag().clone()); + } + } + } + + return itemstack; + } + + public int a() { + return this.width * this.height; + } + + // Spigot start + public java.util.List getIngredients() + { + return java.util.Arrays.asList( items ); + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ShapelessRecipes.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ShapelessRecipes.java new file mode 100644 index 0000000..e9934f9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/ShapelessRecipes.java @@ -0,0 +1,100 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +// CraftBukkit start +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; +// CraftBukkit end + +public class ShapelessRecipes implements IRecipe { + + public final ItemStack result; // Spigot + private final List ingredients; + + public ShapelessRecipes(ItemStack itemstack, List list) { + this.result = itemstack; + this.ingredients = list; + } + + // CraftBukkit start + @SuppressWarnings("unchecked") + public org.bukkit.inventory.ShapelessRecipe toBukkitRecipe() { + CraftItemStack result = CraftItemStack.asCraftMirror(this.result); + CraftShapelessRecipe recipe = new CraftShapelessRecipe(result, this); + for (ItemStack stack : (List) this.ingredients) { + if (stack != null) { + recipe.addIngredient(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), stack.getData()); + } + } + return recipe; + } + // CraftBukkit end + + public ItemStack b() { + return this.result; + } + + public ItemStack[] b(InventoryCrafting inventorycrafting) { + ItemStack[] aitemstack = new ItemStack[inventorycrafting.getSize()]; + + for (int i = 0; i < aitemstack.length; ++i) { + ItemStack itemstack = inventorycrafting.getItem(i); + + if (itemstack != null && itemstack.getItem().r()) { + aitemstack[i] = new ItemStack(itemstack.getItem().q()); + } + } + + return aitemstack; + } + + public boolean a(InventoryCrafting inventorycrafting, World world) { + ArrayList arraylist = Lists.newArrayList(this.ingredients); + + for (int i = 0; i < inventorycrafting.h(); ++i) { + for (int j = 0; j < inventorycrafting.i(); ++j) { + ItemStack itemstack = inventorycrafting.c(j, i); + + if (itemstack != null) { + boolean flag = false; + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + ItemStack itemstack1 = (ItemStack) iterator.next(); + + if (itemstack.getItem() == itemstack1.getItem() && (itemstack1.getData() == 32767 || itemstack.getData() == itemstack1.getData())) { + flag = true; + arraylist.remove(itemstack1); + break; + } + } + + if (!flag) { + return false; + } + } + } + } + + return arraylist.isEmpty(); + } + + public ItemStack craftItem(InventoryCrafting inventorycrafting) { + return this.result.cloneItemStack(); + } + + public int a() { + return this.ingredients.size(); + } + + // Spigot start + public java.util.List getIngredients() + { + return java.util.Collections.unmodifiableList( ingredients ); + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Slot.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Slot.java new file mode 100644 index 0000000..3e8e7af --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Slot.java @@ -0,0 +1,82 @@ +package net.minecraft.server; + +public class Slot { + + public final int index; + public final IInventory inventory; + public int rawSlotIndex; + public int f; + public int g; + + public Slot(IInventory iinventory, int i, int j, int k) { + this.inventory = iinventory; + this.index = i; + this.f = j; + this.g = k; + } + + public void a(ItemStack itemstack, ItemStack itemstack1) { + if (itemstack != null && itemstack1 != null) { + if (itemstack.getItem() == itemstack1.getItem()) { + int i = itemstack1.count - itemstack.count; + + if (i > 0) { + this.a(itemstack, i); + } + + } + } + } + + protected void a(ItemStack itemstack, int i) {} + + protected void c(ItemStack itemstack) {} + + public void a(EntityHuman entityhuman, ItemStack itemstack) { + this.f(); + } + + public boolean isAllowed(ItemStack itemstack) { + return true; + } + + public ItemStack getItem() { + return this.inventory.getItem(this.index); + } + + public boolean hasItem() { + if (getItem() != null && getItem().count == 0) { + set(null); + } + return this.getItem() != null; + } + + public void set(ItemStack itemstack) { + this.inventory.setItem(this.index, itemstack); + this.f(); + } + + public void f() { + this.inventory.update(); + } + + public int getMaxStackSize() { + return this.inventory.getMaxStackSize(); + } + + public int getMaxStackSize(ItemStack itemstack) { + return this.getMaxStackSize(); + } + + public ItemStack a(int i) { + return this.inventory.splitStack(this.index, i); + } + + public boolean a(IInventory iinventory, int i) { + return iinventory == this.inventory && i == this.index; + } + + public boolean isAllowed(EntityHuman entityhuman) { + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SlotFurnaceResult.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SlotFurnaceResult.java new file mode 100644 index 0000000..914be4e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SlotFurnaceResult.java @@ -0,0 +1,87 @@ +package net.minecraft.server; + +// CraftBukkit start +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.FurnaceExtractEvent; +// CraftBukkit end + +public class SlotFurnaceResult extends Slot { + + private EntityHuman a; + private int b; + + public SlotFurnaceResult(EntityHuman entityhuman, IInventory iinventory, int i, int j, int k) { + super(iinventory, i, j, k); + this.a = entityhuman; + } + + public boolean isAllowed(ItemStack itemstack) { + return false; + } + + public ItemStack a(int i) { + if (this.hasItem()) { + this.b += Math.min(i, this.getItem().count); + } + + return super.a(i); + } + + public void a(EntityHuman entityhuman, ItemStack itemstack) { + this.c(itemstack); + super.a(entityhuman, itemstack); + } + + protected void a(ItemStack itemstack, int i) { + this.b += i; + this.c(itemstack); + } + + protected void c(ItemStack itemstack) { + itemstack.a(this.a.world, this.a, this.b); + if (!this.a.world.isClientSide) { + int i = this.b; + float f = RecipesFurnace.getInstance().b(itemstack); + int j; + + if (f == 0.0F) { + i = 0; + } else if (f < 1.0F) { + j = MathHelper.d((float) i * f); + if (j < MathHelper.f((float) i * f) && Math.random() < (double) ((float) i * f - (float) j)) { + ++j; + } + + i = j; + } + + // CraftBukkit start - fire FurnaceExtractEvent + Player player = (Player) a.getBukkitEntity(); + TileEntityFurnace furnace = ((TileEntityFurnace) this.inventory); + org.bukkit.block.Block block = a.world.getWorld().getBlockAt(furnace.position.getX(), furnace.position.getY(), furnace.position.getZ()); + + if (b != 0) { + FurnaceExtractEvent event = new FurnaceExtractEvent(player, block, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(itemstack.getItem()), b, i); + a.world.getServer().getPluginManager().callEvent(event); + i = event.getExpToDrop(); + } + // CraftBukkit end + + while (i > 0) { + j = EntityExperienceOrb.getOrbValue(i); + i -= j; + this.a.world.addEntity(new EntityExperienceOrb(this.a.world, this.a.locX, this.a.locY + 0.5D, this.a.locZ + 0.5D, j)); + } + } + + this.b = 0; + if (itemstack.getItem() == Items.IRON_INGOT) { + this.a.b((Statistic) AchievementList.k); + } + + if (itemstack.getItem() == Items.COOKED_FISH) { + this.a.b((Statistic) AchievementList.p); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SpawnerCreature.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SpawnerCreature.java new file mode 100644 index 0000000..ea17d7e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/SpawnerCreature.java @@ -0,0 +1,310 @@ +package net.minecraft.server; + +import com.google.common.collect.Sets; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.Set; + +// CraftBukkit start +import org.bukkit.craftbukkit.util.LongHash; +import org.bukkit.craftbukkit.util.LongHashSet; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +// CraftBukkit end + +public final class SpawnerCreature { + + private static final int a = (int) Math.pow(17.0D, 2.0D); + private final LongHashSet b = new LongHashSet(); // CraftBukkit + + public SpawnerCreature() {} + + // Spigot start - get entity count only from chunks being processed in b + private int getEntityCount(WorldServer server, Class oClass) + { + // 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; + } + // Spigot end + + public int a(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) { + if (!flag && !flag1) { + return 0; + } else { + this.b.clear(); + int i = 0; + Iterator iterator = worldserver.players.iterator(); + + int j; + int k; + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (!entityhuman.isSpectator() || !entityhuman.affectsSpawning) { // PaperSpigot + int l = MathHelper.floor(entityhuman.locX / 16.0D); + + j = MathHelper.floor(entityhuman.locZ / 16.0D); + byte b0 = 8; + // Spigot Start + b0 = worldserver.spigotConfig.mobSpawnRange; + b0 = ( b0 > worldserver.spigotConfig.viewDistance ) ? (byte) worldserver.spigotConfig.viewDistance : b0; + b0 = ( b0 > 8 ) ? 8 : b0; + // Spigot End + + for (int i1 = -b0; i1 <= b0; ++i1) { + for (k = -b0; k <= b0; ++k) { + boolean flag3 = i1 == -b0 || i1 == b0 || k == -b0 || k == b0; + // CraftBukkit start - use LongHash and LongHashSet + // ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i1 + l, k + j); + + long chunkCoords = LongHash.toLong(i1 + l, k + j); + if (!this.b.contains(chunkCoords)) { + ++i; + if (!flag3 && worldserver.getWorldBorder().isInBounds(i1 + l, k + j)) { + this.b.add(chunkCoords); + } + } + // CraftBukkit end + } + } + } + } + + int j1 = 0; + BlockPosition blockposition = worldserver.getSpawn(); + EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values(); + + j = aenumcreaturetype.length; + + for (int k1 = 0; k1 < j; ++k1) { + EnumCreatureType enumcreaturetype = aenumcreaturetype[k1]; + + // CraftBukkit start - Use per-world spawn limits + int limit = enumcreaturetype.b(); + switch (enumcreaturetype) { + case MONSTER: + limit = worldserver.getWorld().getMonsterSpawnLimit(); + break; + case CREATURE: + limit = worldserver.getWorld().getAnimalSpawnLimit(); + break; + case WATER_CREATURE: + limit = worldserver.getWorld().getWaterAnimalSpawnLimit(); + break; + case AMBIENT: + limit = worldserver.getWorld().getAmbientSpawnLimit(); + break; + } + + if (limit == 0) { + continue; + } + int mobcnt = 0; // Spigot + // CraftBukkit end + + if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2)) { + k = worldserver.a(enumcreaturetype.a()); + int l1 = limit * i / a; // CraftBukkit - use per-world limits + + if ((mobcnt = getEntityCount(worldserver, enumcreaturetype.a())) <= limit * i / 289) { // TacoSpigot - use 17x17 like vanilla (a at top of file) + Iterator iterator1 = this.b.iterator(); + + int moblimit = (limit * i / 256) - mobcnt + 1; // Spigot - up to 1 more than limit + label115: + while (iterator1.hasNext() && (moblimit > 0)) { // Spigot - while more allowed + // CraftBukkit start = use LongHash and LongObjectHashMap + long key = ((Long) iterator1.next()).longValue(); + BlockPosition blockposition1 = getRandomPosition(worldserver, LongHash.msw(key), LongHash.lsw(key)); + // CraftBukkit + int i2 = blockposition1.getX(); + int j2 = blockposition1.getY(); + int k2 = blockposition1.getZ(); + Block block = worldserver.getType(blockposition1).getBlock(); + + if (!block.isOccluding()) { + int l2 = 0; + int i3 = 0; + + while (i3 < 3) { + int j3 = i2; + int k3 = j2; + int l3 = k2; + byte b1 = 6; + BiomeBase.BiomeMeta biomebase_biomemeta = null; + GroupDataEntity groupdataentity = null; + int i4 = 0; + + while (true) { + if (i4 < 4) { + label108: { + j3 += worldserver.random.nextInt(b1) - worldserver.random.nextInt(b1); + k3 += worldserver.random.nextInt(1) - worldserver.random.nextInt(1); + l3 += worldserver.random.nextInt(b1) - worldserver.random.nextInt(b1); + BlockPosition blockposition2 = new BlockPosition(j3, k3, l3); + float f = (float) j3 + 0.5F; + float f1 = (float) l3 + 0.5F; + + if (!worldserver.isPlayerNearbyWhoAffectsSpawning((double) f, (double) k3, (double) f1, 24.0D) && blockposition.c((double) f, (double) k3, (double) f1) >= 576.0D) { // PaperSpigot - Affects Spawning API + if (biomebase_biomemeta == null) { + biomebase_biomemeta = worldserver.a(enumcreaturetype, blockposition2); + if (biomebase_biomemeta == null) { + break label108; + } + } + + if (worldserver.a(enumcreaturetype, biomebase_biomemeta, blockposition2) && a(EntityPositionTypes.a(biomebase_biomemeta.b), worldserver, blockposition2)) { + EntityInsentient entityinsentient; + + try { + entityinsentient = (EntityInsentient) biomebase_biomemeta.b.getConstructor(new Class[] { World.class}).newInstance(new Object[] { worldserver}); + } catch (Exception exception) { + exception.printStackTrace(); + return j1; + } + + entityinsentient.setPositionRotation((double) f, (double) k3, (double) f1, worldserver.random.nextFloat() * 360.0F, 0.0F); + if (entityinsentient.bR() && entityinsentient.canSpawn()) { + groupdataentity = entityinsentient.prepare(worldserver.E(new BlockPosition(entityinsentient)), groupdataentity); + if (entityinsentient.canSpawn()) { + ++l2; + worldserver.addEntity(entityinsentient, SpawnReason.NATURAL); // CraftBukkit - Added a reason for spawning this creature + } + + // Spigot start + if ( --moblimit <= 0 ) + { + // If we're past limit, stop spawn + continue label115; + } + // Spigot end + if (l2 >= entityinsentient.bV()) { + continue label115; + } + } + + j1 += l2; + } + } + + ++i4; + continue; + } + } + + ++i3; + break; + } + } + } + } + } + } + } + + return j1; + } + } + + protected static BlockPosition getRandomPosition(World world, int i, int j) { + Chunk chunk = world.getChunkAt(i, j); + int k = i * 16 + world.random.nextInt(16); + int l = j * 16 + world.random.nextInt(16); + int i1 = MathHelper.c(chunk.f(new BlockPosition(k, 0, l)) + 1, 16); + int j1 = world.random.nextInt(i1 > 0 ? i1 : chunk.g() + 16 - 1); + + return new BlockPosition(k, j1, l); + } + + public static boolean a(EntityInsentient.EnumEntityPositionType entityinsentient_enumentitypositiontype, World world, BlockPosition blockposition) { + if (!world.getWorldBorder().a(blockposition)) { + return false; + } else { + Block block = world.getType(blockposition).getBlock(); + + if (entityinsentient_enumentitypositiontype == EntityInsentient.EnumEntityPositionType.IN_WATER) { + return block.getMaterial().isLiquid() && world.getType(blockposition.down()).getBlock().getMaterial().isLiquid() && !world.getType(blockposition.up()).getBlock().isOccluding(); + } else { + BlockPosition blockposition1 = blockposition.down(); + + if (!World.a((IBlockAccess) world, blockposition1)) { + return false; + } else { + Block block1 = world.getType(blockposition1).getBlock(); + boolean flag = block1 != Blocks.BEDROCK && block1 != Blocks.BARRIER; + + return flag && !block.isOccluding() && !block.getMaterial().isLiquid() && !world.getType(blockposition.up()).getBlock().isOccluding(); + } + } + } + } + + public static void a(World world, BiomeBase biomebase, int i, int j, int k, int l, Random random) { + List list = biomebase.getMobs(EnumCreatureType.CREATURE); + + if (!list.isEmpty()) { + while (random.nextFloat() < biomebase.g()) { + BiomeBase.BiomeMeta biomebase_biomemeta = (BiomeBase.BiomeMeta) WeightedRandom.a(world.random, list); + int i1 = biomebase_biomemeta.c + random.nextInt(1 + biomebase_biomemeta.d - biomebase_biomemeta.c); + GroupDataEntity groupdataentity = null; + int j1 = i + random.nextInt(k); + int k1 = j + random.nextInt(l); + int l1 = j1; + int i2 = k1; + + for (int j2 = 0; j2 < i1; ++j2) { + boolean flag = false; + + for (int k2 = 0; !flag && k2 < 4; ++k2) { + BlockPosition blockposition = world.r(new BlockPosition(j1, 0, k1)); + + if (a(EntityInsentient.EnumEntityPositionType.ON_GROUND, world, blockposition)) { + EntityInsentient entityinsentient; + + try { + entityinsentient = (EntityInsentient) biomebase_biomemeta.b.getConstructor(new Class[] { World.class}).newInstance(new Object[] { world}); + } catch (Exception exception) { + exception.printStackTrace(); + continue; + } + + entityinsentient.setPositionRotation((double) ((float) j1 + 0.5F), (double) blockposition.getY(), (double) ((float) k1 + 0.5F), random.nextFloat() * 360.0F, 0.0F); + // CraftBukkit start - Added a reason for spawning this creature, moved entityinsentient.prepare(groupdataentity) up + groupdataentity = entityinsentient.prepare(world.E(new BlockPosition(entityinsentient)), groupdataentity); + world.addEntity(entityinsentient, SpawnReason.CHUNK_GEN); + // CraftBukkit end + flag = true; + } + + j1 += random.nextInt(5) - random.nextInt(5); + + for (k1 += random.nextInt(5) - random.nextInt(5); j1 < i || j1 >= i + k || k1 < j || k1 >= j + k; k1 = i2 + random.nextInt(5) - random.nextInt(5)) { + j1 = l1 + random.nextInt(5) - random.nextInt(5); + } + } + } + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/StatisticManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/StatisticManager.java new file mode 100644 index 0000000..5d6c3de --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/StatisticManager.java @@ -0,0 +1,66 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Map; + +public class StatisticManager { + + protected final Map a = Maps.newConcurrentMap(); + + public StatisticManager() {} + + public boolean hasAchievement(Achievement achievement) { + return this.getStatisticValue(achievement) > 0; + } + + public boolean b(Achievement achievement) { + return achievement.c == null || this.hasAchievement(achievement.c); + } + + public void b(EntityHuman entityhuman, Statistic statistic, int i) { + if (!statistic.d() || this.b((Achievement) statistic)) { + // CraftBukkit start - fire Statistic events + org.bukkit.event.Cancellable cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.handleStatisticsIncrease(entityhuman, statistic, this.getStatisticValue(statistic), i); + if (cancellable != null && cancellable.isCancelled()) { + return; + } + // CraftBukkit end + this.setStatistic(entityhuman, statistic, this.getStatisticValue(statistic) + i); + } + } + + public void setStatistic(EntityHuman entityhuman, Statistic statistic, int i) { + StatisticWrapper statisticwrapper = (StatisticWrapper) this.a.get(statistic); + + if (statisticwrapper == null) { + statisticwrapper = new StatisticWrapper(); + this.a.put(statistic, statisticwrapper); + } + + statisticwrapper.a(i); + } + + public int getStatisticValue(Statistic statistic) { + StatisticWrapper statisticwrapper = (StatisticWrapper) this.a.get(statistic); + + return statisticwrapper == null ? 0 : statisticwrapper.a(); + } + + public T b(Statistic statistic) { + StatisticWrapper statisticwrapper = (StatisticWrapper) this.a.get(statistic); + + return statisticwrapper != null ? (T) statisticwrapper.b() : null; // CraftBukkit - fix decompile error + } + + public T a(Statistic statistic, T t0) { + StatisticWrapper statisticwrapper = (StatisticWrapper) this.a.get(statistic); + + if (statisticwrapper == null) { + statisticwrapper = new StatisticWrapper(); + this.a.put(statistic, statisticwrapper); + } + + statisticwrapper.a(t0); + return t0; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/StructureGenerator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/StructureGenerator.java new file mode 100644 index 0000000..f6770f6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/StructureGenerator.java @@ -0,0 +1,254 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.Callable; +import java.util.logging.Level; + +public abstract class StructureGenerator extends WorldGenBase { + + private PersistentStructure d; + protected Map e = Maps.newHashMap(); + + public StructureGenerator() {} + + public abstract String a(); + + protected final void a(World world, final int i, final int j, int k, int l, ChunkSnapshot chunksnapshot) { + this.a(world); + if (!this.e.containsKey(Long.valueOf(ChunkCoordIntPair.a(i, j)))) { + this.b.nextInt(); + + try { + if (this.a(i, j)) { + StructureStart structurestart = this.b(i, j); + + this.e.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart); + this.a(i, j, structurestart); + } + + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Exception preparing structure feature"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Feature being prepared"); + + crashreportsystemdetails.a("Is feature chunk", new Callable() { + public String a() throws Exception { + return StructureGenerator.this.a(i, j) ? "True" : "False"; + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Chunk location", String.format("%d,%d", new Object[] { Integer.valueOf(i), Integer.valueOf(j)})); + crashreportsystemdetails.a("Chunk pos hash", new Callable() { + public String a() throws Exception { + return String.valueOf(ChunkCoordIntPair.a(i, j)); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Structure type", new Callable() { + public String a() throws Exception { + return StructureGenerator.this.getClass().getCanonicalName(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + } + + public boolean a(World world, Random random, ChunkCoordIntPair chunkcoordintpair) { + this.a(world); + int i = (chunkcoordintpair.x << 4) + 8; + int j = (chunkcoordintpair.z << 4) + 8; + boolean flag = false; + Iterator iterator = this.e.values().iterator(); + + while (iterator.hasNext()) { + StructureStart structurestart = (StructureStart) iterator.next(); + + if (structurestart.d() && structurestart.a(chunkcoordintpair) && structurestart.a().a(i, j, i + 15, j + 15)) { + structurestart.a(world, random, new StructureBoundingBox(i, j, i + 15, j + 15)); + structurestart.b(chunkcoordintpair); + flag = true; + this.a(structurestart.e(), structurestart.f(), structurestart); + } + } + + return flag; + } + + public boolean b(BlockPosition blockposition) { + if (this.c == null) return false; // PaperSpigot + this.a(this.c); + return this.c(blockposition) != null; + } + + protected StructureStart c(BlockPosition blockposition) { + Iterator iterator = this.e.values().iterator(); + + while (iterator.hasNext()) { + StructureStart structurestart = (StructureStart) iterator.next(); + + if (structurestart.d() && structurestart.a().b(blockposition)) { + Iterator iterator1 = structurestart.b().iterator(); + + while (iterator1.hasNext()) { + StructurePiece structurepiece = (StructurePiece) iterator1.next(); + + if (structurepiece.c().b(blockposition)) { + return structurestart; + } + } + } + } + + return null; + } + + public boolean a(World world, BlockPosition blockposition) { + if (this.c == null) return false; // PaperSpigot + this.a(world); + Iterator iterator = this.e.values().iterator(); + + StructureStart structurestart; + + do { + if (!iterator.hasNext()) { + return false; + } + + structurestart = (StructureStart) iterator.next(); + } while (!structurestart.d() || !structurestart.a().b(blockposition)); + + return true; + } + + public BlockPosition getNearestGeneratedFeature(World world, BlockPosition blockposition) { + this.c = world; + this.a(world); + this.b.setSeed(world.getSeed()); + long i = this.b.nextLong(); + long j = this.b.nextLong(); + long k = (long) (blockposition.getX() >> 4) * i; + long l = (long) (blockposition.getZ() >> 4) * j; + + this.b.setSeed(k ^ l ^ world.getSeed()); + this.a(world, blockposition.getX() >> 4, blockposition.getZ() >> 4, 0, 0, null); + double d0 = Double.MAX_VALUE; + BlockPosition blockposition1 = null; + Iterator iterator = this.e.values().iterator(); + + BlockPosition blockposition2; + double d1; + + while (iterator.hasNext()) { + StructureStart structurestart = (StructureStart) iterator.next(); + + if (structurestart.d()) { + StructurePiece structurepiece = structurestart.b().get(0); + + blockposition2 = structurepiece.a(); + d1 = blockposition2.i(blockposition); + if (d1 < d0) { + d0 = d1; + blockposition1 = blockposition2; + } + } + } + + if (blockposition1 != null) { + return blockposition1; + } else { + List list = this.z_(); + + if (list != null) { + BlockPosition blockposition3 = null; + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) { + blockposition2 = (BlockPosition) iterator1.next(); + d1 = blockposition2.i(blockposition); + if (d1 < d0) { + d0 = d1; + blockposition3 = blockposition2; + } + } + + return blockposition3; + } else { + return null; + } + } + } + + protected List z_() { + return null; + } + + private void a(World world) { + if (this.d == null) { + // Spigot Start + if ( world.spigotConfig.saveStructureInfo && !this.a().equals( "Mineshaft" ) ) + { + this.d = (PersistentStructure) world.a(PersistentStructure.class, this.a()); + } else + { + this.d = new PersistentStructure( this.a() ); + } + // Spigot End + if (this.d == null) { + this.d = new PersistentStructure(this.a()); + world.a(this.a(), this.d); + } else { + NBTTagCompound nbttagcompound = this.d.a(); + Iterator iterator = nbttagcompound.c().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + NBTBase nbtbase = nbttagcompound.get(s); + + if (nbtbase.getTypeId() == 10) { + NBTTagCompound nbttagcompound1 = (NBTTagCompound) nbtbase; + + if (nbttagcompound1.hasKey("ChunkX") && nbttagcompound1.hasKey("ChunkZ")) { + int i = nbttagcompound1.getInt("ChunkX"); + int j = nbttagcompound1.getInt("ChunkZ"); + StructureStart structurestart = WorldGenFactory.a(nbttagcompound1, world); + + if (structurestart != null) { + this.e.put(Long.valueOf(ChunkCoordIntPair.a(i, j)), structurestart); + } + } + } + } + } + } + + } + + private void a(int i, int j, StructureStart structurestart) { + this.d.a(structurestart.a(i, j), i, j); + this.d.c(); + } + + protected abstract boolean a(int i, int j); + + protected abstract StructureStart b(int i, int j); +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntity.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntity.java new file mode 100644 index 0000000..fdcbf44 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntity.java @@ -0,0 +1,250 @@ +package net.minecraft.server; + +import com.google.common.collect.Maps; +import java.util.Map; +import java.util.concurrent.Callable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import co.aikar.timings.SpigotTimings; // Spigot +import co.aikar.timings.Timing; // Spigot +import org.bukkit.inventory.InventoryHolder; // CraftBukkit + +public abstract class TileEntity { + + public Timing tickTimer = SpigotTimings.getTileEntityTimings(this); // Spigot + private static final Logger a = LogManager.getLogger(); + private static Map> f = Maps.newHashMap(); + private static Map, String> g = Maps.newHashMap(); + protected World world; + protected BlockPosition position; + protected boolean d; + private int h; + protected Block e; + + public TileEntity() { + this.position = BlockPosition.ZERO; + this.h = -1; + } + + private static void a(Class oclass, String s) { + if (TileEntity.f.containsKey(s)) { + throw new IllegalArgumentException("Duplicate id: " + s); + } else { + TileEntity.f.put(s, oclass); + TileEntity.g.put(oclass, s); + } + } + + public World getWorld() { + return this.world; + } + + public void a(World world) { + this.world = world; + } + + public boolean t() { + return this.world != null; + } + + public void a(NBTTagCompound nbttagcompound) { + this.position = new BlockPosition(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")); + } + + public void b(NBTTagCompound nbttagcompound) { + String s = (String) TileEntity.g.get(this.getClass()); + + if (s == null) { + throw new RuntimeException(this.getClass() + " is missing a mapping! This is a bug!"); + } else { + nbttagcompound.setString("id", s); + nbttagcompound.setInt("x", this.position.getX()); + nbttagcompound.setInt("y", this.position.getY()); + nbttagcompound.setInt("z", this.position.getZ()); + } + } + + public static TileEntity c(NBTTagCompound nbttagcompound) { + TileEntity tileentity = null; + + try { + Class oclass = (Class) TileEntity.f.get(nbttagcompound.getString("id")); + + if (oclass != null) { + tileentity = (TileEntity) oclass.newInstance(); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + + if (tileentity != null) { + tileentity.a(nbttagcompound); + } else { + TileEntity.a.warn("Skipping BlockEntity with id " + nbttagcompound.getString("id")); + } + + return tileentity; + } + + public int u() { + if (this.h == -1) { + IBlockData iblockdata = this.world.getType(this.position); + + this.h = iblockdata.getBlock().toLegacyData(iblockdata); + } + + return this.h; + } + + public void update() { + if (this.world != null) { + IBlockData iblockdata = this.world.getType(this.position); + + this.h = iblockdata.getBlock().toLegacyData(iblockdata); + this.world.b(this.position, this); + if (this.w() != Blocks.AIR) { + this.world.updateAdjacentComparators(this.position, this.w()); + } + } + + } + + public BlockPosition getPosition() { + return this.position; + } + + public Block w() { + if (this.e == null) { + this.e = this.world.getType(this.position).getBlock(); + } + + return this.e; + } + + public Packet getUpdatePacket() { + return null; + } + + public boolean x() { + return this.d; + } + + public void y() { + this.d = true; + } + + public void D() { + this.d = false; + } + + public boolean c(int i, int j) { + return false; + } + + public void E() { + this.e = null; + this.h = -1; + } + + public void a(CrashReportSystemDetails crashreportsystemdetails) { + crashreportsystemdetails.a("Name", new Callable() { + public String a() throws Exception { + return (String) TileEntity.g.get(TileEntity.this.getClass()) + " // " + TileEntity.this.getClass().getCanonicalName(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if (this.world != null) { + // PaperSpigot start - Prevent tile entity and entity crashes + Block block = this.w(); + if (block != null) { + CrashReportSystemDetails.a(crashreportsystemdetails, this.position, this.w(), this.u()); + } + // PaperSpigot end + crashreportsystemdetails.a("Actual block type", new Callable() { + public String a() throws Exception { + int i = Block.getId(TileEntity.this.world.getType(TileEntity.this.position).getBlock()); + + try { + return String.format("ID #%d (%s // %s)", new Object[] { Integer.valueOf(i), Block.getById(i).a(), Block.getById(i).getClass().getCanonicalName()}); + } catch (Throwable throwable) { + return "ID #" + i; + } + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Actual block data value", new Callable() { + public String a() throws Exception { + IBlockData iblockdata = TileEntity.this.world.getType(TileEntity.this.position); + int i = iblockdata.getBlock().toLegacyData(iblockdata); + + if (i < 0) { + return "Unknown? (Got " + i + ")"; + } else { + String s = String.format("%4s", new Object[] { Integer.toBinaryString(i)}).replace(" ", "0"); + + return String.format("%1$d / 0x%1$X / 0b%2$s", new Object[] { Integer.valueOf(i), s}); + } + } + + public Object call() throws Exception { + return this.a(); + } + }); + } + } + + public void a(BlockPosition blockposition) { + this.position = blockposition; + } + + public boolean F() { + return false; + } + + static { + a(TileEntityFurnace.class, "Furnace"); + a(TileEntityChest.class, "Chest"); + a(TileEntityEnderChest.class, "EnderChest"); + a(BlockJukeBox.TileEntityRecordPlayer.class, "RecordPlayer"); + a(TileEntityDispenser.class, "Trap"); + a(TileEntityDropper.class, "Dropper"); + a(TileEntitySign.class, "Sign"); + a(TileEntityMobSpawner.class, "MobSpawner"); + a(TileEntityNote.class, "Music"); + a(TileEntityPiston.class, "Piston"); + a(TileEntityBrewingStand.class, "Cauldron"); + a(TileEntityEnchantTable.class, "EnchantTable"); + a(TileEntityEnderPortal.class, "Airportal"); + a(TileEntityCommand.class, "Control"); + a(TileEntityBeacon.class, "Beacon"); + a(TileEntitySkull.class, "Skull"); + a(TileEntityLightDetector.class, "DLDetector"); + a(TileEntityHopper.class, "Hopper"); + a(TileEntityComparator.class, "Comparator"); + a(TileEntityFlowerPot.class, "FlowerPot"); + a(TileEntityBanner.class, "Banner"); + } + + // CraftBukkit start - add method + public InventoryHolder getOwner() { + if (world == null) return null; + // Spigot start + org.bukkit.block.Block block = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()); + if (block == null) { + org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "No block for owner at %s %d %d %d", new Object[]{world.getWorld(), position.getX(), position.getY(), position.getZ()}); + return null; + } + // Spigot end + org.bukkit.block.BlockState state = block.getState(); + if (state instanceof InventoryHolder) return (InventoryHolder) state; + return null; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBanner.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBanner.java new file mode 100644 index 0000000..aa5ad2e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBanner.java @@ -0,0 +1,166 @@ +package net.minecraft.server; + +import java.util.List; + +public class TileEntityBanner extends TileEntity { + + public int color; + public NBTTagList patterns; + private boolean g; + private List h; + private List i; + private String j; + + public TileEntityBanner() {} + + public void a(ItemStack itemstack) { + this.patterns = null; + if (itemstack.hasTag() && itemstack.getTag().hasKeyOfType("BlockEntityTag", 10)) { + NBTTagCompound nbttagcompound = itemstack.getTag().getCompound("BlockEntityTag"); + + if (nbttagcompound.hasKey("Patterns")) { + this.patterns = (NBTTagList) nbttagcompound.getList("Patterns", 10).clone(); + // CraftBukkit start + while (this.patterns.size() > 20) { + this.patterns.a(20); // PAIL Rename remove + } + // CraftBukkit end + } + + if (nbttagcompound.hasKeyOfType("Base", 99)) { + this.color = nbttagcompound.getInt("Base"); + } else { + this.color = itemstack.getData() & 15; + } + } else { + this.color = itemstack.getData() & 15; + } + + this.h = null; + this.i = null; + this.j = ""; + this.g = true; + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + a(nbttagcompound, this.color, this.patterns); + } + + public static void a(NBTTagCompound nbttagcompound, int i, NBTTagList nbttaglist) { + nbttagcompound.setInt("Base", i); + if (nbttaglist != null) { + nbttagcompound.set("Patterns", nbttaglist); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.color = nbttagcompound.getInt("Base"); + this.patterns = nbttagcompound.getList("Patterns", 10); + // CraftBukkit start + while (this.patterns.size() > 20) { + this.patterns.a(20); // PAIL Rename remove + } + // CraftBukkit end + this.h = null; + this.i = null; + this.j = null; + this.g = true; + } + + public Packet getUpdatePacket() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + this.b(nbttagcompound); + return new PacketPlayOutTileEntityData(this.position, 6, nbttagcompound); + } + + public int b() { + return this.color; + } + + public static int b(ItemStack itemstack) { + NBTTagCompound nbttagcompound = itemstack.a("BlockEntityTag", false); + + return nbttagcompound != null && nbttagcompound.hasKey("Base") ? nbttagcompound.getInt("Base") : itemstack.getData(); + } + + public static int c(ItemStack itemstack) { + NBTTagCompound nbttagcompound = itemstack.a("BlockEntityTag", false); + + return nbttagcompound != null && nbttagcompound.hasKey("Patterns") ? nbttagcompound.getList("Patterns", 10).size() : 0; + } + + public NBTTagList d() { + return this.patterns; + } + + public static void e(ItemStack itemstack) { + NBTTagCompound nbttagcompound = itemstack.a("BlockEntityTag", false); + + if (nbttagcompound != null && nbttagcompound.hasKeyOfType("Patterns", 9)) { + NBTTagList nbttaglist = nbttagcompound.getList("Patterns", 10); + + if (nbttaglist.size() > 0) { + nbttaglist.a(nbttaglist.size() - 1); + if (nbttaglist.isEmpty()) { + itemstack.getTag().remove("BlockEntityTag"); + if (itemstack.getTag().isEmpty()) { + itemstack.setTag((NBTTagCompound) null); + } + } + + } + } + } + + public static enum EnumBannerPatternType { + + BASE("base", "b"), SQUARE_BOTTOM_LEFT("square_bottom_left", "bl", " ", " ", "# "), SQUARE_BOTTOM_RIGHT("square_bottom_right", "br", " ", " ", " #"), SQUARE_TOP_LEFT("square_top_left", "tl", "# ", " ", " "), SQUARE_TOP_RIGHT("square_top_right", "tr", " #", " ", " "), STRIPE_BOTTOM("stripe_bottom", "bs", " ", " ", "###"), STRIPE_TOP("stripe_top", "ts", "###", " ", " "), STRIPE_LEFT("stripe_left", "ls", "# ", "# ", "# "), STRIPE_RIGHT("stripe_right", "rs", " #", " #", " #"), STRIPE_CENTER("stripe_center", "cs", " # ", " # ", " # "), STRIPE_MIDDLE("stripe_middle", "ms", " ", "###", " "), STRIPE_DOWNRIGHT("stripe_downright", "drs", "# ", " # ", " #"), STRIPE_DOWNLEFT("stripe_downleft", "dls", " #", " # ", "# "), STRIPE_SMALL("small_stripes", "ss", "# #", "# #", " "), CROSS("cross", "cr", "# #", " # ", "# #"), STRAIGHT_CROSS("straight_cross", "sc", " # ", "###", " # "), TRIANGLE_BOTTOM("triangle_bottom", "bt", " ", " # ", "# #"), TRIANGLE_TOP("triangle_top", "tt", "# #", " # ", " "), TRIANGLES_BOTTOM("triangles_bottom", "bts", " ", "# #", " # "), TRIANGLES_TOP("triangles_top", "tts", " # ", "# #", " "), DIAGONAL_LEFT("diagonal_left", "ld", "## ", "# ", " "), DIAGONAL_RIGHT("diagonal_up_right", "rd", " ", " #", " ##"), DIAGONAL_LEFT_MIRROR("diagonal_up_left", "lud", " ", "# ", "## "), DIAGONAL_RIGHT_MIRROR("diagonal_right", "rud", " ##", " #", " "), CIRCLE_MIDDLE("circle", "mc", " ", " # ", " "), RHOMBUS_MIDDLE("rhombus", "mr", " # ", "# #", " # "), HALF_VERTICAL("half_vertical", "vh", "## ", "## ", "## "), HALF_HORIZONTAL("half_horizontal", "hh", "###", "###", " "), HALF_VERTICAL_MIRROR("half_vertical_right", "vhr", " ##", " ##", " ##"), HALF_HORIZONTAL_MIRROR("half_horizontal_bottom", "hhb", " ", "###", "###"), BORDER("border", "bo", "###", "# #", "###"), CURLY_BORDER("curly_border", "cbo", new ItemStack(Blocks.VINE)), CREEPER("creeper", "cre", new ItemStack(Items.SKULL, 1, 4)), GRADIENT("gradient", "gra", "# #", " # ", " # "), GRADIENT_UP("gradient_up", "gru", " # ", " # ", "# #"), BRICKS("bricks", "bri", new ItemStack(Blocks.BRICK_BLOCK)), SKULL("skull", "sku", new ItemStack(Items.SKULL, 1, 1)), FLOWER("flower", "flo", new ItemStack(Blocks.RED_FLOWER, 1, BlockFlowers.EnumFlowerVarient.OXEYE_DAISY.b())), MOJANG("mojang", "moj", new ItemStack(Items.GOLDEN_APPLE, 1, 1)); + + private String N; + private String O; + private String[] P; + private ItemStack Q; + + private EnumBannerPatternType(String s, String s1) { + this.P = new String[3]; + this.N = s; + this.O = s1; + } + + private EnumBannerPatternType(String s, String s1, ItemStack itemstack) { + this(s, s1); + this.Q = itemstack; + } + + private EnumBannerPatternType(String s, String s1, String s2, String s3, String s4) { + this(s, s1); + this.P[0] = s2; + this.P[1] = s3; + this.P[2] = s4; + } + + public String b() { + return this.O; + } + + public String[] c() { + return this.P; + } + + public boolean d() { + return this.Q != null || this.P[0] != null; + } + + public boolean e() { + return this.Q != null; + } + + public ItemStack f() { + return this.Q; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBeacon.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBeacon.java new file mode 100644 index 0000000..ad7f69e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBeacon.java @@ -0,0 +1,393 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.github.paperspigot.event.block.BeaconEffectEvent; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +// CraftBukkit start +// CraftBukkit end +// PaperSpigot start +// PaperSpigot end + +public class TileEntityBeacon extends TileEntityContainer implements IUpdatePlayerListBox, IInventory { + + public static final MobEffectList[][] a = new MobEffectList[][] { { MobEffectList.FASTER_MOVEMENT, MobEffectList.FASTER_DIG}, { MobEffectList.RESISTANCE, MobEffectList.JUMP}, { MobEffectList.INCREASE_DAMAGE}, { MobEffectList.REGENERATION}}; + private final List f = Lists.newArrayList(); + private boolean i; + private int j = -1; + private int k; + private int l; + private ItemStack inventorySlot; + private String n; + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return new ItemStack[] { this.inventorySlot }; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public TileEntityBeacon() {} + + public void c() { + if (this.world.getTime() % 80L == 0L) { + this.m(); + } + + } + + public void m() { + this.B(); + this.A(); + } + + private void A() { + if (this.i && this.j > 0 && !this.world.isClientSide && this.k > 0) { + double d0 = this.j * 10 + 10; + byte b0 = 0; + + if (this.j >= 4 && this.k == this.l) { + b0 = 1; + } + + int i = this.position.getX(); + int j = this.position.getY(); + int k = this.position.getZ(); + AxisAlignedBB axisalignedbb = (new AxisAlignedBB(i, j, k, i + 1, j + 1, k + 1)).grow(d0, d0, d0).a(0.0D, this.world.getHeight(), 0.0D); + List list = this.world.a(EntityHuman.class, axisalignedbb); + Iterator iterator = list.iterator(); + + EntityHuman entityhuman; + // PaperSpigot start + org.bukkit.block.Block block = world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()); + PotionEffect primaryEffect = new PotionEffect(PotionEffectType.getById(this.k), 180, b0, true, true); + // PaperSpigot end + + while (iterator.hasNext()) { + entityhuman = (EntityHuman) iterator.next(); + // PaperSpigot start - BeaconEffectEvent + BeaconEffectEvent event = new BeaconEffectEvent(block, primaryEffect, (Player) entityhuman.getBukkitEntity(), true); + if (CraftEventFactory.callEvent(event).isCancelled()) continue; + + PotionEffect effect = event.getEffect(); + entityhuman.addEffect(new MobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles())); + // PaperSpigot end + } + + if (this.j >= 4 && this.k != this.l && this.l > 0) { + iterator = list.iterator(); + PotionEffect secondaryEffect = new PotionEffect(PotionEffectType.getById(this.l), 180, 0, true, true); // PaperSpigot + + while (iterator.hasNext()) { + entityhuman = (EntityHuman) iterator.next(); + // PaperSpigot start - BeaconEffectEvent + BeaconEffectEvent event = new BeaconEffectEvent(block, secondaryEffect, (Player) entityhuman.getBukkitEntity(), false); + if (CraftEventFactory.callEvent(event).isCancelled()) continue; + + PotionEffect effect = event.getEffect(); + entityhuman.addEffect(new MobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles())); + // PaperSpigot end + } + } + } + + } + + private void B() { + int i = this.j; + int j = this.position.getX(); + int k = this.position.getY(); + int l = this.position.getZ(); + + this.j = 0; + this.f.clear(); + this.i = true; + TileEntityBeacon.BeaconColorTracker tileentitybeacon_beaconcolortracker = new TileEntityBeacon.BeaconColorTracker(EntitySheep.a(EnumColor.WHITE)); + + this.f.add(tileentitybeacon_beaconcolortracker); + boolean flag = true; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + int i1; + + for (i1 = k + 1; i1 < 256; ++i1) { + IBlockData iblockdata = this.world.getType(blockposition_mutableblockposition.c(j, i1, l)); + float[] afloat; + + if (iblockdata.getBlock() == Blocks.STAINED_GLASS) { + afloat = EntitySheep.a(iblockdata.get(BlockStainedGlass.COLOR)); + } else { + if (iblockdata.getBlock() != Blocks.STAINED_GLASS_PANE) { + if (iblockdata.getBlock().p() >= 15 && iblockdata.getBlock() != Blocks.BEDROCK) { + this.i = false; + this.f.clear(); + break; + } + + tileentitybeacon_beaconcolortracker.a(); + continue; + } + + afloat = EntitySheep.a(iblockdata.get(BlockStainedGlassPane.COLOR)); + } + + if (!flag) { + afloat = new float[] { (tileentitybeacon_beaconcolortracker.b()[0] + afloat[0]) / 2.0F, (tileentitybeacon_beaconcolortracker.b()[1] + afloat[1]) / 2.0F, (tileentitybeacon_beaconcolortracker.b()[2] + afloat[2]) / 2.0F}; + } + + if (Arrays.equals(afloat, tileentitybeacon_beaconcolortracker.b())) { + tileentitybeacon_beaconcolortracker.a(); + } else { + tileentitybeacon_beaconcolortracker = new TileEntityBeacon.BeaconColorTracker(afloat); + this.f.add(tileentitybeacon_beaconcolortracker); + } + + flag = false; + } + + if (this.i) { + for (i1 = 1; i1 <= 4; this.j = i1++) { + int j1 = k - i1; + + if (j1 < 0) { + break; + } + + boolean flag1 = true; + + for (int k1 = j - i1; k1 <= j + i1 && flag1; ++k1) { + for (int l1 = l - i1; l1 <= l + i1; ++l1) { + Block block = this.world.getType(k1, j1, l1).getBlock(); + + if (block != Blocks.EMERALD_BLOCK && block != Blocks.GOLD_BLOCK && block != Blocks.DIAMOND_BLOCK && block != Blocks.IRON_BLOCK) { + flag1 = false; + break; + } + } + } + + if (!flag1) { + break; + } + } + + if (this.j == 0) { + this.i = false; + } + } + + if (!this.world.isClientSide && this.j == 4 && i < this.j) { + Iterator iterator = this.world.a(EntityHuman.class, (new AxisAlignedBB(j, k, l, j, k - 4, l)).grow(10.0D, 5.0D, 10.0D)).iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + entityhuman.b(AchievementList.K); + } + } + + } + + public Packet getUpdatePacket() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + this.b(nbttagcompound); + return new PacketPlayOutTileEntityData(this.position, 3, nbttagcompound); + } + + private int h(int i) { + if (i >= 0 && i < MobEffectList.byId.length && MobEffectList.byId[i] != null) { + MobEffectList mobeffectlist = MobEffectList.byId[i]; + + return mobeffectlist != MobEffectList.FASTER_MOVEMENT && mobeffectlist != MobEffectList.FASTER_DIG && mobeffectlist != MobEffectList.RESISTANCE && mobeffectlist != MobEffectList.JUMP && mobeffectlist != MobEffectList.INCREASE_DAMAGE && mobeffectlist != MobEffectList.REGENERATION ? 0 : i; + } else { + return 0; + } + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.k = this.h(nbttagcompound.getInt("Primary")); + this.l = this.h(nbttagcompound.getInt("Secondary")); + this.j = nbttagcompound.getInt("Levels"); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("Primary", this.k); + nbttagcompound.setInt("Secondary", this.l); + nbttagcompound.setInt("Levels", this.j); + } + + public int getSize() { + return 1; + } + + public ItemStack getItem(int i) { + return i == 0 ? this.inventorySlot : null; + } + + public ItemStack splitStack(int i, int j) { + if (i == 0 && this.inventorySlot != null) { + if (j >= this.inventorySlot.count) { + ItemStack itemstack = this.inventorySlot; + + this.inventorySlot = null; + return itemstack; + } else { + this.inventorySlot.count -= j; + return new ItemStack(this.inventorySlot.getItem(), j, this.inventorySlot.getData()); + } + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + if (i == 0 && this.inventorySlot != null) { + ItemStack itemstack = this.inventorySlot; + + this.inventorySlot = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + if (i == 0) { + this.inventorySlot = itemstack; + } + + } + + public String getName() { + return this.hasCustomName() ? this.n : "container.beacon"; + } + + public boolean hasCustomName() { + return this.n != null && this.n.length() > 0; + } + + public void a(String s) { + this.n = s; + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { + return this.world.getTileEntity(this.position) == this && entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return itemstack.getItem() == Items.EMERALD || itemstack.getItem() == Items.DIAMOND || itemstack.getItem() == Items.GOLD_INGOT || itemstack.getItem() == Items.IRON_INGOT; + } + + public String getContainerName() { + return "minecraft:beacon"; + } + + public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerBeacon(playerinventory, this); + } + + public int getProperty(int i) { + switch (i) { + case 0: + return this.j; + + case 1: + return this.k; + + case 2: + return this.l; + + default: + return 0; + } + } + + public void b(int i, int j) { + switch (i) { + case 0: + this.j = j; + break; + + case 1: + this.k = this.h(j); + break; + + case 2: + this.l = this.h(j); + } + + } + + public int g() { + return 3; + } + + public void l() { + this.inventorySlot = null; + } + + public boolean c(int i, int j) { + if (i == 1) { + this.m(); + return true; + } else { + return super.c(i, j); + } + } + + public static class BeaconColorTracker { + + private final float[] a; + private int b; + + public BeaconColorTracker(float[] afloat) { + this.a = afloat; + this.b = 1; + } + + protected void a() { + ++this.b; + } + + public float[] b() { + return this.a; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBrewingStand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBrewingStand.java new file mode 100644 index 0000000..07d5a19 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityBrewingStand.java @@ -0,0 +1,347 @@ +package net.minecraft.server; + +import java.util.Arrays; +import java.util.List; + +// CraftBukkit start +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.BrewEvent; +// CraftBukkit end + +public class TileEntityBrewingStand extends TileEntityContainer implements IUpdatePlayerListBox, IWorldInventory { + + private static final int[] a = new int[] { 3}; + private static final int[] f = new int[] { 0, 1, 2}; + private ItemStack[] items = new ItemStack[4]; + public int brewTime; + private boolean[] i; + private Item j; + private String k; + private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field + + public TileEntityBrewingStand() {} + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = 64; + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public ItemStack[] getContents() { + return this.items; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public String getName() { + return this.hasCustomName() ? this.k : "container.brewing"; + } + + public boolean hasCustomName() { + return this.k != null && this.k.length() > 0; + } + + public void a(String s) { + this.k = s; + } + + public int getSize() { + return this.items.length; + } + + public void c() { + // CraftBukkit start - Use wall time instead of ticks for brewing + int elapsedTicks = MinecraftServer.currentTick - this.lastTick; + this.lastTick = MinecraftServer.currentTick; + + if (this.brewTime > 0) { + this.brewTime -= elapsedTicks; + if (this.brewTime <= 0) { // == -> <= + // CraftBukkit end + this.o(); + this.update(); + } else if (!this.n()) { + this.brewTime = 0; + this.update(); + } else if (this.j != this.items[3].getItem()) { + this.brewTime = 0; + this.update(); + } + } else if (this.n()) { + this.brewTime = 400; + this.j = this.items[3].getItem(); + } + + if (!this.world.isClientSide) { + boolean[] aboolean = this.m(); + + if (!Arrays.equals(aboolean, this.i)) { + this.i = aboolean; + IBlockData iblockdata = this.world.getType(this.getPosition()); + + if (!(iblockdata.getBlock() instanceof BlockBrewingStand)) { + return; + } + + for (int i = 0; i < BlockBrewingStand.HAS_BOTTLE.length; ++i) { + iblockdata = iblockdata.set(BlockBrewingStand.HAS_BOTTLE[i], Boolean.valueOf(aboolean[i])); + } + + this.world.setTypeAndData(this.position, iblockdata, 2); + } + } + + } + + private boolean n() { + if (this.items[3] != null && this.items[3].count > 0) { + ItemStack itemstack = this.items[3]; + + if (!itemstack.getItem().l(itemstack)) { + return false; + } else { + boolean flag = false; + + for (int i = 0; i < 3; ++i) { + if (this.items[i] != null && this.items[i].getItem() == Items.POTION) { + int j = this.items[i].getData(); + int k = this.c(j, itemstack); + + if (!ItemPotion.f(j) && ItemPotion.f(k)) { + flag = true; + break; + } + + List list = Items.POTION.e(j); + List list1 = Items.POTION.e(k); + + if ((j <= 0 || list != list1) && (list == null || !list.equals(list1) && list1 != null) && j != k) { + flag = true; + break; + } + } + } + + return flag; + } + } else { + return false; + } + } + + private void o() { + if (this.n()) { + ItemStack itemstack = this.items[3]; + + // CraftBukkit start + if (getOwner() != null) { + BrewEvent event = new BrewEvent(world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), (org.bukkit.inventory.BrewerInventory) this.getOwner().getInventory()); + org.bukkit.Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + } + // CraftBukkit end + + for (int i = 0; i < 3; ++i) { + if (this.items[i] != null && this.items[i].getItem() == Items.POTION) { + int j = this.items[i].getData(); + int k = this.c(j, itemstack); + List list = Items.POTION.e(j); + List list1 = Items.POTION.e(k); + + if ((j <= 0 || list != list1) && (list == null || !list.equals(list1) && list1 != null)) { + if (j != k) { + this.items[i].setData(k); + } + } else if (!ItemPotion.f(j) && ItemPotion.f(k)) { + this.items[i].setData(k); + } + } + } + + if (itemstack.getItem().r()) { + this.items[3] = new ItemStack(itemstack.getItem().q()); + } else { + --this.items[3].count; + if (this.items[3].count <= 0) { + this.items[3] = null; + } + } + + } + } + + private int c(int i, ItemStack itemstack) { + return itemstack == null ? i : (itemstack.getItem().l(itemstack) ? PotionBrewer.a(i, itemstack.getItem().j(itemstack)) : i); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getList("Items", 10); + + this.items = new ItemStack[this.getSize()]; + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + byte b0 = nbttagcompound1.getByte("Slot"); + + if (b0 >= 0 && b0 < this.items.length) { + this.items[b0] = ItemStack.createStack(nbttagcompound1); + } + } + + this.brewTime = nbttagcompound.getShort("BrewTime"); + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.k = nbttagcompound.getString("CustomName"); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setShort("BrewTime", (short) this.brewTime); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setByte("Slot", (byte) i); + this.items[i].save(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Items", nbttaglist); + if (this.hasCustomName()) { + nbttagcompound.setString("CustomName", this.k); + } + + } + + public ItemStack getItem(int i) { + return i >= 0 && i < this.items.length ? this.items[i] : null; + } + + public ItemStack splitStack(int i, int j) { + if (i >= 0 && i < this.items.length) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + if (i >= 0 && i < this.items.length) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + if (i >= 0 && i < this.items.length) { + this.items[i] = itemstack; + } + + } + + public int getMaxStackSize() { + return this.maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return i == 3 ? itemstack.getItem().l(itemstack) : itemstack.getItem() == Items.POTION || itemstack.getItem() == Items.GLASS_BOTTLE; + } + + public boolean[] m() { + boolean[] aboolean = new boolean[3]; + + for (int i = 0; i < 3; ++i) { + if (this.items[i] != null) { + aboolean[i] = true; + } + } + + return aboolean; + } + + public int[] getSlotsForFace(EnumDirection enumdirection) { + return enumdirection == EnumDirection.UP ? TileEntityBrewingStand.a : TileEntityBrewingStand.f; + } + + public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { + return this.b(i, itemstack); + } + + public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { + return true; + } + + public String getContainerName() { + return "minecraft:brewing_stand"; + } + + public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerBrewingStand(playerinventory, this); + } + + public int getProperty(int i) { + switch (i) { + case 0: + return this.brewTime; + + default: + return 0; + } + } + + public void b(int i, int j) { + switch (i) { + case 0: + this.brewTime = j; + + default: + } + } + + public int g() { + return 1; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityChest.java new file mode 100644 index 0000000..5192d95 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityChest.java @@ -0,0 +1,519 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +// CraftBukkit start +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +// CraftBukkit end + +public class TileEntityChest extends TileEntityContainer implements IInventory { // PaperSpigot - remove IUpdatePlayerListBox + + private ItemStack[] items = new ItemStack[27]; + public boolean a; + public TileEntityChest f; // PaperSpigot - adjacentChestZNeg + public TileEntityChest g; // PaperSpigot - adjacentChestXPos + public TileEntityChest h; // PaperSpigot - adjacentChestXNeg + public TileEntityChest i; // PaperSpigot - adjacentChestZPos + public float j; // PaperSpigot - lidAngle + public float k; + public int l; // PaperSpigot - numPlayersUsing + private int n; + private int o = -1; + private String p; + + public TileEntityChest() {} + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public int getSize() { + return 27; + } + + public ItemStack getItem(int i) { + return this.items[i]; + } + + public ItemStack splitStack(int i, int j) { + if (this.items[i] != null) { + ItemStack itemstack; + + if (this.items[i].count <= j) { + itemstack = this.items[i]; + this.items[i] = null; + this.update(); + return itemstack; + } else { + itemstack = this.items[i].cloneAndSubtract(j); + if (this.items[i].count == 0) { + this.items[i] = null; + } + + this.update(); + return itemstack; + } + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.items[i] != null) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + this.items[i] = itemstack; + if (itemstack != null && itemstack.count > this.getMaxStackSize()) { + itemstack.count = this.getMaxStackSize(); + } + + this.update(); + } + + public String getName() { + return this.hasCustomName() ? this.p : "container.chest"; + } + + public boolean hasCustomName() { + return this.p != null && this.p.length() > 0; + } + + public void a(String s) { + this.p = s; + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getList("Items", 10); + + this.items = new ItemStack[this.getSize()]; + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.p = nbttagcompound.getString("CustomName"); + } + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + int j = nbttagcompound1.getByte("Slot") & 255; + + if (j >= 0 && j < this.items.length) { + this.items[j] = ItemStack.createStack(nbttagcompound1); + } + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setByte("Slot", (byte) i); + this.items[i].save(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Items", nbttaglist); + if (this.hasCustomName()) { + nbttagcompound.setString("CustomName", this.p); + } + + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { + if (this.world == null) return true; // CraftBukkit + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + + public void E() { + super.E(); + this.a = false; + } + + private void a(TileEntityChest tileentitychest, EnumDirection enumdirection) { + if (tileentitychest.x()) { + this.a = false; + } else if (this.a) { + switch (TileEntityChest.SyntheticClass_1.a[enumdirection.ordinal()]) { + case 1: + if (this.f != tileentitychest) { + this.a = false; + } + break; + + case 2: + if (this.i != tileentitychest) { + this.a = false; + } + break; + + case 3: + if (this.g != tileentitychest) { + this.a = false; + } + break; + + case 4: + if (this.h != tileentitychest) { + this.a = false; + } + } + } + + } + + public void m() { + if (!this.a) { + this.a = true; + this.h = this.a(EnumDirection.WEST); + this.g = this.a(EnumDirection.EAST); + this.f = this.a(EnumDirection.NORTH); + this.i = this.a(EnumDirection.SOUTH); + } + } + + protected TileEntityChest a(EnumDirection enumdirection) { + BlockPosition blockposition = this.position.shift(enumdirection); + + if (this.b(blockposition)) { + TileEntity tileentity = this.world.getTileEntity(blockposition); + + if (tileentity instanceof TileEntityChest) { + TileEntityChest tileentitychest = (TileEntityChest) tileentity; + + tileentitychest.a(this, enumdirection.opposite()); + return tileentitychest; + } + } + + return null; + } + + private boolean b(BlockPosition blockposition) { + if (this.world == null) { + return false; + } else { + Block block = this.world.getType(blockposition).getBlock(); + + return block instanceof BlockChest && ((BlockChest) block).b == this.n(); + } + } + + public void c() { + // PaperSpigot - Move chest sounds out of the tick loop + /* + this.m(); + int i = this.position.getX(); + int j = this.position.getY(); + int k = this.position.getZ(); + + ++this.n; + float f; + + if (!this.world.isClientSide && this.l != 0 && (this.n + i + j + k) % 200 == 0) { + this.l = 0; + f = 5.0F; + List list = this.world.a(EntityHuman.class, new AxisAlignedBB((double) ((float) i - f), (double) ((float) j - f), (double) ((float) k - f), (double) ((float) (i + 1) + f), (double) ((float) (j + 1) + f), (double) ((float) (k + 1) + f))); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (entityhuman.activeContainer instanceof ContainerChest) { + IInventory iinventory = ((ContainerChest) entityhuman.activeContainer).e(); + + if (iinventory == this || iinventory instanceof InventoryLargeChest && ((InventoryLargeChest) iinventory).a((IInventory) this)) { + ++this.l; + } + } + } + } + + this.k = this.j; + f = 0.1F; + double d0; + + if (this.l > 0 && this.j == 0.0F && this.f == null && this.h == null) { + double d1 = (double) i + 0.5D; + + d0 = (double) k + 0.5D; + if (this.i != null) { + d0 += 0.5D; + } + + if (this.g != null) { + d1 += 0.5D; + } + + this.world.makeSound(d1, (double) j + 0.5D, d0, "random.chestopen", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + } + + if (this.l == 0 && this.j > 0.0F || this.l > 0 && this.j < 1.0F) { + float f1 = this.j; + + if (this.l > 0) { + this.j += f; + } else { + this.j -= f; + } + + if (this.j > 1.0F) { + this.j = 1.0F; + } + + float f2 = 0.5F; + + if (this.j < f2 && f1 >= f2 && this.f == null && this.h == null) { + d0 = (double) i + 0.5D; + double d2 = (double) k + 0.5D; + + if (this.i != null) { + d2 += 0.5D; + } + + if (this.g != null) { + d0 += 0.5D; + } + + this.world.makeSound(d0, (double) j + 0.5D, d2, "random.chestclosed", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + } + + if (this.j < 0.0F) { + this.j = 0.0F; + } + } + */ + // PaperSpigot end + } + + public boolean c(int i, int j) { + if (i == 1) { + this.l = j; + return true; + } else { + return super.c(i, j); + } + } + + public void startOpen(EntityHuman entityhuman) { + if (!entityhuman.isSpectator()) { + if (this.l < 0) { + this.l = 0; + } + int oldPower = Math.max(0, Math.min(15, this.l)); // CraftBukkit - Get power before new viewer is added + + ++this.l; + if (this.world == null) return; // CraftBukkit + + // PaperSpigot start - Move chest open sound out of the tick loop + this.m(); + + if (this.l > 0 && this.j == 0.0F && this.f == null && this.h == null) { + this.j = 0.7F; + + double d0 = (double) this.position.getZ() + 0.5D; + double d1 = (double) this.position.getX() + 0.5D; + + if (this.i != null) { + d0 += 0.5D; + } + + if (this.g != null) { + d1 += 0.5D; + } + + this.world.makeSound(d1, (double) this.position.getY() + 0.5D, d0, "random.chestopen", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + } + // PaperSpigot end + + this.world.playBlockAction(this.position, this.w(), 1, this.l); + + // CraftBukkit start - Call redstone event + if (this.w() == Blocks.TRAPPED_CHEST) { + int newPower = Math.max(0, Math.min(15, this.l)); + + if (oldPower != newPower) { + org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, position.getX(), position.getY(), position.getZ(), oldPower, newPower); + } + } + // CraftBukkit end + this.world.applyPhysics(this.position, this.w()); + this.world.applyPhysics(this.position.down(), this.w()); + } + + } + + public void closeContainer(EntityHuman entityhuman) { + if (!entityhuman.isSpectator() && this.w() instanceof BlockChest) { + int oldPower = Math.max(0, Math.min(15, this.l)); // CraftBukkit - Get power before new viewer is added + --this.l; + if (this.world == null) return; // CraftBukkit + + // PaperSpigot start - Move chest close sound handling out of the tick loop + if (this.l == 0 && this.j > 0.0F || this.l > 0 && this.j < 1.0F) { + float f = 0.1F; + + if (this.l > 0) { + this.j += f; + } else { + this.j -= f; + } + + double d0 = (double) this.getPosition().getX() + 0.5D; + double d2 = (double) this.getPosition().getZ() + 0.5D; + + if (this.i != null) { + d2 += 0.5D; + } + + if (this.g != null) { + d0 += 0.5D; + } + + this.world.makeSound(d0, (double) this.getPosition().getY() + 0.5D, d2, "random.chestclosed", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + this.j = 0.0F; + } + // PaperSpigot end + + this.world.playBlockAction(this.position, this.w(), 1, this.l); + + // CraftBukkit start - Call redstone event + if (this.w() == Blocks.TRAPPED_CHEST) { + int newPower = Math.max(0, Math.min(15, this.l)); + + if (oldPower != newPower) { + org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, position.getX(), position.getY(), position.getZ(), oldPower, newPower); + } + } + // CraftBukkit end + this.world.applyPhysics(this.position, this.w()); + this.world.applyPhysics(this.position.down(), this.w()); + } + + } + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public void y() { + super.y(); + this.E(); + this.m(); + } + + public int n() { + if (this.o == -1) { + if (this.world == null || !(this.w() instanceof BlockChest)) { + return 0; + } + + this.o = ((BlockChest) this.w()).b; + } + + return this.o; + } + + public String getContainerName() { + return "minecraft:chest"; + } + + public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerChest(playerinventory, this, entityhuman); + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } + + // CraftBukkit start + // PAIL + @Override + public boolean F() { + return true; + } + // CraftBukkit end + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + TileEntityChest.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + TileEntityChest.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + TileEntityChest.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + TileEntityChest.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityCommand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityCommand.java new file mode 100644 index 0000000..f102934 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityCommand.java @@ -0,0 +1,65 @@ +package net.minecraft.server; + +public class TileEntityCommand extends TileEntity { + + private final CommandBlockListenerAbstract a = new CommandBlockListenerAbstract() { + { + sender = new org.bukkit.craftbukkit.command.CraftBlockCommandSender(this); // CraftBukkit - add sender + } + public BlockPosition getChunkCoordinates() { + return TileEntityCommand.this.position; + } + + public Vec3D d() { + return new Vec3D((double) TileEntityCommand.this.position.getX() + 0.5D, (double) TileEntityCommand.this.position.getY() + 0.5D, (double) TileEntityCommand.this.position.getZ() + 0.5D); + } + + public World getWorld() { + return TileEntityCommand.this.getWorld(); + } + + public void setCommand(String s) { + super.setCommand(s); + TileEntityCommand.this.update(); + } + + public void h() { + TileEntityCommand.this.getWorld().notify(TileEntityCommand.this.position); + } + + public Entity f() { + return null; + } + }; + + public TileEntityCommand() {} + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.a.a(nbttagcompound); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.a.b(nbttagcompound); + } + + public Packet getUpdatePacket() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + this.b(nbttagcompound); + return new PacketPlayOutTileEntityData(this.position, 2, nbttagcompound); + } + + public boolean F() { + return true; + } + + public CommandBlockListenerAbstract getCommandBlock() { + return this.a; + } + + public CommandObjectiveExecutor c() { + return this.a.n(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityDispenser.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityDispenser.java new file mode 100644 index 0000000..9be494b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityDispenser.java @@ -0,0 +1,215 @@ +package net.minecraft.server; + +import java.util.Random; + +// CraftBukkit start +import java.util.List; + +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +// CraftBukkit end + +public class TileEntityDispenser extends TileEntityContainer implements IInventory { + + private static final Random f = new Random(); + private ItemStack[] items = new ItemStack[9]; + protected String a; + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public TileEntityDispenser() {} + + public int getSize() { + return 9; + } + + public ItemStack getItem(int i) { + return this.items[i]; + } + + public ItemStack splitStack(int i, int j) { + if (this.items[i] != null) { + ItemStack itemstack; + + if (this.items[i].count <= j) { + itemstack = this.items[i]; + this.items[i] = null; + this.update(); + return itemstack; + } else { + itemstack = this.items[i].cloneAndSubtract(j); + if (this.items[i].count == 0) { + this.items[i] = null; + } + + this.update(); + return itemstack; + } + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.items[i] != null) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public int m() { + int i = -1; + int j = 1; + + for (int k = 0; k < this.items.length; ++k) { + if (this.items[k] != null && TileEntityDispenser.f.nextInt(j++) == 0) { + if (this.items[k].count == 0) continue; // CraftBukkit + i = k; + } + } + + return i; + } + + public void setItem(int i, ItemStack itemstack) { + this.items[i] = itemstack; + if (itemstack != null && itemstack.count > this.getMaxStackSize()) { + itemstack.count = this.getMaxStackSize(); + } + + this.update(); + } + + public int addItem(ItemStack itemstack) { + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] == null || this.items[i].getItem() == null) { + this.setItem(i, itemstack); + return i; + } + } + + return -1; + } + + public String getName() { + return this.hasCustomName() ? this.a : "container.dispenser"; + } + + public void a(String s) { + this.a = s; + } + + public boolean hasCustomName() { + return this.a != null; + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getList("Items", 10); + + this.items = new ItemStack[this.getSize()]; + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + int j = nbttagcompound1.getByte("Slot") & 255; + + if (j >= 0 && j < this.items.length) { + this.items[j] = ItemStack.createStack(nbttagcompound1); + } + } + + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.a = nbttagcompound.getString("CustomName"); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setByte("Slot", (byte) i); + this.items[i].save(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Items", nbttaglist); + if (this.hasCustomName()) { + nbttagcompound.setString("CustomName", this.a); + } + + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public String getContainerName() { + return "minecraft:dispenser"; + } + + public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerDispenser(playerinventory, this); + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityEnderChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityEnderChest.java new file mode 100644 index 0000000..00fceda --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityEnderChest.java @@ -0,0 +1,113 @@ +package net.minecraft.server; + +public class TileEntityEnderChest extends TileEntity { // PaperSpigot - remove IUpdatePlayerListBox + + public float a; // PaperSpigot - lidAngle + public float f; + public int g; // PaperSpigot - numPlayersUsing + private int h; + + public TileEntityEnderChest() {} + + public void c() { + // PaperSpigot start - Move enderchest sound handling out of the tick loop + /* + if (++this.h % 20 * 4 == 0) { + this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.g); + } + + this.f = this.a; + int i = this.position.getX(); + int j = this.position.getY(); + int k = this.position.getZ(); + float f = 0.1F; + double d0; + + if (this.g > 0 && this.a == 0.0F) { + double d1 = (double) i + 0.5D; + + d0 = (double) k + 0.5D; + this.world.makeSound(d1, (double) j + 0.5D, d0, "random.chestopen", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + } + + if (this.g == 0 && this.a > 0.0F || this.g > 0 && this.a < 1.0F) { + float f1 = this.a; + + if (this.g > 0) { + this.a += f; + } else { + this.a -= f; + } + + if (this.a > 1.0F) { + this.a = 1.0F; + } + + float f2 = 0.5F; + + if (this.a < f2 && f1 >= f2) { + d0 = (double) i + 0.5D; + double d2 = (double) k + 0.5D; + + this.world.makeSound(d0, (double) j + 0.5D, d2, "random.chestclosed", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + } + + if (this.a < 0.0F) { + this.a = 0.0F; + } + } + */ + // PaperSpigot end + } + + public boolean c(int i, int j) { + if (i == 1) { + this.g = j; + return true; + } else { + return super.c(i, j); + } + } + + public void y() { + this.E(); + super.y(); + } + + public void b() { + ++this.g; + + // PaperSpigot start - Move enderchest open sounds out of the tick loop + if (this.g > 0 && this.a == 0.0F) { + this.a = 0.7F; + + double d1 = (double) this.getPosition().getX() + 0.5D; + double d0 = (double) this.getPosition().getZ() + 0.5D; + + this.world.makeSound(d1, (double) this.getPosition().getY() + 0.5D, d0, "random.chestopen", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + } + // PaperSpigot end + + this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.g); + } + + public void d() { + --this.g; + + // PaperSpigot start - Move enderchest close sounds out of the tick loop + if (this.g == 0 && this.a > 0.0F || this.g > 0 && this.a < 1.0F) { + double d0 = (double) this.getPosition().getX() + 0.5D; + double d2 = (double) this.getPosition().getZ() + 0.5D; + + this.world.makeSound(d0, (double) this.getPosition().getY() + 0.5D, d2, "random.chestclosed", 0.5F, this.world.random.nextFloat() * 0.1F + 0.9F); + this.a = 0.0F; + } + // PaperSpigot end + + this.world.playBlockAction(this.position, Blocks.ENDER_CHEST, 1, this.g); + } + + public boolean a(EntityHuman entityhuman) { + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityFurnace.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityFurnace.java new file mode 100644 index 0000000..0e3f35a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityFurnace.java @@ -0,0 +1,448 @@ +package net.minecraft.server; + +// CraftBukkit start +import java.util.List; + +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.FurnaceBurnEvent; +import org.bukkit.event.inventory.FurnaceSmeltEvent; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +// CraftBukkit end + +public class TileEntityFurnace extends TileEntityContainer implements IUpdatePlayerListBox, IWorldInventory { + + private static final int[] a = new int[] { 0}; + private static final int[] f = new int[] { 2, 1}; + private static final int[] g = new int[] { 1}; + private ItemStack[] items = new ItemStack[3]; + public int burnTime; + private int ticksForCurrentFuel; + public int cookTime; + private int cookTimeTotal; + private String m; + + // CraftBukkit start - add fields and methods + private int lastTick = MinecraftServer.currentTick; + private int maxStack = MAX_STACK; + public List transaction = new java.util.ArrayList(); + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public TileEntityFurnace() {} + + public int getSize() { + return this.items.length; + } + + public ItemStack getItem(int i) { + return this.items[i]; + } + + public ItemStack splitStack(int i, int j) { + if (this.items[i] != null) { + ItemStack itemstack; + + if (this.items[i].count <= j) { + itemstack = this.items[i]; + this.items[i] = null; + return itemstack; + } else { + itemstack = this.items[i].cloneAndSubtract(j); + if (this.items[i].count == 0) { + this.items[i] = null; + } + + return itemstack; + } + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.items[i] != null) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + boolean flag = itemstack != null && itemstack.doMaterialsMatch(this.items[i]) && ItemStack.equals(itemstack, this.items[i]); + + this.items[i] = itemstack; + if (itemstack != null && itemstack.count > this.getMaxStackSize()) { + itemstack.count = this.getMaxStackSize(); + } + + if (i == 0 && !flag) { + this.cookTimeTotal = this.a(itemstack); + this.cookTime = 0; + this.update(); + } + + } + + public String getName() { + return this.hasCustomName() ? this.m : "container.furnace"; + } + + public boolean hasCustomName() { + return this.m != null && this.m.length() > 0; + } + + public void a(String s) { + this.m = s; + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getList("Items", 10); + + this.items = new ItemStack[this.getSize()]; + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + byte b0 = nbttagcompound1.getByte("Slot"); + + if (b0 >= 0 && b0 < this.items.length) { + this.items[b0] = ItemStack.createStack(nbttagcompound1); + } + } + + this.burnTime = nbttagcompound.getShort("BurnTime"); + this.cookTime = nbttagcompound.getShort("CookTime"); + this.cookTimeTotal = nbttagcompound.getShort("CookTimeTotal"); + this.ticksForCurrentFuel = fuelTime(this.items[1]); + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.m = nbttagcompound.getString("CustomName"); + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setShort("BurnTime", (short) this.burnTime); + nbttagcompound.setShort("CookTime", (short) this.cookTime); + nbttagcompound.setShort("CookTimeTotal", (short) this.cookTimeTotal); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setByte("Slot", (byte) i); + this.items[i].save(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Items", nbttaglist); + if (this.hasCustomName()) { + nbttagcompound.setString("CustomName", this.m); + } + + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public boolean isBurning() { + return this.burnTime > 0; + } + + public void c() { + boolean flag = (this.w() == Blocks.LIT_FURNACE); // CraftBukkit - SPIGOT-844 - Check if furnace block is lit using the block instead of burn time // PAIL: Rename + boolean flag1 = false; + + // CraftBukkit start - Use wall time instead of ticks for cooking + int elapsedTicks = MinecraftServer.currentTick - this.lastTick; + this.lastTick = MinecraftServer.currentTick; + + // CraftBukkit - moved from below + if (this.isBurning() && this.canBurn()) { + this.cookTime += elapsedTicks; + if (this.cookTime >= this.cookTimeTotal) { + this.cookTime = 0; + this.cookTimeTotal = this.a(this.items[0]); + this.burn(); + flag1 = true; + } + } else { + this.cookTime = 0; + } + // CraftBukkit end + + if (this.isBurning()) { + this.burnTime -= elapsedTicks; // CraftBukkit - use elapsedTicks in place of constant + } + + if (!this.world.isClientSide) { + if (!this.isBurning() && (this.items[1] == null || this.items[0] == null)) { + if (!this.isBurning() && this.cookTime > 0) { + this.cookTime = MathHelper.clamp(this.cookTime - 2, 0, this.cookTimeTotal); + } + } else { + // CraftBukkit start - Handle multiple elapsed ticks + if (this.burnTime <= 0 && this.canBurn()) { // CraftBukkit - == to <= + CraftItemStack fuel = CraftItemStack.asCraftMirror(this.items[1]); + + FurnaceBurnEvent furnaceBurnEvent = new FurnaceBurnEvent(this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), fuel, fuelTime(this.items[1])); + this.world.getServer().getPluginManager().callEvent(furnaceBurnEvent); + + if (furnaceBurnEvent.isCancelled()) { + return; + } + + this.ticksForCurrentFuel = furnaceBurnEvent.getBurnTime(); + this.burnTime += this.ticksForCurrentFuel; + if (this.burnTime > 0 && furnaceBurnEvent.isBurning()) { + // CraftBukkit end + flag1 = true; + if (this.items[1] != null) { + --this.items[1].count; + if (this.items[1].count == 0) { + Item item = this.items[1].getItem().q(); + + this.items[1] = item != null ? new ItemStack(item) : null; + } + } + } + } + + /* CraftBukkit start - Moved up + if (this.isBurning() && this.canBurn()) { + ++this.cookTime; + if (this.cookTime == this.cookTimeTotal) { + this.cookTime = 0; + this.cookTimeTotal = this.a(this.items[0]); + this.burn(); + flag1 = true; + } + } else { + this.cookTime = 0; + } + */ + } + + if (flag != this.isBurning()) { + flag1 = true; + BlockFurnace.a(this.isBurning(), this.world, this.position); + this.E(); // CraftBukkit - Invalidate tile entity's cached block type // PAIL: Rename + } + } + + if (flag1) { + this.update(); + } + + } + + public int a(ItemStack itemstack) { + return 200; + } + + private boolean canBurn() { + if (this.items[0] == null) { + return false; + } else { + ItemStack itemstack = RecipesFurnace.getInstance().getResult(this.items[0]); + + // CraftBukkit - consider resultant count instead of current count + return itemstack == null ? false : (this.items[2] == null ? true : (!this.items[2].doMaterialsMatch(itemstack) ? false : (this.items[2].count + itemstack.count <= this.getMaxStackSize() && this.items[2].count < this.items[2].getMaxStackSize() ? true : this.items[2].count + itemstack.count <= itemstack.getMaxStackSize()))); + } + } + + public void burn() { + if (this.canBurn()) { + ItemStack itemstack = RecipesFurnace.getInstance().getResult(this.items[0]); + + // CraftBukkit start - fire FurnaceSmeltEvent + CraftItemStack source = CraftItemStack.asCraftMirror(this.items[0]); + org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack); + + FurnaceSmeltEvent furnaceSmeltEvent = new FurnaceSmeltEvent(this.world.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()), source, result); + this.world.getServer().getPluginManager().callEvent(furnaceSmeltEvent); + + if (furnaceSmeltEvent.isCancelled()) { + return; + } + + result = furnaceSmeltEvent.getResult(); + itemstack = CraftItemStack.asNMSCopy(result); + + if (itemstack != null) { + if (this.items[2] == null) { + this.items[2] = itemstack; + } else if (CraftItemStack.asCraftMirror(this.items[2]).isSimilar(result)) { + this.items[2].count += itemstack.count; + } else { + return; + } + } + + /* + if (this.items[2] == null) { + this.items[2] = itemstack.cloneItemStack(); + } else if (this.items[2].getItem() == itemstack.getItem()) { + ++this.items[2].count; + } + */ + // CraftBukkit end + + if (this.items[0].getItem() == Item.getItemOf(Blocks.SPONGE) && this.items[0].getData() == 1 && this.items[1] != null && this.items[1].getItem() == Items.BUCKET) { + this.items[1] = new ItemStack(Items.WATER_BUCKET); + } + + --this.items[0].count; + if (this.items[0].count <= 0) { + this.items[0] = null; + } + + } + } + + public static int fuelTime(ItemStack itemstack) { + if (itemstack == null) { + return 0; + } else { + Item item = itemstack.getItem(); + + if (item instanceof ItemBlock && Block.asBlock(item) != Blocks.AIR) { + Block block = Block.asBlock(item); + + if (block == Blocks.WOODEN_SLAB) { + return 150; + } + + if (block.getMaterial() == Material.WOOD) { + return 300; + } + + if (block == Blocks.COAL_BLOCK) { + return 16000; + } + } + + 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))))))); + } + } + + public static boolean isFuel(ItemStack itemstack) { + return fuelTime(itemstack) > 0; + } + + public boolean a(EntityHuman entityhuman) { + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return i == 2 ? false : (i != 1 ? true : isFuel(itemstack) || SlotFurnaceFuel.c_(itemstack)); + } + + public int[] getSlotsForFace(EnumDirection enumdirection) { + return enumdirection == EnumDirection.DOWN ? TileEntityFurnace.f : (enumdirection == EnumDirection.UP ? TileEntityFurnace.a : TileEntityFurnace.g); + } + + public boolean canPlaceItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { + return this.b(i, itemstack); + } + + public boolean canTakeItemThroughFace(int i, ItemStack itemstack, EnumDirection enumdirection) { + if (enumdirection == EnumDirection.DOWN && i == 1) { + Item item = itemstack.getItem(); + + if (item != Items.WATER_BUCKET && item != Items.BUCKET) { + return false; + } + } + + return true; + } + + public String getContainerName() { + return "minecraft:furnace"; + } + + public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerFurnace(playerinventory, this); + } + + public int getProperty(int i) { + switch (i) { + case 0: + return this.burnTime; + + case 1: + return this.ticksForCurrentFuel; + + case 2: + return this.cookTime; + + case 3: + return this.cookTimeTotal; + + default: + return 0; + } + } + + public void b(int i, int j) { + switch (i) { + case 0: + this.burnTime = j; + break; + + case 1: + this.ticksForCurrentFuel = j; + break; + + case 2: + this.cookTime = j; + break; + + case 3: + this.cookTimeTotal = j; + } + + } + + public int g() { + return 4; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityHopper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityHopper.java new file mode 100644 index 0000000..4d7f160 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityHopper.java @@ -0,0 +1,690 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +// CraftBukkit start +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.entity.CraftItem; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryMoveItemEvent; +import org.bukkit.event.inventory.InventoryPickupItemEvent; +import org.bukkit.inventory.Inventory; +// CraftBukkit end +import net.techcable.tacospigot.HopperHelper; // TacoSpigot + +public class TileEntityHopper extends TileEntityContainer implements IHopper, IUpdatePlayerListBox { + + private ItemStack[] items = new ItemStack[5]; + private String f; + private int g = -1; + + // CraftBukkit start - add fields and methods + public List transaction = new java.util.ArrayList(); + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() { + return this.items; + } + + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + public List getViewers() { + return transaction; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + // CraftBukkit end + + public TileEntityHopper() {} + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + NBTTagList nbttaglist = nbttagcompound.getList("Items", 10); + + this.items = new ItemStack[this.getSize()]; + if (nbttagcompound.hasKeyOfType("CustomName", 8)) { + this.f = nbttagcompound.getString("CustomName"); + } + + this.g = nbttagcompound.getInt("TransferCooldown"); + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + byte b0 = nbttagcompound1.getByte("Slot"); + + if (b0 >= 0 && b0 < this.items.length) { + this.items[b0] = ItemStack.createStack(nbttagcompound1); + } + } + + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + NBTTagList nbttaglist = new NBTTagList(); + + for (int i = 0; i < this.items.length; ++i) { + if (this.items[i] != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setByte("Slot", (byte) i); + this.items[i].save(nbttagcompound1); + nbttaglist.add(nbttagcompound1); + } + } + + nbttagcompound.set("Items", nbttaglist); + nbttagcompound.setInt("TransferCooldown", this.g); + if (this.hasCustomName()) { + nbttagcompound.setString("CustomName", this.f); + } + + } + + public void update() { + super.update(); + } + + public int getSize() { + return this.items.length; + } + + public ItemStack getItem(int i) { + return this.items[i]; + } + + public ItemStack splitStack(int i, int j) { + if (this.items[i] != null) { + ItemStack itemstack; + + if (this.items[i].count <= j) { + itemstack = this.items[i]; + this.items[i] = null; + return itemstack; + } else { + itemstack = this.items[i].cloneAndSubtract(j); + if (this.items[i].count == 0) { + this.items[i] = null; + } + + return itemstack; + } + } else { + return null; + } + } + + public ItemStack splitWithoutUpdate(int i) { + if (this.items[i] != null) { + ItemStack itemstack = this.items[i]; + + this.items[i] = null; + return itemstack; + } else { + return null; + } + } + + public void setItem(int i, ItemStack itemstack) { + this.items[i] = itemstack; + if (itemstack != null && itemstack.count > this.getMaxStackSize()) { + itemstack.count = this.getMaxStackSize(); + } + + } + + public String getName() { + return this.hasCustomName() ? this.f : "container.hopper"; + } + + public boolean hasCustomName() { + return this.f != null && this.f.length() > 0; + } + + public void a(String s) { + this.f = s; + } + + public int getMaxStackSize() { + return maxStack; // CraftBukkit + } + + public boolean a(EntityHuman entityhuman) { + return this.world.getTileEntity(this.position) != this ? false : entityhuman.e((double) this.position.getX() + 0.5D, (double) this.position.getY() + 0.5D, (double) this.position.getZ() + 0.5D) <= 64.0D; + } + + public void startOpen(EntityHuman entityhuman) {} + + public void closeContainer(EntityHuman entityhuman) {} + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + public void c() { + if (this.world != null && !this.world.isClientSide) { + --this.g; + if (!this.n()) { + this.d(0); + this.m(); + } + + } + } + + public boolean m() { + if (this.world != null && !this.world.isClientSide) { + if (!this.n() && BlockHopper.f(this.u())) { + boolean flag = false; + + if (!this.p()) { + flag = this.r(); + } + + if (!this.q()) { + flag = a((IHopper) this) || flag; + } + + if (flag) { + this.d(world.spigotConfig.hopperTransfer); // Spigot + this.update(); + return true; + } + } + // PaperSpigot start + if (world.paperSpigotConfig.useHopperCheck && !world.tacoSpigotConfig.isHopperPushBased && !this.n()) { // TacoSpigot - dont use hopper check in push mode + this.d(world.spigotConfig.hopperCheck); + } + // PaperSpigot end + return false; + } else { + return false; + } + } + + private boolean p() { + ItemStack[] aitemstack = this.items; + int i = aitemstack.length; + + for (int j = 0; j < i; ++j) { + ItemStack itemstack = aitemstack[j]; + + if (itemstack != null) { + return false; + } + } + + return true; + } + + // TacoSpigot start + public boolean canAcceptItems() { + return !this.n() && !this.q() && BlockHopper.f(this.u()); + } + // TacoSpigot end + + private boolean q() { + ItemStack[] aitemstack = this.items; + int i = aitemstack.length; + + for (int j = 0; j < i; ++j) { + ItemStack itemstack = aitemstack[j]; + + if (itemstack == null || itemstack.count != itemstack.getMaxStackSize()) { + return false; + } + } + + return true; + } + + private boolean r() { + // TacoSpigot start - Don't use inefficient H() which does another bounding box search + IInventory iinventory = HopperHelper.getInventory(getWorld(), getPosition().shift(BlockHopper.b(this.u()))); + // TacoSpigot end + + if (iinventory == null) { + return false; + } else { + EnumDirection enumdirection = BlockHopper.b(this.u()).opposite(); + + if (this.a(iinventory, enumdirection)) { + return false; + } else { + for (int i = 0; i < this.getSize(); ++i) { + if (this.getItem(i) != null) { + ItemStack itemstack = this.getItem(i).cloneItemStack(); + // ItemStack itemstack1 = addItem(iinventory, this.splitStack(i, 1), enumdirection); + + // CraftBukkit start - Call event when pushing items into other inventories + CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, world.spigotConfig.hopperAmount)); // Spigot + // TacoSpigot start - add an option to turn of InventoryMoveItemEvent + final org.bukkit.inventory.ItemStack stack; + if (HopperHelper.isFireInventoryMoveItemEvent(this)) { + // TacoSpigot end + + Inventory destinationInventory; + // Have to special case large chests as they work oddly + if (iinventory instanceof InventoryLargeChest) { + destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); + } else { + destinationInventory = iinventory.getOwner().getInventory(); + } + + InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); + this.getWorld().getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + this.setItem(i, itemstack); + this.d(world.spigotConfig.hopperTransfer); // Spigot + return false; + } + // TacoSpigot start + stack = event.getItem(); + // handle cases where the event is not fired + } else { + stack = oitemstack; + } + int origCount = stack.getAmount(); // Spigot + ItemStack itemstack1 = addItem(iinventory, CraftItemStack.asNMSCopy(stack), enumdirection); + // TacoSpigot end + + if (itemstack1 == null || itemstack1.count == 0) { + if (stack.equals(oitemstack)) { // TacoSpigot - event.getItem() -> stack + iinventory.update(); + } else { + this.setItem(i, itemstack); + } + // CraftBukkit end + return true; + } + itemstack.count -= origCount - itemstack1.count; // Spigot + this.setItem(i, itemstack); + } + } + + return false; + } + } + } + + private boolean a(IInventory iinventory, EnumDirection enumdirection) { + if (iinventory instanceof IWorldInventory) { + IWorldInventory iworldinventory = (IWorldInventory) iinventory; + int[] aint = iworldinventory.getSlotsForFace(enumdirection); + + for (int i = 0; i < aint.length; ++i) { + ItemStack itemstack = iworldinventory.getItem(aint[i]); + + if (itemstack == null || itemstack.count != itemstack.getMaxStackSize()) { + return false; + } + } + } else { + int j = iinventory.getSize(); + + for (int k = 0; k < j; ++k) { + ItemStack itemstack1 = iinventory.getItem(k); + + if (itemstack1 == null || itemstack1.count != itemstack1.getMaxStackSize()) { + return false; + } + } + } + + return true; + } + + private static boolean b(IInventory iinventory, EnumDirection enumdirection) { + if (iinventory instanceof IWorldInventory) { + IWorldInventory iworldinventory = (IWorldInventory) iinventory; + int[] aint = iworldinventory.getSlotsForFace(enumdirection); + + for (int i = 0; i < aint.length; ++i) { + if (iworldinventory.getItem(aint[i]) != null) { + return false; + } + } + } else { + int j = iinventory.getSize(); + + for (int k = 0; k < j; ++k) { + if (iinventory.getItem(k) != null) { + return false; + } + } + } + + return true; + } + + // TacoSpigot start - Split methods, one that pushes and one that pulls + @Deprecated + public static boolean a(IHopper ihopper) { + IInventory iinventory; + if (ihopper.getWorld().tacoSpigotConfig.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 { + iinventory = b(ihopper); // Use old behavior for BB entity searching + } + return acceptItem(ihopper, iinventory); + } + + public static boolean acceptItem(IHopper ihopper, IInventory iinventory) { + // TacoSpigot end + if (iinventory != null) { + EnumDirection enumdirection = EnumDirection.DOWN; + + if (b(iinventory, enumdirection)) { + return false; + } + + if (iinventory instanceof IWorldInventory) { + IWorldInventory iworldinventory = (IWorldInventory) iinventory; + int[] aint = iworldinventory.getSlotsForFace(enumdirection); + + for (int i = 0; i < aint.length; ++i) { + if (a(ihopper, iinventory, aint[i], enumdirection)) { + return true; + } + } + } else { + int j = iinventory.getSize(); + + for (int k = 0; k < j; ++k) { + if (a(ihopper, iinventory, k, enumdirection)) { + return true; + } + } + } + } else if (!ihopper.getWorld().tacoSpigotConfig.isHopperPushBased || !(ihopper instanceof TileEntityHopper)) { // TacoSpigot - only search for entities in 'pull mode' + Iterator iterator = a(ihopper.getWorld(), ihopper.A(), ihopper.B() + 1.0D, ihopper.C()).iterator(); + + while (iterator.hasNext()) { + EntityItem entityitem = (EntityItem) iterator.next(); + + if (a((IInventory) ihopper, entityitem)) { + return true; + } + } + } + + return false; + } + + private static boolean a(IHopper ihopper, IInventory iinventory, int i, EnumDirection enumdirection) { + ItemStack itemstack = iinventory.getItem(i); + + if (itemstack != null && b(iinventory, itemstack, i, enumdirection)) { + ItemStack itemstack1 = itemstack.cloneItemStack(); + // ItemStack itemstack2 = addItem(ihopper, iinventory.splitStack(i, 1), (EnumDirection) null); + // CraftBukkit start - Call event on collection of items from inventories into the hopper + CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, ihopper.getWorld().spigotConfig.hopperAmount)); // Spigot + // TacoSpigot start - add an option to turn of InventoryMoveItemEvent + final org.bukkit.inventory.ItemStack stack; + if (HopperHelper.isFireInventoryMoveItemEvent(ihopper)) { + // TacoSpigot end + + Inventory sourceInventory; + // Have to special case large chests as they work oddly + if (iinventory instanceof InventoryLargeChest) { + sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); + } else { + sourceInventory = iinventory.getOwner().getInventory(); + } + + InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), ihopper.getOwner().getInventory(), false); + + ihopper.getWorld().getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + iinventory.setItem(i, itemstack1); + + if (ihopper instanceof TileEntityHopper) { + ((TileEntityHopper) ihopper).d(ihopper.getWorld().spigotConfig.hopperTransfer); // Spigot + } else if (ihopper instanceof EntityMinecartHopper) { + ((EntityMinecartHopper) ihopper).m(ihopper.getWorld().spigotConfig.hopperTransfer / 2); // Spigot + } + return false; + } + // TacoSpigot start + stack = event.getItem(); + // handle cases where the event is not fired + } else { + stack = oitemstack; + } + int origCount = stack.getAmount(); // Spigot + ItemStack itemstack2 = addItem(ihopper, CraftItemStack.asNMSCopy(stack), null); + // TacoSpigot end + + if (itemstack2 == null || itemstack2.count == 0) { + if (stack.equals(oitemstack)) { + iinventory.update(); + } else { + iinventory.setItem(i, itemstack1); + } + // CraftBukkit end + return true; + } + itemstack1.count -= origCount - itemstack2.count; // Spigot + + iinventory.setItem(i, itemstack1); + } + + return false; + } + + public static boolean a(IInventory iinventory, EntityItem entityitem) { + boolean flag = false; + + if (entityitem == null) { + return false; + } else { + // CraftBukkit start + InventoryPickupItemEvent event = new InventoryPickupItemEvent(iinventory.getOwner().getInventory(), (org.bukkit.entity.Item) entityitem.getBukkitEntity()); + entityitem.world.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } + // CraftBukkit end + ItemStack itemstack = entityitem.getItemStack().cloneItemStack(); + ItemStack itemstack1 = addItem(iinventory, itemstack, (EnumDirection) null); + + if (itemstack1 != null && itemstack1.count != 0) { + entityitem.setItemStack(itemstack1); + } else { + flag = true; + entityitem.die(); + } + + return flag; + } + } + + public static ItemStack addItem(IInventory iinventory, ItemStack itemstack, EnumDirection enumdirection) { + if (iinventory instanceof IWorldInventory && enumdirection != null) { + IWorldInventory iworldinventory = (IWorldInventory) iinventory; + int[] aint = iworldinventory.getSlotsForFace(enumdirection); + + for (int i = 0; i < aint.length && itemstack != null && itemstack.count > 0; ++i) { + itemstack = c(iinventory, itemstack, aint[i], enumdirection); + } + } else { + int j = iinventory.getSize(); + + for (int k = 0; k < j && itemstack != null && itemstack.count > 0; ++k) { + itemstack = c(iinventory, itemstack, k, enumdirection); + } + } + + if (itemstack != null && itemstack.count == 0) { + itemstack = null; + } + + return itemstack; + } + + private static boolean a(IInventory iinventory, ItemStack itemstack, int i, EnumDirection enumdirection) { + return !iinventory.b(i, itemstack) ? false : !(iinventory instanceof IWorldInventory) || ((IWorldInventory) iinventory).canPlaceItemThroughFace(i, itemstack, enumdirection); + } + + private static boolean b(IInventory iinventory, ItemStack itemstack, int i, EnumDirection enumdirection) { + return !(iinventory instanceof IWorldInventory) || ((IWorldInventory) iinventory).canTakeItemThroughFace(i, itemstack, enumdirection); + } + + private static ItemStack c(IInventory iinventory, ItemStack itemstack, int i, EnumDirection enumdirection) { + ItemStack itemstack1 = iinventory.getItem(i); + + if (a(iinventory, itemstack, i, enumdirection)) { + boolean flag = false; + + if (itemstack1 == null) { + iinventory.setItem(i, itemstack); + itemstack = null; + flag = true; + } else if (a(itemstack1, itemstack)) { + int j = itemstack.getMaxStackSize() - itemstack1.count; + int k = Math.min(itemstack.count, j); + + itemstack.count -= k; + itemstack1.count += k; + flag = k > 0; + } + + if (flag) { + if (iinventory instanceof TileEntityHopper) { + TileEntityHopper tileentityhopper = (TileEntityHopper) iinventory; + + if (tileentityhopper.o()) { + tileentityhopper.d(tileentityhopper.world.spigotConfig.hopperTransfer); // Spigot + } + + iinventory.update(); + } + + iinventory.update(); + } + } + + return itemstack; + } + + private IInventory H() { + EnumDirection enumdirection = BlockHopper.b(this.u()); + + return b(this.getWorld(), (double) (this.position.getX() + enumdirection.getAdjacentX()), (double) (this.position.getY() + enumdirection.getAdjacentY()), (double) (this.position.getZ() + enumdirection.getAdjacentZ())); + } + + public static IInventory b(IHopper ihopper) { + return b(ihopper.getWorld(), ihopper.A(), ihopper.B() + 1.0D, ihopper.C()); + } + + public static List a(World world, double d0, double d1, double d2) { + return world.a(EntityItem.class, new AxisAlignedBB(d0 - 0.5D, d1 - 0.5D, d2 - 0.5D, d0 + 0.5D, d1 + 0.5D, d2 + 0.5D), IEntitySelector.a); + } + + public static IInventory b(World world, double d0, double d1, double d2) { + Object object = null; + int i = MathHelper.floor(d0); + int j = MathHelper.floor(d1); + int k = MathHelper.floor(d2); + BlockPosition blockposition = new BlockPosition(i, j, k); + if ( !world.isLoaded( blockposition ) ) return null; // Spigot + Block block = world.getType(blockposition).getBlock(); + + if (block.isTileEntity()) { + TileEntity tileentity = world.getTileEntity(blockposition); + + if (tileentity instanceof IInventory) { + object = (IInventory) tileentity; + if (object instanceof TileEntityChest && block instanceof BlockChest) { + object = ((BlockChest) block).f(world, blockposition); + } + } + } + + if (object == null) { + List list = world.a((Entity) null, new AxisAlignedBB(d0 - 0.5D, d1 - 0.5D, d2 - 0.5D, d0 + 0.5D, d1 + 0.5D, d2 + 0.5D), IEntitySelector.c); + + if (list.size() > 0) { + object = (IInventory) list.get(world.random.nextInt(list.size())); + } + } + + return (IInventory) object; + } + + // TacoSpigot start + public AxisAlignedBB getHopperLookupBoundingBox() { + // Change this if b(IHopper) ever changes + return getHopperLookupBoundingBox(this.A(), this.B() + 1.0D, this.C()); + } + + private static AxisAlignedBB getHopperLookupBoundingBox(double d0, double d1, double d2) { + // Change this if the above ever changes + return new AxisAlignedBB(d0 - 0.5D, d1 - 0.5D, d2 - 0.5D, d0 + 0.5D, d1 + 0.5D, d2 + 0.5D); + } + // TacoSpigot end + + private static boolean a(ItemStack itemstack, ItemStack itemstack1) { + return itemstack.getItem() != itemstack1.getItem() ? false : (itemstack.getData() != itemstack1.getData() ? false : (itemstack.count > itemstack.getMaxStackSize() ? false : ItemStack.equals(itemstack, itemstack1))); + } + + public double A() { + return (double) this.position.getX() + 0.5D; + } + + public double B() { + return (double) this.position.getY() + 0.5D; + } + + public double C() { + return (double) this.position.getZ() + 0.5D; + } + + public void d(int i) { + this.g = i; + } + + public boolean n() { + return this.g > 0; + } + + public boolean o() { + return this.g <= 1; + } + + public String getContainerName() { + return "minecraft:hopper"; + } + + public Container createContainer(PlayerInventory playerinventory, EntityHuman entityhuman) { + return new ContainerHopper(playerinventory, this, entityhuman); + } + + public int getProperty(int i) { + return 0; + } + + public void b(int i, int j) {} + + public int g() { + return 0; + } + + public void l() { + for (int i = 0; i < this.items.length; ++i) { + this.items[i] = null; + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityLightDetector.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityLightDetector.java new file mode 100644 index 0000000..f75e2de --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityLightDetector.java @@ -0,0 +1,16 @@ +package net.minecraft.server; + +public class TileEntityLightDetector extends TileEntity implements IUpdatePlayerListBox { + + public TileEntityLightDetector() {} + + public void c() { + if (this.world != null && !this.world.isClientSide && this.world.getTime() % 20L == 0L) { + this.e = this.w(); + if (this.e instanceof BlockDaylightDetector) { + ((BlockDaylightDetector) this.e).f(this.world, this.position); + } + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityNote.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityNote.java new file mode 100644 index 0000000..a3ab62a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityNote.java @@ -0,0 +1,55 @@ +package net.minecraft.server; + +public class TileEntityNote extends TileEntity { + + public byte note; + public boolean f; + + public TileEntityNote() {} + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setByte("note", this.note); + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.note = nbttagcompound.getByte("note"); + this.note = (byte) MathHelper.clamp(this.note, 0, 24); + } + + public void b() { + this.note = (byte) ((this.note + 1) % 25); + this.update(); + } + + public void play(World world, BlockPosition blockposition) { + if (world.getType(blockposition.up()).getBlock().getMaterial() == Material.AIR) { + Material material = world.getType(blockposition.down()).getBlock().getMaterial(); + byte b0 = 0; + + if (material == Material.STONE) { + b0 = 1; + } + + if (material == Material.SAND) { + b0 = 2; + } + + if (material == Material.SHATTERABLE) { + b0 = 3; + } + + if (material == Material.WOOD) { + b0 = 4; + } + + // CraftBukkit start + org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(this.world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), b0, this.note); + if (!event.isCancelled()) { + world.playBlockAction(blockposition, Blocks.NOTEBLOCK, event.getInstrument().getType(), event.getNote().getId()); + } + // CraftBukkit end + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityPiston.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityPiston.java new file mode 100644 index 0000000..2e11fa1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntityPiston.java @@ -0,0 +1,173 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; + +public class TileEntityPiston extends TileEntity implements IUpdatePlayerListBox { + + private IBlockData a; + private EnumDirection f; + private boolean g; + private boolean h; + private float i; + private float j; + private List k = Lists.newArrayList(); + + public TileEntityPiston() {} + + public TileEntityPiston(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1) { + this.a = iblockdata; + this.f = enumdirection; + this.g = flag; + this.h = flag1; + } + + public IBlockData b() { + return this.a; + } + + public int u() { + return 0; + } + + public boolean d() { + return this.g; + } + + public EnumDirection e() { + return this.f; + } + + public float a(float f) { + if (f > 1.0F) { + f = 1.0F; + } + + return this.j + (this.i - this.j) * f; + } + + private void a(float f, float f1) { + if (this.g) { + f = 1.0F - f; + } else { + --f; + } + + AxisAlignedBB axisalignedbb = Blocks.PISTON_EXTENSION.a(this.world, this.position, this.a, f, this.f); + + if (axisalignedbb != null) { + List list = this.world.getEntities((Entity) null, axisalignedbb); + + if (!list.isEmpty()) { + this.k.addAll(list); + Iterator iterator = this.k.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (this.a.getBlock() == Blocks.SLIME && this.g) { + switch (TileEntityPiston.SyntheticClass_1.a[this.f.k().ordinal()]) { + case 1: + entity.motX = (double) this.f.getAdjacentX(); + break; + + case 2: + entity.motY = (double) this.f.getAdjacentY(); + break; + + case 3: + entity.motZ = (double) this.f.getAdjacentZ(); + } + } else { + entity.move((double) (f1 * (float) this.f.getAdjacentX()), (double) (f1 * (float) this.f.getAdjacentY()), (double) (f1 * (float) this.f.getAdjacentZ())); + } + } + + this.k.clear(); + } + } + + } + + public void h() { + if (this.j < 1.0F && this.world != null) { + this.j = this.i = 1.0F; + this.world.t(this.position); + this.y(); + if (this.world.getType(this.position).getBlock() == Blocks.PISTON_EXTENSION) { + this.world.setTypeAndData(this.position, this.a, 3); + this.world.d(this.position, this.a.getBlock()); + } + } + + } + + public void c() { + if (this.world == null) return; // CraftBukkit + this.j = this.i; + if (this.j >= 1.0F) { + this.a(1.0F, 0.25F); + this.world.t(this.position); + this.y(); + if (this.world.getType(this.position).getBlock() == Blocks.PISTON_EXTENSION) { + this.world.setTypeAndData(this.position, this.a, 3); + this.world.d(this.position, this.a.getBlock()); + } + + } else { + this.i += 0.5F; + if (this.i >= 1.0F) { + this.i = 1.0F; + } + + if (this.g) { + this.a(this.i, this.i - this.j + 0.0625F); + } + + } + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.a = Block.getById(nbttagcompound.getInt("blockId")).fromLegacyData(nbttagcompound.getInt("blockData")); + this.f = EnumDirection.fromType1(nbttagcompound.getInt("facing")); + this.j = this.i = nbttagcompound.getFloat("progress"); + this.g = nbttagcompound.getBoolean("extending"); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("blockId", Block.getId(this.a.getBlock())); + nbttagcompound.setInt("blockData", this.a.getBlock().toLegacyData(this.a)); + nbttagcompound.setInt("facing", this.f.a()); + nbttagcompound.setFloat("progress", this.j); + nbttagcompound.setBoolean("extending", this.g); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.EnumAxis.values().length]; + + static { + try { + TileEntityPiston.SyntheticClass_1.a[EnumDirection.EnumAxis.X.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + TileEntityPiston.SyntheticClass_1.a[EnumDirection.EnumAxis.Y.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + TileEntityPiston.SyntheticClass_1.a[EnumDirection.EnumAxis.Z.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntitySign.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntitySign.java new file mode 100644 index 0000000..e927fd2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntitySign.java @@ -0,0 +1,193 @@ +package net.minecraft.server; + +import com.google.gson.JsonParseException; + +public class TileEntitySign extends TileEntity { + + public final IChatBaseComponent[] lines = new IChatBaseComponent[] { new ChatComponentText(""), new ChatComponentText(""), new ChatComponentText(""), new ChatComponentText("")}; + public int f = -1; + public boolean isEditable = true; + private EntityHuman h; + private final CommandObjectiveExecutor i = new CommandObjectiveExecutor(); + + public TileEntitySign() {} + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + + for (int i = 0; i < 4; ++i) { + String s = IChatBaseComponent.ChatSerializer.a(this.lines[i]); + + nbttagcompound.setString("Text" + (i + 1), s); + } + + // CraftBukkit start + if (Boolean.getBoolean("convertLegacySigns")) { + nbttagcompound.setBoolean("Bukkit.isConverted", true); + } + // CraftBukkit end + + this.i.b(nbttagcompound); + } + + public void a(NBTTagCompound nbttagcompound) { + this.isEditable = false; + super.a(nbttagcompound); + ICommandListener icommandlistener = new ICommandListener() { + public String getName() { + return "Sign"; + } + + public IChatBaseComponent getScoreboardDisplayName() { + return new ChatComponentText(this.getName()); + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) {} + + public boolean a(int i, String s) { + return true; + } + + public BlockPosition getChunkCoordinates() { + return TileEntitySign.this.position; + } + + public Vec3D d() { + return new Vec3D((double) TileEntitySign.this.position.getX() + 0.5D, (double) TileEntitySign.this.position.getY() + 0.5D, (double) TileEntitySign.this.position.getZ() + 0.5D); + } + + public World getWorld() { + return TileEntitySign.this.world; + } + + public Entity f() { + return null; + } + + public boolean getSendCommandFeedback() { + return false; + } + + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) {} + }; + + // CraftBukkit start - Add an option to convert signs correctly + // This is done with a flag instead of all the time because + // we have no way to tell whether a sign is from 1.7.10 or 1.8 + + boolean oldSign = Boolean.getBoolean("convertLegacySigns") && !nbttagcompound.getBoolean("Bukkit.isConverted"); + + for (int i = 0; i < 4; ++i) { + String s = nbttagcompound.getString("Text" + (i + 1)); + if (s != null && s.length() > 2048) { + s = "\"\""; + } + + try { + IChatBaseComponent ichatbasecomponent = IChatBaseComponent.ChatSerializer.a(s); + + if (oldSign) { + lines[i] = org.bukkit.craftbukkit.util.CraftChatMessage.fromString(s)[0]; + continue; + } + // CraftBukkit end + + try { + this.lines[i] = ChatComponentUtils.filterForDisplay(icommandlistener, ichatbasecomponent, (Entity) null); + } catch (CommandException commandexception) { + this.lines[i] = ichatbasecomponent; + } + } catch (JsonParseException jsonparseexception) { + this.lines[i] = new ChatComponentText(s); + } + } + + this.i.a(nbttagcompound); + } + + public Packet getUpdatePacket() { + IChatBaseComponent[] aichatbasecomponent = new IChatBaseComponent[4]; + + System.arraycopy(this.lines, 0, aichatbasecomponent, 0, 4); + return new PacketPlayOutUpdateSign(this.world, this.position, aichatbasecomponent); + } + + public boolean F() { + return true; + } + + public boolean b() { + return this.isEditable; + } + + public void a(EntityHuman entityhuman) { + this.h = entityhuman; + } + + public EntityHuman c() { + return this.h; + } + + public boolean b(final EntityHuman entityhuman) { + ICommandListener icommandlistener = new ICommandListener() { + public String getName() { + return entityhuman.getName(); + } + + public IChatBaseComponent getScoreboardDisplayName() { + return entityhuman.getScoreboardDisplayName(); + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) {} + + public boolean a(int i, String s) { + return i <= 2; + } + + public BlockPosition getChunkCoordinates() { + return TileEntitySign.this.position; + } + + public Vec3D d() { + return new Vec3D((double) TileEntitySign.this.position.getX() + 0.5D, (double) TileEntitySign.this.position.getY() + 0.5D, (double) TileEntitySign.this.position.getZ() + 0.5D); + } + + public World getWorld() { + return entityhuman.getWorld(); + } + + public Entity f() { + return entityhuman; + } + + public boolean getSendCommandFeedback() { + return false; + } + + public void a(CommandObjectiveExecutor.EnumCommandResult commandobjectiveexecutor_enumcommandresult, int i) { + TileEntitySign.this.i.a(this, commandobjectiveexecutor_enumcommandresult, i); + } + }; + + for (int i = 0; i < this.lines.length; ++i) { + ChatModifier chatmodifier = this.lines[i] == null ? null : this.lines[i].getChatModifier(); + + if (chatmodifier != null && chatmodifier.h() != null) { + ChatClickable chatclickable = chatmodifier.h(); + + if (chatclickable.a() == ChatClickable.EnumClickAction.RUN_COMMAND) { + // CraftBukkit start + // MinecraftServer.getServer().getCommandHandler().a(tileentitysignplayerwrapper, chatclickable.b()); + CommandBlockListenerAbstract.executeCommand(entityhuman, (org.bukkit.entity.Player) entityhuman.getBukkitEntity(), chatclickable.b()); + // CraftBukkit end + } + } + } + + return true; + } + + public CommandObjectiveExecutor d() { + return this.i; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntitySkull.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntitySkull.java new file mode 100644 index 0000000..58014c5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/TileEntitySkull.java @@ -0,0 +1,206 @@ +package net.minecraft.server; + +import com.google.common.collect.Iterables; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import java.util.UUID; + +// Spigot start +import com.google.common.base.Predicate; +import com.google.common.cache.LoadingCache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.mojang.authlib.Agent; +import com.mojang.authlib.ProfileLookupCallback; +// Spigot end + +public class TileEntitySkull extends TileEntity { + + private int a; + private int rotation; + private GameProfile g = null; + // Spigot start + public static final Executor executor = Executors.newFixedThreadPool(3, + new ThreadFactoryBuilder() + .setNameFormat("Head Conversion Thread - %1$d") + .build() + ); + public static final LoadingCache skinCache = CacheBuilder.newBuilder() + .maximumSize( 5000 ) + .expireAfterAccess( 60, TimeUnit.MINUTES ) + .build( new CacheLoader() + { + @Override + public GameProfile load(String key) throws Exception + { + final GameProfile[] profiles = new GameProfile[1]; + ProfileLookupCallback gameProfileLookup = new ProfileLookupCallback() { + + @Override + public void onProfileLookupSucceeded(GameProfile gp) { + profiles[0] = gp; + } + + @Override + public void onProfileLookupFailed(GameProfile gp, Exception excptn) { + profiles[0] = gp; + } + }; + + MinecraftServer.getServer().getGameProfileRepository().findProfilesByNames(new String[] { key }, Agent.MINECRAFT, gameProfileLookup); + + GameProfile profile = profiles[ 0 ]; + if (profile == null) { + UUID uuid = EntityHuman.a(new GameProfile(null, key)); + profile = new GameProfile(uuid, key); + + gameProfileLookup.onProfileLookupSucceeded(profile); + } else + { + + Property property = Iterables.getFirst( profile.getProperties().get( "textures" ), null ); + + if ( property == null ) + { + profile = MinecraftServer.getServer().aD().fillProfileProperties( profile, true ); + } + } + + + return profile; + } + } ); + + // Spigot end + + public TileEntitySkull() {} + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setByte("SkullType", (byte) (this.a & 255)); + nbttagcompound.setByte("Rot", (byte) (this.rotation & 255)); + if (this.g != null) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + GameProfileSerializer.serialize(nbttagcompound1, this.g); + nbttagcompound.set("Owner", nbttagcompound1); + } + + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.a = nbttagcompound.getByte("SkullType"); + this.rotation = nbttagcompound.getByte("Rot"); + if (this.a == 3) { + if (nbttagcompound.hasKeyOfType("Owner", 10)) { + this.g = GameProfileSerializer.deserialize(nbttagcompound.getCompound("Owner")); + } else if (nbttagcompound.hasKeyOfType("ExtraType", 8)) { + String s = nbttagcompound.getString("ExtraType"); + + if (!UtilColor.b(s)) { + this.g = new GameProfile((UUID) null, s); + this.e(); + } + } + } + + } + + public GameProfile getGameProfile() { + return this.g; + } + + public Packet getUpdatePacket() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + this.b(nbttagcompound); + return new PacketPlayOutTileEntityData(this.position, 4, nbttagcompound); + } + + public void setSkullType(int i) { + this.a = i; + this.g = null; + } + + public void setGameProfile(GameProfile gameprofile) { + this.a = 3; + this.g = gameprofile; + this.e(); + } + + private void e() { + // Spigot start + GameProfile profile = this.g; + setSkullType( 0 ); // Work around client bug + b(profile, new Predicate() { + + @Override + public boolean apply(GameProfile input) { + setSkullType(3); // Work around client bug + g = input; + update(); + if (world != null) { + world.notify(position); + } + return false; + } + }); + // Spigot end + } + + // Spigot start - Support async lookups + public static void b(final GameProfile gameprofile, final Predicate callback) { + if (gameprofile != null && !UtilColor.b(gameprofile.getName())) { + if (gameprofile.isComplete() && gameprofile.getProperties().containsKey("textures")) { + callback.apply(gameprofile); + } else if (MinecraftServer.getServer() == null) { + callback.apply(gameprofile); + } else { + GameProfile profile = skinCache.getIfPresent(gameprofile.getName()); + if (profile != null && Iterables.getFirst(profile.getProperties().get("textures"), (Object) null) != null) { + callback.apply(profile); + } else { + executor.execute(new Runnable() { + @Override + public void run() { + final GameProfile profile = skinCache.getUnchecked(gameprofile.getName().toLowerCase()); + MinecraftServer.getServer().processQueue.add(new Runnable() { + @Override + public void run() { + if (profile == null) { + callback.apply(gameprofile); + } else { + callback.apply(profile); + } + } + }); + } + }); + } + } + } else { + callback.apply(gameprofile); + } + } + // Spigot end + + public int getSkullType() { + return this.a; + } + + public void setRotation(int i) { + this.rotation = i; + } + + // CraftBukkit start - add method + public int getRotation() { + return this.rotation; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/UserCache.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/UserCache.java new file mode 100644 index 0000000..0f82e06 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/UserCache.java @@ -0,0 +1,343 @@ +package net.minecraft.server; + +import com.google.common.base.Charsets; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.io.Files; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.mojang.authlib.Agent; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.ProfileLookupCallback; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.UUID; +import org.apache.commons.io.IOUtils; + +public class UserCache { + + public static final SimpleDateFormat a = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); + private final Map c = Maps.newHashMap(); + private final Map d = Maps.newHashMap(); + private final java.util.Deque e = new java.util.concurrent.LinkedBlockingDeque(); // CraftBukkit + private final MinecraftServer f; + protected final Gson b; + private final File g; + private static final ParameterizedType h = new ParameterizedType() { + public Type[] getActualTypeArguments() { + return new Type[] { UserCache.UserCacheEntry.class}; + } + + public Type getRawType() { + return List.class; + } + + public Type getOwnerType() { + return null; + } + }; + + public UserCache(MinecraftServer minecraftserver, File file) { + this.f = minecraftserver; + this.g = file; + GsonBuilder gsonbuilder = new GsonBuilder(); + + gsonbuilder.registerTypeHierarchyAdapter(UserCache.UserCacheEntry.class, new UserCache.BanEntrySerializer(null)); + this.b = gsonbuilder.create(); + this.b(); + } + + private static GameProfile a(MinecraftServer minecraftserver, String s) { + final GameProfile[] agameprofile = new GameProfile[1]; + ProfileLookupCallback profilelookupcallback = new ProfileLookupCallback() { + public void onProfileLookupSucceeded(GameProfile gameprofile) { + agameprofile[0] = gameprofile; + } + + public void onProfileLookupFailed(GameProfile gameprofile, Exception exception) { + agameprofile[0] = null; + } + }; + + minecraftserver.getGameProfileRepository().findProfilesByNames(new String[] { s}, Agent.MINECRAFT, profilelookupcallback); + if (!minecraftserver.getOnlineMode() && agameprofile[0] == null) { + UUID uuid = EntityHuman.a(new GameProfile((UUID) null, s)); + GameProfile gameprofile = new GameProfile(uuid, s); + + profilelookupcallback.onProfileLookupSucceeded(gameprofile); + } + + return agameprofile[0]; + } + + public void a(GameProfile gameprofile) { + this.a(gameprofile, (Date) null); + } + + private void a(GameProfile gameprofile, Date date) { + UUID uuid = gameprofile.getId(); + + if (date == null) { + Calendar calendar = Calendar.getInstance(); + + calendar.setTime(new Date()); + calendar.add(2, 1); + date = calendar.getTime(); + } + + String s = gameprofile.getName().toLowerCase(Locale.ROOT); + UserCache.UserCacheEntry usercache_usercacheentry = new UserCache.UserCacheEntry(gameprofile, date, null); + + if (this.d.containsKey(uuid)) { + UserCache.UserCacheEntry usercache_usercacheentry1 = (UserCache.UserCacheEntry) this.d.get(uuid); + + this.c.remove(usercache_usercacheentry1.a().getName().toLowerCase(Locale.ROOT)); + this.e.remove(gameprofile); + } + + this.c.put(gameprofile.getName().toLowerCase(Locale.ROOT), usercache_usercacheentry); + this.d.put(uuid, usercache_usercacheentry); + this.e.addFirst(gameprofile); + if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.c(); // Spigot - skip saving if disabled + } + + public GameProfile getProfile(String s) { + String s1 = s.toLowerCase(Locale.ROOT); + UserCache.UserCacheEntry usercache_usercacheentry = (UserCache.UserCacheEntry) this.c.get(s1); + + if (usercache_usercacheentry != null && (new Date()).getTime() >= usercache_usercacheentry.c.getTime()) { + this.d.remove(usercache_usercacheentry.a().getId()); + this.c.remove(usercache_usercacheentry.a().getName().toLowerCase(Locale.ROOT)); + this.e.remove(usercache_usercacheentry.a()); + usercache_usercacheentry = null; + } + + GameProfile gameprofile; + + if (usercache_usercacheentry != null) { + gameprofile = usercache_usercacheentry.a(); + this.e.remove(gameprofile); + this.e.addFirst(gameprofile); + } else { + gameprofile = a(this.f, s); // Spigot - use correct case for offline players + if (gameprofile != null) { + this.a(gameprofile); + usercache_usercacheentry = (UserCache.UserCacheEntry) this.c.get(s1); + } + } + + if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.c(); // Spigot - skip saving if disabled + return usercache_usercacheentry == null ? null : usercache_usercacheentry.a(); + } + + public String[] a() { + ArrayList arraylist = Lists.newArrayList(this.c.keySet()); + + return (String[]) arraylist.toArray(new String[arraylist.size()]); + } + + public GameProfile a(UUID uuid) { + UserCache.UserCacheEntry usercache_usercacheentry = (UserCache.UserCacheEntry) this.d.get(uuid); + + return usercache_usercacheentry == null ? null : usercache_usercacheentry.a(); + } + + private UserCache.UserCacheEntry b(UUID uuid) { + UserCache.UserCacheEntry usercache_usercacheentry = (UserCache.UserCacheEntry) this.d.get(uuid); + + if (usercache_usercacheentry != null) { + GameProfile gameprofile = usercache_usercacheentry.a(); + + this.e.remove(gameprofile); + this.e.addFirst(gameprofile); + } + + return usercache_usercacheentry; + } + + public void b() { + BufferedReader bufferedreader = null; + + try { + bufferedreader = Files.newReader(this.g, Charsets.UTF_8); + List list = (List) this.b.fromJson(bufferedreader, UserCache.h); + + this.c.clear(); + this.d.clear(); + this.e.clear(); + Iterator iterator = Lists.reverse(list).iterator(); + + while (iterator.hasNext()) { + UserCache.UserCacheEntry usercache_usercacheentry = (UserCache.UserCacheEntry) iterator.next(); + + if (usercache_usercacheentry != null) { + this.a(usercache_usercacheentry.a(), usercache_usercacheentry.b()); + } + } + } catch (FileNotFoundException filenotfoundexception) { + ; + // Spigot Start + } catch (com.google.gson.JsonSyntaxException ex) { + JsonList.a.warn( "Usercache.json is corrupted or has bad formatting. Deleting it to prevent further issues." ); + this.g.delete(); + // Spigot End + } catch (JsonParseException jsonparseexception) { + ; + } finally { + IOUtils.closeQuietly(bufferedreader); + } + + } + + public void c() { + String s = this.b.toJson(this.a(org.spigotmc.SpigotConfig.userCacheCap)); + BufferedWriter bufferedwriter = null; + + try { + bufferedwriter = Files.newWriter(this.g, Charsets.UTF_8); + bufferedwriter.write(s); + return; + } catch (FileNotFoundException filenotfoundexception) { + return; + } catch (IOException ioexception) { + ; + } finally { + IOUtils.closeQuietly(bufferedwriter); + } + + } + + private List a(int i) { + ArrayList arraylist = Lists.newArrayList(); + ArrayList arraylist1 = Lists.newArrayList(Iterators.limit(this.e.iterator(), i)); + Iterator iterator = arraylist1.iterator(); + + while (iterator.hasNext()) { + GameProfile gameprofile = (GameProfile) iterator.next(); + UserCache.UserCacheEntry usercache_usercacheentry = this.b(gameprofile.getId()); + + if (usercache_usercacheentry != null) { + arraylist.add(usercache_usercacheentry); + } + } + + return arraylist; + } + + class UserCacheEntry { + + private final GameProfile b; + private final Date c; + + private UserCacheEntry(GameProfile gameprofile, Date date) { + this.b = gameprofile; + this.c = date; + } + + public GameProfile a() { + return this.b; + } + + public Date b() { + return this.c; + } + + UserCacheEntry(GameProfile gameprofile, Date date, Object object) { + this(gameprofile, date); + } + } + + class BanEntrySerializer implements JsonDeserializer, JsonSerializer { + + private BanEntrySerializer() {} + + public JsonElement a(UserCache.UserCacheEntry usercache_usercacheentry, Type type, JsonSerializationContext jsonserializationcontext) { + JsonObject jsonobject = new JsonObject(); + + jsonobject.addProperty("name", usercache_usercacheentry.a().getName()); + UUID uuid = usercache_usercacheentry.a().getId(); + + jsonobject.addProperty("uuid", uuid == null ? "" : uuid.toString()); + jsonobject.addProperty("expiresOn", UserCache.a.format(usercache_usercacheentry.b())); + return jsonobject; + } + + public UserCache.UserCacheEntry a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { + if (jsonelement.isJsonObject()) { + JsonObject jsonobject = jsonelement.getAsJsonObject(); + JsonElement jsonelement1 = jsonobject.get("name"); + JsonElement jsonelement2 = jsonobject.get("uuid"); + JsonElement jsonelement3 = jsonobject.get("expiresOn"); + + if (jsonelement1 != null && jsonelement2 != null) { + String s = jsonelement2.getAsString(); + String s1 = jsonelement1.getAsString(); + Date date = null; + + if (jsonelement3 != null) { + try { + date = UserCache.a.parse(jsonelement3.getAsString()); + } catch (ParseException parseexception) { + date = null; + } + } + + if (s1 != null && s != null) { + UUID uuid; + + try { + uuid = UUID.fromString(s); + } catch (Throwable throwable) { + return null; + } + + UserCache.UserCacheEntry usercache_usercacheentry = UserCache.this.new UserCacheEntry(new GameProfile(uuid, s1), date, null); + + return usercache_usercacheentry; + } else { + return null; + } + } else { + return null; + } + } else { + return null; + } + } + + public JsonElement serialize(UserCacheEntry object, Type type, JsonSerializationContext jsonserializationcontext) { // CraftBukkit - decompile error + return this.a((UserCache.UserCacheEntry) object, type, jsonserializationcontext); + } + + public UserCacheEntry deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { // CraftBukkit - decompile error + return this.a(jsonelement, type, jsondeserializationcontext); + } + + BanEntrySerializer(Object object) { + this(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Village.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Village.java new file mode 100644 index 0000000..02f7ab5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/Village.java @@ -0,0 +1,480 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import com.mojang.authlib.GameProfile; + +import java.util.Iterator; +import java.util.List; +import java.util.TreeMap; +import java.util.UUID; + +public class Village { + + private World a; + private final List b = Lists.newArrayList(); + private BlockPosition c; + private BlockPosition d; + private int e; + private int f; + private int g; + private int h; + private int i; + private final TreeMap j; + private final List k; + private int l; + + public Village() { + this.c = BlockPosition.ZERO; + this.d = BlockPosition.ZERO; + this.j = new TreeMap(); + this.k = Lists.newArrayList(); + } + + public Village(World world) { + this.c = BlockPosition.ZERO; + this.d = BlockPosition.ZERO; + this.j = new TreeMap(); + this.k = Lists.newArrayList(); + this.a = world; + } + + public void a(World world) { + this.a = world; + } + + public void a(int i) { + this.g = i; + this.m(); + this.l(); + if (i % 20 == 0) { + this.k(); + } + + if (i % 30 == 0) { + this.j(); + } + + int j = this.h / 10; + + if (this.l < j && this.b.size() > 20 && this.a.random.nextInt(7000) == 0) { + Vec3D vec3d = this.a(this.d, 2, 4, 2); + + if (vec3d != null) { + EntityIronGolem entityirongolem = new EntityIronGolem(this.a); + + entityirongolem.setPosition(vec3d.a, vec3d.b, vec3d.c); + this.a.addEntity(entityirongolem, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE); // CraftBukkit + ++this.l; + } + } + + } + + private Vec3D a(BlockPosition blockposition, int i, int j, int k) { + for (int l = 0; l < 10; ++l) { + BlockPosition blockposition1 = blockposition.a(this.a.random.nextInt(16) - 8, this.a.random.nextInt(6) - 3, this.a.random.nextInt(16) - 8); + + if (this.a(blockposition1) && this.a(new BlockPosition(i, j, k), blockposition1)) { + return new Vec3D(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); + } + } + + return null; + } + + private boolean a(BlockPosition blockposition, BlockPosition blockposition1) { + if (!World.a(this.a, blockposition1.down())) { + return false; + } else { + int i = blockposition1.getX() - blockposition.getX() / 2; + int j = blockposition1.getZ() - blockposition.getZ() / 2; + + for (int k = i; k < i + blockposition.getX(); ++k) { + for (int l = blockposition1.getY(); l < blockposition1.getY() + blockposition.getY(); ++l) { + for (int i1 = j; i1 < j + blockposition.getZ(); ++i1) { + if (this.a.getType(k, l, i1).getBlock().isOccluding()) { + return false; + } + } + } + } + + return true; + } + } + + private void j() { + List list = this.a.a(EntityIronGolem.class, new AxisAlignedBB(this.d.getX() - this.e, this.d.getY() - 4, this.d.getZ() - this.e, this.d.getX() + this.e, this.d.getY() + 4, this.d.getZ() + this.e)); + + this.l = list.size(); + } + + private void k() { + List list = this.a.a(EntityVillager.class, new AxisAlignedBB(this.d.getX() - this.e, this.d.getY() - 4, this.d.getZ() - this.e, this.d.getX() + this.e, this.d.getY() + 4, this.d.getZ() + this.e)); + + this.h = list.size(); + if (this.h == 0) { + this.j.clear(); + } + + } + + public BlockPosition a() { + return this.d; + } + + public int b() { + return this.e; + } + + public int c() { + return this.b.size(); + } + + public int d() { + return this.g - this.f; + } + + public int e() { + return this.h; + } + + public boolean a(BlockPosition blockposition) { + return this.d.i(blockposition) < (double) (this.e * this.e); + } + + public List f() { + return this.b; + } + + public VillageDoor b(BlockPosition blockposition) { + VillageDoor villagedoor = null; + int i = Integer.MAX_VALUE; + Iterator iterator = this.b.iterator(); + + while (iterator.hasNext()) { + VillageDoor villagedoor1 = (VillageDoor) iterator.next(); + int j = villagedoor1.a(blockposition); + + if (j < i) { + villagedoor = villagedoor1; + i = j; + } + } + + return villagedoor; + } + + public VillageDoor c(BlockPosition blockposition) { + VillageDoor villagedoor = null; + int i = Integer.MAX_VALUE; + Iterator iterator = this.b.iterator(); + + while (iterator.hasNext()) { + VillageDoor villagedoor1 = (VillageDoor) iterator.next(); + int j = villagedoor1.a(blockposition); + + if (j > 256) { + j *= 1000; + } else { + j = villagedoor1.c(); + } + + if (j < i) { + villagedoor = villagedoor1; + i = j; + } + } + + return villagedoor; + } + + public VillageDoor e(BlockPosition blockposition) { + if (this.d.i(blockposition) > (double) (this.e * this.e)) { + return null; + } else { + Iterator iterator = this.b.iterator(); + + VillageDoor villagedoor; + + do { + if (!iterator.hasNext()) { + return null; + } + + villagedoor = (VillageDoor) iterator.next(); + } while (villagedoor.d().getX() != blockposition.getX() || villagedoor.d().getZ() != blockposition.getZ() || Math.abs(villagedoor.d().getY() - blockposition.getY()) > 1); + + return villagedoor; + } + } + + public void a(VillageDoor villagedoor) { + this.b.add(villagedoor); + this.c = this.c.a(villagedoor.d()); + this.n(); + this.f = villagedoor.h(); + } + + public boolean g() { + return this.b.isEmpty(); + } + + public void a(EntityLiving entityliving) { + Iterator iterator = this.k.iterator(); + + Village.Aggressor village_aggressor; + + do { + if (!iterator.hasNext()) { + this.k.add(new Village.Aggressor(entityliving, this.g)); + return; + } + + village_aggressor = (Village.Aggressor) iterator.next(); + } while (village_aggressor.a != entityliving); + + village_aggressor.b = this.g; + } + + public EntityLiving b(EntityLiving entityliving) { + double d0 = Double.MAX_VALUE; + Village.Aggressor village_aggressor = null; + + for (int i = 0; i < this.k.size(); ++i) { + Village.Aggressor village_aggressor1 = this.k.get(i); + double d1 = village_aggressor1.a.h(entityliving); + + if (d1 <= d0) { + village_aggressor = village_aggressor1; + d0 = d1; + } + } + + return village_aggressor != null ? village_aggressor.a : null; + } + + public EntityHuman c(EntityLiving entityliving) { + double d0 = Double.MAX_VALUE; + EntityHuman entityhuman = null; + Iterator iterator = this.j.keySet().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + + if (this.d(s)) { + EntityHuman entityhuman1 = this.a.a(s); + + if (entityhuman1 != null) { + double d1 = entityhuman1.h(entityliving); + + if (d1 <= d0) { + entityhuman = entityhuman1; + d0 = d1; + } + } + } + } + + return entityhuman; + } + + private void l() { + Iterator iterator = this.k.iterator(); + + while (iterator.hasNext()) { + Village.Aggressor village_aggressor = (Village.Aggressor) iterator.next(); + + if (!village_aggressor.a.isAlive() || Math.abs(this.g - village_aggressor.b) > 300) { + iterator.remove(); + } + } + + } + + private void m() { + boolean flag = false; + boolean flag1 = this.a.random.nextInt(50) == 0; + Iterator iterator = this.b.iterator(); + + while (iterator.hasNext()) { + VillageDoor villagedoor = (VillageDoor) iterator.next(); + + if (flag1) { + villagedoor.a(); + } + + if (!this.f(villagedoor.d()) || Math.abs(this.g - villagedoor.h()) > 1200) { + this.c = this.c.b(villagedoor.d()); + flag = true; + villagedoor.a(true); + iterator.remove(); + } + } + + if (flag) { + this.n(); + } + + } + + private boolean f(BlockPosition blockposition) { + Block block = this.a.getType(blockposition).getBlock(); + + return block instanceof BlockDoor && block.getMaterial() == Material.WOOD; + } + + private void n() { + int i = this.b.size(); + + if (i == 0) { + this.d = new BlockPosition(0, 0, 0); + this.e = 0; + } else { + this.d = new BlockPosition(this.c.getX() / i, this.c.getY() / i, this.c.getZ() / i); + int j = 0; + + VillageDoor villagedoor; + + for (Iterator iterator = this.b.iterator(); iterator.hasNext(); j = Math.max(villagedoor.a(this.d), j)) { + villagedoor = (VillageDoor) iterator.next(); + } + + this.e = Math.max(32, (int) Math.sqrt(j) + 1); + } + } + + public int a(String s) { + Integer integer = this.j.get(s); + + return integer != null ? integer.intValue() : 0; + } + + public int a(String s, int i) { + int j = this.a(s); + int k = MathHelper.clamp(j + i, -30, 10); + + this.j.put(s, Integer.valueOf(k)); + return k; + } + + public boolean d(String s) { + return this.a(s) <= -15; + } + + public void a(NBTTagCompound nbttagcompound) { + this.h = nbttagcompound.getInt("PopSize"); + this.e = nbttagcompound.getInt("Radius"); + this.l = nbttagcompound.getInt("Golems"); + this.f = nbttagcompound.getInt("Stable"); + this.g = nbttagcompound.getInt("Tick"); + this.i = nbttagcompound.getInt("MTick"); + this.d = new BlockPosition(nbttagcompound.getInt("CX"), nbttagcompound.getInt("CY"), nbttagcompound.getInt("CZ")); + this.c = new BlockPosition(nbttagcompound.getInt("ACX"), nbttagcompound.getInt("ACY"), nbttagcompound.getInt("ACZ")); + NBTTagList nbttaglist = nbttagcompound.getList("Doors", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + NBTTagCompound nbttagcompound1 = nbttaglist.get(i); + VillageDoor villagedoor = new VillageDoor(new BlockPosition(nbttagcompound1.getInt("X"), nbttagcompound1.getInt("Y"), nbttagcompound1.getInt("Z")), nbttagcompound1.getInt("IDX"), nbttagcompound1.getInt("IDZ"), nbttagcompound1.getInt("TS")); + + this.b.add(villagedoor); + } + + NBTTagList nbttaglist1 = nbttagcompound.getList("Players", 10); + + for (int j = 0; j < nbttaglist1.size(); ++j) { + NBTTagCompound nbttagcompound2 = nbttaglist1.get(j); + + if (nbttagcompound2.hasKey("UUID")) { + UserCache usercache = MinecraftServer.getServer().getUserCache(); + GameProfile gameprofile = usercache.a(UUID.fromString(nbttagcompound2.getString("UUID"))); + + if (gameprofile != null) { + this.j.put(gameprofile.getName(), Integer.valueOf(nbttagcompound2.getInt("S"))); + } + } else { + this.j.put(nbttagcompound2.getString("Name"), Integer.valueOf(nbttagcompound2.getInt("S"))); + } + } + + } + + public void b(NBTTagCompound nbttagcompound) { + nbttagcompound.setInt("PopSize", this.h); + nbttagcompound.setInt("Radius", this.e); + nbttagcompound.setInt("Golems", this.l); + nbttagcompound.setInt("Stable", this.f); + nbttagcompound.setInt("Tick", this.g); + nbttagcompound.setInt("MTick", this.i); + nbttagcompound.setInt("CX", this.d.getX()); + nbttagcompound.setInt("CY", this.d.getY()); + nbttagcompound.setInt("CZ", this.d.getZ()); + nbttagcompound.setInt("ACX", this.c.getX()); + nbttagcompound.setInt("ACY", this.c.getY()); + nbttagcompound.setInt("ACZ", this.c.getZ()); + NBTTagList nbttaglist = new NBTTagList(); + Iterator iterator = this.b.iterator(); + + while (iterator.hasNext()) { + VillageDoor villagedoor = (VillageDoor) iterator.next(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.setInt("X", villagedoor.d().getX()); + nbttagcompound1.setInt("Y", villagedoor.d().getY()); + nbttagcompound1.setInt("Z", villagedoor.d().getZ()); + nbttagcompound1.setInt("IDX", villagedoor.f()); + nbttagcompound1.setInt("IDZ", villagedoor.g()); + nbttagcompound1.setInt("TS", villagedoor.h()); + nbttaglist.add(nbttagcompound1); + } + + nbttagcompound.set("Doors", nbttaglist); + NBTTagList nbttaglist1 = new NBTTagList(); + Iterator iterator1 = this.j.keySet().iterator(); + + while (iterator1.hasNext()) { + String s = (String) iterator1.next(); + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); + UserCache usercache = MinecraftServer.getServer().getUserCache(); + GameProfile gameprofile = usercache.getProfile(s); + + if (gameprofile != null) { + nbttagcompound2.setString("UUID", gameprofile.getId().toString()); + nbttagcompound2.setInt("S", this.j.get(s).intValue()); + nbttaglist1.add(nbttagcompound2); + } + } + + nbttagcompound.set("Players", nbttaglist1); + } + + public void h() { + this.i = this.g; + } + + public boolean i() { + return this.i == 0 || this.g - this.i >= 3600; + } + + public void b(int i) { + Iterator iterator = this.j.keySet().iterator(); + + while (iterator.hasNext()) { + String s = (String) iterator.next(); + + this.a(s, i); + } + + } + + class Aggressor { + + public EntityLiving a; + public int b; + + Aggressor(EntityLiving entityliving, int i) { + this.a = entityliving; + this.b = i; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/VillageSiege.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/VillageSiege.java new file mode 100644 index 0000000..42d6737 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/VillageSiege.java @@ -0,0 +1,162 @@ +package net.minecraft.server; + +import java.util.Iterator; +import java.util.List; + +public class VillageSiege { + + private World a; + private boolean b; + private int c = -1; + private int d; + private int e; + private Village f; + private int g; + private int h; + private int i; + + public VillageSiege(World world) { + this.a = world; + } + + public void a() { + if (this.a.w()) { + this.c = 0; + } else if (this.c != 2) { + if (this.c == 0) { + float f = this.a.c(0.0F); + + if ((double) f < 0.5D || (double) f > 0.501D) { + return; + } + + this.c = this.a.random.nextInt(10) == 0 ? 1 : 2; + this.b = false; + if (this.c == 2) { + return; + } + } + + if (this.c != -1) { + if (!this.b) { + if (!this.b()) { + return; + } + + this.b = true; + } + + if (this.e > 0) { + --this.e; + } else { + this.e = 2; + if (this.d > 0) { + this.c(); + --this.d; + } else { + this.c = 2; + } + + } + } + } + } + + private boolean b() { + List list = this.a.players; + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (!entityhuman.isSpectator()) { + this.f = this.a.ae().getClosestVillage(new BlockPosition(entityhuman), 1); + if (this.f != null && this.f.c() >= 10 && this.f.d() >= 20 && this.f.e() >= 20) { + BlockPosition blockposition = this.f.a(); + float f = (float) this.f.b(); + boolean flag = false; + int i = 0; + + while (true) { + if (i < 10) { + float f1 = this.a.random.nextFloat() * 3.1415927F * 2.0F; + + this.g = blockposition.getX() + (int) ((double) (MathHelper.cos(f1) * f) * 0.9D); + this.h = blockposition.getY(); + this.i = blockposition.getZ() + (int) ((double) (MathHelper.sin(f1) * f) * 0.9D); + flag = false; + Iterator iterator1 = this.a.ae().getVillages().iterator(); + + while (iterator1.hasNext()) { + Village village = (Village) iterator1.next(); + + if (village != this.f && village.a(new BlockPosition(this.g, this.h, this.i))) { + flag = true; + break; + } + } + + if (flag) { + ++i; + continue; + } + } + + if (flag) { + return false; + } + + Vec3D vec3d = this.a(new BlockPosition(this.g, this.h, this.i)); + + if (vec3d != null) { + this.e = 0; + this.d = 20; + return true; + } + break; + } + } + } + } + + return false; + } + + private boolean c() { + Vec3D vec3d = this.a(new BlockPosition(this.g, this.h, this.i)); + + if (vec3d == null) { + return false; + } else { + EntityZombie entityzombie; + + try { + entityzombie = new EntityZombie(this.a); + entityzombie.prepare(this.a.E(new BlockPosition(entityzombie)), (GroupDataEntity) null); + entityzombie.setVillager(false); + } catch (Exception exception) { + exception.printStackTrace(); + return false; + } + + entityzombie.setPositionRotation(vec3d.a, vec3d.b, vec3d.c, this.a.random.nextFloat() * 360.0F, 0.0F); + this.a.addEntity(entityzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_INVASION); // CraftBukkit + BlockPosition blockposition = this.f.a(); + + entityzombie.a(blockposition, this.f.b()); + return true; + } + } + + private Vec3D a(BlockPosition blockposition) { + for (int i = 0; i < 10; ++i) { + BlockPosition blockposition1 = blockposition.a(this.a.random.nextInt(16) - 8, this.a.random.nextInt(6) - 3, this.a.random.nextInt(16) - 8); + + if (this.f.a(blockposition1) && SpawnerCreature.a(EntityInsentient.EnumEntityPositionType.ON_GROUND, this.a, blockposition1)) { + return new Vec3D((double) blockposition1.getX(), (double) blockposition1.getY(), (double) blockposition1.getZ()); + } + } + + return null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/World.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/World.java new file mode 100644 index 0000000..6ac5947 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/World.java @@ -0,0 +1,3416 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import org.bukkit.Bukkit; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.event.block.BlockCanBuildEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.generator.ChunkGenerator; + +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.logging.Level; + +// PaperSpigot start +// PaperSpigot end + +// CraftBukkit start +// CraftBukkit end + +public abstract class World implements IBlockAccess { + + private int a = 63; + protected boolean e; + // Spigot start - guard entity list from removals + public final List entityList = new java.util.ArrayList() + { + @Override + public Entity remove(int index) + { + guard(); + return super.remove( index ); + } + + @Override + public boolean remove(Object o) + { + guard(); + return super.remove( o ); + } + + private void guard() + { + if ( guardEntityList ) + { + throw new java.util.ConcurrentModificationException(); + } + } + }; + // Spigot end + protected final Set g = Sets.newHashSet(); // Paper + //public final List h = Lists.newArrayList(); // PaperSpigot - Remove unused list + public final List tileEntityList = Lists.newArrayList(); + private final List b = Lists.newArrayList(); + private final Set c = Sets.newHashSet(); // Paper + public final List players = Lists.newArrayList(); + public final List k = Lists.newArrayList(); + protected final IntHashMap entitiesById = new IntHashMap(); + private final long d = 16777215L; + private int I; + protected int m = (new Random()).nextInt(); + protected final int n = 1013904223; + protected float o; + protected float p; + protected float q; + protected float r; + private int J; + public final Random random = new Random(); + public WorldProvider worldProvider; // CraftBukkit - remove final + protected List u = Lists.newArrayList(); + protected IChunkProvider chunkProvider; + protected final IDataManager dataManager; + public WorldData worldData; // CraftBukkit - public + protected boolean isLoading; + public PersistentCollection worldMaps; // CraftBukkit - public + protected PersistentVillage villages; + public final MethodProfiler methodProfiler; + private final Calendar K = Calendar.getInstance(); + public Scoreboard scoreboard = new Scoreboard(); // CraftBukkit - public + public final boolean isClientSide; + // CraftBukkit - longhashset + // protected LongHashSet chunkTickList = new LongHashSet(); // Spigot + private int L; + public boolean allowMonsters; // CraftBukkit - public + public boolean allowAnimals; // CraftBukkit - public + private boolean M; + private final WorldBorder N; + int[] H; + + // CraftBukkit start Added the following + private final CraftWorld world; + public boolean pvpMode; + public boolean keepSpawnInMemory = true; + public ChunkGenerator generator; + + public boolean captureBlockStates = false; + public boolean captureTreeGeneration = false; + public ArrayList capturedBlockStates= new ArrayList(){ + @Override + public boolean add( BlockState blockState ) { + Iterator blockStateIterator = this.iterator(); + while( blockStateIterator.hasNext() ) { + BlockState blockState1 = blockStateIterator.next(); + if ( blockState1.getLocation().equals( blockState.getLocation() ) ) { + return false; + } + } + + return super.add( blockState ); + } + }; + public long ticksPerAnimalSpawns; + public long ticksPerMonsterSpawns; + public boolean populating; + private int tickPosition; + + // Spigot start + private boolean guardEntityList; + protected final gnu.trove.map.hash.TLongShortHashMap chunkTickList; + protected float growthOdds = 100; + protected float modifiedOdds = 100; + private final byte chunkTickRadius; + public static boolean haveWeSilencedAPhysicsCrash; + public static String blockLocation; + private final org.spigotmc.TickLimiter entityLimiter; + private final org.spigotmc.TickLimiter tileLimiter; + private int tileTickPosition; + public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("PaperSpigot - Lighting Thread").build()); // PaperSpigot - Asynchronous lighting updates + public final Map explosionDensityCache = new HashMap(); // PaperSpigot - Optimize explosions + + public static long chunkToKey(int x, int z) + { + long k = ( ( ( (long) x ) & 0xFFFF0000L ) << 16 ) | ( ( ( (long) x ) & 0x0000FFFFL ) << 0 ); + k |= ( ( ( (long) z ) & 0xFFFF0000L ) << 32 ) | ( ( ( (long) z ) & 0x0000FFFFL ) << 16 ); + return k; + } + + public static int keyToX(long k) + { + return (int) ( ( ( k >> 16 ) & 0xFFFF0000 ) | ( k & 0x0000FFFF ) ); + } + + public static int keyToZ(long k) + { + return (int) ( ( ( k >> 32 ) & 0xFFFF0000L ) | ( ( k >> 16 ) & 0x0000FFFF ) ); + } + // Spigot end + + public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot + + public final org.github.paperspigot.PaperSpigotWorldConfig paperSpigotConfig; // PaperSpigot + + public final co.aikar.timings.WorldTimingsHandler timings; // Spigot + public final net.techcable.tacospigot.TacoSpigotWorldConfig tacoSpigotConfig; + + public CraftWorld getWorld() { + return this.world; + } + + public CraftServer getServer() { + return (CraftServer) Bukkit.getServer(); + } + + public Chunk getChunkIfLoaded(int x, int z) { + return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(x, z); + } + + 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.generator = gen; + this.world = new CraftWorld((WorldServer) this, gen, env); + this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit + this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit + // CraftBukkit end + // Spigot start + this.chunkTickRadius = (byte) ( ( this.getServer().getViewDistance() < 7 ) ? this.getServer().getViewDistance() : 7 ); + this.chunkTickList = new gnu.trove.map.hash.TLongShortHashMap( spigotConfig.chunksPerTick * 5, 0.7f, Long.MIN_VALUE, Short.MIN_VALUE ); + this.chunkTickList.setAutoCompactionFactor( 0 ); + // Spigot end + + this.L = this.random.nextInt(12000); + this.allowMonsters = true; + this.allowAnimals = true; + this.H = new int['\u8000']; + this.dataManager = idatamanager; + this.methodProfiler = methodprofiler; + this.worldData = worlddata; + this.worldProvider = worldprovider; + this.isClientSide = flag; + this.N = worldprovider.getWorldBorder(); + // CraftBukkit start + // Moved from PlayerList + this.N.a(new IWorldBorderListener() { + public void a(WorldBorder worldborder, double d0) { + getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_SIZE), World.this); + } + + public void a(WorldBorder worldborder, double d0, double d1, long i) { + getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.LERP_SIZE), World.this); + } + + public void a(WorldBorder worldborder, double d0, double d1) { + getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_CENTER), World.this); + } + + public void a(WorldBorder worldborder, int i) { + getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_WARNING_TIME), World.this); + } + + public void b(WorldBorder worldborder, int i) { + getServer().getHandle().sendAll(new PacketPlayOutWorldBorder(worldborder, PacketPlayOutWorldBorder.EnumWorldBorderAction.SET_WARNING_BLOCKS), World.this); + } + + public void b(WorldBorder worldborder, double d0) {} + + public void c(WorldBorder worldborder, double d0) {} + }); + this.getServer().addWorld(this.world); + // CraftBukkit end + this.keepSpawnInMemory = this.paperSpigotConfig.keepSpawnInMemory; // PaperSpigot + timings = new co.aikar.timings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings + this.entityLimiter = new org.spigotmc.TickLimiter(spigotConfig.entityMaxTickTime); + this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime); + } + + public World b() { + return this; + } + + public BiomeBase getBiome(final BlockPosition blockposition) { + if (this.isLoaded(blockposition)) { + Chunk chunk = this.getChunkAtWorldCoords(blockposition); + + try { + return chunk.getBiome(blockposition, this.worldProvider.m()); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Getting biome"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Coordinates of biome request"); + + crashreportsystemdetails.a("Location", new Callable() { + public String a() throws Exception { + return CrashReportSystemDetails.a(blockposition); + } + + public Object call() throws Exception { + return this.a(); + } + }); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + return BiomeBase.PLAINS; + } + throw new ReportedException(crashreport); + } + } else { + return this.worldProvider.m().getBiome(blockposition, BiomeBase.PLAINS); + } + } + + public WorldChunkManager getWorldChunkManager() { + return this.worldProvider.m(); + } + + protected abstract IChunkProvider k(); + + public void a(WorldSettings worldsettings) { + this.worldData.d(true); + } + + public Block c(BlockPosition blockposition) { + BlockPosition blockposition1; + + for (blockposition1 = new BlockPosition(blockposition.getX(), this.F(), blockposition.getZ()); !this.isEmpty(blockposition1.up()); blockposition1 = blockposition1.up()) { + } + + return this.getType(blockposition1).getBlock(); + } + + private boolean isValidLocation(BlockPosition blockposition) { + return isValidLocation(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } + + // Mythic - Reduce churn rate + private boolean isValidLocation(int x, int y, int z) { + return x >= -30000000 && z >= -30000000 && x < 30000000 && z < 30000000 && y >= 0 && y < 256; + } + + public boolean isEmpty(BlockPosition blockposition) { + return isEmpty(blockposition.getX(), blockposition.getY(), blockposition.getZ()); + } + + // Mythic - Reduce churn rate + public boolean isEmpty(int x, int y, int z) { + return this.getType(x, y, z).getBlock().getMaterial() == Material.AIR; + } + + public boolean isLoaded(BlockPosition blockposition) { + return this.a(blockposition, true); + } + + // Mythic - Reduce churn rate + public boolean isLoaded(int x, int y, int z) { + return a(x, y, z, true); + } + + public boolean a(BlockPosition blockposition, boolean flag) { + return a(blockposition.getX(), blockposition.getY(), blockposition.getZ(), flag); + } + + // Mythic - Reduce churn rate + public boolean a(int x, int y, int z, boolean flag) { + return this.isValidLocation(x, y, z) && this.isChunkLoaded(x >> 4, z >> 4, flag); + } + + public boolean areChunksLoaded(BlockPosition blockposition, int i) { + return this.areChunksLoaded(blockposition, i, true); + } + + // Mythic - Reduce churn rate + public boolean areChunksLoaded(int x, int y, int z, int i) { + return areChunksLoaded(x, y, z, i, true); + } + + public boolean areChunksLoaded(BlockPosition blockposition, int i, boolean flag) { + return areChunksLoaded(blockposition.getX(), blockposition.getY(), blockposition.getZ(), i, flag); + } + + // Mythic - Reduce churn rate + public boolean areChunksLoaded(int x, int y, int z, int i, boolean flag) { + return this.isAreaLoaded(x - i, y - i, z - i, x + i, y + i, z + i, flag); + } + + public boolean areChunksLoadedBetween(BlockPosition blockposition, BlockPosition blockposition1) { + return this.areChunksLoadedBetween(blockposition, blockposition1, true); + } + + // Mythic - Reduce churn rate + public boolean areChunksLoadedBetween(int x1, int y1, int z1, int x2, int y2, int z2) { + return areChunksLoadedBetween(x1, y1, z1, x2, y2, z2, true); + } + + public boolean areChunksLoadedBetween(BlockPosition blockposition, BlockPosition blockposition1, boolean flag) { + return this.isAreaLoaded(blockposition.getX(), blockposition.getY(), blockposition.getZ(), blockposition1.getX(), blockposition1.getY(), blockposition1.getZ(), flag); + } + + // Mythic - Reduce churn rate + public boolean areChunksLoadedBetween(int x1, int y1, int z1, int x2, int y2, int z2, boolean flag) { + return isAreaLoaded(x1, y1, z1, x2, y2, z2, flag); + } + + public boolean a(StructureBoundingBox structureboundingbox) { + return this.b(structureboundingbox, true); + } + + public boolean b(StructureBoundingBox structureboundingbox, boolean flag) { + return this.isAreaLoaded(structureboundingbox.a, structureboundingbox.b, structureboundingbox.c, structureboundingbox.d, structureboundingbox.e, structureboundingbox.f, flag); + } + + private boolean isAreaLoaded(int i, int j, int k, int l, int i1, int j1, boolean flag) { + if (i1 >= 0 && j < 256) { + i >>= 4; + k >>= 4; + l >>= 4; + j1 >>= 4; + + for (int k1 = i; k1 <= l; ++k1) { + for (int l1 = k; l1 <= j1; ++l1) { + if (!this.isChunkLoaded(k1, l1, flag)) { + return false; + } + } + } + + return true; + } else { + return false; + } + } + + protected boolean isChunkLoaded(int i, int j, boolean flag) { + return this.chunkProvider.isChunkLoaded(i, j) && (flag || !this.chunkProvider.getOrCreateChunk(i, j).isEmpty()); + } + + public Chunk getChunkAtWorldCoords(BlockPosition blockposition) { + return getChunkAtWorldCoords(blockposition.getX(), blockposition.getZ()); + } + + // Mythic - Reduce churn rate + public Chunk getChunkAtWorldCoords(int x, int z) { + return this.getChunkAt(x >> 4, z >> 4); + } + + public Chunk getChunkAt(int i, int j) { + return this.chunkProvider.getOrCreateChunk(i, j); + } + + public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { + // CraftBukkit start - tree generation + if (this.captureTreeGeneration) { + BlockState blockstate = null; + Iterator it = capturedBlockStates.iterator(); + while (it.hasNext()) { + BlockState previous = it.next(); + if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) { + blockstate = previous; + it.remove(); + break; + } + } + if (blockstate == null) { + blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, blockposition.getX(), blockposition.getY(), blockposition.getZ(), i); + } + blockstate.setTypeId(CraftMagicNumbers.getId(iblockdata.getBlock())); + blockstate.setRawData((byte) iblockdata.getBlock().toLegacyData(iblockdata)); + this.capturedBlockStates.add(blockstate); + return true; + } + // CraftBukkit end + if (!this.isValidLocation(blockposition)) { + return false; + } else if (!this.isClientSide && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + return false; + } else { + Chunk chunk = this.getChunkAtWorldCoords(blockposition); + Block block = iblockdata.getBlock(); + + // CraftBukkit start - capture blockstates + BlockState blockstate = null; + if (this.captureBlockStates) { + blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, blockposition.getX(), blockposition.getY(), blockposition.getZ(), i); + this.capturedBlockStates.add(blockstate); + } + // CraftBukkit end + + IBlockData iblockdata1 = chunk.a(blockposition, iblockdata); + + if (iblockdata1 == null) { + // CraftBukkit start - remove blockstate if failed + if (this.captureBlockStates) { + this.capturedBlockStates.remove(blockstate); + } + // CraftBukkit end + return false; + } else { + Block block1 = iblockdata1.getBlock(); + + if (block.p() != block1.p() || block.r() != block1.r()) { + this.methodProfiler.a("checkLight"); + this.x(blockposition); + this.methodProfiler.b(); + } + + /* + if ((i & 2) != 0 && (!this.isClientSide || (i & 4) == 0) && chunk.isReady()) { + this.notify(blockposition); + } + + if (!this.isClientSide && (i & 1) != 0) { + this.update(blockposition, iblockdata1.getBlock()); + if (block.isComplexRedstone()) { + this.updateAdjacentComparators(blockposition, block); + } + } + */ + + // CraftBukkit start + if (!this.captureBlockStates) { // Don't notify clients or update physics while capturing blockstates + // Modularize client and physic updates + notifyAndUpdatePhysics(blockposition, chunk, block1, block, i); + } + // CraftBukkit end + + return true; + } + } + } + + // CraftBukkit start - Split off from original setTypeAndData(int i, int j, int k, Block block, int l, int i1) method in order to directly send client and physic updates + public void notifyAndUpdatePhysics(BlockPosition blockposition, Chunk chunk, Block oldBlock, Block newBLock, int flag) { + if ((flag & 2) != 0 && (chunk == null || chunk.isReady())) { // allow chunk to be null here as chunk.isReady() is false when we send our notification during block placement + this.notify(blockposition); + } + + if (!this.isClientSide && (flag & 1) != 0) { + this.update(blockposition, oldBlock); + if (newBLock.isComplexRedstone()) { + this.updateAdjacentComparators(blockposition, newBLock); + } + } + } + // CraftBukkit end + + public boolean setAir(BlockPosition blockposition) { + return this.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); + } + + public boolean setAir(BlockPosition blockposition, boolean flag) { + IBlockData iblockdata = this.getType(blockposition); + Block block = iblockdata.getBlock(); + + if (block.getMaterial() == Material.AIR) { + return false; + } else { + this.triggerEffect(2001, blockposition, Block.getCombinedId(iblockdata)); + if (flag) { + block.b(this, blockposition, iblockdata, 0); + } + + return this.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 3); + } + } + + public boolean setTypeUpdate(BlockPosition blockposition, IBlockData iblockdata) { + return this.setTypeAndData(blockposition, iblockdata, 3); + } + + public void notify(BlockPosition blockposition) { + for (int i = 0; i < this.u.size(); ++i) { + this.u.get(i).a(blockposition); + } + + } + + public void update(BlockPosition blockposition, Block block) { + if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) { + // CraftBukkit start + if (populating) { + return; + } + // CraftBukkit end + this.applyPhysics(blockposition, block); + } + + } + + public void a(int i, int j, int k, int l) { + int i1; + + if (k > l) { + i1 = l; + l = k; + k = i1; + } + + if (!this.worldProvider.o()) { + for (i1 = k; i1 <= l; ++i1) { + this.updateLight(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); // PaperSpigot - Asynchronous lighting updates + } + } + + this.b(i, k, j, i, l, j); + } + + public void b(BlockPosition blockposition, BlockPosition blockposition1) { + this.b(blockposition.getX(), blockposition.getY(), blockposition.getZ(), blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); + } + + public void b(int i, int j, int k, int l, int i1, int j1) { + for (int k1 = 0; k1 < this.u.size(); ++k1) { + this.u.get(k1).a(i, j, k, l, i1, j1); + } + + } + + public boolean applyPhysics(BlockPosition blockposition, Block block) { + if(!MythicConfiguration.Options.World.Physics.enabled) return false; + + if(MythicConfiguration.Options.World.Physics.Limits.enabled) { + Chunk chunk = getChunkAtWorldCoords(blockposition); + if(!chunk.physics.test()) return false; + } + + this.d(blockposition.west(), block); + this.d(blockposition.east(), block); + this.d(blockposition.down(), block); + this.d(blockposition.up(), block); + this.d(blockposition.north(), block); + this.d(blockposition.south(), block); + spigotConfig.antiXrayInstance.updateNearbyBlocks(this, blockposition); // Spigot + return true; + } + + public void a(BlockPosition blockposition, Block block, EnumDirection enumdirection) { + if (enumdirection != EnumDirection.WEST) { + this.d(blockposition.west(), block); + } + + if (enumdirection != EnumDirection.EAST) { + this.d(blockposition.east(), block); + } + + if (enumdirection != EnumDirection.DOWN) { + this.d(blockposition.down(), block); + } + + if (enumdirection != EnumDirection.UP) { + this.d(blockposition.up(), block); + } + + if (enumdirection != EnumDirection.NORTH) { + this.d(blockposition.north(), block); + } + + if (enumdirection != EnumDirection.SOUTH) { + this.d(blockposition.south(), block); + } + + } + + public void d(BlockPosition blockposition, final Block block) { + if (!this.isClientSide) { + IBlockData iblockdata = this.getType(blockposition); + + 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))) { + // TacoSpigot end + BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftMagicNumbers.getId(block)); + this.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + } + // CraftBukkit end + iblockdata.getBlock().doPhysics(this, blockposition, iblockdata, block); + } catch (StackOverflowError stackoverflowerror) { // Spigot Start + haveWeSilencedAPhysicsCrash = true; + blockLocation = blockposition.getX() + ", " + blockposition.getY() + ", " + blockposition.getZ(); // Spigot End + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Exception while updating neighbours"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being updated"); + + crashreportsystemdetails.a("Source block type", new Callable() { + public String a() throws Exception { + try { + return String.format("ID #%d (%s // %s)", Integer.valueOf(Block.getId(block)), block.a(), block.getClass().getCanonicalName()); + } catch (Throwable throwable) { + return "ID #" + Block.getId(block); + } + } + + public Object call() throws Exception { + return this.a(); + } + }); + CrashReportSystemDetails.a(crashreportsystemdetails, blockposition, iblockdata); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + } + + public boolean a(BlockPosition blockposition, Block block) { + return false; + } + + public boolean i(BlockPosition blockposition) { + return this.getChunkAtWorldCoords(blockposition).d(blockposition); + } + + public boolean j(BlockPosition blockposition) { + if (blockposition.getY() >= this.F()) { + return this.i(blockposition); + } else { + BlockPosition blockposition1 = new BlockPosition(blockposition.getX(), this.F(), blockposition.getZ()); + + if (!this.i(blockposition1)) { + return false; + } else { + for (blockposition1 = blockposition1.down(); blockposition1.getY() > blockposition.getY(); blockposition1 = blockposition1.down()) { + Block block = this.getType(blockposition1).getBlock(); + + if (block.p() > 0 && !block.getMaterial().isLiquid()) { + return false; + } + } + + return true; + } + } + } + + public int k(BlockPosition blockposition) { + if (blockposition.getY() < 0) { + return 0; + } else { + if (blockposition.getY() >= 256) { + blockposition = new BlockPosition(blockposition.getX(), 255, blockposition.getZ()); + } + + return this.getChunkAtWorldCoords(blockposition).a(blockposition, 0); + } + } + + public int getLightLevel(BlockPosition blockposition) { + return this.c(blockposition, true); + } + + // Mythic - Reduce churn rate + public int getLightLevel(int x, int y, int z) { + return c(x, y, z, true); + } + + public int c(BlockPosition blockposition, boolean flag) { + return c(blockposition.getX(), blockposition.getY(), blockposition.getZ(), flag); + } + + // Mythic - Reduce churn rate + public int c(int x, int y, int z, boolean flag) { + if (x >= -30000000 && z >= -30000000 && x < 30000000 && z < 30000000) { + if (flag && this.getType(x, y, z).getBlock().s()) { + int i = this.c(x, y + 1 , z, false); + int j = this.c(x + 1, y, z, false); + int k = this.c(x - 1, y, z, false); + int l = this.c(x, y, z + 1, false); + int i1 = this.c(x, y, z - 1, false); + + if (j > i) { + i = j; + } + + if (k > i) { + i = k; + } + + if (l > i) { + i = l; + } + + if (i1 > i) { + i = i1; + } + + return i; + } else if (y < 0) { + return 0; + } else { + if (y >= 256) { + y = 255; + } + + Chunk chunk = this.getChunkAtWorldCoords(x, z); + + return chunk.aNew(x, y, z, this.I); + } + } else { + return 15; + } + } + + // Mythic - Reduce churn rate + public int getHighestBlockYAt(int x, int z) { + int i; + + if (x>= -30000000 && z >= -30000000 && x < 30000000 && z < 30000000) { + if (this.isChunkLoaded(x >> 4, z >> 4, true)) { + i = this.getChunkAt(x >> 4, z >> 4).b(x & 15, z & 15); + } else { + i = 0; + } + } else { + i = this.F() + 1; + } + return i; + } + + public BlockPosition getHighestBlockYAt(BlockPosition blockposition) { + 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); + } else { + i = 0; + } + } else { + i = this.F() + 1; + } + + 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)) { + return 0; + } else { + Chunk chunk = this.getChunkAt(i >> 4, j >> 4); + + return chunk.v(); + } + } else { + return this.F() + 1; + } + } + + public int b(EnumSkyBlock enumskyblock, BlockPosition blockposition) { + if (blockposition.getY() < 0) { + blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ()); + } + + if (!this.isValidLocation(blockposition)) { + return enumskyblock.c; + } else if (!this.isLoaded(blockposition)) { + return enumskyblock.c; + } else { + Chunk chunk = this.getChunkAtWorldCoords(blockposition); + + return chunk.getBrightness(enumskyblock, blockposition); + } + } + + public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { + if (this.isValidLocation(blockposition)) { + if (this.isLoaded(blockposition)) { + Chunk chunk = this.getChunkAtWorldCoords(blockposition); + + chunk.a(enumskyblock, blockposition, i); + this.n(blockposition); + } + } + } + + public void n(BlockPosition blockposition) { + for (int i = 0; i < this.u.size(); ++i) { + this.u.get(i).b(blockposition); + } + + } + + public float o(BlockPosition blockposition) { + return this.worldProvider.p()[this.getLightLevel(blockposition)]; + } + + // Spigot start + public IBlockData getType(BlockPosition blockposition) + { + return getType( blockposition, true ); + } + + public IBlockData getType(BlockPosition blockposition, boolean useCaptured) { + return getType(blockposition.getX(), blockposition.getY(), blockposition.getZ(), useCaptured); + } + + // Mythic - Reduce churn rate + public IBlockData getType(int x, int y, int z) { + return getType(x, y, z, true); + } + + // Mythic - Reduce churn rate + public IBlockData getType(int x, int y, int z, boolean useCaptured) { + // CraftBukkit start - tree generation + if (captureTreeGeneration && useCaptured) { + // Spigot end + Iterator it = capturedBlockStates.iterator(); + while (it.hasNext()) { + BlockState previous = it.next(); + if (previous.getX() == x && previous.getY() == y && previous.getZ() == z) { + return CraftMagicNumbers.getBlock(previous.getTypeId()).fromLegacyData(previous.getRawData()); + } + } + } + // CraftBukkit end + if (!this.isValidLocation(x, y, z)) { + return Blocks.AIR.getBlockData(); + } else { + Chunk chunk = this.getChunkAtWorldCoords(x, z); + + return chunk.getBlockData(x, y, z); + } + } + + public boolean w() { + return this.I < 4; + } + + public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1) { + return this.rayTrace(vec3d, vec3d1, false, false, false); + } + + public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1, boolean flag) { + return this.rayTrace(vec3d, vec3d1, flag, false, false); + } + + public MovingObjectPosition rayTrace(Vec3D vec3d, Vec3D vec3d1, boolean flag, boolean flag1, boolean flag2) { + if (!Double.isNaN(vec3d.a) && !Double.isNaN(vec3d.b) && !Double.isNaN(vec3d.c)) { + if (!Double.isNaN(vec3d1.a) && !Double.isNaN(vec3d1.b) && !Double.isNaN(vec3d1.c)) { + int i = MathHelper.floor(vec3d1.a); + int j = MathHelper.floor(vec3d1.b); + int k = MathHelper.floor(vec3d1.c); + int l = MathHelper.floor(vec3d.a); + int i1 = MathHelper.floor(vec3d.b); + int j1 = MathHelper.floor(vec3d.c); + BlockPosition blockposition = new BlockPosition(l, i1, j1); + IBlockData iblockdata = this.getType(blockposition); + Block block = iblockdata.getBlock(); + + if ((!flag1 || block.a(this, blockposition, iblockdata) != null) && block.a(iblockdata, flag)) { + MovingObjectPosition movingobjectposition = block.a(this, blockposition, vec3d, vec3d1); + + if (movingobjectposition != null) { + return movingobjectposition; + } + } + + MovingObjectPosition movingobjectposition1 = null; + int k1 = 200; + + while (k1-- >= 0) { + if (Double.isNaN(vec3d.a) || Double.isNaN(vec3d.b) || Double.isNaN(vec3d.c)) { + return null; + } + + if (l == i && i1 == j && j1 == k) { + return flag2 ? movingobjectposition1 : null; + } + + boolean flag3 = true; + boolean flag4 = true; + boolean flag5 = true; + double d0 = 999.0D; + double d1 = 999.0D; + double d2 = 999.0D; + + if (i > l) { + d0 = (double) l + 1.0D; + } else if (i < l) { + d0 = (double) l + 0.0D; + } else { + flag3 = false; + } + + if (j > i1) { + d1 = (double) i1 + 1.0D; + } else if (j < i1) { + d1 = (double) i1 + 0.0D; + } else { + flag4 = false; + } + + if (k > j1) { + d2 = (double) j1 + 1.0D; + } else if (k < j1) { + d2 = (double) j1 + 0.0D; + } else { + flag5 = false; + } + + double d3 = 999.0D; + double d4 = 999.0D; + double d5 = 999.0D; + double d6 = vec3d1.a - vec3d.a; + double d7 = vec3d1.b - vec3d.b; + double d8 = vec3d1.c - vec3d.c; + + if (flag3) { + d3 = (d0 - vec3d.a) / d6; + } + + if (flag4) { + d4 = (d1 - vec3d.b) / d7; + } + + if (flag5) { + d5 = (d2 - vec3d.c) / d8; + } + + if (d3 == -0.0D) { + d3 = -1.0E-4D; + } + + if (d4 == -0.0D) { + d4 = -1.0E-4D; + } + + if (d5 == -0.0D) { + d5 = -1.0E-4D; + } + + EnumDirection enumdirection; + + if (d3 < d4 && d3 < d5) { + enumdirection = i > l ? EnumDirection.WEST : EnumDirection.EAST; + vec3d = new Vec3D(d0, vec3d.b + d7 * d3, vec3d.c + d8 * d3); + } else if (d4 < d5) { + enumdirection = j > i1 ? EnumDirection.DOWN : EnumDirection.UP; + vec3d = new Vec3D(vec3d.a + d6 * d4, d1, vec3d.c + d8 * d4); + } else { + enumdirection = k > j1 ? EnumDirection.NORTH : EnumDirection.SOUTH; + vec3d = new Vec3D(vec3d.a + d6 * d5, vec3d.b + d7 * d5, d2); + } + + l = MathHelper.floor(vec3d.a) - (enumdirection == EnumDirection.EAST ? 1 : 0); + i1 = MathHelper.floor(vec3d.b) - (enumdirection == EnumDirection.UP ? 1 : 0); + j1 = MathHelper.floor(vec3d.c) - (enumdirection == EnumDirection.SOUTH ? 1 : 0); + blockposition = new BlockPosition(l, i1, j1); + IBlockData iblockdata1 = this.getType(blockposition); + Block block1 = iblockdata1.getBlock(); + + if (!flag1 || block1.a(this, blockposition, iblockdata1) != null) { + if (block1.a(iblockdata1, flag)) { + MovingObjectPosition movingobjectposition2 = block1.a(this, blockposition, vec3d, vec3d1); + + if (movingobjectposition2 != null) { + return movingobjectposition2; + } + } else { + movingobjectposition1 = new MovingObjectPosition(MovingObjectPosition.EnumMovingObjectType.MISS, vec3d, enumdirection, blockposition); + } + } + } + + return flag2 ? movingobjectposition1 : null; + } else { + return null; + } + } else { + return null; + } + } + + // Mythic - Hide projectiles and items + private void broadcastHiddenSound(EntityPlayer entityPlayer, Entity entity, String s, float f, float f1) { + entityPlayer.playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect(s, entity.locX, entity.locY, entity.locZ, f, f1)); + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a(entityPlayer, s, entity.locX, entity.locY, entity.locZ, f, f1); + } + } + + // Mythic - Play sound only to visible players + public void makeHiddenSound(Entity entity, String s, float f, float f1) { + if (entity instanceof EntityPlayer || entity instanceof EntityHuman) { + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a((EntityHuman) entity, s, entity.locX, entity.locY, entity.locZ, f, f1); + } + } else { + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a(s, entity.locX, entity.locY, entity.locZ, f, f1); + } + } + } + + public void makeSound(Entity entity, String s, float f, float f1) { + if (entity instanceof EntityPlayer || entity instanceof EntityHuman) { + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a((EntityHuman) entity, s, entity.locX, entity.locY, entity.locZ, f, f1); + } + } else { + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a(s, entity.locX, entity.locY, entity.locZ, f, f1); + } + } + } + + public void a(EntityHuman entityhuman, String s, float f, float f1) { + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a(entityhuman, s, entityhuman.locX, entityhuman.locY, entityhuman.locZ, f, f1); + } + + } + + public void makeSound(double d0, double d1, double d2, String s, float f, float f1) { + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a(s, d0, d1, d2, f, f1); + } + + } + + public void a(double d0, double d1, double d2, String s, float f, float f1, boolean flag) {} + + public void a(BlockPosition blockposition, String s) { + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a(s, blockposition); + } + + } + + public void addParticle(EnumParticle enumparticle, double d0, double d1, double d2, double d3, double d4, double d5, int... aint) { + this.a(enumparticle.c(), enumparticle.e(), d0, d1, d2, d3, d4, d5, aint); + } + + private void a(int i, boolean flag, double d0, double d1, double d2, double d3, double d4, double d5, int... aint) { + for (IWorldAccess iWorldAccess : this.u) { + iWorldAccess.a(i, flag, d0, d1, d2, d3, d4, d5, aint); + } + + } + + public boolean strikeLightning(Entity entity) { + this.k.add(entity); + return true; + } + + public boolean addEntity(Entity entity) { + // CraftBukkit start - Used for entities other than creatures + return addEntity(entity, SpawnReason.DEFAULT); + } + + public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason + org.spigotmc.AsyncCatcher.catchOp( "entity add"); // Spigot + if (entity == null) return false; + // CraftBukkit end + int i = MathHelper.floor(entity.locX / 16.0D); + int j = MathHelper.floor(entity.locZ / 16.0D); + boolean flag = entity.attachedToPlayer; + + if (entity instanceof EntityHuman) { + flag = true; + } + + // CraftBukkit start + org.bukkit.event.Cancellable event = null; + if (entity instanceof EntityLiving && !(entity instanceof EntityPlayer)) { + boolean isAnimal = entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal || entity instanceof EntityGolem; + boolean isMonster = entity instanceof EntityMonster || entity instanceof EntityGhast || entity instanceof EntitySlime; + + if (spawnReason != SpawnReason.CUSTOM) { + if (isAnimal && !allowAnimals || isMonster && !allowMonsters) { + entity.dead = true; + return false; + } + } + + event = CraftEventFactory.callCreatureSpawnEvent((EntityLiving) entity, spawnReason); + } else if (entity instanceof EntityItem) { + event = CraftEventFactory.callItemSpawnEvent((EntityItem) entity); + } else if (entity.getBukkitEntity() instanceof org.bukkit.entity.Projectile) { + // Not all projectiles extend EntityProjectile, so check for Bukkit interface instead + event = CraftEventFactory.callProjectileLaunchEvent(entity); + } + // Spigot start + else if (entity instanceof EntityExperienceOrb) { + EntityExperienceOrb xp = (EntityExperienceOrb) entity; + double radius = spigotConfig.expMerge; + if (radius > 0) { + List entities = this.getEntities(entity, entity.getBoundingBox().grow(radius, radius, radius)); + for (Entity e : entities) { + if (e instanceof EntityExperienceOrb) { + EntityExperienceOrb loopItem = (EntityExperienceOrb) e; + if (!loopItem.dead) { + xp.value += loopItem.value; + loopItem.die(); + } + } + } + } + } // Spigot end + + if (event != null && (event.isCancelled() || entity.dead)) { + entity.dead = true; + return false; + } + // CraftBukkit end + + if (!flag && !this.isChunkLoaded(i, j, true)) { + entity.dead = true; + return false; + } else { + if (entity instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) entity; + + this.players.add(entityhuman); + this.everyoneSleeping(); + } + + this.getChunkAt(i, j).a(entity); + this.entityList.add(entity); + this.a(entity); + return true; + } + } + + protected void a(Entity entity) { + for (int i = 0; i < this.u.size(); ++i) { + this.u.get(i).a(entity); + } + + entity.valid = true; // CraftBukkit + } + + protected void b(Entity entity) { + for (int i = 0; i < this.u.size(); ++i) { + this.u.get(i).b(entity); + } + + entity.valid = false; // CraftBukkit + } + + public void kill(Entity entity) { + if (entity.passenger != null) { + entity.passenger.mount(null); + } + + if (entity.vehicle != null) { + entity.mount(null); + } + + entity.die(); + if (entity instanceof EntityHuman) { + this.players.remove(entity); + // Spigot start + for ( Object o : worldMaps.c ) + { + if ( o instanceof WorldMap ) + { + WorldMap map = (WorldMap) o; + map.i.remove( entity ); + for (Iterator iter = map.g.iterator(); iter.hasNext(); ) + { + if ( iter.next().trackee == entity ) + { + iter.remove(); + } + } + } + } + // Spigot end + this.everyoneSleeping(); + this.b(entity); + } + + } + + public void removeEntity(Entity entity) { + org.spigotmc.AsyncCatcher.catchOp( "entity remove"); // Spigot + entity.die(); + if (entity instanceof EntityHuman) { + this.players.remove(entity); + this.everyoneSleeping(); + } + + if (!guardEntityList) { // Spigot - It will get removed after the tick if we are ticking + int i = entity.ae; + int j = entity.ag; + + if (entity.ad && this.isChunkLoaded(i, j, true)) { + this.getChunkAt(i, j).b(entity); + } + + // CraftBukkit start - Decrement loop variable field if we've already ticked this entity + int index = this.entityList.indexOf(entity); + if (index != -1) { + if (index <= this.tickPosition) { + this.tickPosition--; + } + this.entityList.remove(index); + } + // CraftBukkit end + } // Spigot + this.b(entity); + } + + public void addIWorldAccess(IWorldAccess iworldaccess) { + this.u.add(iworldaccess); + } + + public List getCubes(Entity entity, AxisAlignedBB axisalignedbb) { + ArrayList arraylist = Lists.newArrayList(); + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.d + 1.0D); + int k = MathHelper.floor(axisalignedbb.b); + int l = MathHelper.floor(axisalignedbb.e + 1.0D); + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); + WorldBorder worldborder = this.getWorldBorder(); + boolean flag = entity.aT(); + boolean flag1 = this.a(worldborder, entity); + IBlockData iblockdata = Blocks.STONE.getBlockData(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + // Spigot start + int ystart = ( ( k - 1 ) < 0 ) ? 0 : ( k - 1 ); + for ( int chunkx = ( i >> 4 ); chunkx <= ( ( j - 1 ) >> 4 ); chunkx++ ) + { + int cx = chunkx << 4; + for ( int chunkz = ( i1 >> 4 ); chunkz <= ( ( j1 - 1 ) >> 4 ); chunkz++ ) + { + Chunk chunk = this.getChunkIfLoaded( chunkx, chunkz ); + if ( chunk == null ) + { + // PaperSpigot start + if (entity.loadChunks) { + chunk = ((ChunkProviderServer) entity.world.chunkProvider).getChunkAt(chunkx, chunkz); + } else { + entity.inUnloadedChunk = true; // PaperSpigot - Remove entities in unloaded chunks + continue; + } + // PaperSpigot end + } + int cz = chunkz << 4; + // Compute ranges within chunk + int xstart = ( i < cx ) ? cx : i; + int xend = ( j < ( cx + 16 ) ) ? j : ( cx + 16 ); + int zstart = ( i1 < cz ) ? cz : i1; + int zend = ( j1 < ( cz + 16 ) ) ? j1 : ( cz + 16 ); + // Loop through blocks within chunk + for ( int x = xstart; x < xend; x++ ) + { + for ( int z = zstart; z < zend; z++ ) + { + for ( int y = ystart; y < l; y++ ) + { + BlockPosition blockposition = new BlockPosition( x, y, z ); + + if (flag && flag1) { + entity.h(false); + } else if (!flag && !flag1) { + entity.h(true); + } + + IBlockData block; + if (!this.getWorldBorder().a(blockposition) && flag1) { + block = Blocks.STONE.getBlockData(); + } else + { + block = chunk.getBlockData( blockposition ); + } + if ( block != null ) + { + // PaperSpigot start - FallingBlocks and TNT collide with specific non-collidable blocks + Block b = block.getBlock(); + if (entity.world.paperSpigotConfig.fallingBlocksCollideWithSigns && (entity instanceof EntityTNTPrimed || entity instanceof EntityFallingBlock) && (b instanceof BlockSign || b instanceof BlockFenceGate || b instanceof BlockTorch || b instanceof BlockButtonAbstract || b instanceof BlockLever || b instanceof BlockTripwireHook || b instanceof BlockTripwire || b instanceof BlockChest || b instanceof BlockSlowSand || b instanceof BlockBed || b instanceof BlockEnderChest || b instanceof BlockEnchantmentTable || b instanceof BlockBrewingStand)) { + AxisAlignedBB aabb = AxisAlignedBB.a(x, y, z, x + 1.0, y + 1.0, z + 1.0); + if (axisalignedbb.b(aabb)) arraylist.add(aabb); + } else { + b.a(this, blockposition, block, axisalignedbb, arraylist, entity); + } + // PaperSpigot end + } + } + } + } + } + } + // Spigot end + + if(MythicConfiguration.Options.World.checkEntityCubes) { + if (entity instanceof EntityItem) return arraylist; // PaperSpigot - Optimize item movement + if (entity instanceof EntityArmorStand) return arraylist; // TacoSpigot - Optimize armor stand movement + if (entity instanceof EntityTNTPrimed) return arraylist; // TacoSpigot - Optimize tnt entity movement + if (entity instanceof EntityFallingBlock) return arraylist; // TacoSpigot - Optimize falling block movement + + double d0 = 0.25D; + List list = this.getEntities(entity, axisalignedbb.grow(d0, d0, d0)); + + for (int j2 = 0; j2 < list.size(); ++j2) { + if (entity.passenger != list && entity.vehicle != list) { + AxisAlignedBB axisalignedbb1 = ((Entity) list.get(j2)).S(); + + if (axisalignedbb1 != null && axisalignedbb1.b(axisalignedbb)) { + arraylist.add(axisalignedbb1); + } + + axisalignedbb1 = entity.j((Entity) list.get(j2)); + if (axisalignedbb1 != null && axisalignedbb1.b(axisalignedbb)) { + arraylist.add(axisalignedbb1); + } + } + } + } + + return arraylist; + } + + public boolean a(WorldBorder worldborder, Entity entity) { + double d0 = worldborder.b(); + double d1 = worldborder.c(); + double d2 = worldborder.d(); + double d3 = worldborder.e(); + + if (entity.aT()) { + ++d0; + ++d1; + --d2; + --d3; + } else { + --d0; + --d1; + ++d2; + ++d3; + } + + return entity.locX > d0 && entity.locX < d2 && entity.locZ > d1 && entity.locZ < d3; + } + + public List a(AxisAlignedBB axisalignedbb) { + ArrayList arraylist = Lists.newArrayList(); + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.d + 1.0D); + int k = MathHelper.floor(axisalignedbb.b); + int l = MathHelper.floor(axisalignedbb.e + 1.0D); + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k1 = i; k1 < j; ++k1) { + for (int l1 = i1; l1 < j1; ++l1) { + if (this.isLoaded(blockposition_mutableblockposition.c(k1, 64, l1))) { + for (int i2 = k - 1; i2 < l; ++i2) { + blockposition_mutableblockposition.c(k1, i2, l1); + IBlockData iblockdata; + + if (k1 >= -30000000 && k1 < 30000000 && l1 >= -30000000 && l1 < 30000000) { + iblockdata = this.getType(blockposition_mutableblockposition); + } else { + iblockdata = Blocks.BEDROCK.getBlockData(); + } + + iblockdata.getBlock().a(this, blockposition_mutableblockposition, iblockdata, axisalignedbb, arraylist, null); + } + } + } + } + + return arraylist; + } + + public int a(float f) { + float f1 = this.c(f); + float f2 = 1.0F - (MathHelper.cos(f1 * 3.1415927F * 2.0F) * 2.0F + 0.5F); + + f2 = MathHelper.a(f2, 0.0F, 1.0F); + f2 = 1.0F - f2; + f2 = (float) ((double) f2 * (1.0D - (double) (this.j(f) * 5.0F) / 16.0D)); + f2 = (float) ((double) f2 * (1.0D - (double) (this.h(f) * 5.0F) / 16.0D)); + f2 = 1.0F - f2; + return (int) (f2 * 11.0F); + } + + public float c(float f) { + return this.worldProvider.a(this.worldData.getDayTime(), f); + } + + public float y() { + return WorldProvider.a[this.worldProvider.a(this.worldData.getDayTime())]; + } + + public float d(float f) { + float f1 = this.c(f); + + return f1 * 3.1415927F * 2.0F; + } + + public BlockPosition q(BlockPosition blockposition) { + return this.getChunkAtWorldCoords(blockposition).h(blockposition); + } + + public BlockPosition r(BlockPosition blockposition) { + Chunk chunk = this.getChunkAtWorldCoords(blockposition); + + BlockPosition blockposition1; + BlockPosition blockposition2; + + for (blockposition1 = new BlockPosition(blockposition.getX(), chunk.g() + 16, blockposition.getZ()); blockposition1.getY() >= 0; blockposition1 = blockposition2) { + blockposition2 = blockposition1.down(); + Material material = chunk.getType(blockposition2).getMaterial(); + + if (material.isSolid() && material != Material.LEAVES) { + break; + } + } + + return blockposition1; + } + + public void a(BlockPosition blockposition, Block block, int i) {} + + public void a(BlockPosition blockposition, Block block, int i, int j) {} + + public void b(BlockPosition blockposition, Block block, int i, int j) {} + + public void tickEntities() { + this.methodProfiler.a("entities"); + this.methodProfiler.a("global"); + + int i; + Entity entity; + CrashReport crashreport; + CrashReportSystemDetails crashreportsystemdetails; + + for (i = 0; i < this.k.size(); ++i) { + entity = this.k.get(i); + // CraftBukkit start - Fixed an NPE + if (entity == null) { + continue; + } + // CraftBukkit end + + try { + ++entity.ticksLived; + entity.t_(); + } catch (Throwable throwable) { + crashreport = CrashReport.a(throwable, "Ticking entity"); + crashreportsystemdetails = crashreport.a("Entity being ticked"); + if (entity == null) { + crashreportsystemdetails.a("Entity", "~~NULL~~"); + } else { + entity.appendEntityCrashDetails(crashreportsystemdetails); + } + + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + + if (entity.dead) { + this.k.remove(i--); + } + } + + this.methodProfiler.c("remove"); + timings.entityRemoval.startTiming(); // Spigot + this.entityList.removeAll(this.g); + + int j; + int k; + + // Paper start - Set based removal lists + for (Entity e : this.g) { + j = e.ae; + k = e.ag; + if (e.ad && this.isChunkLoaded(j, k, true)) { + this.getChunkAt(j, k).b(e); + } + } + + for (Entity e : this.g) { + this.b(e); + } + // Paper end + + this.g.clear(); + timings.entityRemoval.stopTiming(); // Spigot + this.methodProfiler.c("regular"); + + org.spigotmc.ActivationRange.activateEntities(this); // Spigot + timings.entityTick.startTiming(); // Spigot + guardEntityList = true; // Spigot + // CraftBukkit start - Use field for loop variable + co.aikar.timings.TimingHistory.entityTicks += this.entityList.size(); // Spigot + int entitiesThisCycle = 0; + // PaperSpigot start - Disable tick limiters + //if (tickPosition < 0) tickPosition = 0; + for (tickPosition = 0; tickPosition < entityList.size(); tickPosition++) { + // PaperSpigot end + tickPosition = (tickPosition < entityList.size()) ? tickPosition : 0; + entity = this.entityList.get(this.tickPosition); + // CraftBukkit end + if (entity.vehicle != null) { + if (!entity.vehicle.dead && entity.vehicle.passenger == entity) { + continue; + } + + entity.vehicle.passenger = null; + entity.vehicle = null; + } + + this.methodProfiler.a("tick"); + if (!entity.dead) { + try { + entity.tickTimer.startTiming(); // Spigot + this.g(entity); + entity.tickTimer.stopTiming(); // Spigot + } catch (Throwable throwable1) { + // PaperSpigot start - Prevent tile entity and entity crashes + entity.tickTimer.stopTiming(); + System.err.println("Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX + "," + entity.locY + "," + entity.locZ); + throwable1.printStackTrace(); + entity.dead = true; + continue; + // PaperSpigot end + } + } + + this.methodProfiler.b(); + this.methodProfiler.a("remove"); + if (entity.dead) { + j = entity.ae; + k = entity.ag; + if (entity.ad && this.isChunkLoaded(j, k, true)) { + this.getChunkAt(j, k).b(entity); + } + + guardEntityList = false; // Spigot + this.entityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable + guardEntityList = true; // Spigot + this.b(entity); + } + + this.methodProfiler.b(); + } + guardEntityList = false; // Spigot + + timings.entityTick.stopTiming(); // Spigot + this.methodProfiler.c("blockEntities"); + timings.tileEntityTick.startTiming(); // Spigot + this.M = true; + // CraftBukkit start - From below, clean up tile entities before ticking them + if (!this.c.isEmpty()) { + this.tileEntityList.removeAll(this.c); + //this.h.removeAll(this.c); // PaperSpigot - Remove unused list + this.c.clear(); + } + // CraftBukkit end + + if(MythicConfiguration.Options.World.tickTiles) { + // Spigot start + int tilesThisCycle = 0; + for (tileTickPosition = 0; tileTickPosition < tileEntityList.size(); tileTickPosition++) { // PaperSpigot - Disable tick limiters + tileTickPosition = (tileTickPosition < tileEntityList.size()) ? tileTickPosition : 0; + TileEntity tileentity = this.tileEntityList.get(tileTickPosition); + // Spigot start + if (tileentity == null) { + getServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash"); + tilesThisCycle--; + this.tileEntityList.remove(tileTickPosition--); + continue; + } + // Spigot end + + if (!tileentity.x() && tileentity.t()) { + BlockPosition blockposition = tileentity.getPosition(); + + if (this.isLoaded(blockposition) && this.N.a(blockposition)) { + try { + tileentity.tickTimer.startTiming(); // Spigot + ((IUpdatePlayerListBox) tileentity).c(); + } catch (Throwable throwable2) { + // PaperSpigot start - Prevent tile entity and entity crashes + tileentity.tickTimer.stopTiming(); + System.err.println("TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ()); + throwable2.printStackTrace(); + tilesThisCycle--; + this.tileEntityList.remove(tileTickPosition--); + continue; + // PaperSpigot end + } + // Spigot start + finally { + tileentity.tickTimer.stopTiming(); + } + // Spigot end + } + } + + if (tileentity.x()) { + tilesThisCycle--; + this.tileEntityList.remove(tileTickPosition--); + //this.h.remove(tileentity); // PaperSpigot - Remove unused list + if (this.isLoaded(tileentity.getPosition())) { + this.getChunkAtWorldCoords(tileentity.getPosition()).e(tileentity.getPosition()); + } + } + } + } + + timings.tileEntityTick.stopTiming(); // Spigot + timings.tileEntityPending.startTiming(); // Spigot + this.M = false; + /* CraftBukkit start - Moved up + if (!this.c.isEmpty()) { + this.tileEntityList.removeAll(this.c); + this.h.removeAll(this.c); + this.c.clear(); + } + // CraftBukkit end */ + + this.methodProfiler.c("pendingBlockEntities"); + if(MythicConfiguration.Options.World.tickPendingTiles) { + if (!this.b.isEmpty()) { + for (int l = 0; l < this.b.size(); ++l) { + TileEntity tileentity1 = this.b.get(l); + + if (!tileentity1.x()) { + /* CraftBukkit start - Order matters, moved down + if (!this.h.contains(tileentity1)) { + this.a(tileentity1); + } + // CraftBukkit end */ + + if (this.isLoaded(tileentity1.getPosition())) { + this.getChunkAtWorldCoords(tileentity1.getPosition()).a(tileentity1.getPosition(), tileentity1); + } + + this.notify(tileentity1.getPosition()); + } + } + + this.b.clear(); + } + } + + timings.tileEntityPending.stopTiming(); // Spigot + co.aikar.timings.TimingHistory.tileEntityTicks += this.tileEntityList.size(); // Spigot + + this.methodProfiler.b(); + this.methodProfiler.b(); + } + + public boolean a(TileEntity tileentity) { + boolean flag = true; // PaperSpigot - Remove unused list + + if (flag && tileentity instanceof IUpdatePlayerListBox) { + this.tileEntityList.add(tileentity); + } + + return flag; + } + + public void a(Collection collection) { + if (this.M) { + this.b.addAll(collection); + } else { + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + TileEntity tileentity = (TileEntity) iterator.next(); + + //this.h.add(tileentity); // PaperSpigot - Remove unused list + if (tileentity instanceof IUpdatePlayerListBox) { + this.tileEntityList.add(tileentity); + } + } + } + + } + + public void g(Entity entity) { + this.entityJoinedWorld(entity, true); + } + + public void entityJoinedWorld(Entity entity, boolean flag) { + int i = MathHelper.floor(entity.locX); + int j = MathHelper.floor(entity.locZ); + byte b0 = 32; + + // Spigot start + if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { + entity.ticksLived++; + entity.inactiveTick(); + // PaperSpigot start - Remove entities in unloaded chunks + if (!this.isChunkLoaded(i, j, true) && ((entity instanceof EntityEnderPearl && this.paperSpigotConfig.removeUnloadedEnderPearls) || + (entity instanceof EntityFallingBlock && this.paperSpigotConfig.removeUnloadedFallingBlocks) || + (entity instanceof EntityTNTPrimed && this.paperSpigotConfig.removeUnloadedTNTEntities))) { + entity.inUnloadedChunk = true; + entity.die(); + } + // PaperSpigot end + } else { + // CraftBukkit end + entity.P = entity.locX; + entity.Q = entity.locY; + entity.R = entity.locZ; + entity.lastYaw = entity.yaw; + entity.lastPitch = entity.pitch; + if (flag && entity.ad) { + ++entity.ticksLived; + ++co.aikar.timings.TimingHistory.activatedEntityTicks; // Spigot + if (entity.vehicle != null) { + entity.ak(); + } else { + entity.t_(); + } + } + + this.methodProfiler.a("chunkCheck"); + if (Double.isNaN(entity.locX) || Double.isInfinite(entity.locX)) { + entity.locX = entity.P; + } + + if (Double.isNaN(entity.locY) || Double.isInfinite(entity.locY)) { + entity.locY = entity.Q; + } + + if (Double.isNaN(entity.locZ) || Double.isInfinite(entity.locZ)) { + entity.locZ = entity.R; + } + + if (Double.isNaN(entity.pitch) || Double.isInfinite(entity.pitch)) { + entity.pitch = entity.lastPitch; + } + + if (Double.isNaN(entity.yaw) || Double.isInfinite(entity.yaw)) { + entity.yaw = entity.lastYaw; + } + + int k = MathHelper.floor(entity.locX / 16.0D); + int l = MathHelper.floor(entity.locY / 16.0D); + int i1 = MathHelper.floor(entity.locZ / 16.0D); + + if (!entity.ad || entity.ae != k || entity.af != l || entity.ag != i1) { + if (entity.loadChunks) entity.loadChunks(); // PaperSpigot - Force load chunks + if (entity.ad && this.isChunkLoaded(entity.ae, entity.ag, true)) { + this.getChunkAt(entity.ae, entity.ag).a(entity, entity.af); + } + + if (this.isChunkLoaded(k, i1, true)) { + entity.ad = true; + this.getChunkAt(k, i1).a(entity); + } else { + entity.ad = false; + } + } + + this.methodProfiler.b(); + if (flag && entity.ad && entity.passenger != null) { + if (!entity.passenger.dead && entity.passenger.vehicle == entity) { + this.g(entity.passenger); + } else { + entity.passenger.vehicle = null; + entity.passenger = null; + } + } + + } + } + + public boolean b(AxisAlignedBB axisalignedbb) { + return this.a(axisalignedbb, (Entity) null); + } + + public boolean a(AxisAlignedBB axisalignedbb, Entity entity) { + List list = this.getEntities(null, axisalignedbb); + + for (int i = 0; i < list.size(); ++i) { + Entity entity1 = (Entity) list.get(i); + + // PaperSpigot start - Allow block placement if the placer cannot see the vanished blocker + if (entity instanceof EntityPlayer && entity1 instanceof EntityPlayer) { + if (!((EntityPlayer) entity).getBukkitEntity().canSee(((EntityPlayer) entity1).getBukkitEntity())) { + continue; + } + } + + if (!entity1.dead && entity1.k && entity1 != entity && (entity == null || entity.vehicle != entity1 && entity.passenger != entity1)) { + return false; + } + } + + return true; + } + + public boolean c(AxisAlignedBB axisalignedbb) { + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.d); + int k = MathHelper.floor(axisalignedbb.b); + int l = MathHelper.floor(axisalignedbb.e); + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k1 = i; k1 <= j; ++k1) { + for (int l1 = k; l1 <= l; ++l1) { + for (int i2 = i1; i2 <= j1; ++i2) { + Block block = this.getType(blockposition_mutableblockposition.c(k1, l1, i2)).getBlock(); + + if (block.getMaterial() != Material.AIR) { + return true; + } + } + } + } + + return false; + } + + public boolean containsLiquid(AxisAlignedBB axisalignedbb) { + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.d); + int k = MathHelper.floor(axisalignedbb.b); + int l = MathHelper.floor(axisalignedbb.e); + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k1 = i; k1 <= j; ++k1) { + for (int l1 = k; l1 <= l; ++l1) { + for (int i2 = i1; i2 <= j1; ++i2) { + Block block = this.getType(blockposition_mutableblockposition.c(k1, l1, i2)).getBlock(); + + if (block.getMaterial().isLiquid()) { + return true; + } + } + } + } + + return false; + } + + public boolean e(AxisAlignedBB axisalignedbb) { + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.d + 1.0D); + int k = MathHelper.floor(axisalignedbb.b); + int l = MathHelper.floor(axisalignedbb.e + 1.0D); + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); + + if (this.isAreaLoaded(i, k, i1, j, l, j1, true)) { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k1 = i; k1 < j; ++k1) { + for (int l1 = k; l1 < l; ++l1) { + for (int i2 = i1; i2 < j1; ++i2) { + Block block = this.getType(blockposition_mutableblockposition.c(k1, l1, i2)).getBlock(); + + if (block == Blocks.FIRE || block == Blocks.FLOWING_LAVA || block == Blocks.LAVA) { + return true; + } + } + } + } + } + + return false; + } + + public boolean a(AxisAlignedBB axisalignedbb, Material material, Entity entity) { + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.d + 1.0D); + int k = MathHelper.floor(axisalignedbb.b); + int l = MathHelper.floor(axisalignedbb.e + 1.0D); + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); + + if (!this.isAreaLoaded(i, k, i1, j, l, j1, true)) { + return false; + } else { + boolean flag = false; + Vec3D vec3d = new Vec3D(0.0D, 0.0D, 0.0D); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k1 = i; k1 < j; ++k1) { + for (int l1 = k; l1 < l; ++l1) { + for (int i2 = i1; i2 < j1; ++i2) { + blockposition_mutableblockposition.c(k1, l1, i2); + IBlockData iblockdata = this.getType(blockposition_mutableblockposition); + Block block = iblockdata.getBlock(); + + if (block.getMaterial() == material) { + double d0 = (float) (l1 + 1) - BlockFluids.b(iblockdata.get(BlockFluids.LEVEL).intValue()); + + if ((double) l >= d0) { + flag = true; + vec3d = block.a(this, blockposition_mutableblockposition, entity, vec3d); + } + } + } + } + } + + if (vec3d.b() > 0.0D && entity.aL()) { + vec3d = vec3d.a(); + double d1 = 0.014D; + + entity.motX += vec3d.a * d1; + entity.motY += vec3d.b * d1; + entity.motZ += vec3d.c * d1; + } + + return flag; + } + } + + public boolean a(AxisAlignedBB axisalignedbb, Material material) { + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.d + 1.0D); + int k = MathHelper.floor(axisalignedbb.b); + int l = MathHelper.floor(axisalignedbb.e + 1.0D); + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k1 = i; k1 < j; ++k1) { + for (int l1 = k; l1 < l; ++l1) { + for (int i2 = i1; i2 < j1; ++i2) { + if (this.getType(blockposition_mutableblockposition.c(k1, l1, i2)).getBlock().getMaterial() == material) { + return true; + } + } + } + } + + return false; + } + + public boolean b(AxisAlignedBB axisalignedbb, Material material) { + int i = MathHelper.floor(axisalignedbb.a); + int j = MathHelper.floor(axisalignedbb.d + 1.0D); + int k = MathHelper.floor(axisalignedbb.b); + int l = MathHelper.floor(axisalignedbb.e + 1.0D); + int i1 = MathHelper.floor(axisalignedbb.c); + int j1 = MathHelper.floor(axisalignedbb.f + 1.0D); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k1 = i; k1 < j; ++k1) { + for (int l1 = k; l1 < l; ++l1) { + for (int i2 = i1; i2 < j1; ++i2) { + IBlockData iblockdata = this.getType(blockposition_mutableblockposition.c(k1, l1, i2)); + Block block = iblockdata.getBlock(); + + if (block.getMaterial() == material) { + int j2 = iblockdata.get(BlockFluids.LEVEL).intValue(); + double d0 = l1 + 1; + + if (j2 < 8) { + d0 = (double) (l1 + 1) - (double) j2 / 8.0D; + } + + if (d0 >= axisalignedbb.b) { + return true; + } + } + } + } + } + + return false; + } + + public Explosion explode(Entity entity, double d0, double d1, double d2, float f, boolean flag) { + return this.createExplosion(entity, d0, d1, d2, f, false, flag); + } + + public Explosion createExplosion(Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { + Explosion explosion = new Explosion(this, entity, d0, d1, d2, f, flag, flag1); + + explosion.a(); + explosion.a(true); + return explosion; + } + + public float a(Vec3D vec3d, AxisAlignedBB axisalignedbb) { + double d0 = 1.0D / ((axisalignedbb.d - axisalignedbb.a) * 2.0D + 1.0D); + double d1 = 1.0D / ((axisalignedbb.e - axisalignedbb.b) * 2.0D + 1.0D); + double d2 = 1.0D / ((axisalignedbb.f - axisalignedbb.c) * 2.0D + 1.0D); + double d3 = (1.0D - Math.floor(1.0D / d0) * d0) / 2.0D; + double d4 = (1.0D - Math.floor(1.0D / d2) * d2) / 2.0D; + + if (d0 >= 0.0D && d1 >= 0.0D && d2 >= 0.0D) { + int i = 0; + int j = 0; + + for (float f = 0.0F; f <= 1.0F; f = (float) ((double) f + d0)) { + for (float f1 = 0.0F; f1 <= 1.0F; f1 = (float) ((double) f1 + d1)) { + for (float f2 = 0.0F; f2 <= 1.0F; f2 = (float) ((double) f2 + d2)) { + double d5 = axisalignedbb.a + (axisalignedbb.d - axisalignedbb.a) * (double) f; + double d6 = axisalignedbb.b + (axisalignedbb.e - axisalignedbb.b) * (double) f1; + double d7 = axisalignedbb.c + (axisalignedbb.f - axisalignedbb.c) * (double) f2; + + if (this.rayTrace(new Vec3D(d5 + d3, d6, d7 + d4), vec3d) == null) { + ++i; + } + + ++j; + } + } + } + + return (float) i / (float) j; + } else { + return 0.0F; + } + } + + public boolean douseFire(EntityHuman entityhuman, BlockPosition blockposition, EnumDirection enumdirection) { + blockposition = blockposition.shift(enumdirection); + if (this.getType(blockposition).getBlock() == Blocks.FIRE) { + this.a(entityhuman, 1004, blockposition, 0); + this.setAir(blockposition); + return true; + } else { + return false; + } + } + + public Map capturedTileEntities = Maps.newHashMap(); + + public TileEntity getTileEntity(BlockPosition blockposition) { + if (!this.isValidLocation(blockposition)) { + return null; + } else { + // CraftBukkit start + if (capturedTileEntities.containsKey(blockposition)) { + return capturedTileEntities.get(blockposition); + } + // CraftBukkit end + + TileEntity tileentity = null; + int i; + TileEntity tileentity1; + + if (this.M) { + for (i = 0; i < this.b.size(); ++i) { + tileentity1 = this.b.get(i); + if (!tileentity1.x() && tileentity1.getPosition().equals(blockposition)) { + tileentity = tileentity1; + break; + } + } + } + + if (tileentity == null) { + tileentity = this.getChunkAtWorldCoords(blockposition).a(blockposition, Chunk.EnumTileEntityState.IMMEDIATE); + } + + if (tileentity == null) { + for (i = 0; i < this.b.size(); ++i) { + tileentity1 = this.b.get(i); + if (!tileentity1.x() && tileentity1.getPosition().equals(blockposition)) { + tileentity = tileentity1; + break; + } + } + } + + return tileentity; + } + } + + public void setTileEntity(BlockPosition blockposition, TileEntity tileentity) { + if (tileentity != null && !tileentity.x()) { + // CraftBukkit start + if (captureBlockStates) { + tileentity.a(this); + tileentity.a(blockposition); + capturedTileEntities.put(blockposition, tileentity); + return; + } + // CraftBukkit end + if (this.M) { + tileentity.a(blockposition); + Iterator iterator = this.b.iterator(); + + while (iterator.hasNext()) { + TileEntity tileentity1 = (TileEntity) iterator.next(); + + if (tileentity1.getPosition().equals(blockposition)) { + tileentity1.y(); + iterator.remove(); + } + } + + tileentity.a(this); // Spigot - No null worlds + this.b.add(tileentity); + } else { + this.a(tileentity); + this.getChunkAtWorldCoords(blockposition).a(blockposition, tileentity); + } + } + + } + + public void t(BlockPosition blockposition) { + TileEntity tileentity = this.getTileEntity(blockposition); + + if (tileentity != null && this.M) { + tileentity.y(); + this.b.remove(tileentity); + } else { + if (tileentity != null) { + this.b.remove(tileentity); + //this.h.remove(tileentity); // PaperSpigot - Remove unused list + this.tileEntityList.remove(tileentity); + } + + this.getChunkAtWorldCoords(blockposition).e(blockposition); + } + + } + + public void b(TileEntity tileentity) { + this.c.add(tileentity); + } + + public boolean u(BlockPosition blockposition) { + IBlockData iblockdata = this.getType(blockposition); + AxisAlignedBB axisalignedbb = iblockdata.getBlock().a(this, blockposition, iblockdata); + + return axisalignedbb != null && axisalignedbb.a() >= 1.0D; + } + + public static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition) { + IBlockData iblockdata = iblockaccess.getType(blockposition); + Block block = iblockdata.getBlock(); + + return block.getMaterial().k() && block.d() || (block instanceof BlockStairs ? iblockdata.get(BlockStairs.HALF) == BlockStairs.EnumHalf.TOP : (block instanceof BlockStepAbstract ? iblockdata.get(BlockStepAbstract.HALF) == BlockStepAbstract.EnumSlabHalf.TOP : (block instanceof BlockHopper || (block instanceof BlockSnow && iblockdata.get(BlockSnow.LAYERS).intValue() == 7)))); + } + + // Mythic - Reduce churn rate + public static boolean a(IBlockAccess iblockaccess, int x, int y, int z) { + IBlockData iblockdata = iblockaccess.getType(x, y, z); + Block block = iblockdata.getBlock(); + + return block.getMaterial().k() && block.d() || (block instanceof BlockStairs ? iblockdata.get(BlockStairs.HALF) == BlockStairs.EnumHalf.TOP : (block instanceof BlockStepAbstract ? iblockdata.get(BlockStepAbstract.HALF) == BlockStepAbstract.EnumSlabHalf.TOP : (block instanceof BlockHopper || (block instanceof BlockSnow && iblockdata.get(BlockSnow.LAYERS).intValue() == 7)))); + } + + public boolean d(BlockPosition blockposition, boolean flag) { + if (!this.isValidLocation(blockposition)) { + return flag; + } else { + Chunk chunk = this.chunkProvider.getChunkAt(blockposition); + + if (chunk.isEmpty()) { + return flag; + } else { + Block block = this.getType(blockposition).getBlock(); + + return block.getMaterial().k() && block.d(); + } + } + } + + public void B() { + int i = this.a(1.0F); + + if (i != this.I) { + this.I = i; + } + + } + + public void setSpawnFlags(boolean flag, boolean flag1) { + this.allowMonsters = flag; + this.allowAnimals = flag1; + } + + public void doTick() { + this.p(); + } + + protected void C() { + if (this.worldData.hasStorm()) { + this.p = 1.0F; + if (this.worldData.isThundering()) { + this.r = 1.0F; + } + } + + } + + protected void p() { + if(!MythicConfiguration.Options.World.weather) return; + + if (!this.worldProvider.o()) { + if (!this.isClientSide) { + int i = this.worldData.A(); + + if (i > 0) { + --i; + this.worldData.i(i); + this.worldData.setThunderDuration(this.worldData.isThundering() ? 1 : 2); + this.worldData.setWeatherDuration(this.worldData.hasStorm() ? 1 : 2); + } + + int j = this.worldData.getThunderDuration(); + + if (j <= 0) { + if (this.worldData.isThundering()) { + this.worldData.setThunderDuration(this.random.nextInt(12000) + 3600); + } else { + this.worldData.setThunderDuration(this.random.nextInt(168000) + 12000); + } + } else { + --j; + this.worldData.setThunderDuration(j); + if (j <= 0) { + this.worldData.setThundering(!this.worldData.isThundering()); + } + } + + this.q = this.r; + if (this.worldData.isThundering()) { + this.r = (float) ((double) this.r + 0.01D); + } else { + this.r = (float) ((double) this.r - 0.01D); + } + + this.r = MathHelper.a(this.r, 0.0F, 1.0F); + int k = this.worldData.getWeatherDuration(); + + if (k <= 0) { + if (this.worldData.hasStorm()) { + this.worldData.setWeatherDuration(this.random.nextInt(12000) + 12000); + } else { + this.worldData.setWeatherDuration(this.random.nextInt(168000) + 12000); + } + } else { + --k; + this.worldData.setWeatherDuration(k); + if (k <= 0) { + this.worldData.setStorm(!this.worldData.hasStorm()); + } + } + + this.o = this.p; + if (this.worldData.hasStorm()) { + this.p = (float) ((double) this.p + 0.01D); + } else { + this.p = (float) ((double) this.p - 0.01D); + } + + this.p = MathHelper.a(this.p, 0.0F, 1.0F); + + // CraftBukkit start + for (int idx = 0; idx < this.players.size(); ++idx) { + if (((EntityPlayer) this.players.get(idx)).world == this) { + ((EntityPlayer) this.players.get(idx)).tickWeather(); + } + } + // CraftBukkit end + } + } + } + + protected void D() { + // this.chunkTickList.clear(); // CraftBukkit - removed + this.methodProfiler.a("buildList"); + + // Mythic - Option for ticking chunk blocks + if(!MythicConfiguration.Options.World.tickChunkBlocks) return; + + int i; + EntityHuman entityhuman; + int j; + int k; + int l; + + // Spigot start + int optimalChunks = spigotConfig.chunksPerTick; + // Quick conditions to allow us to exist early + if ( optimalChunks > 0 ) { + // Keep chunks with growth inside of the optimal chunk range + int chunksPerPlayer = Math.min( 200, Math.max( 1, (int) ( ( ( optimalChunks - players.size() ) / (double) players.size() ) + 0.5 ) ) ); + int randRange = 3 + chunksPerPlayer / 30; + // Limit to normal tick radius - including view distance + randRange = ( randRange > chunkTickRadius ) ? chunkTickRadius : randRange; + // odds of growth happening vs growth happening in vanilla + this.growthOdds = this.modifiedOdds = Math.max( 35, Math.min( 100, ( ( chunksPerPlayer + 1 ) * 100F ) / 15F ) ); + // Spigot end + for (i = 0; i < this.players.size(); ++i) { + entityhuman = this.players.get(i); + j = MathHelper.floor(entityhuman.locX / 16.0D); + k = MathHelper.floor(entityhuman.locZ / 16.0D); + l = this.q(); + + // Spigot start - Always update the chunk the player is on + long key = chunkToKey( j, k ); + int existingPlayers = Math.max( 0, chunkTickList.get( key ) ); // filter out -1 + chunkTickList.put( key, (short) ( existingPlayers + 1 ) ); + + // Check and see if we update the chunks surrounding the player this tick + for ( int chunk = 0; chunk < chunksPerPlayer; chunk++ ) + { + int dx = ( random.nextBoolean() ? 1 : -1 ) * random.nextInt( randRange ); + int dz = ( random.nextBoolean() ? 1 : -1 ) * random.nextInt( randRange ); + long hash = chunkToKey( dx + j, dz + k ); + if ( !chunkTickList.contains( hash ) && this.chunkProvider.isChunkLoaded(dx + j, dz + k ) ) + { + chunkTickList.put( hash, (short) -1 ); // no players + } + } + } + // Spigot End + } + + this.methodProfiler.b(); + if (this.L > 0) { + --this.L; + } + + this.methodProfiler.a("playerCheckLight"); + if (spigotConfig.randomLightUpdates && !this.players.isEmpty()) { // Spigot + i = this.random.nextInt(this.players.size()); + entityhuman = this.players.get(i); + j = MathHelper.floor(entityhuman.locX) + this.random.nextInt(11) - 5; + k = MathHelper.floor(entityhuman.locY) + this.random.nextInt(11) - 5; + l = MathHelper.floor(entityhuman.locZ) + this.random.nextInt(11) - 5; + this.x(new BlockPosition(j, k, l)); + } + + this.methodProfiler.b(); + } + + protected abstract int q(); + + protected void a(int i, int j, Chunk chunk) { + this.methodProfiler.c("moodSound"); + if (!this.paperSpigotConfig.disableMoodSounds && this.L == 0 && !this.isClientSide) { // PaperSpigot - Disable mood sounds + this.m = this.m * 3 + 1013904223; + int k = this.m >> 2; + int l = k & 15; + int i1 = k >> 8 & 15; + int j1 = k >> 16 & 255; + BlockPosition blockposition = new BlockPosition(l, j1, i1); + Block block = chunk.getType(blockposition); + + l += i; + i1 += j; + if (block.getMaterial() == Material.AIR && this.k(blockposition) <= this.random.nextInt(8) && this.b(EnumSkyBlock.SKY, blockposition) <= 0) { + EntityHuman entityhuman = this.findNearbyPlayer((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D, 8.0D); + + if (entityhuman != null && entityhuman.e((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D) > 4.0D) { + this.makeSound((double) l + 0.5D, (double) j1 + 0.5D, (double) i1 + 0.5D, "ambient.cave.cave", 0.7F, 0.8F + this.random.nextFloat() * 0.2F); + this.L = this.random.nextInt(12000) + 6000; + } + } + } + + this.methodProfiler.c("checkLight"); + chunk.m(); + } + + protected void h() { + this.D(); + } + + public void a(Block block, BlockPosition blockposition, Random random) { + this.e = true; + block.b(this, blockposition, this.getType(blockposition), random); + this.e = false; + } + + public boolean v(BlockPosition blockposition) { + return this.e(blockposition, false); + } + + public boolean w(BlockPosition blockposition) { + return this.e(blockposition, true); + } + + public boolean e(BlockPosition blockposition, boolean flag) { + BiomeBase biomebase = this.getBiome(blockposition); + float f = biomebase.a(blockposition); + + if (f > 0.15F) { + return false; + } else { + if (blockposition.getY() >= 0 && blockposition.getY() < 256 && this.b(EnumSkyBlock.BLOCK, blockposition) < 10) { + IBlockData iblockdata = this.getType(blockposition); + Block block = iblockdata.getBlock(); + + if ((block == Blocks.WATER || block == Blocks.FLOWING_WATER) && iblockdata.get(BlockFluids.LEVEL).intValue() == 0) { + if (!flag) { + return true; + } + + boolean flag1 = this.F(blockposition.west()) && this.F(blockposition.east()) && this.F(blockposition.north()) && this.F(blockposition.south()); + + return !flag1; + } + } + + return false; + } + } + + private boolean F(BlockPosition blockposition) { + return this.getType(blockposition).getBlock().getMaterial() == Material.WATER; + } + + public boolean f(BlockPosition blockposition, boolean flag) { + BiomeBase biomebase = this.getBiome(blockposition); + float f = biomebase.a(blockposition); + + if (f > 0.15F) { + return false; + } else if (!flag) { + return true; + } else { + if (blockposition.getY() >= 0 && blockposition.getY() < 256 && this.b(EnumSkyBlock.BLOCK, blockposition) < 10) { + Block block = this.getType(blockposition).getBlock(); + + return block.getMaterial() == Material.AIR && Blocks.SNOW_LAYER.canPlace(this, blockposition); + } + + return false; + } + } + + public boolean x(BlockPosition blockposition) { + boolean flag = false; + + if (!this.worldProvider.o()) { + flag |= this.updateLight(EnumSkyBlock.SKY, blockposition); // PaperSpigot - Asynchronous lighting updates + } + + flag |= this.updateLight(EnumSkyBlock.BLOCK, blockposition); // PaperSpigot - Asynchronous lighting updates + return flag; + } + + private int a(BlockPosition blockposition, EnumSkyBlock enumskyblock) { + if (enumskyblock == EnumSkyBlock.SKY && this.i(blockposition)) { + return 15; + } else { + Block block = this.getType(blockposition).getBlock(); + int i = enumskyblock == EnumSkyBlock.SKY ? 0 : block.r(); + int j = block.p(); + + if (j >= 15 && block.r() > 0) { + j = 1; + } + + if (j < 1) { + j = 1; + } + + if (j >= 15) { + return 0; + } else if (i >= 14) { + return i; + } else { + EnumDirection[] aenumdirection = EnumDirection.values(); + int k = aenumdirection.length; + + for (int l = 0; l < k; ++l) { + EnumDirection enumdirection = aenumdirection[l]; + BlockPosition blockposition1 = blockposition.shift(enumdirection); + int i1 = this.b(enumskyblock, blockposition1) - j; + + if (i1 > i) { + i = i1; + } + + if (i >= 14) { + return i; + } + } + + return i; + } + } + } + + public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition, Chunk chunk, List neighbors) { // PaperSpigot + // CraftBukkit start - Use neighbor cache instead of looking up + //Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); + if (chunk == null /*|| !chunk.areNeighborsLoaded(1)*/ /*!this.areChunksLoaded(blockposition, 17, false)*/) { + // CraftBukkit end + return false; + } else { + int i = 0; + int j = 0; + + this.methodProfiler.a("getBrightness"); + int k = this.b(enumskyblock, blockposition); + int l = this.a(blockposition, enumskyblock); + int i1 = blockposition.getX(); + int j1 = blockposition.getY(); + int k1 = blockposition.getZ(); + int l1; + int i2; + int j2; + int k2; + int l2; + int i3; + int j3; + int k3; + + if (l > k) { + this.H[j++] = 133152; + } else if (l < k) { + this.H[j++] = 133152 | k << 18; + + while (i < j) { + l1 = this.H[i++]; + i2 = (l1 & 63) - 32 + i1; + j2 = (l1 >> 6 & 63) - 32 + j1; + k2 = (l1 >> 12 & 63) - 32 + k1; + int l3 = l1 >> 18 & 15; + BlockPosition blockposition1 = new BlockPosition(i2, j2, k2); + + l2 = this.b(enumskyblock, blockposition1); + if (l2 == l3) { + this.a(enumskyblock, blockposition1, 0); + if (l3 > 0) { + i3 = MathHelper.a(i2 - i1); + j3 = MathHelper.a(j2 - j1); + k3 = MathHelper.a(k2 - k1); + if (i3 + j3 + k3 < 17) { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + EnumDirection[] aenumdirection = EnumDirection.values(); + int i4 = aenumdirection.length; + + for (int j4 = 0; j4 < i4; ++j4) { + EnumDirection enumdirection = aenumdirection[j4]; + int k4 = i2 + enumdirection.getAdjacentX(); + int l4 = j2 + enumdirection.getAdjacentY(); + int i5 = k2 + enumdirection.getAdjacentZ(); + + blockposition_mutableblockposition.c(k4, l4, i5); + int j5 = Math.max(1, this.getType(blockposition_mutableblockposition).getBlock().p()); + + l2 = this.b(enumskyblock, blockposition_mutableblockposition); + if (l2 == l3 - j5 && j < this.H.length) { + this.H[j++] = k4 - i1 + 32 | l4 - j1 + 32 << 6 | i5 - k1 + 32 << 12 | l3 - j5 << 18; + } + } + } + } + } + } + + i = 0; + } + + this.methodProfiler.b(); + this.methodProfiler.a("checkedPosition < toCheckCount"); + + while (i < j) { + l1 = this.H[i++]; + i2 = (l1 & 63) - 32 + i1; + j2 = (l1 >> 6 & 63) - 32 + j1; + k2 = (l1 >> 12 & 63) - 32 + k1; + BlockPosition blockposition2 = new BlockPosition(i2, j2, k2); + int k5 = this.b(enumskyblock, blockposition2); + + l2 = this.a(blockposition2, enumskyblock); + if (l2 != k5) { + this.a(enumskyblock, blockposition2, l2); + if (l2 > k5) { + i3 = Math.abs(i2 - i1); + j3 = Math.abs(j2 - j1); + k3 = Math.abs(k2 - k1); + boolean flag = j < this.H.length - 6; + + if (i3 + j3 + k3 < 17 && flag) { + if (this.b(enumskyblock, blockposition2.west()) < l2) { + this.H[j++] = i2 - 1 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); + } + + if (this.b(enumskyblock, blockposition2.east()) < l2) { + this.H[j++] = i2 + 1 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); + } + + if (this.b(enumskyblock, blockposition2.down()) < l2) { + this.H[j++] = i2 - i1 + 32 + (j2 - 1 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); + } + + if (this.b(enumskyblock, blockposition2.up()) < l2) { + this.H[j++] = i2 - i1 + 32 + (j2 + 1 - j1 + 32 << 6) + (k2 - k1 + 32 << 12); + } + + if (this.b(enumskyblock, blockposition2.north()) < l2) { + this.H[j++] = i2 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 - 1 - k1 + 32 << 12); + } + + if (this.b(enumskyblock, blockposition2.south()) < l2) { + this.H[j++] = i2 - i1 + 32 + (j2 - j1 + 32 << 6) + (k2 + 1 - k1 + 32 << 12); + } + } + } + } + } + + // PaperSpigot start - Asynchronous light updates + if (chunk.world.paperSpigotConfig.useAsyncLighting) { + chunk.pendingLightUpdates.decrementAndGet(); + if (neighbors != null) { + for (Chunk neighbor : neighbors) { + neighbor.pendingLightUpdates.decrementAndGet(); + } + } + } + // PaperSpigot end + this.methodProfiler.b(); + return true; + } + } + + /** + * PaperSpigot - Asynchronous lighting updates + */ + public boolean updateLight(final EnumSkyBlock enumskyblock, final BlockPosition position) { + int x = position.getX(); + int z = position.getZ(); + final Chunk chunk = this.getChunkIfLoaded(x >> 4, z >> 4); + if (chunk == null || !chunk.areNeighborsLoaded(1)) { + return false; + } + + if (!chunk.world.paperSpigotConfig.useAsyncLighting) { + return this.c(enumskyblock, position, chunk, null); + } + + chunk.pendingLightUpdates.incrementAndGet(); + chunk.lightUpdateTime = chunk.world.getTime(); + + final List neighbors = new ArrayList(); + for (int cx = (x >> 4) - 1; cx <= (x >> 4) + 1; ++cx) { + for (int cz = (z >> 4) - 1; cz <= (z >> 4) + 1; ++cz) { + if (cx != x >> 4 && cz != z >> 4) { + Chunk neighbor = this.getChunkIfLoaded(cx, cz); + if (neighbor != null) { + neighbor.pendingLightUpdates.incrementAndGet(); + neighbor.lightUpdateTime = chunk.world.getTime(); + neighbors.add(neighbor); + } + } + } + } + + if (!Bukkit.isPrimaryThread()) { + return this.c(enumskyblock, position, chunk, neighbors); + } + + lightingExecutor.submit(new Runnable() { + @Override + public void run() { + World.this.c(enumskyblock, position, chunk, neighbors); + } + }); + return true; + } + + public boolean a(boolean flag) { + return false; + } + + public List a(Chunk chunk, boolean flag) { + return null; + } + + public List a(StructureBoundingBox structureboundingbox, boolean flag) { + return null; + } + + public List getEntities(Entity entity, AxisAlignedBB axisalignedbb) { + return this.a(entity, axisalignedbb, IEntitySelector.d); + } + + public List a(Entity entity, AxisAlignedBB axisalignedbb, Predicate predicate) { + ArrayList arraylist = Lists.newArrayList(); + int i = MathHelper.floor((axisalignedbb.a - 2.0D) / 16.0D); + int j = MathHelper.floor((axisalignedbb.d + 2.0D) / 16.0D); + int k = MathHelper.floor((axisalignedbb.c - 2.0D) / 16.0D); + int l = MathHelper.floor((axisalignedbb.f + 2.0D) / 16.0D); + + for (int i1 = i; i1 <= j; ++i1) { + for (int j1 = k; j1 <= l; ++j1) { + if (this.isChunkLoaded(i1, j1, true)) { + this.getChunkAt(i1, j1).a(entity, axisalignedbb, arraylist, predicate); + } + } + } + + return arraylist; + } + + public List a(Class oclass, Predicate predicate) { + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = this.entityList.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply((T) entity)) { // CraftBukkit - fix decompile error + arraylist.add(entity); + } + } + + return arraylist; + } + + public List b(Class oclass, Predicate predicate) { + ArrayList arraylist = Lists.newArrayList(); + Iterator iterator = this.players.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply((T) entity)) { // CraftBukkit - fix decompile error + arraylist.add(entity); + } + } + + return arraylist; + } + + public List a(Class oclass, AxisAlignedBB axisalignedbb) { + return this.a(oclass, axisalignedbb, IEntitySelector.d); + } + + public List a(Class oclass, AxisAlignedBB axisalignedbb, Predicate predicate) { + int i = MathHelper.floor((axisalignedbb.a - 2.0D) / 16.0D); + int j = MathHelper.floor((axisalignedbb.d + 2.0D) / 16.0D); + int k = MathHelper.floor((axisalignedbb.c - 2.0D) / 16.0D); + int l = MathHelper.floor((axisalignedbb.f + 2.0D) / 16.0D); + ArrayList arraylist = Lists.newArrayList(); + + for (int i1 = i; i1 <= j; ++i1) { + for (int j1 = k; j1 <= l; ++j1) { + if (this.isChunkLoaded(i1, j1, true)) { + this.getChunkAt(i1, j1).a(oclass, axisalignedbb, arraylist, predicate); + } + } + } + + return arraylist; + } + + public T a(Class oclass, AxisAlignedBB axisalignedbb, T t0) { + List list = this.a(oclass, axisalignedbb); + Entity entity = null; + double d0 = Double.MAX_VALUE; + + for (int i = 0; i < list.size(); ++i) { + Entity entity1 = (Entity) list.get(i); + + if (entity1 != t0 && IEntitySelector.d.apply(entity1)) { + double d1 = t0.h(entity1); + + if (d1 <= d0) { + entity = entity1; + d0 = d1; + } + } + } + + return (T) entity; // CraftBukkit fix decompile error + } + + public Entity a(int i) { + return this.entitiesById.get(i); + } + + public void b(BlockPosition blockposition, TileEntity tileentity) { + if (this.isLoaded(blockposition)) { + this.getChunkAtWorldCoords(blockposition).e(); + } + + } + + public int a(Class oclass) { + int i = 0; + Iterator iterator = this.entityList.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + // CraftBukkit start - Split out persistent check, don't apply it to special persistent mobs + if (entity instanceof EntityInsentient) { + EntityInsentient entityinsentient = (EntityInsentient) entity; + if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) { + continue; + } + } + + if (oclass.isAssignableFrom(entity.getClass())) { + // if ((!(entity instanceof EntityInsentient) || !((EntityInsentient) entity).isPersistent()) && oclass.isAssignableFrom(entity.getClass())) { + // CraftBukkit end + ++i; + } + } + + return i; + } + + public void b(Collection collection) { + org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot + // CraftBukkit start + // this.entityList.addAll(collection); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) { + Entity entity = (Entity) iterator.next(); + + if (entity == null) { + continue; + } + this.entityList.add(entity); + // CraftBukkit end + this.a(entity); + } + + } + + public void c(Collection collection) { + this.g.addAll(collection); + } + + public boolean a(Block block, BlockPosition blockposition, boolean flag, EnumDirection enumdirection, Entity entity, ItemStack itemstack) { + Block block1 = this.getType(blockposition).getBlock(); + AxisAlignedBB axisalignedbb = flag ? null : block.a(this, blockposition, block.getBlockData()); + + // CraftBukkit start - store default return + boolean defaultReturn = (axisalignedbb == null || this.a(axisalignedbb, entity)) && (block1.getMaterial() == Material.ORIENTABLE && block == Blocks.ANVIL || block1.getMaterial().isReplaceable() && block.canPlace(this, blockposition, enumdirection, itemstack)); + BlockCanBuildEvent event = new BlockCanBuildEvent(this.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftMagicNumbers.getId(block), defaultReturn); + this.getServer().getPluginManager().callEvent(event); + + return event.isBuildable(); + // CraftBukkit end + } + + public int F() { + return this.a; + } + + public void b(int i) { + this.a = i; + } + + public int getBlockPower(BlockPosition blockposition, EnumDirection enumdirection) { + IBlockData iblockdata = this.getType(blockposition); + + return iblockdata.getBlock().b(this, blockposition, iblockdata, enumdirection); + } + + public WorldType G() { + return this.worldData.getType(); + } + + public int getBlockPower(BlockPosition blockposition) { + byte b0 = 0; + int i = Math.max(b0, this.getBlockPower(blockposition.down(), EnumDirection.DOWN)); + + if (i >= 15) { + return i; + } else { + i = Math.max(i, this.getBlockPower(blockposition.up(), EnumDirection.UP)); + if (i >= 15) { + return i; + } else { + i = Math.max(i, this.getBlockPower(blockposition.north(), EnumDirection.NORTH)); + if (i >= 15) { + return i; + } else { + i = Math.max(i, this.getBlockPower(blockposition.south(), EnumDirection.SOUTH)); + if (i >= 15) { + return i; + } else { + i = Math.max(i, this.getBlockPower(blockposition.west(), EnumDirection.WEST)); + if (i >= 15) { + return i; + } else { + i = Math.max(i, this.getBlockPower(blockposition.east(), EnumDirection.EAST)); + return i >= 15 ? i : i; + } + } + } + } + } + } + + public boolean isBlockFacePowered(BlockPosition blockposition, EnumDirection enumdirection) { + return this.getBlockFacePower(blockposition, enumdirection) > 0; + } + + public int getBlockFacePower(BlockPosition blockposition, EnumDirection enumdirection) { + IBlockData iblockdata = this.getType(blockposition); + Block block = iblockdata.getBlock(); + + return block.isOccluding() ? this.getBlockPower(blockposition) : block.a(this, blockposition, iblockdata, enumdirection); + } + + public boolean isBlockIndirectlyPowered(BlockPosition blockposition) { + return this.getBlockFacePower(blockposition.down(), EnumDirection.DOWN) > 0 || (this.getBlockFacePower(blockposition.up(), EnumDirection.UP) > 0 || (this.getBlockFacePower(blockposition.north(), EnumDirection.NORTH) > 0 || (this.getBlockFacePower(blockposition.south(), EnumDirection.SOUTH) > 0 || (this.getBlockFacePower(blockposition.west(), EnumDirection.WEST) > 0 || this.getBlockFacePower(blockposition.east(), EnumDirection.EAST) > 0)))); + } + + public int A(BlockPosition blockposition) { + int i = 0; + EnumDirection[] aenumdirection = EnumDirection.values(); + int j = aenumdirection.length; + + for (int k = 0; k < j; ++k) { + EnumDirection enumdirection = aenumdirection[k]; + int l = this.getBlockFacePower(blockposition.shift(enumdirection), enumdirection); + + if (l >= 15) { + return 15; + } + + if (l > i) { + i = l; + } + } + + return i; + } + + public EntityHuman findNearbyPlayer(Entity entity, double d0) { + return this.findNearbyPlayer(entity.locX, entity.locY, entity.locZ, d0); + } + + public EntityHuman findNearbyPlayer(double d0, double d1, double d2, double d3) { + double d4 = -1.0D; + EntityHuman entityhuman = null; + + for (int i = 0; i < this.players.size(); ++i) { + EntityHuman entityhuman1 = this.players.get(i); + // CraftBukkit start - Fixed an NPE + if (entityhuman1 == null || entityhuman1.dead) { + continue; + } + // CraftBukkit end + + if (IEntitySelector.d.apply(entityhuman1)) { + double d5 = entityhuman1.e(d0, d1, d2); + + if ((d3 < 0.0D || d5 < d3 * d3) && (d4 == -1.0D || d5 < d4)) { + d4 = d5; + entityhuman = entityhuman1; + } + } + } + + return entityhuman; + } + + public boolean isPlayerNearby(double d0, double d1, double d2, double d3) { + for (int i = 0; i < this.players.size(); ++i) { + EntityHuman entityhuman = this.players.get(i); + + if (IEntitySelector.d.apply(entityhuman)) { + double d4 = entityhuman.e(d0, d1, d2); + + if (d3 < 0.0D || d4 < d3 * d3) { + return true; + } + } + } + + return false; + } + + // PaperSpigot start - Modified methods for affects spawning + public EntityHuman findNearbyPlayerWhoAffectsSpawning(Entity entity, double d0) { + return this.findNearbyPlayerWhoAffectsSpawning(entity.locX, entity.locY, entity.locZ, d0); + } + + public EntityHuman findNearbyPlayerWhoAffectsSpawning(double d0, double d1, double d2, double d3) { + double d4 = -1.0D; + EntityHuman entityhuman = null; + + for (int i = 0; i < this.players.size(); ++i) { + EntityHuman entityhuman1 = this.players.get(i); + // CraftBukkit start - Fixed an NPE + if (entityhuman1 == null || entityhuman1.dead || !entityhuman1.affectsSpawning) { + continue; + } + // CraftBukkit end + + if (IEntitySelector.d.apply(entityhuman1)) { + double d5 = entityhuman1.e(d0, d1, d2); + + if ((d3 < 0.0D || d5 < d3 * d3) && (d4 == -1.0D || d5 < d4)) { + d4 = d5; + entityhuman = entityhuman1; + } + } + } + + return entityhuman; + } + + public boolean isPlayerNearbyWhoAffectsSpawning(double d0, double d1, double d2, double d3) { + for (int i = 0; i < this.players.size(); ++i) { + EntityHuman entityhuman = this.players.get(i); + + if (IEntitySelector.d.apply(entityhuman)) { + double d4 = entityhuman.e(d0, d1, d2); + + if (d3 < 0.0D || d4 < d3 * d3 && entityhuman.affectsSpawning) { + return true; + } + } + } + + return false; + } + // PaperSpigot end + + public EntityHuman a(String s) { + for (int i = 0; i < this.players.size(); ++i) { + EntityHuman entityhuman = this.players.get(i); + + if (s.equals(entityhuman.getName())) { + return entityhuman; + } + } + + return null; + } + + public EntityHuman b(UUID uuid) { + for (int i = 0; i < this.players.size(); ++i) { + EntityHuman entityhuman = this.players.get(i); + + if (uuid.equals(entityhuman.getUniqueID())) { + return entityhuman; + } + } + + return null; + } + + public void checkSession() throws ExceptionWorldConflict { + this.dataManager.checkSession(); + } + + public long getSeed() { + return this.worldData.getSeed(); + } + + public long getTime() { + return this.worldData.getTime(); + } + + public long getDayTime() { + return this.worldData.getDayTime(); + } + + public void setDayTime(long i) { + this.worldData.setDayTime(i); + } + + public BlockPosition getSpawn() { + BlockPosition blockposition = new BlockPosition(this.worldData.c(), this.worldData.d(), this.worldData.e()); + + if (!this.getWorldBorder().a(blockposition)) { + blockposition = this.getHighestBlockYAt(new BlockPosition(this.getWorldBorder().getCenterX(), 0.0D, this.getWorldBorder().getCenterZ())); + } + + return blockposition; + } + + public void B(BlockPosition blockposition) { + this.worldData.setSpawn(blockposition); + } + + public boolean a(EntityHuman entityhuman, BlockPosition blockposition) { + return true; + } + + public void broadcastEntityEffect(Entity entity, byte b0) {} + + public IChunkProvider N() { + return this.chunkProvider; + } + + public void playBlockAction(BlockPosition blockposition, Block block, int i, int j) { + block.a(this, blockposition, this.getType(blockposition), i, j); + } + + public IDataManager getDataManager() { + return this.dataManager; + } + + public WorldData getWorldData() { + return this.worldData; + } + + public GameRules getGameRules() { + return this.worldData.x(); + } + + public void everyoneSleeping() {} + + // CraftBukkit start + // Calls the method that checks to see if players are sleeping + // Called by CraftPlayer.setPermanentSleeping() + public void checkSleepStatus() { + if (!this.isClientSide) { + this.everyoneSleeping(); + } + } + // CraftBukkit end + + public float h(float f) { + return (this.q + (this.r - this.q) * f) * this.j(f); + } + + public float j(float f) { + return this.o + (this.p - this.o) * f; + } + + public boolean R() { + return (double) this.h(1.0F) > 0.9D; + } + + public boolean S() { + return (double) this.j(1.0F) > 0.2D; + } + + public boolean isRainingAt(BlockPosition blockposition) { + if (!this.S()) { + return false; + } else if (!this.i(blockposition)) { + return false; + } else if (this.q(blockposition).getY() > blockposition.getY()) { + return false; + } else { + BiomeBase biomebase = this.getBiome(blockposition); + + return !biomebase.d() && (!this.f(blockposition, false) && biomebase.e()); + } + } + + public boolean D(BlockPosition blockposition) { + BiomeBase biomebase = this.getBiome(blockposition); + + return biomebase.f(); + } + + public PersistentCollection T() { + return this.worldMaps; + } + + public void a(String s, PersistentBase persistentbase) { + this.worldMaps.a(s, persistentbase); + } + + public PersistentBase a(Class oclass, String s) { + return this.worldMaps.get(oclass, s); + } + + public int b(String s) { + return this.worldMaps.a(s); + } + + public void a(int i, BlockPosition blockposition, int j) { + for (int k = 0; k < this.u.size(); ++k) { + this.u.get(k).a(i, blockposition, j); + } + + } + + public void triggerEffect(int i, BlockPosition blockposition, int j) { + this.a(null, i, blockposition, j); + } + + public void a(EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { + try { + for (int k = 0; k < this.u.size(); ++k) { + this.u.get(k).a(entityhuman, i, blockposition, j); + } + + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Playing level event"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Level event being played"); + + crashreportsystemdetails.a("Block coordinates", CrashReportSystemDetails.a(blockposition)); + crashreportsystemdetails.a("Event source", entityhuman); + crashreportsystemdetails.a("Event type", Integer.valueOf(i)); + crashreportsystemdetails.a("Event data", Integer.valueOf(j)); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + + public int getHeight() { + return 256; + } + + public int V() { + return this.worldProvider.o() ? 128 : 256; + } + + public Random a(int i, int j, int k) { + long l = (long) i * 341873128712L + (long) j * 132897987541L + this.getWorldData().getSeed() + (long) k; + + this.random.setSeed(l); + return this.random; + } + + public BlockPosition a(String s, BlockPosition blockposition) { + return this.N().findNearestMapFeature(this, s, blockposition); + } + + public CrashReportSystemDetails a(CrashReport crashreport) { + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Affected level", 1); + + crashreportsystemdetails.a("Level name", this.worldData == null ? "????" : this.worldData.getName()); + crashreportsystemdetails.a("All players", new Callable() { + public String a() { + return World.this.players.size() + " total; " + World.this.players.toString(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Chunk stats", new Callable() { + public String a() { + return World.this.chunkProvider.getName(); + } + + public Object call() throws Exception { + return this.a(); + } + }); + + try { + this.worldData.a(crashreportsystemdetails); + } catch (Throwable throwable) { + crashreportsystemdetails.a("Level Data Unobtainable", throwable); + } + + return crashreportsystemdetails; + } + + public void c(int i, BlockPosition blockposition, int j) { + for (int k = 0; k < this.u.size(); ++k) { + IWorldAccess iworldaccess = this.u.get(k); + + iworldaccess.b(i, blockposition, j); + } + + } + + public Calendar Y() { + if (this.getTime() % 600L == 0L) { + this.K.setTimeInMillis(MinecraftServer.az()); + } + + return this.K; + } + + public Scoreboard getScoreboard() { + return this.scoreboard; + } + + public void updateAdjacentComparators(BlockPosition blockposition, Block block) { + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + BlockPosition blockposition1 = blockposition.shift(enumdirection); + + if (this.isLoaded(blockposition1)) { + IBlockData iblockdata = this.getType(blockposition1); + + if (Blocks.UNPOWERED_COMPARATOR.e(iblockdata.getBlock())) { + iblockdata.getBlock().doPhysics(this, blockposition1, iblockdata, block); + } else if (iblockdata.getBlock().isOccluding()) { + blockposition1 = blockposition1.shift(enumdirection); + iblockdata = this.getType(blockposition1); + if (Blocks.UNPOWERED_COMPARATOR.e(iblockdata.getBlock())) { + iblockdata.getBlock().doPhysics(this, blockposition1, iblockdata, block); + } + } + } + } + + } + + public DifficultyDamageScaler E(BlockPosition blockposition) { + long i = 0L; + float f = 0.0F; + + if (this.isLoaded(blockposition)) { + f = this.y(); + i = this.getChunkAtWorldCoords(blockposition).w(); + } + + return new DifficultyDamageScaler(this.getDifficulty(), this.getDayTime(), i, f); + } + + public EnumDifficulty getDifficulty() { + return this.getWorldData().getDifficulty(); + } + + public int ab() { + return this.I; + } + + public void c(int i) { + this.I = i; + } + + public void d(int i) { + this.J = i; + } + + public boolean ad() { + return this.isLoading; + } + + public PersistentVillage ae() { + return this.villages; + } + + public WorldBorder getWorldBorder() { + return this.N; + } + + public boolean c(int i, int j) { + BlockPosition blockposition = this.getSpawn(); + int k = i * 16 + 8 - blockposition.getX(); + int l = j * 16 + 8 - blockposition.getZ(); + short short0 = 128; + + return k >= -short0 && k <= short0 && l >= -short0 && l <= short0 && this.keepSpawnInMemory; // CraftBukkit - Added 'this.keepSpawnInMemory' + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldBorder.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldBorder.java new file mode 100644 index 0000000..7ea4046 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldBorder.java @@ -0,0 +1,267 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; + +public class WorldBorder { + + private final List a = Lists.newArrayList(); + private double b = 0.0D; + private double c = 0.0D; + private double d = 6.0E7D; + private double e; + private long f; + private long g; + private int h; + private double i; + private double j; + private int k; + private int l; + public WorldServer world; // CraftBukkit + + public WorldBorder() { + this.e = this.d; + this.h = 29999984; + this.i = 0.2D; + this.j = 5.0D; + this.k = 15; + this.l = 5; + } + + public boolean a(BlockPosition blockposition) { + return (double) (blockposition.getX() + 1) > this.b() && (double) blockposition.getX() < this.d() && (double) (blockposition.getZ() + 1) > this.c() && (double) blockposition.getZ() < this.e(); + } + + // CraftBukkit start - split method + public boolean isInBounds(ChunkCoordIntPair chunkcoordintpair) { + return isInBounds(chunkcoordintpair.x, chunkcoordintpair.z); + } + + // Inlined the getters from ChunkCoordIntPair + public boolean isInBounds(long chunkcoords) { + return isInBounds(org.bukkit.craftbukkit.util.LongHash.msw(chunkcoords), org.bukkit.craftbukkit.util.LongHash.lsw(chunkcoords)); + } + + // Inlined the getters from ChunkCoordIntPair + public boolean isInBounds(int x, int z) { + return (double) ((x << 4) + 15) > this.b() && (double) (x << 4) < this.d() && (double) ((z << 4) + 15) > this.c() && (double) (x << 4) < this.e(); + } + + public boolean a(AxisAlignedBB axisalignedbb) { + return axisalignedbb.d > this.b() && axisalignedbb.a < this.d() && axisalignedbb.f > this.c() && axisalignedbb.c < this.e(); + } + + public double a(Entity entity) { + return this.b(entity.locX, entity.locZ); + } + + public double b(double d0, double d1) { + double d2 = d1 - this.c(); + double d3 = this.e() - d1; + double d4 = d0 - this.b(); + double d5 = this.d() - d0; + double d6 = Math.min(d4, d5); + + d6 = Math.min(d6, d2); + return Math.min(d6, d3); + } + + public EnumWorldBorderState getState() { + return this.e < this.d ? EnumWorldBorderState.SHRINKING : (this.e > this.d ? EnumWorldBorderState.GROWING : EnumWorldBorderState.STATIONARY); + } + + public double b() { + double d0 = this.getCenterX() - this.getSize() / 2.0D; + + if (d0 < (double) (-this.h)) { + d0 = (double) (-this.h); + } + + return d0; + } + + public double c() { + double d0 = this.getCenterZ() - this.getSize() / 2.0D; + + if (d0 < (double) (-this.h)) { + d0 = (double) (-this.h); + } + + return d0; + } + + public double d() { + double d0 = this.getCenterX() + this.getSize() / 2.0D; + + if (d0 > (double) this.h) { + d0 = (double) this.h; + } + + return d0; + } + + public double e() { + double d0 = this.getCenterZ() + this.getSize() / 2.0D; + + if (d0 > (double) this.h) { + d0 = (double) this.h; + } + + return d0; + } + + public double getCenterX() { + return this.b; + } + + public double getCenterZ() { + return this.c; + } + + public void setCenter(double d0, double d1) { + this.b = d0; + this.c = d1; + Iterator iterator = this.k().iterator(); + + while (iterator.hasNext()) { + IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); + + iworldborderlistener.a(this, d0, d1); + } + + } + + public double getSize() { + if (this.getState() != EnumWorldBorderState.STATIONARY) { + double d0 = (double) ((float) (System.currentTimeMillis() - this.g) / (float) (this.f - this.g)); + + if (d0 < 1.0D) { + return this.d + (this.e - this.d) * d0; + } + + this.setSize(this.e); + } + + return this.d; + } + + public long i() { + return this.getState() != EnumWorldBorderState.STATIONARY ? this.f - System.currentTimeMillis() : 0L; + } + + public double j() { + return this.e; + } + + public void setSize(double d0) { + this.d = d0; + this.e = d0; + this.f = System.currentTimeMillis(); + this.g = this.f; + Iterator iterator = this.k().iterator(); + + while (iterator.hasNext()) { + IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); + + iworldborderlistener.a(this, d0); + } + + } + + public void transitionSizeBetween(double d0, double d1, long i) { + this.d = d0; + this.e = d1; + this.g = System.currentTimeMillis(); + this.f = this.g + i; + Iterator iterator = this.k().iterator(); + + while (iterator.hasNext()) { + IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); + + iworldborderlistener.a(this, d0, d1, i); + } + + } + + protected List k() { + return Lists.newArrayList(this.a); + } + + public void a(IWorldBorderListener iworldborderlistener) { + if (a.contains(iworldborderlistener)) return; // CraftBukkit + this.a.add(iworldborderlistener); + } + + public void a(int i) { + this.h = i; + } + + public int l() { + return this.h; + } + + public double getDamageBuffer() { + return this.j; + } + + public void setDamageBuffer(double d0) { + this.j = d0; + Iterator iterator = this.k().iterator(); + + while (iterator.hasNext()) { + IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); + + iworldborderlistener.c(this, d0); + } + + } + + public double getDamageAmount() { + return this.i; + } + + public void setDamageAmount(double d0) { + this.i = d0; + Iterator iterator = this.k().iterator(); + + while (iterator.hasNext()) { + IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); + + iworldborderlistener.b(this, d0); + } + + } + + public int getWarningTime() { + return this.k; + } + + public void setWarningTime(int i) { + this.k = i; + Iterator iterator = this.k().iterator(); + + while (iterator.hasNext()) { + IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); + + iworldborderlistener.a(this, i); + } + + } + + public int getWarningDistance() { + return this.l; + } + + public void setWarningDistance(int i) { + this.l = i; + Iterator iterator = this.k().iterator(); + + while (iterator.hasNext()) { + IWorldBorderListener iworldborderlistener = (IWorldBorderListener) iterator.next(); + + iworldborderlistener.b(this, i); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldData.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldData.java new file mode 100644 index 0000000..3a7b22b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldData.java @@ -0,0 +1,711 @@ +package net.minecraft.server; + +import java.util.concurrent.Callable; +// CraftBukkit start +import org.bukkit.Bukkit; +import org.bukkit.event.weather.ThunderChangeEvent; +import org.bukkit.event.weather.WeatherChangeEvent; +// CraftBukkit end + +public class WorldData { + + public static final EnumDifficulty a = EnumDifficulty.NORMAL; + private long b; + private WorldType c; + private String d; + private int e; + private int f; + private int g; + private long h; + private long i; + private long j; + private long k; + private NBTTagCompound l; + private int m; + private String n; + private int o; + private int p; + private boolean q; + private int r; + private boolean s; + private int t; + private WorldSettings.EnumGamemode u; + private boolean v; + private boolean w; + private boolean x; + private boolean y; + private EnumDifficulty z; + private boolean A; + private double B; + private double C; + private double D; + private long E; + private double F; + private double G; + private double H; + private int I; + private int J; + private GameRules K; + public WorldServer world; // CraftBukkit + + protected WorldData() { + this.c = WorldType.NORMAL; + this.d = ""; + this.B = 0.0D; + this.C = 0.0D; + this.D = 6.0E7D; + this.E = 0L; + this.F = 0.0D; + this.G = 5.0D; + this.H = 0.2D; + this.I = 5; + this.J = 15; + this.K = new GameRules(); + } + + public WorldData(NBTTagCompound nbttagcompound) { + this.c = WorldType.NORMAL; + this.d = ""; + this.B = 0.0D; + this.C = 0.0D; + this.D = 6.0E7D; + this.E = 0L; + this.F = 0.0D; + this.G = 5.0D; + this.H = 0.2D; + this.I = 5; + this.J = 15; + this.K = new GameRules(); + this.b = nbttagcompound.getLong("RandomSeed"); + if (nbttagcompound.hasKeyOfType("generatorName", 8)) { + String s = nbttagcompound.getString("generatorName"); + + this.c = WorldType.getType(s); + if (this.c == null) { + this.c = WorldType.NORMAL; + } else if (this.c.f()) { + int i = 0; + + if (nbttagcompound.hasKeyOfType("generatorVersion", 99)) { + i = nbttagcompound.getInt("generatorVersion"); + } + + this.c = this.c.a(i); + } + + if (nbttagcompound.hasKeyOfType("generatorOptions", 8)) { + this.d = nbttagcompound.getString("generatorOptions"); + } + } + + this.u = WorldSettings.EnumGamemode.getById(nbttagcompound.getInt("GameType")); + if (nbttagcompound.hasKeyOfType("MapFeatures", 99)) { + this.v = nbttagcompound.getBoolean("MapFeatures"); + } else { + this.v = true; + } + + this.e = nbttagcompound.getInt("SpawnX"); + this.f = nbttagcompound.getInt("SpawnY"); + this.g = nbttagcompound.getInt("SpawnZ"); + this.h = nbttagcompound.getLong("Time"); + if (nbttagcompound.hasKeyOfType("DayTime", 99)) { + this.i = nbttagcompound.getLong("DayTime"); + } else { + this.i = this.h; + } + + this.j = nbttagcompound.getLong("LastPlayed"); + this.k = nbttagcompound.getLong("SizeOnDisk"); + this.n = nbttagcompound.getString("LevelName"); + this.o = nbttagcompound.getInt("version"); + this.p = nbttagcompound.getInt("clearWeatherTime"); + this.r = nbttagcompound.getInt("rainTime"); + this.q = nbttagcompound.getBoolean("raining"); + this.t = nbttagcompound.getInt("thunderTime"); + this.s = nbttagcompound.getBoolean("thundering"); + this.w = nbttagcompound.getBoolean("hardcore"); + if (nbttagcompound.hasKeyOfType("initialized", 99)) { + this.y = nbttagcompound.getBoolean("initialized"); + } else { + this.y = true; + } + + if (nbttagcompound.hasKeyOfType("allowCommands", 99)) { + this.x = nbttagcompound.getBoolean("allowCommands"); + } else { + this.x = this.u == WorldSettings.EnumGamemode.CREATIVE; + } + + if (nbttagcompound.hasKeyOfType("Player", 10)) { + this.l = nbttagcompound.getCompound("Player"); + this.m = this.l.getInt("Dimension"); + } + + if (nbttagcompound.hasKeyOfType("GameRules", 10)) { + this.K.a(nbttagcompound.getCompound("GameRules")); + } + + if (nbttagcompound.hasKeyOfType("Difficulty", 99)) { + this.z = EnumDifficulty.getById(nbttagcompound.getByte("Difficulty")); + } + + if (nbttagcompound.hasKeyOfType("DifficultyLocked", 1)) { + this.A = nbttagcompound.getBoolean("DifficultyLocked"); + } + + if (nbttagcompound.hasKeyOfType("BorderCenterX", 99)) { + this.B = nbttagcompound.getDouble("BorderCenterX"); + } + + if (nbttagcompound.hasKeyOfType("BorderCenterZ", 99)) { + this.C = nbttagcompound.getDouble("BorderCenterZ"); + } + + if (nbttagcompound.hasKeyOfType("BorderSize", 99)) { + this.D = nbttagcompound.getDouble("BorderSize"); + } + + if (nbttagcompound.hasKeyOfType("BorderSizeLerpTime", 99)) { + this.E = nbttagcompound.getLong("BorderSizeLerpTime"); + } + + if (nbttagcompound.hasKeyOfType("BorderSizeLerpTarget", 99)) { + this.F = nbttagcompound.getDouble("BorderSizeLerpTarget"); + } + + if (nbttagcompound.hasKeyOfType("BorderSafeZone", 99)) { + this.G = nbttagcompound.getDouble("BorderSafeZone"); + } + + if (nbttagcompound.hasKeyOfType("BorderDamagePerBlock", 99)) { + this.H = nbttagcompound.getDouble("BorderDamagePerBlock"); + } + + if (nbttagcompound.hasKeyOfType("BorderWarningBlocks", 99)) { + this.I = nbttagcompound.getInt("BorderWarningBlocks"); + } + + if (nbttagcompound.hasKeyOfType("BorderWarningTime", 99)) { + this.J = nbttagcompound.getInt("BorderWarningTime"); + } + + } + + public WorldData(WorldSettings worldsettings, String s) { + this.c = WorldType.NORMAL; + this.d = ""; + this.B = 0.0D; + this.C = 0.0D; + this.D = 6.0E7D; + this.E = 0L; + this.F = 0.0D; + this.G = 5.0D; + this.H = 0.2D; + this.I = 5; + this.J = 15; + this.K = new GameRules(); + this.a(worldsettings); + this.n = s; + this.z = WorldData.a; + this.y = false; + } + + public void a(WorldSettings worldsettings) { + this.b = worldsettings.d(); + this.u = worldsettings.e(); + this.v = worldsettings.g(); + this.w = worldsettings.f(); + this.c = worldsettings.h(); + this.d = worldsettings.j(); + this.x = worldsettings.i(); + } + + public WorldData(WorldData worlddata) { + this.c = WorldType.NORMAL; + this.d = ""; + this.B = 0.0D; + this.C = 0.0D; + this.D = 6.0E7D; + this.E = 0L; + this.F = 0.0D; + this.G = 5.0D; + this.H = 0.2D; + this.I = 5; + this.J = 15; + this.K = new GameRules(); + this.b = worlddata.b; + this.c = worlddata.c; + this.d = worlddata.d; + this.u = worlddata.u; + this.v = worlddata.v; + this.e = worlddata.e; + this.f = worlddata.f; + this.g = worlddata.g; + this.h = worlddata.h; + this.i = worlddata.i; + this.j = worlddata.j; + this.k = worlddata.k; + this.l = worlddata.l; + this.m = worlddata.m; + this.n = worlddata.n; + this.o = worlddata.o; + this.r = worlddata.r; + this.q = worlddata.q; + this.t = worlddata.t; + this.s = worlddata.s; + this.w = worlddata.w; + this.x = worlddata.x; + this.y = worlddata.y; + this.K = worlddata.K; + this.z = worlddata.z; + this.A = worlddata.A; + this.B = worlddata.B; + this.C = worlddata.C; + this.D = worlddata.D; + this.E = worlddata.E; + this.F = worlddata.F; + this.G = worlddata.G; + this.H = worlddata.H; + this.J = worlddata.J; + this.I = worlddata.I; + } + + public NBTTagCompound a() { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + this.a(nbttagcompound, this.l); + return nbttagcompound; + } + + public NBTTagCompound a(NBTTagCompound nbttagcompound) { + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + this.a(nbttagcompound1, nbttagcompound); + return nbttagcompound1; + } + + private void a(NBTTagCompound nbttagcompound, NBTTagCompound nbttagcompound1) { + nbttagcompound.setLong("RandomSeed", this.b); + nbttagcompound.setString("generatorName", this.c.name()); + nbttagcompound.setInt("generatorVersion", this.c.getVersion()); + nbttagcompound.setString("generatorOptions", this.d); + nbttagcompound.setInt("GameType", this.u.getId()); + nbttagcompound.setBoolean("MapFeatures", this.v); + nbttagcompound.setInt("SpawnX", this.e); + nbttagcompound.setInt("SpawnY", this.f); + nbttagcompound.setInt("SpawnZ", this.g); + nbttagcompound.setLong("Time", this.h); + nbttagcompound.setLong("DayTime", this.i); + nbttagcompound.setLong("SizeOnDisk", this.k); + nbttagcompound.setLong("LastPlayed", MinecraftServer.az()); + nbttagcompound.setString("LevelName", this.n); + nbttagcompound.setInt("version", this.o); + nbttagcompound.setInt("clearWeatherTime", this.p); + nbttagcompound.setInt("rainTime", this.r); + nbttagcompound.setBoolean("raining", this.q); + nbttagcompound.setInt("thunderTime", this.t); + nbttagcompound.setBoolean("thundering", this.s); + nbttagcompound.setBoolean("hardcore", this.w); + nbttagcompound.setBoolean("allowCommands", this.x); + nbttagcompound.setBoolean("initialized", this.y); + nbttagcompound.setDouble("BorderCenterX", this.B); + nbttagcompound.setDouble("BorderCenterZ", this.C); + nbttagcompound.setDouble("BorderSize", this.D); + nbttagcompound.setLong("BorderSizeLerpTime", this.E); + nbttagcompound.setDouble("BorderSafeZone", this.G); + nbttagcompound.setDouble("BorderDamagePerBlock", this.H); + nbttagcompound.setDouble("BorderSizeLerpTarget", this.F); + nbttagcompound.setDouble("BorderWarningBlocks", (double) this.I); + nbttagcompound.setDouble("BorderWarningTime", (double) this.J); + if (this.z != null) { + nbttagcompound.setByte("Difficulty", (byte) this.z.a()); + } + + nbttagcompound.setBoolean("DifficultyLocked", this.A); + nbttagcompound.set("GameRules", this.K.a()); + if (nbttagcompound1 != null) { + nbttagcompound.set("Player", nbttagcompound1); + } + + } + + public long getSeed() { + return this.b; + } + + public int c() { + return this.e; + } + + public int d() { + return this.f; + } + + public int e() { + return this.g; + } + + public long getTime() { + return this.h; + } + + public long getDayTime() { + return this.i; + } + + public NBTTagCompound i() { + return this.l; + } + + public void setTime(long i) { + this.h = i; + } + + public void setDayTime(long i) { + this.i = i; + } + + public void setSpawn(BlockPosition blockposition) { + this.e = blockposition.getX(); + this.f = blockposition.getY(); + this.g = blockposition.getZ(); + } + + public String getName() { + return this.n; + } + + public void a(String s) { + this.n = s; + } + + public int l() { + return this.o; + } + + public void e(int i) { + this.o = i; + } + + public int A() { + return this.p; + } + + public void i(int i) { + this.p = i; + } + + public boolean isThundering() { + return this.s; + } + + public void setThundering(boolean flag) { + // CraftBukkit start + org.bukkit.World world = Bukkit.getWorld(getName()); + if (world != null) { + ThunderChangeEvent thunder = new ThunderChangeEvent(world, flag); + Bukkit.getServer().getPluginManager().callEvent(thunder); + if (thunder.isCancelled()) { + return; + } + + setThunderDuration(0); // Will force a time reset + } + // CraftBukkit end + this.s = flag; + } + + public int getThunderDuration() { + return this.t; + } + + public void setThunderDuration(int i) { + this.t = i; + } + + public boolean hasStorm() { + return this.q; + } + + public void setStorm(boolean flag) { + // CraftBukkit start + org.bukkit.World world = Bukkit.getWorld(getName()); + if (world != null) { + WeatherChangeEvent weather = new WeatherChangeEvent(world, flag); + Bukkit.getServer().getPluginManager().callEvent(weather); + if (weather.isCancelled()) { + return; + } + + setWeatherDuration(0); // Will force a time reset + } + // CraftBukkit end + this.q = flag; + } + + public int getWeatherDuration() { + return this.r; + } + + public void setWeatherDuration(int i) { + this.r = i; + } + + public WorldSettings.EnumGamemode getGameType() { + return this.u; + } + + public boolean shouldGenerateMapFeatures() { + return this.v; + } + + public void f(boolean flag) { + this.v = flag; + } + + public void setGameType(WorldSettings.EnumGamemode worldsettings_enumgamemode) { + this.u = worldsettings_enumgamemode; + } + + public boolean isHardcore() { + return this.w; + } + + public void g(boolean flag) { + this.w = flag; + } + + public WorldType getType() { + return this.c; + } + + public void a(WorldType worldtype) { + this.c = worldtype; + } + + public String getGeneratorOptions() { + return this.d; + } + + public boolean v() { + return this.x; + } + + public void c(boolean flag) { + this.x = flag; + } + + public boolean w() { + return this.y; + } + + public void d(boolean flag) { + this.y = flag; + } + + public GameRules x() { + return this.K; + } + + public double C() { + return this.B; + } + + public double D() { + return this.C; + } + + public double E() { + return this.D; + } + + public void a(double d0) { + this.D = d0; + } + + public long F() { + return this.E; + } + + public void e(long i) { + this.E = i; + } + + public double G() { + return this.F; + } + + public void b(double d0) { + this.F = d0; + } + + public void c(double d0) { + this.C = d0; + } + + public void d(double d0) { + this.B = d0; + } + + public double H() { + return this.G; + } + + public void e(double d0) { + this.G = d0; + } + + public double I() { + return this.H; + } + + public void f(double d0) { + this.H = d0; + } + + public int J() { + return this.I; + } + + public int K() { + return this.J; + } + + public void j(int i) { + this.I = i; + } + + public void k(int i) { + this.J = i; + } + + public EnumDifficulty getDifficulty() { + return this.z; + } + + public void setDifficulty(EnumDifficulty enumdifficulty) { + this.z = enumdifficulty; + // CraftBukkit start + PacketPlayOutServerDifficulty packet = new PacketPlayOutServerDifficulty(this.getDifficulty(), this.isDifficultyLocked()); + for (EntityPlayer player : (java.util.List) (java.util.List) world.players) { + player.playerConnection.sendPacket(packet); + } + // CraftBukkit end + } + + public boolean isDifficultyLocked() { + return this.A; + } + + public void e(boolean flag) { + this.A = flag; + } + + public void a(CrashReportSystemDetails crashreportsystemdetails) { + crashreportsystemdetails.a("Level seed", new Callable() { + public String a() throws Exception { + return String.valueOf(WorldData.this.getSeed()); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Level generator", new Callable() { + public String a() throws Exception { + return String.format("ID %02d - %s, ver %d. Features enabled: %b", new Object[] { Integer.valueOf(WorldData.this.c.g()), WorldData.this.c.name(), Integer.valueOf(WorldData.this.c.getVersion()), Boolean.valueOf(WorldData.this.v)}); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Level generator options", new Callable() { + public String a() throws Exception { + return WorldData.this.d; + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Level spawn location", new Callable() { + public String a() throws Exception { + return CrashReportSystemDetails.a((double) WorldData.this.e, (double) WorldData.this.f, (double) WorldData.this.g); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Level time", new Callable() { + public String a() throws Exception { + return String.format("%d game time, %d day time", new Object[] { Long.valueOf(WorldData.this.h), Long.valueOf(WorldData.this.i)}); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Level dimension", new Callable() { + public String a() throws Exception { + return String.valueOf(WorldData.this.m); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Level storage version", new Callable() { + public String a() throws Exception { + String s = "Unknown?"; + + try { + switch (WorldData.this.o) { + case 19132: + s = "McRegion"; + break; + + case 19133: + s = "Anvil"; + } + } catch (Throwable throwable) { + ; + } + + return String.format("0x%05X - %s", new Object[] { Integer.valueOf(WorldData.this.o), s}); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Level weather", new Callable() { + public String a() throws Exception { + return String.format("Rain time: %d (now: %b), thunder time: %d (now: %b)", new Object[] { Integer.valueOf(WorldData.this.r), Boolean.valueOf(WorldData.this.q), Integer.valueOf(WorldData.this.t), Boolean.valueOf(WorldData.this.s)}); + } + + public Object call() throws Exception { + return this.a(); + } + }); + crashreportsystemdetails.a("Level game mode", new Callable() { + public String a() throws Exception { + return String.format("Game mode: %s (ID %d). Hardcore: %b. Cheats: %b", new Object[] { WorldData.this.u.b(), Integer.valueOf(WorldData.this.u.getId()), Boolean.valueOf(WorldData.this.w), Boolean.valueOf(WorldData.this.x)}); + } + + public Object call() throws Exception { + return this.a(); + } + }); + } + + // CraftBukkit start - Check if the name stored in NBT is the correct one + public void checkName( String name ) { + if ( !this.n.equals( name ) ) { + this.n = name; + } + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenForestTree.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenForestTree.java new file mode 100644 index 0000000..ffbc47d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenForestTree.java @@ -0,0 +1,178 @@ +package net.minecraft.server; + +import java.util.Random; + +public class WorldGenForestTree extends WorldGenTreeAbstract { + + private static final IBlockData a = Blocks.LOG2.getBlockData().set(BlockLog2.VARIANT, BlockWood.EnumLogVariant.DARK_OAK); + private static final IBlockData b = Blocks.LEAVES2.getBlockData().set(BlockLeaves2.VARIANT, BlockWood.EnumLogVariant.DARK_OAK).set(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + + public WorldGenForestTree(boolean flag) { + super(flag); + } + + public boolean generate(World world, Random random, BlockPosition blockposition) { + int i = random.nextInt(3) + random.nextInt(2) + 6; + int j = blockposition.getX(); + int k = blockposition.getY(); + int l = blockposition.getZ(); + + if (k >= 1 && k + i + 1 < 256) { + BlockPosition blockposition1 = blockposition.down(); + Block block = world.getType(blockposition1).getBlock(); + + if (block != Blocks.GRASS && block != Blocks.DIRT) { + return false; + } else if (!this.a(world, blockposition, i)) { + return false; + } else { + this.a(world, blockposition1); + this.a(world, blockposition1.east()); + this.a(world, blockposition1.south()); + this.a(world, blockposition1.south().east()); + EnumDirection enumdirection = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(random); + int i1 = i - random.nextInt(4); + int j1 = 2 - random.nextInt(3); + int k1 = j; + int l1 = l; + int i2 = k + i - 1; + + int j2; + int k2; + + for (j2 = 0; j2 < i; ++j2) { + if (j2 >= i1 && j1 > 0) { + k1 += enumdirection.getAdjacentX(); + l1 += enumdirection.getAdjacentZ(); + --j1; + } + + k2 = k + j2; + BlockPosition blockposition2 = new BlockPosition(k1, k2, l1); + Material material = world.getType(blockposition2).getBlock().getMaterial(); + + if (material == Material.AIR || material == Material.LEAVES) { + this.b(world, blockposition2); + this.b(world, blockposition2.east()); + this.b(world, blockposition2.south()); + this.b(world, blockposition2.east().south()); + } + } + + for (j2 = -2; j2 <= 0; ++j2) { + for (k2 = -2; k2 <= 0; ++k2) { + byte b0 = -1; + + this.a(world, k1 + j2, i2 + b0, l1 + k2); + this.a(world, 1 + k1 - j2, i2 + b0, l1 + k2); + this.a(world, k1 + j2, i2 + b0, 1 + l1 - k2); + this.a(world, 1 + k1 - j2, i2 + b0, 1 + l1 - k2); + if ((j2 > -2 || k2 > -1) && (j2 != -1 || k2 != -2)) { + byte b1 = 1; + + this.a(world, k1 + j2, i2 + b1, l1 + k2); + this.a(world, 1 + k1 - j2, i2 + b1, l1 + k2); + this.a(world, k1 + j2, i2 + b1, 1 + l1 - k2); + this.a(world, 1 + k1 - j2, i2 + b1, 1 + l1 - k2); + } + } + } + + if (random.nextBoolean()) { + this.a(world, k1, i2 + 2, l1); + this.a(world, k1 + 1, i2 + 2, l1); + this.a(world, k1 + 1, i2 + 2, l1 + 1); + this.a(world, k1, i2 + 2, l1 + 1); + } + + for (j2 = -3; j2 <= 4; ++j2) { + for (k2 = -3; k2 <= 4; ++k2) { + if ((j2 != -3 || k2 != -3) && (j2 != -3 || k2 != 4) && (j2 != 4 || k2 != -3) && (j2 != 4 || k2 != 4) && (Math.abs(j2) < 3 || Math.abs(k2) < 3)) { + this.a(world, k1 + j2, i2, l1 + k2); + } + } + } + + for (j2 = -1; j2 <= 2; ++j2) { + for (k2 = -1; k2 <= 2; ++k2) { + if ((j2 < 0 || j2 > 1 || k2 < 0 || k2 > 1) && random.nextInt(3) <= 0) { + int l2 = random.nextInt(3) + 2; + + int i3; + + for (i3 = 0; i3 < l2; ++i3) { + this.b(world, new BlockPosition(j + j2, i2 - i3 - 1, l + k2)); + } + + int j3; + + for (i3 = -1; i3 <= 1; ++i3) { + for (j3 = -1; j3 <= 1; ++j3) { + this.a(world, k1 + j2 + i3, i2, l1 + k2 + j3); + } + } + + for (i3 = -2; i3 <= 2; ++i3) { + for (j3 = -2; j3 <= 2; ++j3) { + if (Math.abs(i3) != 2 || Math.abs(j3) != 2) { + this.a(world, k1 + j2 + i3, i2 - 1, l1 + k2 + j3); + } + } + } + } + } + } + + return true; + } + } else { + return false; + } + } + + private boolean a(World world, BlockPosition blockposition, int i) { + int j = blockposition.getX(); + int k = blockposition.getY(); + int l = blockposition.getZ(); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int i1 = 0; i1 <= i + 1; ++i1) { + byte b0 = 1; + + if (i1 == 0) { + b0 = 0; + } + + if (i1 >= i - 1) { + b0 = 2; + } + + for (int j1 = -b0; j1 <= b0; ++j1) { + for (int k1 = -b0; k1 <= b0; ++k1) { + if (!this.a(world.getType(blockposition_mutableblockposition.c(j + j1, k + i1, l + k1)).getBlock())) { + return false; + } + } + } + } + + return true; + } + + private void b(World world, BlockPosition blockposition) { + if (this.a(world.getType(blockposition).getBlock())) { + this.a(world, blockposition, WorldGenForestTree.a); + } + + } + + private void a(World world, int i, int j, int k) { + BlockPosition blockposition = new BlockPosition(i, j, k); + Block block = world.getType(blockposition).getBlock(); + + if (block.getMaterial() == Material.AIR) { + this.a(world, blockposition, WorldGenForestTree.b); + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenGroundBush.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenGroundBush.java new file mode 100644 index 0000000..16bdc77 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenGroundBush.java @@ -0,0 +1,58 @@ +package net.minecraft.server; + +import java.util.Random; + +public class WorldGenGroundBush extends WorldGenTrees { + + private final IBlockData a; + private final IBlockData b; + + public WorldGenGroundBush(IBlockData iblockdata, IBlockData iblockdata1) { + super(false); + this.b = iblockdata; + this.a = iblockdata1; + } + + public boolean generate(World world, Random random, BlockPosition blockposition) { + Block block; + + while (((block = world.getType(blockposition).getBlock()).getMaterial() == Material.AIR || block.getMaterial() == Material.LEAVES) && blockposition.getY() > 0) { + blockposition = blockposition.down(); + } + + Block block1 = world.getType(blockposition).getBlock(); + + if (block1 == Blocks.DIRT || block1 == Blocks.GRASS) { + blockposition = blockposition.up(); + this.a(world, blockposition, this.b); + + for (int i = blockposition.getY(); i <= blockposition.getY() + 2; ++i) { + int j = i - blockposition.getY(); + int k = 2 - j; + + for (int l = blockposition.getX() - k; l <= blockposition.getX() + k; ++l) { + int i1 = l - blockposition.getX(); + + for (int j1 = blockposition.getZ() - k; j1 <= blockposition.getZ() + k; ++j1) { + int k1 = j1 - blockposition.getZ(); + + if (Math.abs(i1) != k || Math.abs(k1) != k || random.nextInt(2) != 0) { + BlockPosition blockposition1 = new BlockPosition(l, i, j1); + + if (!world.getType(blockposition1).getBlock().o()) { + this.a(world, blockposition1, this.a); + } + } + } + } + } + // CraftBukkit start - Return false if gen was unsuccessful + } else { + return false; + } + // CraftBukkit end + + + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenLargeFeature.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenLargeFeature.java new file mode 100644 index 0000000..171be82 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenLargeFeature.java @@ -0,0 +1,131 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Map.Entry; + +public class WorldGenLargeFeature extends StructureGenerator { + + private static final List d = Arrays.asList(new BiomeBase[] { BiomeBase.DESERT, BiomeBase.DESERT_HILLS, BiomeBase.JUNGLE, BiomeBase.JUNGLE_HILLS, BiomeBase.SWAMPLAND}); + private List f; + private int g; + private int h; + + public WorldGenLargeFeature() { + this.f = Lists.newArrayList(); + this.g = 32; + this.h = 8; + this.f.add(new BiomeBase.BiomeMeta(EntityWitch.class, 1, 1, 1)); + } + + public WorldGenLargeFeature(Map map) { + this(); + Iterator iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + + if (((String) entry.getKey()).equals("distance")) { + this.g = MathHelper.a((String) entry.getValue(), this.g, this.h + 1); + } + } + + } + + public String a() { + return "Temple"; + } + + protected boolean a(int i, int j) { + int k = i; + int l = j; + + if (i < 0) { + i -= this.g - 1; + } + + if (j < 0) { + j -= this.g - 1; + } + + int i1 = i / this.g; + int j1 = j / this.g; + Random random = this.c.a(i1, j1, this.c.spigotConfig.largeFeatureSeed); // Spigot + + i1 *= this.g; + j1 *= this.g; + i1 += random.nextInt(this.g - this.h); + j1 += random.nextInt(this.g - this.h); + if (k == i1 && l == j1) { + BiomeBase biomebase = this.c.getWorldChunkManager().getBiome(new BlockPosition(k * 16 + 8, 0, l * 16 + 8)); + + if (biomebase == null) { + return false; + } + + Iterator iterator = WorldGenLargeFeature.d.iterator(); + + while (iterator.hasNext()) { + BiomeBase biomebase1 = (BiomeBase) iterator.next(); + + if (biomebase == biomebase1) { + return true; + } + } + } + + return false; + } + + protected StructureStart b(int i, int j) { + return new WorldGenLargeFeature.WorldGenLargeFeatureStart(this.c, this.b, i, j); + } + + public boolean a(BlockPosition blockposition) { + StructureStart structurestart = this.c(blockposition); + + if (structurestart != null && structurestart instanceof WorldGenLargeFeature.WorldGenLargeFeatureStart && !structurestart.a.isEmpty()) { + StructurePiece structurepiece = (StructurePiece) structurestart.a.getFirst(); + + return structurepiece instanceof WorldGenRegistration.WorldGenWitchHut; + } else { + return false; + } + } + + public List b() { + return this.f; + } + + public static class WorldGenLargeFeatureStart extends StructureStart { + + public WorldGenLargeFeatureStart() {} + + public WorldGenLargeFeatureStart(World world, Random random, int i, int j) { + super(i, j); + BiomeBase biomebase = world.getBiome(new BlockPosition(i * 16 + 8, 0, j * 16 + 8)); + + if (biomebase != BiomeBase.JUNGLE && biomebase != BiomeBase.JUNGLE_HILLS) { + if (biomebase == BiomeBase.SWAMPLAND) { + WorldGenRegistration.WorldGenWitchHut worldgenregistration_worldgenwitchhut = new WorldGenRegistration.WorldGenWitchHut(random, i * 16, j * 16); + + this.a.add(worldgenregistration_worldgenwitchhut); + } else if (biomebase == BiomeBase.DESERT || biomebase == BiomeBase.DESERT_HILLS) { + WorldGenRegistration.WorldGenPyramidPiece worldgenregistration_worldgenpyramidpiece = new WorldGenRegistration.WorldGenPyramidPiece(random, i * 16, j * 16); + + this.a.add(worldgenregistration_worldgenpyramidpiece); + } + } else { + WorldGenRegistration.WorldGenJungleTemple worldgenregistration_worldgenjungletemple = new WorldGenRegistration.WorldGenJungleTemple(random, i * 16, j * 16); + + this.a.add(worldgenregistration_worldgenjungletemple); + } + + this.c(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenMegaTreeAbstract.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenMegaTreeAbstract.java new file mode 100644 index 0000000..285e482 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenMegaTreeAbstract.java @@ -0,0 +1,115 @@ +package net.minecraft.server; + +import java.util.Random; + +public abstract class WorldGenMegaTreeAbstract extends WorldGenTreeAbstract { + + protected final int a; + protected final IBlockData b; + protected final IBlockData c; + protected int d; + + public WorldGenMegaTreeAbstract(boolean flag, int i, int j, IBlockData iblockdata, IBlockData iblockdata1) { + super(flag); + this.a = i; + this.d = j; + this.b = iblockdata; + this.c = iblockdata1; + } + + protected int a(Random random) { + int i = random.nextInt(3) + this.a; + + if (this.d > 1) { + i += random.nextInt(this.d); + } + + return i; + } + + private boolean c(World world, BlockPosition blockposition, int i) { + boolean flag = true; + + if (blockposition.getY() >= 1 && blockposition.getY() + i + 1 <= 256) { + for (int j = 0; j <= 1 + i; ++j) { + byte b0 = 2; + + if (j == 0) { + b0 = 1; + } else if (j >= 1 + i - 2) { + b0 = 2; + } + + for (int k = -b0; k <= b0 && flag; ++k) { + for (int l = -b0; l <= b0 && flag; ++l) { + if (blockposition.getY() + j < 0 || blockposition.getY() + j >= 256 || (!this.a(world.getType(blockposition.a(k, j, l)).getBlock()) && world.getType(blockposition.a(k, j, l)).getBlock() != Blocks.SAPLING)) { // CraftBukkit - ignore our own saplings + flag = false; + } + } + } + } + + return flag; + } else { + return false; + } + } + + private boolean a(BlockPosition blockposition, World world) { + BlockPosition blockposition1 = blockposition.down(); + Block block = world.getType(blockposition1).getBlock(); + + if ((block == Blocks.GRASS || block == Blocks.DIRT) && blockposition.getY() >= 2) { + this.a(world, blockposition1); + this.a(world, blockposition1.east()); + this.a(world, blockposition1.south()); + this.a(world, blockposition1.south().east()); + return true; + } else { + return false; + } + } + + protected boolean a(World world, Random random, BlockPosition blockposition, int i) { + return this.c(world, blockposition, i) && this.a(blockposition, world); + } + + protected void a(World world, BlockPosition blockposition, int i) { + int j = i * i; + + for (int k = -i; k <= i + 1; ++k) { + for (int l = -i; l <= i + 1; ++l) { + int i1 = k - 1; + int j1 = l - 1; + + if (k * k + l * l <= j || i1 * i1 + j1 * j1 <= j || k * k + j1 * j1 <= j || i1 * i1 + l * l <= j) { + BlockPosition blockposition1 = blockposition.a(k, 0, l); + Material material = world.getType(blockposition1).getBlock().getMaterial(); + + if (material == Material.AIR || material == Material.LEAVES) { + this.a(world, blockposition1, this.c); + } + } + } + } + + } + + protected void b(World world, BlockPosition blockposition, int i) { + int j = i * i; + + for (int k = -i; k <= i; ++k) { + for (int l = -i; l <= i; ++l) { + if (k * k + l * l <= j) { + BlockPosition blockposition1 = blockposition.a(k, 0, l); + Material material = world.getType(blockposition1).getBlock().getMaterial(); + + if (material == Material.AIR || material == Material.LEAVES) { + this.a(world, blockposition1, this.c); + } + } + } + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenPackedIce2.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenPackedIce2.java new file mode 100644 index 0000000..38534c2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenPackedIce2.java @@ -0,0 +1,102 @@ +package net.minecraft.server; + +import net.jafama.FastMath; + +import java.util.Random; + +public class WorldGenPackedIce2 extends WorldGenerator { + + public WorldGenPackedIce2() {} + + public boolean generate(World world, Random random, BlockPosition blockposition) { + while (world.isEmpty(blockposition) && blockposition.getY() > 2) { + blockposition = blockposition.down(); + } + + if (world.getType(blockposition).getBlock() != Blocks.SNOW) { + return false; + } else { + blockposition = blockposition.up(random.nextInt(4)); + int i = random.nextInt(4) + 7; + int j = i / 4 + random.nextInt(2); + + if (j > 1 && random.nextInt(60) == 0) { + blockposition = blockposition.up(10 + random.nextInt(30)); + } + + int k; + int l; + + for (k = 0; k < i; ++k) { + float f = (1.0F - (float) k / (float) i) * (float) j; + + l = MathHelper.f(f); + + for (int i1 = -l; i1 <= l; ++i1) { + float f1 = (float) MathHelper.a(i1) - 0.25F; + + for (int j1 = -l; j1 <= l; ++j1) { + float f2 = (float) MathHelper.a(j1) - 0.25F; + + if ((i1 == 0 && j1 == 0 || f1 * f1 + f2 * f2 <= f * f) && (i1 != -l && i1 != l && j1 != -l && j1 != l || random.nextFloat() <= 0.75F)) { + Block block = world.getType(blockposition.a(i1, k, j1)).getBlock(); + + if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW || block == Blocks.ICE) { + world.setTypeUpdate(blockposition.a(i1, k, j1), Blocks.PACKED_ICE.getBlockData()); // Spigot + } + + if (k != 0 && l > 1) { + block = world.getType(blockposition.a(i1, -k, j1)).getBlock(); + if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW || block == Blocks.ICE) { + world.setTypeUpdate(blockposition.a(i1, -k, j1), Blocks.PACKED_ICE.getBlockData()); // Spigot + } + } + } + } + } + } + + k = j - 1; + if (k < 0) { + k = 0; + } else if (k > 1) { + k = 1; + } + + for (int k1 = -k; k1 <= k; ++k1) { + l = -k; + + while (l <= k) { + BlockPosition blockposition1 = blockposition.a(k1, -1, l); + int l1 = 50; + + if (FastMath.abs(k1) == 1 && FastMath.abs(l) == 1) { + l1 = random.nextInt(5); + } + + while (true) { + if (blockposition1.getY() > 50) { + Block block1 = world.getType(blockposition1).getBlock(); + + if (block1.getMaterial() == Material.AIR || block1 == Blocks.DIRT || block1 == Blocks.SNOW || block1 == Blocks.ICE || block1 == Blocks.PACKED_ICE) { + world.setTypeUpdate(blockposition1, Blocks.PACKED_ICE.getBlockData()); // Spigot + blockposition1 = blockposition1.down(); + --l1; + if (l1 <= 0) { + blockposition1 = blockposition1.down(random.nextInt(5) + 1); + l1 = random.nextInt(5); + } + continue; + } + } + + ++l; + break; + } + } + } + + return true; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenRegistration.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenRegistration.java new file mode 100644 index 0000000..12e4b10 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenRegistration.java @@ -0,0 +1,654 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class WorldGenRegistration { + + public static void a() { + WorldGenFactory.a(WorldGenRegistration.WorldGenPyramidPiece.class, "TeDP"); + WorldGenFactory.a(WorldGenRegistration.WorldGenJungleTemple.class, "TeJP"); + WorldGenFactory.a(WorldGenRegistration.WorldGenWitchHut.class, "TeSH"); + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + WorldGenRegistration.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + WorldGenRegistration.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + } + } + + public static class WorldGenWitchHut extends WorldGenRegistration.WorldGenScatteredPiece { + + private boolean e; + + public WorldGenWitchHut() {} + + public WorldGenWitchHut(Random random, int i, int j) { + super(random, i, 64, j, 7, 7, 9); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setBoolean("Witch", this.e); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.e = nbttagcompound.getBoolean("Witch"); + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (!this.a(world, structureboundingbox, 0)) { + return false; + } else { + this.a(world, structureboundingbox, 1, 1, 1, 5, 1, 7, Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), false); + this.a(world, structureboundingbox, 1, 4, 2, 5, 4, 7, Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), false); + this.a(world, structureboundingbox, 2, 1, 0, 4, 1, 0, Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), false); + this.a(world, structureboundingbox, 2, 2, 2, 3, 3, 2, Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), false); + this.a(world, structureboundingbox, 1, 2, 3, 1, 3, 6, Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), false); + this.a(world, structureboundingbox, 5, 2, 3, 5, 3, 6, Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), false); + this.a(world, structureboundingbox, 2, 2, 7, 4, 3, 7, Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), Blocks.PLANKS.fromLegacyData(BlockWood.EnumLogVariant.SPRUCE.a()), false); + this.a(world, structureboundingbox, 1, 0, 2, 1, 3, 2, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 5, 0, 2, 5, 3, 2, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 7, 1, 3, 7, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 5, 0, 7, 5, 3, 7, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, Blocks.FENCE.getBlockData(), 2, 3, 2, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 3, 3, 7, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 1, 3, 4, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 5, 3, 4, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 5, 3, 5, structureboundingbox); + this.a(world, Blocks.FLOWER_POT.getBlockData().set(BlockFlowerPot.CONTENTS, BlockFlowerPot.EnumFlowerPotContents.MUSHROOM_RED), 1, 3, 5, structureboundingbox); + this.a(world, Blocks.CRAFTING_TABLE.getBlockData(), 3, 2, 6, structureboundingbox); + this.a(world, Blocks.cauldron.getBlockData(), 4, 2, 6, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 2, 1, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 5, 2, 1, structureboundingbox); + int i = this.a(Blocks.OAK_STAIRS, 3); + int j = this.a(Blocks.OAK_STAIRS, 1); + int k = this.a(Blocks.OAK_STAIRS, 0); + int l = this.a(Blocks.OAK_STAIRS, 2); + + this.a(world, structureboundingbox, 0, 4, 1, 6, 4, 1, Blocks.SPRUCE_STAIRS.fromLegacyData(i), Blocks.SPRUCE_STAIRS.fromLegacyData(i), false); + this.a(world, structureboundingbox, 0, 4, 2, 0, 4, 7, Blocks.SPRUCE_STAIRS.fromLegacyData(k), Blocks.SPRUCE_STAIRS.fromLegacyData(k), false); + this.a(world, structureboundingbox, 6, 4, 2, 6, 4, 7, Blocks.SPRUCE_STAIRS.fromLegacyData(j), Blocks.SPRUCE_STAIRS.fromLegacyData(j), false); + this.a(world, structureboundingbox, 0, 4, 8, 6, 4, 8, Blocks.SPRUCE_STAIRS.fromLegacyData(l), Blocks.SPRUCE_STAIRS.fromLegacyData(l), false); + + int i1; + int j1; + + for (i1 = 2; i1 <= 7; i1 += 5) { + for (j1 = 1; j1 <= 5; j1 += 4) { + this.b(world, Blocks.LOG.getBlockData(), j1, -1, i1, structureboundingbox); + } + } + + if (!this.e) { + i1 = this.a(2, 5); + j1 = this.d(2); + int k1 = this.b(2, 5); + + if (structureboundingbox.b((BaseBlockPosition) (new BlockPosition(i1, j1, k1)))) { + this.e = true; + EntityWitch entitywitch = new EntityWitch(world); + + entitywitch.setPositionRotation((double) i1 + 0.5D, (double) j1, (double) k1 + 0.5D, 0.0F, 0.0F); + entitywitch.prepare(world.E(new BlockPosition(i1, j1, k1)), (GroupDataEntity) null); + world.addEntity(entitywitch, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason + } + } + + return true; + } + } + } + + public static class WorldGenJungleTemple extends WorldGenRegistration.WorldGenScatteredPiece { + + private boolean e; + private boolean f; + private boolean g; + private boolean h; + private static final List i = Lists.newArrayList(new StructurePieceTreasure[] { new StructurePieceTreasure(Items.DIAMOND, 0, 1, 3, 3), new StructurePieceTreasure(Items.IRON_INGOT, 0, 1, 5, 10), new StructurePieceTreasure(Items.GOLD_INGOT, 0, 2, 7, 15), new StructurePieceTreasure(Items.EMERALD, 0, 1, 3, 2), new StructurePieceTreasure(Items.BONE, 0, 4, 6, 20), new StructurePieceTreasure(Items.ROTTEN_FLESH, 0, 3, 7, 16), new StructurePieceTreasure(Items.SADDLE, 0, 1, 1, 3), new StructurePieceTreasure(Items.IRON_HORSE_ARMOR, 0, 1, 1, 1), new StructurePieceTreasure(Items.GOLDEN_HORSE_ARMOR, 0, 1, 1, 1), new StructurePieceTreasure(Items.DIAMOND_HORSE_ARMOR, 0, 1, 1, 1)}); + private static final List j = Lists.newArrayList(new StructurePieceTreasure[] { new StructurePieceTreasure(Items.ARROW, 0, 2, 7, 30)}); + private static WorldGenRegistration.WorldGenJungleTemple.WorldGenJungleTemple$WorldGenJungleTemplePiece k = new WorldGenRegistration.WorldGenJungleTemple.WorldGenJungleTemple$WorldGenJungleTemplePiece((WorldGenRegistration.SyntheticClass_1) null); + + public WorldGenJungleTemple() {} + + public WorldGenJungleTemple(Random random, int i, int j) { + super(random, i, 64, j, 12, 10, 15); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setBoolean("placedMainChest", this.e); + nbttagcompound.setBoolean("placedHiddenChest", this.f); + nbttagcompound.setBoolean("placedTrap1", this.g); + nbttagcompound.setBoolean("placedTrap2", this.h); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.e = nbttagcompound.getBoolean("placedMainChest"); + this.f = nbttagcompound.getBoolean("placedHiddenChest"); + this.g = nbttagcompound.getBoolean("placedTrap1"); + this.h = nbttagcompound.getBoolean("placedTrap2"); + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (!this.a(world, structureboundingbox, 0)) { + return false; + } else { + int i = this.a(Blocks.STONE_STAIRS, 3); + int j = this.a(Blocks.STONE_STAIRS, 2); + int k = this.a(Blocks.STONE_STAIRS, 0); + int l = this.a(Blocks.STONE_STAIRS, 1); + + this.a(world, structureboundingbox, 0, -4, 0, this.a - 1, 0, this.c - 1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 2, 1, 2, 9, 2, 2, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 2, 1, 12, 9, 2, 12, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 2, 1, 3, 2, 2, 11, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 9, 1, 3, 9, 2, 11, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 1, 3, 1, 10, 6, 1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 1, 3, 13, 10, 6, 13, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 1, 3, 2, 1, 6, 12, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 10, 3, 2, 10, 6, 12, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 2, 3, 2, 9, 3, 12, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 2, 6, 2, 9, 6, 12, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 3, 7, 3, 8, 7, 11, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 4, 8, 4, 7, 8, 10, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 3, 1, 3, 8, 2, 11); + this.a(world, structureboundingbox, 4, 3, 6, 7, 3, 9); + this.a(world, structureboundingbox, 2, 4, 2, 9, 5, 12); + this.a(world, structureboundingbox, 4, 6, 5, 7, 6, 9); + this.a(world, structureboundingbox, 5, 7, 6, 6, 7, 8); + this.a(world, structureboundingbox, 5, 1, 2, 6, 2, 2); + this.a(world, structureboundingbox, 5, 2, 12, 6, 2, 12); + this.a(world, structureboundingbox, 5, 5, 1, 6, 5, 1); + this.a(world, structureboundingbox, 5, 5, 13, 6, 5, 13); + this.a(world, Blocks.AIR.getBlockData(), 1, 5, 5, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 10, 5, 5, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 1, 5, 9, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 10, 5, 9, structureboundingbox); + + int i1; + + for (i1 = 0; i1 <= 14; i1 += 14) { + this.a(world, structureboundingbox, 2, 4, i1, 2, 5, i1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 4, 4, i1, 4, 5, i1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 7, 4, i1, 7, 5, i1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 9, 4, i1, 9, 5, i1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + } + + this.a(world, structureboundingbox, 5, 6, 0, 6, 6, 0, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + + for (i1 = 0; i1 <= 11; i1 += 11) { + for (int j1 = 2; j1 <= 12; j1 += 2) { + this.a(world, structureboundingbox, i1, 4, j1, i1, 5, j1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + } + + this.a(world, structureboundingbox, i1, 6, 5, i1, 6, 5, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, i1, 6, 9, i1, 6, 9, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + } + + this.a(world, structureboundingbox, 2, 7, 2, 2, 9, 2, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 9, 7, 2, 9, 9, 2, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 2, 7, 12, 2, 9, 12, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 9, 7, 12, 9, 9, 12, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 4, 9, 4, 4, 9, 4, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 7, 9, 4, 7, 9, 4, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 4, 9, 10, 4, 9, 10, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 7, 9, 10, 7, 9, 10, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 5, 9, 7, 6, 9, 7, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 5, 9, 6, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 6, 9, 6, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(j), 5, 9, 8, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(j), 6, 9, 8, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 4, 0, 0, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 5, 0, 0, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 6, 0, 0, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 7, 0, 0, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 4, 1, 8, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 4, 2, 9, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 4, 3, 10, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 7, 1, 8, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 7, 2, 9, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(i), 7, 3, 10, structureboundingbox); + this.a(world, structureboundingbox, 4, 1, 9, 4, 1, 9, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 7, 1, 9, 7, 1, 9, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 4, 1, 10, 7, 2, 10, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 5, 4, 5, 6, 4, 5, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(k), 4, 4, 5, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(l), 7, 4, 5, structureboundingbox); + + for (i1 = 0; i1 < 4; ++i1) { + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(j), 5, 0 - i1, 6 + i1, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(j), 6, 0 - i1, 6 + i1, structureboundingbox); + this.a(world, structureboundingbox, 5, 0 - i1, 7 + i1, 6, 0 - i1, 9 + i1); + } + + this.a(world, structureboundingbox, 1, -3, 12, 10, -1, 13); + this.a(world, structureboundingbox, 1, -3, 1, 3, -1, 13); + this.a(world, structureboundingbox, 1, -3, 1, 9, -1, 5); + + for (i1 = 1; i1 <= 13; i1 += 2) { + this.a(world, structureboundingbox, 1, -3, i1, 1, -2, i1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + } + + for (i1 = 2; i1 <= 12; i1 += 2) { + this.a(world, structureboundingbox, 1, -1, i1, 3, -1, i1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + } + + this.a(world, structureboundingbox, 2, -2, 1, 5, -2, 1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 7, -2, 1, 9, -2, 1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 6, -3, 1, 6, -3, 1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 6, -1, 1, 6, -1, 1, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, Blocks.TRIPWIRE_HOOK.fromLegacyData(this.a(Blocks.TRIPWIRE_HOOK, EnumDirection.EAST.b())).set(BlockTripwireHook.ATTACHED, Boolean.valueOf(true)), 1, -3, 8, structureboundingbox); + this.a(world, Blocks.TRIPWIRE_HOOK.fromLegacyData(this.a(Blocks.TRIPWIRE_HOOK, EnumDirection.WEST.b())).set(BlockTripwireHook.ATTACHED, Boolean.valueOf(true)), 4, -3, 8, structureboundingbox); + this.a(world, Blocks.TRIPWIRE.getBlockData().set(BlockTripwire.ATTACHED, Boolean.valueOf(true)), 2, -3, 8, structureboundingbox); + this.a(world, Blocks.TRIPWIRE.getBlockData().set(BlockTripwire.ATTACHED, Boolean.valueOf(true)), 3, -3, 8, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 5, -3, 7, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 5, -3, 6, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 5, -3, 5, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 5, -3, 4, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 5, -3, 3, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 5, -3, 2, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 5, -3, 1, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 4, -3, 1, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 3, -3, 1, structureboundingbox); + if (!this.g) { + this.g = this.a(world, structureboundingbox, random, 3, -2, 1, EnumDirection.NORTH.a(), WorldGenRegistration.WorldGenJungleTemple.j, 2); + } + + this.a(world, Blocks.VINE.fromLegacyData(15), 3, -2, 2, structureboundingbox); + this.a(world, Blocks.TRIPWIRE_HOOK.fromLegacyData(this.a(Blocks.TRIPWIRE_HOOK, EnumDirection.NORTH.b())).set(BlockTripwireHook.ATTACHED, Boolean.valueOf(true)), 7, -3, 1, structureboundingbox); + this.a(world, Blocks.TRIPWIRE_HOOK.fromLegacyData(this.a(Blocks.TRIPWIRE_HOOK, EnumDirection.SOUTH.b())).set(BlockTripwireHook.ATTACHED, Boolean.valueOf(true)), 7, -3, 5, structureboundingbox); + this.a(world, Blocks.TRIPWIRE.getBlockData().set(BlockTripwire.ATTACHED, Boolean.valueOf(true)), 7, -3, 2, structureboundingbox); + this.a(world, Blocks.TRIPWIRE.getBlockData().set(BlockTripwire.ATTACHED, Boolean.valueOf(true)), 7, -3, 3, structureboundingbox); + this.a(world, Blocks.TRIPWIRE.getBlockData().set(BlockTripwire.ATTACHED, Boolean.valueOf(true)), 7, -3, 4, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 8, -3, 6, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 9, -3, 6, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 9, -3, 5, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 9, -3, 4, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 9, -2, 4, structureboundingbox); + if (!this.h) { + this.h = this.a(world, structureboundingbox, random, 9, -2, 3, EnumDirection.WEST.a(), WorldGenRegistration.WorldGenJungleTemple.j, 2); + } + + this.a(world, Blocks.VINE.fromLegacyData(15), 8, -1, 3, structureboundingbox); + this.a(world, Blocks.VINE.fromLegacyData(15), 8, -2, 3, structureboundingbox); + if (!this.e) { + this.e = this.a(world, structureboundingbox, random, 8, -3, 3, StructurePieceTreasure.a(WorldGenRegistration.WorldGenJungleTemple.i, new StructurePieceTreasure[] { Items.ENCHANTED_BOOK.b(random)}), 2 + random.nextInt(5)); + } + + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 9, -3, 2, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 8, -3, 1, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 4, -3, 5, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 5, -2, 5, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 5, -1, 5, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 6, -3, 5, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 7, -2, 5, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 7, -1, 5, structureboundingbox); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 8, -3, 5, structureboundingbox); + this.a(world, structureboundingbox, 9, -1, 1, 9, -1, 5, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 8, -3, 8, 10, -1, 10); + this.a(world, Blocks.STONEBRICK.fromLegacyData(BlockSmoothBrick.P), 8, -2, 11, structureboundingbox); + this.a(world, Blocks.STONEBRICK.fromLegacyData(BlockSmoothBrick.P), 9, -2, 11, structureboundingbox); + this.a(world, Blocks.STONEBRICK.fromLegacyData(BlockSmoothBrick.P), 10, -2, 11, structureboundingbox); + this.a(world, Blocks.LEVER.fromLegacyData(BlockLever.a(EnumDirection.fromType1(this.a(Blocks.LEVER, EnumDirection.NORTH.a())))), 8, -2, 12, structureboundingbox); + this.a(world, Blocks.LEVER.fromLegacyData(BlockLever.a(EnumDirection.fromType1(this.a(Blocks.LEVER, EnumDirection.NORTH.a())))), 9, -2, 12, structureboundingbox); + this.a(world, Blocks.LEVER.fromLegacyData(BlockLever.a(EnumDirection.fromType1(this.a(Blocks.LEVER, EnumDirection.NORTH.a())))), 10, -2, 12, structureboundingbox); + this.a(world, structureboundingbox, 8, -3, 8, 8, -3, 10, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, structureboundingbox, 10, -3, 8, 10, -3, 10, false, random, WorldGenRegistration.WorldGenJungleTemple.k); + this.a(world, Blocks.MOSSY_COBBLESTONE.getBlockData(), 10, -2, 9, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 8, -2, 9, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 8, -2, 10, structureboundingbox); + this.a(world, Blocks.REDSTONE_WIRE.getBlockData(), 10, -1, 9, structureboundingbox); + this.a(world, Blocks.STICKY_PISTON.fromLegacyData(EnumDirection.UP.a()), 9, -2, 8, structureboundingbox); + this.a(world, Blocks.STICKY_PISTON.fromLegacyData(this.a(Blocks.STICKY_PISTON, EnumDirection.WEST.a())), 10, -2, 8, structureboundingbox); + this.a(world, Blocks.STICKY_PISTON.fromLegacyData(this.a(Blocks.STICKY_PISTON, EnumDirection.WEST.a())), 10, -1, 8, structureboundingbox); + this.a(world, Blocks.UNPOWERED_REPEATER.fromLegacyData(this.a(Blocks.UNPOWERED_REPEATER, EnumDirection.NORTH.b())), 10, -2, 10, structureboundingbox); + if (!this.f) { + this.f = this.a(world, structureboundingbox, random, 9, -3, 10, StructurePieceTreasure.a(WorldGenRegistration.WorldGenJungleTemple.i, new StructurePieceTreasure[] { Items.ENCHANTED_BOOK.b(random)}), 2 + random.nextInt(5)); + } + + return true; + } + } + + static class WorldGenJungleTemple$WorldGenJungleTemplePiece extends StructurePiece.StructurePieceBlockSelector { + + private WorldGenJungleTemple$WorldGenJungleTemplePiece() {} + + public void a(Random random, int i, int j, int k, boolean flag) { + if (random.nextFloat() < 0.4F) { + this.a = Blocks.COBBLESTONE.getBlockData(); + } else { + this.a = Blocks.MOSSY_COBBLESTONE.getBlockData(); + } + + } + + WorldGenJungleTemple$WorldGenJungleTemplePiece(WorldGenRegistration.SyntheticClass_1 worldgenregistration_syntheticclass_1) { + this(); + } + } + } + + public static class WorldGenPyramidPiece extends WorldGenRegistration.WorldGenScatteredPiece { + + private boolean[] e = new boolean[4]; + private static final List f = Lists.newArrayList(new StructurePieceTreasure[] { new StructurePieceTreasure(Items.DIAMOND, 0, 1, 3, 3), new StructurePieceTreasure(Items.IRON_INGOT, 0, 1, 5, 10), new StructurePieceTreasure(Items.GOLD_INGOT, 0, 2, 7, 15), new StructurePieceTreasure(Items.EMERALD, 0, 1, 3, 2), new StructurePieceTreasure(Items.BONE, 0, 4, 6, 20), new StructurePieceTreasure(Items.ROTTEN_FLESH, 0, 3, 7, 16), new StructurePieceTreasure(Items.SADDLE, 0, 1, 1, 3), new StructurePieceTreasure(Items.IRON_HORSE_ARMOR, 0, 1, 1, 1), new StructurePieceTreasure(Items.GOLDEN_HORSE_ARMOR, 0, 1, 1, 1), new StructurePieceTreasure(Items.DIAMOND_HORSE_ARMOR, 0, 1, 1, 1)}); + + public WorldGenPyramidPiece() {} + + public WorldGenPyramidPiece(Random random, int i, int j) { + super(random, i, 64, j, 21, 15, 21); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setBoolean("hasPlacedChest0", this.e[0]); + nbttagcompound.setBoolean("hasPlacedChest1", this.e[1]); + nbttagcompound.setBoolean("hasPlacedChest2", this.e[2]); + nbttagcompound.setBoolean("hasPlacedChest3", this.e[3]); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.e[0] = nbttagcompound.getBoolean("hasPlacedChest0"); + this.e[1] = nbttagcompound.getBoolean("hasPlacedChest1"); + this.e[2] = nbttagcompound.getBoolean("hasPlacedChest2"); + this.e[3] = nbttagcompound.getBoolean("hasPlacedChest3"); + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + this.a(world, structureboundingbox, 0, -4, 0, this.a - 1, 0, this.c - 1, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + + int i; + + for (i = 1; i <= 9; ++i) { + this.a(world, structureboundingbox, i, i, i, this.a - 1 - i, i, this.c - 1 - i, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, i + 1, i, i + 1, this.a - 2 - i, i, this.c - 2 - i, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + } + + int j; + + for (i = 0; i < this.a; ++i) { + for (j = 0; j < this.c; ++j) { + byte b0 = -5; + + this.b(world, Blocks.SANDSTONE.getBlockData(), i, b0, j, structureboundingbox); + } + } + + i = this.a(Blocks.SANDSTONE_STAIRS, 3); + j = this.a(Blocks.SANDSTONE_STAIRS, 2); + int k = this.a(Blocks.SANDSTONE_STAIRS, 0); + int l = this.a(Blocks.SANDSTONE_STAIRS, 1); + int i1 = ~EnumColor.ORANGE.getInvColorIndex() & 15; + int j1 = ~EnumColor.BLUE.getInvColorIndex() & 15; + + this.a(world, structureboundingbox, 0, 0, 0, 4, 9, 4, Blocks.SANDSTONE.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 1, 10, 1, 3, 10, 3, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(i), 2, 10, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(j), 2, 10, 4, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(k), 0, 10, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(l), 4, 10, 2, structureboundingbox); + this.a(world, structureboundingbox, this.a - 5, 0, 0, this.a - 1, 9, 4, Blocks.SANDSTONE.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, this.a - 4, 10, 1, this.a - 2, 10, 3, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(i), this.a - 3, 10, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(j), this.a - 3, 10, 4, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(k), this.a - 5, 10, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(l), this.a - 1, 10, 2, structureboundingbox); + this.a(world, structureboundingbox, 8, 0, 0, 12, 4, 4, Blocks.SANDSTONE.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 9, 1, 0, 11, 3, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 9, 1, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 9, 2, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 9, 3, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 10, 3, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 11, 3, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 11, 2, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 11, 1, 1, structureboundingbox); + this.a(world, structureboundingbox, 4, 1, 1, 8, 3, 3, Blocks.SANDSTONE.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 4, 1, 2, 8, 2, 2, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 12, 1, 1, 16, 3, 3, Blocks.SANDSTONE.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 12, 1, 2, 16, 2, 2, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 5, 4, 5, this.a - 6, 4, this.c - 6, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, 9, 4, 9, 11, 4, 11, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 8, 1, 8, 8, 3, 8, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, structureboundingbox, 12, 1, 8, 12, 3, 8, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, structureboundingbox, 8, 1, 12, 8, 3, 12, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, structureboundingbox, 12, 1, 12, 12, 3, 12, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, structureboundingbox, 1, 1, 5, 4, 4, 11, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, this.a - 5, 1, 5, this.a - 2, 4, 11, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, 6, 7, 9, 6, 7, 11, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, this.a - 7, 7, 9, this.a - 7, 7, 11, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, 5, 5, 9, 5, 7, 11, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, structureboundingbox, this.a - 6, 5, 9, this.a - 6, 7, 11, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, Blocks.AIR.getBlockData(), 5, 5, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 5, 6, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 6, 6, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), this.a - 6, 5, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), this.a - 6, 6, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), this.a - 7, 6, 10, structureboundingbox); + this.a(world, structureboundingbox, 2, 4, 4, 2, 6, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, this.a - 3, 4, 4, this.a - 3, 6, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(i), 2, 4, 5, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(i), 2, 3, 4, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(i), this.a - 3, 4, 5, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(i), this.a - 3, 3, 4, structureboundingbox); + this.a(world, structureboundingbox, 1, 1, 3, 2, 2, 3, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, this.a - 3, 1, 3, this.a - 2, 2, 3, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, Blocks.SANDSTONE_STAIRS.getBlockData(), 1, 1, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.getBlockData(), this.a - 2, 1, 2, structureboundingbox); + this.a(world, Blocks.STONE_SLAB.fromLegacyData(BlockDoubleStepAbstract.EnumStoneSlabVariant.SAND.a()), 1, 2, 2, structureboundingbox); + this.a(world, Blocks.STONE_SLAB.fromLegacyData(BlockDoubleStepAbstract.EnumStoneSlabVariant.SAND.a()), this.a - 2, 2, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(l), 2, 1, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE_STAIRS.fromLegacyData(k), this.a - 3, 1, 2, structureboundingbox); + this.a(world, structureboundingbox, 4, 3, 5, 4, 3, 18, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, this.a - 5, 3, 5, this.a - 5, 3, 17, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, 3, 1, 5, 4, 2, 16, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, this.a - 6, 1, 5, this.a - 5, 2, 16, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + + int k1; + + for (k1 = 5; k1 <= 17; k1 += 2) { + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 4, 1, k1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), 4, 2, k1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), this.a - 5, 1, k1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), this.a - 5, 2, k1, structureboundingbox); + } + + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 10, 0, 7, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 10, 0, 8, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 9, 0, 9, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 11, 0, 9, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 8, 0, 10, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 12, 0, 10, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 7, 0, 10, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 13, 0, 10, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 9, 0, 11, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 11, 0, 11, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 10, 0, 12, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 10, 0, 13, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(j1), 10, 0, 10, structureboundingbox); + + for (k1 = 0; k1 <= this.a - 1; k1 += this.a - 1) { + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 2, 1, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 2, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 2, 3, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 3, 1, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 3, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 3, 3, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 4, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), k1, 4, 2, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 4, 3, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 5, 1, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 5, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 5, 3, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 6, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), k1, 6, 2, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 6, 3, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 7, 1, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 7, 2, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 7, 3, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 8, 1, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 8, 2, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 8, 3, structureboundingbox); + } + + for (k1 = 2; k1 <= this.a - 3; k1 += this.a - 3 - 2) { + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1 - 1, 2, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 2, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1 + 1, 2, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1 - 1, 3, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 3, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1 + 1, 3, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1 - 1, 4, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), k1, 4, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1 + 1, 4, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1 - 1, 5, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 5, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1 + 1, 5, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1 - 1, 6, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), k1, 6, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1 + 1, 6, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1 - 1, 7, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1, 7, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), k1 + 1, 7, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1 - 1, 8, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1, 8, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), k1 + 1, 8, 0, structureboundingbox); + } + + this.a(world, structureboundingbox, 8, 4, 0, 12, 6, 0, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, Blocks.AIR.getBlockData(), 8, 6, 0, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 12, 6, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 9, 5, 0, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), 10, 5, 0, structureboundingbox); + this.a(world, Blocks.STAINED_HARDENED_CLAY.fromLegacyData(i1), 11, 5, 0, structureboundingbox); + this.a(world, structureboundingbox, 8, -14, 8, 12, -11, 12, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, structureboundingbox, 8, -10, 8, 12, -10, 12, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), false); + this.a(world, structureboundingbox, 8, -9, 8, 12, -9, 12, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), false); + this.a(world, structureboundingbox, 8, -8, 8, 12, -1, 12, Blocks.SANDSTONE.getBlockData(), Blocks.SANDSTONE.getBlockData(), false); + this.a(world, structureboundingbox, 9, -11, 9, 11, -1, 11, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, Blocks.STONE_PRESSURE_PLATE.getBlockData(), 10, -11, 10, structureboundingbox); + this.a(world, structureboundingbox, 9, -13, 9, 11, -13, 11, Blocks.TNT.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, Blocks.AIR.getBlockData(), 8, -11, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 8, -10, 10, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), 7, -10, 10, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 7, -11, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 12, -11, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 12, -10, 10, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), 13, -10, 10, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 13, -11, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 10, -11, 8, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 10, -10, 8, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), 10, -10, 7, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 10, -11, 7, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 10, -11, 12, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 10, -10, 12, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.CHISELED.a()), 10, -10, 13, structureboundingbox); + this.a(world, Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()), 10, -11, 13, structureboundingbox); + Iterator iterator = EnumDirection.EnumDirectionLimit.HORIZONTAL.iterator(); + + while (iterator.hasNext()) { + EnumDirection enumdirection = (EnumDirection) iterator.next(); + + if (!this.e[enumdirection.b()]) { + int l1 = enumdirection.getAdjacentX() * 2; + int i2 = enumdirection.getAdjacentZ() * 2; + + this.e[enumdirection.b()] = this.a(world, structureboundingbox, random, 10 + l1, -11, 10 + i2, StructurePieceTreasure.a(WorldGenRegistration.WorldGenPyramidPiece.f, new StructurePieceTreasure[] { Items.ENCHANTED_BOOK.b(random)}), 2 + random.nextInt(5)); + } + } + + return true; + } + } + + abstract static class WorldGenScatteredPiece extends StructurePiece { + + protected int a; + protected int b; + protected int c; + protected int d = -1; + + public WorldGenScatteredPiece() {} + + protected WorldGenScatteredPiece(Random random, int i, int j, int k, int l, int i1, int j1) { + super(0); + this.a = l; + this.b = i1; + this.c = j1; + this.m = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(random); + switch (WorldGenRegistration.SyntheticClass_1.a[this.m.ordinal()]) { + case 1: + case 2: + this.l = new StructureBoundingBox(i, j, k, i + l - 1, j + i1 - 1, k + j1 - 1); + break; + + default: + this.l = new StructureBoundingBox(i, j, k, i + j1 - 1, j + i1 - 1, k + l - 1); + } + + } + + protected void a(NBTTagCompound nbttagcompound) { + nbttagcompound.setInt("Width", this.a); + nbttagcompound.setInt("Height", this.b); + nbttagcompound.setInt("Depth", this.c); + nbttagcompound.setInt("HPos", this.d); + } + + protected void b(NBTTagCompound nbttagcompound) { + this.a = nbttagcompound.getInt("Width"); + this.b = nbttagcompound.getInt("Height"); + this.c = nbttagcompound.getInt("Depth"); + this.d = nbttagcompound.getInt("HPos"); + } + + protected boolean a(World world, StructureBoundingBox structureboundingbox, int i) { + if (this.d >= 0) { + return true; + } else { + int j = 0; + int k = 0; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int l = this.l.c; l <= this.l.f; ++l) { + for (int i1 = this.l.a; i1 <= this.l.d; ++i1) { + blockposition_mutableblockposition.c(i1, 64, l); + if (structureboundingbox.b((BaseBlockPosition) blockposition_mutableblockposition)) { + j += Math.max(world.r(blockposition_mutableblockposition).getY(), world.worldProvider.getSeaLevel()); + ++k; + } + } + } + + if (k == 0) { + return false; + } else { + this.d = j / k; + this.l.a(0, this.d - this.l.b + i, 0); + return true; + } + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenVillage.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenVillage.java new file mode 100644 index 0000000..6648a70 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenVillage.java @@ -0,0 +1,138 @@ +package net.minecraft.server; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Map.Entry; + +public class WorldGenVillage extends StructureGenerator { + + public static final List d = Arrays.asList(new BiomeBase[] { BiomeBase.PLAINS, BiomeBase.DESERT, BiomeBase.SAVANNA}); + private int f; + private int g; + private int h; + + public WorldGenVillage() { + this.g = 32; + this.h = 8; + } + + public WorldGenVillage(Map map) { + this(); + Iterator iterator = map.entrySet().iterator(); + + while (iterator.hasNext()) { + Entry entry = (Entry) iterator.next(); + + if (((String) entry.getKey()).equals("size")) { + this.f = MathHelper.a((String) entry.getValue(), this.f, 0); + } else if (((String) entry.getKey()).equals("distance")) { + this.g = MathHelper.a((String) entry.getValue(), this.g, this.h + 1); + } + } + + } + + public String a() { + return "Village"; + } + + protected boolean a(int i, int j) { + int k = i; + int l = j; + + if (i < 0) { + i -= this.g - 1; + } + + if (j < 0) { + j -= this.g - 1; + } + + int i1 = i / this.g; + int j1 = j / this.g; + Random random = this.c.a(i1, j1, this.c.spigotConfig.villageSeed); // Spigot + + i1 *= this.g; + j1 *= this.g; + i1 += random.nextInt(this.g - this.h); + j1 += random.nextInt(this.g - this.h); + if (k == i1 && l == j1) { + boolean flag = this.c.getWorldChunkManager().a(k * 16 + 8, l * 16 + 8, 0, WorldGenVillage.d); + + if (flag) { + return true; + } + } + + return false; + } + + protected StructureStart b(int i, int j) { + return new WorldGenVillage.WorldGenVillageStart(this.c, this.b, i, j, this.f); + } + + public static class WorldGenVillageStart extends StructureStart { + + private boolean c; + + public WorldGenVillageStart() {} + + public WorldGenVillageStart(World world, Random random, int i, int j, int k) { + super(i, j); + List list = WorldGenVillagePieces.a(random, k); + WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece = new WorldGenVillagePieces.WorldGenVillageStartPiece(world.getWorldChunkManager(), 0, random, (i << 4) + 2, (j << 4) + 2, list, k); + + this.a.add(worldgenvillagepieces_worldgenvillagestartpiece); + worldgenvillagepieces_worldgenvillagestartpiece.a((StructurePiece) worldgenvillagepieces_worldgenvillagestartpiece, (List) this.a, random); + List list1 = worldgenvillagepieces_worldgenvillagestartpiece.g; + List list2 = worldgenvillagepieces_worldgenvillagestartpiece.f; + + int l; + + while (!list1.isEmpty() || !list2.isEmpty()) { + StructurePiece structurepiece; + + if (list1.isEmpty()) { + l = random.nextInt(list2.size()); + structurepiece = (StructurePiece) list2.remove(l); + structurepiece.a((StructurePiece) worldgenvillagepieces_worldgenvillagestartpiece, (List) this.a, random); + } else { + l = random.nextInt(list1.size()); + structurepiece = (StructurePiece) list1.remove(l); + structurepiece.a((StructurePiece) worldgenvillagepieces_worldgenvillagestartpiece, (List) this.a, random); + } + } + + this.c(); + l = 0; + Iterator iterator = this.a.iterator(); + + while (iterator.hasNext()) { + StructurePiece structurepiece1 = (StructurePiece) iterator.next(); + + if (!(structurepiece1 instanceof WorldGenVillagePieces.WorldGenVillageRoadPiece)) { + ++l; + } + } + + this.c = l > 2; + } + + public boolean d() { + return this.c; + } + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setBoolean("Valid", this.c); + } + + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.c = nbttagcompound.getBoolean("Valid"); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenVillagePieces.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenVillagePieces.java new file mode 100644 index 0000000..3ed55f4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldGenVillagePieces.java @@ -0,0 +1,1647 @@ +package net.minecraft.server; + +import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +public class WorldGenVillagePieces { + + public static void a() { + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageLibrary.class, "ViBH"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageFarm2.class, "ViDF"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageFarm.class, "ViF"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageLight.class, "ViL"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageButcher.class, "ViPH"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageHouse.class, "ViSH"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageHut.class, "ViSmH"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageTemple.class, "ViST"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageBlacksmith.class, "ViS"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageStartPiece.class, "ViStart"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageRoad.class, "ViSR"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageHouse2.class, "ViTRH"); + WorldGenFactory.a(WorldGenVillagePieces.WorldGenVillageWell.class, "ViW"); + } + + public static List a(Random random, int i) { + ArrayList arraylist = Lists.newArrayList(); + + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageHouse.class, 4, MathHelper.nextInt(random, 2 + i, 4 + i * 2))); + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageTemple.class, 20, MathHelper.nextInt(random, 0 + i, 1 + i))); + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageLibrary.class, 20, MathHelper.nextInt(random, 0 + i, 2 + i))); + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageHut.class, 3, MathHelper.nextInt(random, 2 + i, 5 + i * 3))); + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageButcher.class, 15, MathHelper.nextInt(random, 0 + i, 2 + i))); + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageFarm2.class, 3, MathHelper.nextInt(random, 1 + i, 4 + i))); + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageFarm.class, 3, MathHelper.nextInt(random, 2 + i, 4 + i * 2))); + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageBlacksmith.class, 15, MathHelper.nextInt(random, 0, 1 + i))); + arraylist.add(new WorldGenVillagePieces.WorldGenVillagePieceWeight(WorldGenVillagePieces.WorldGenVillageHouse2.class, 8, MathHelper.nextInt(random, 0 + i, 3 + i * 2))); + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + if (((WorldGenVillagePieces.WorldGenVillagePieceWeight) iterator.next()).d == 0) { + iterator.remove(); + } + } + + return arraylist; + } + + private static int a(List list) { + boolean flag = false; + int i = 0; + + WorldGenVillagePieces.WorldGenVillagePieceWeight worldgenvillagepieces_worldgenvillagepieceweight; + + for (Iterator iterator = list.iterator(); iterator.hasNext(); i += worldgenvillagepieces_worldgenvillagepieceweight.b) { + worldgenvillagepieces_worldgenvillagepieceweight = (WorldGenVillagePieces.WorldGenVillagePieceWeight) iterator.next(); + if (worldgenvillagepieces_worldgenvillagepieceweight.d > 0 && worldgenvillagepieces_worldgenvillagepieceweight.c < worldgenvillagepieces_worldgenvillagepieceweight.d) { + flag = true; + } + } + + return flag ? i : -1; + } + + private static WorldGenVillagePieces.WorldGenVillagePiece a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, WorldGenVillagePieces.WorldGenVillagePieceWeight worldgenvillagepieces_worldgenvillagepieceweight, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + Class oclass = worldgenvillagepieces_worldgenvillagepieceweight.a; + Object object = null; + + if (oclass == WorldGenVillagePieces.WorldGenVillageHouse.class) { + object = WorldGenVillagePieces.WorldGenVillageHouse.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } else if (oclass == WorldGenVillagePieces.WorldGenVillageTemple.class) { + object = WorldGenVillagePieces.WorldGenVillageTemple.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } else if (oclass == WorldGenVillagePieces.WorldGenVillageLibrary.class) { + object = WorldGenVillagePieces.WorldGenVillageLibrary.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } else if (oclass == WorldGenVillagePieces.WorldGenVillageHut.class) { + object = WorldGenVillagePieces.WorldGenVillageHut.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } else if (oclass == WorldGenVillagePieces.WorldGenVillageButcher.class) { + object = WorldGenVillagePieces.WorldGenVillageButcher.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } else if (oclass == WorldGenVillagePieces.WorldGenVillageFarm2.class) { + object = WorldGenVillagePieces.WorldGenVillageFarm2.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } else if (oclass == WorldGenVillagePieces.WorldGenVillageFarm.class) { + object = WorldGenVillagePieces.WorldGenVillageFarm.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } else if (oclass == WorldGenVillagePieces.WorldGenVillageBlacksmith.class) { + object = WorldGenVillagePieces.WorldGenVillageBlacksmith.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } else if (oclass == WorldGenVillagePieces.WorldGenVillageHouse2.class) { + object = WorldGenVillagePieces.WorldGenVillageHouse2.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l); + } + + return (WorldGenVillagePieces.WorldGenVillagePiece) object; + } + + private static WorldGenVillagePieces.WorldGenVillagePiece c(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + int i1 = a(worldgenvillagepieces_worldgenvillagestartpiece.e); + + if (i1 <= 0) { + return null; + } else { + int j1 = 0; + + while (j1 < 5) { + ++j1; + int k1 = random.nextInt(i1); + Iterator iterator = worldgenvillagepieces_worldgenvillagestartpiece.e.iterator(); + + while (iterator.hasNext()) { + WorldGenVillagePieces.WorldGenVillagePieceWeight worldgenvillagepieces_worldgenvillagepieceweight = (WorldGenVillagePieces.WorldGenVillagePieceWeight) iterator.next(); + + k1 -= worldgenvillagepieces_worldgenvillagepieceweight.b; + if (k1 < 0) { + if (!worldgenvillagepieces_worldgenvillagepieceweight.a(l) || worldgenvillagepieces_worldgenvillagepieceweight == worldgenvillagepieces_worldgenvillagestartpiece.d && worldgenvillagepieces_worldgenvillagestartpiece.e.size() > 1) { + break; + } + + WorldGenVillagePieces.WorldGenVillagePiece worldgenvillagepieces_worldgenvillagepiece = a(worldgenvillagepieces_worldgenvillagestartpiece, worldgenvillagepieces_worldgenvillagepieceweight, list, random, i, j, k, enumdirection, l); + + if (worldgenvillagepieces_worldgenvillagepiece != null) { + ++worldgenvillagepieces_worldgenvillagepieceweight.c; + worldgenvillagepieces_worldgenvillagestartpiece.d = worldgenvillagepieces_worldgenvillagepieceweight; + if (!worldgenvillagepieces_worldgenvillagepieceweight.a()) { + worldgenvillagepieces_worldgenvillagestartpiece.e.remove(worldgenvillagepieces_worldgenvillagepieceweight); + } + + return worldgenvillagepieces_worldgenvillagepiece; + } + } + } + } + + StructureBoundingBox structureboundingbox = WorldGenVillagePieces.WorldGenVillageLight.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection); + + if (structureboundingbox != null) { + return new WorldGenVillagePieces.WorldGenVillageLight(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection); + } else { + return null; + } + } + } + + private static StructurePiece d(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + if (l > 50) { + return null; + } else if (Math.abs(i - worldgenvillagepieces_worldgenvillagestartpiece.c().a) <= 112 && Math.abs(k - worldgenvillagepieces_worldgenvillagestartpiece.c().c) <= 112) { + WorldGenVillagePieces.WorldGenVillagePiece worldgenvillagepieces_worldgenvillagepiece = c(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection, l + 1); + + if (worldgenvillagepieces_worldgenvillagepiece != null) { + int i1 = (worldgenvillagepieces_worldgenvillagepiece.l.a + worldgenvillagepieces_worldgenvillagepiece.l.d) / 2; + int j1 = (worldgenvillagepieces_worldgenvillagepiece.l.c + worldgenvillagepieces_worldgenvillagepiece.l.f) / 2; + int k1 = worldgenvillagepieces_worldgenvillagepiece.l.d - worldgenvillagepieces_worldgenvillagepiece.l.a; + int l1 = worldgenvillagepieces_worldgenvillagepiece.l.f - worldgenvillagepieces_worldgenvillagepiece.l.c; + int i2 = k1 > l1 ? k1 : l1; + + if (worldgenvillagepieces_worldgenvillagestartpiece.e().a(i1, j1, i2 / 2 + 4, WorldGenVillage.d)) { + list.add(worldgenvillagepieces_worldgenvillagepiece); + worldgenvillagepieces_worldgenvillagestartpiece.f.add(worldgenvillagepieces_worldgenvillagepiece); + return worldgenvillagepieces_worldgenvillagepiece; + } + } + + return null; + } else { + return null; + } + } + + private static StructurePiece e(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + if (l > 3 + worldgenvillagepieces_worldgenvillagestartpiece.c) { + return null; + } else if (Math.abs(i - worldgenvillagepieces_worldgenvillagestartpiece.c().a) <= 112 && Math.abs(k - worldgenvillagepieces_worldgenvillagestartpiece.c().c) <= 112) { + StructureBoundingBox structureboundingbox = WorldGenVillagePieces.WorldGenVillageRoad.a(worldgenvillagepieces_worldgenvillagestartpiece, list, random, i, j, k, enumdirection); + + if (structureboundingbox != null && structureboundingbox.b > 10) { + WorldGenVillagePieces.WorldGenVillageRoad worldgenvillagepieces_worldgenvillageroad = new WorldGenVillagePieces.WorldGenVillageRoad(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection); + int i1 = (worldgenvillagepieces_worldgenvillageroad.l.a + worldgenvillagepieces_worldgenvillageroad.l.d) / 2; + int j1 = (worldgenvillagepieces_worldgenvillageroad.l.c + worldgenvillagepieces_worldgenvillageroad.l.f) / 2; + int k1 = worldgenvillagepieces_worldgenvillageroad.l.d - worldgenvillagepieces_worldgenvillageroad.l.a; + int l1 = worldgenvillagepieces_worldgenvillageroad.l.f - worldgenvillagepieces_worldgenvillageroad.l.c; + int i2 = k1 > l1 ? k1 : l1; + + if (worldgenvillagepieces_worldgenvillagestartpiece.e().a(i1, j1, i2 / 2 + 4, WorldGenVillage.d)) { + list.add(worldgenvillagepieces_worldgenvillageroad); + worldgenvillagepieces_worldgenvillagestartpiece.g.add(worldgenvillagepieces_worldgenvillageroad); + return worldgenvillagepieces_worldgenvillageroad; + } + } + + return null; + } else { + return null; + } + } + + static class SyntheticClass_1 { + + static final int[] a = new int[EnumDirection.values().length]; + + static { + try { + WorldGenVillagePieces.SyntheticClass_1.a[EnumDirection.NORTH.ordinal()] = 1; + } catch (NoSuchFieldError nosuchfielderror) { + ; + } + + try { + WorldGenVillagePieces.SyntheticClass_1.a[EnumDirection.SOUTH.ordinal()] = 2; + } catch (NoSuchFieldError nosuchfielderror1) { + ; + } + + try { + WorldGenVillagePieces.SyntheticClass_1.a[EnumDirection.WEST.ordinal()] = 3; + } catch (NoSuchFieldError nosuchfielderror2) { + ; + } + + try { + WorldGenVillagePieces.SyntheticClass_1.a[EnumDirection.EAST.ordinal()] = 4; + } catch (NoSuchFieldError nosuchfielderror3) { + ; + } + + } + } + + public static class WorldGenVillageLight extends WorldGenVillagePieces.WorldGenVillagePiece { + + public WorldGenVillageLight() {} + + public WorldGenVillageLight(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + } + + public static StructureBoundingBox a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 3, 4, 2, enumdirection); + + return StructurePiece.a(list, structureboundingbox) != null ? null : structureboundingbox; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 4 - 1, 0); + } + + this.a(world, structureboundingbox, 0, 0, 0, 2, 3, 1, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, Blocks.FENCE.getBlockData(), 1, 0, 0, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 1, 0, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 2, 0, structureboundingbox); + this.a(world, Blocks.WOOL.fromLegacyData(EnumColor.WHITE.getInvColorIndex()), 1, 3, 0, structureboundingbox); + boolean flag = this.m == EnumDirection.EAST || this.m == EnumDirection.NORTH; + + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m.e()), flag ? 2 : 0, 3, 0, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m), 1, 3, 1, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m.f()), flag ? 0 : 2, 3, 0, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m.opposite()), 1, 3, -1, structureboundingbox); + return true; + } + } + + public static class WorldGenVillageFarm2 extends WorldGenVillagePieces.WorldGenVillagePiece { + + private Block a; + private Block b; + private Block c; + private Block d; + + public WorldGenVillageFarm2() {} + + public WorldGenVillageFarm2(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + this.a = this.a(random); + this.b = this.a(random); + this.c = this.a(random); + this.d = this.a(random); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setInt("CA", Block.REGISTRY.b(this.a)); + nbttagcompound.setInt("CB", Block.REGISTRY.b(this.b)); + nbttagcompound.setInt("CC", Block.REGISTRY.b(this.c)); + nbttagcompound.setInt("CD", Block.REGISTRY.b(this.d)); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.a = Block.getById(nbttagcompound.getInt("CA")); + this.b = Block.getById(nbttagcompound.getInt("CB")); + this.c = Block.getById(nbttagcompound.getInt("CC")); + this.d = Block.getById(nbttagcompound.getInt("CD")); + } + + private Block a(Random random) { + switch (random.nextInt(5)) { + case 0: + return Blocks.CARROTS; + + case 1: + return Blocks.POTATOES; + + default: + return Blocks.WHEAT; + } + } + + public static WorldGenVillagePieces.WorldGenVillageFarm2 a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 13, 4, 9, enumdirection); + + return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageFarm2(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 4 - 1, 0); + } + + this.a(world, structureboundingbox, 0, 1, 0, 12, 4, 8, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 1, 2, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); + this.a(world, structureboundingbox, 4, 0, 1, 5, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); + this.a(world, structureboundingbox, 7, 0, 1, 8, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); + this.a(world, structureboundingbox, 10, 0, 1, 11, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); + this.a(world, structureboundingbox, 0, 0, 0, 0, 0, 8, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 6, 0, 0, 6, 0, 8, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 12, 0, 0, 12, 0, 8, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 0, 11, 0, 0, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 8, 11, 0, 8, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 3, 0, 1, 3, 0, 7, Blocks.WATER.getBlockData(), Blocks.WATER.getBlockData(), false); + this.a(world, structureboundingbox, 9, 0, 1, 9, 0, 7, Blocks.WATER.getBlockData(), Blocks.WATER.getBlockData(), false); + + int i; + + for (i = 1; i <= 7; ++i) { + this.a(world, this.a.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 1, 1, i, structureboundingbox); + this.a(world, this.a.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 2, 1, i, structureboundingbox); + this.a(world, this.b.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 4, 1, i, structureboundingbox); + this.a(world, this.b.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 5, 1, i, structureboundingbox); + this.a(world, this.c.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 7, 1, i, structureboundingbox); + this.a(world, this.c.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 8, 1, i, structureboundingbox); + this.a(world, this.d.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 10, 1, i, structureboundingbox); + this.a(world, this.d.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 11, 1, i, structureboundingbox); + } + + for (i = 0; i < 9; ++i) { + for (int j = 0; j < 13; ++j) { + this.b(world, j, 4, i, structureboundingbox); + this.b(world, Blocks.DIRT.getBlockData(), j, -1, i, structureboundingbox); + } + } + + return true; + } + } + + public static class WorldGenVillageFarm extends WorldGenVillagePieces.WorldGenVillagePiece { + + private Block a; + private Block b; + + public WorldGenVillageFarm() {} + + public WorldGenVillageFarm(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + this.a = this.a(random); + this.b = this.a(random); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setInt("CA", Block.REGISTRY.b(this.a)); + nbttagcompound.setInt("CB", Block.REGISTRY.b(this.b)); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.a = Block.getById(nbttagcompound.getInt("CA")); + this.b = Block.getById(nbttagcompound.getInt("CB")); + } + + private Block a(Random random) { + switch (random.nextInt(5)) { + case 0: + return Blocks.CARROTS; + + case 1: + return Blocks.POTATOES; + + default: + return Blocks.WHEAT; + } + } + + public static WorldGenVillagePieces.WorldGenVillageFarm a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 7, 4, 9, enumdirection); + + return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageFarm(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 4 - 1, 0); + } + + this.a(world, structureboundingbox, 0, 1, 0, 6, 4, 8, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 1, 2, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); + this.a(world, structureboundingbox, 4, 0, 1, 5, 0, 7, Blocks.FARMLAND.getBlockData(), Blocks.FARMLAND.getBlockData(), false); + this.a(world, structureboundingbox, 0, 0, 0, 0, 0, 8, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 6, 0, 0, 6, 0, 8, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 0, 5, 0, 0, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 8, 5, 0, 8, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 3, 0, 1, 3, 0, 7, Blocks.WATER.getBlockData(), Blocks.WATER.getBlockData(), false); + + int i; + + for (i = 1; i <= 7; ++i) { + this.a(world, this.a.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 1, 1, i, structureboundingbox); + this.a(world, this.a.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 2, 1, i, structureboundingbox); + this.a(world, this.b.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 4, 1, i, structureboundingbox); + this.a(world, this.b.fromLegacyData(MathHelper.nextInt(random, 2, 7)), 5, 1, i, structureboundingbox); + } + + for (i = 0; i < 9; ++i) { + for (int j = 0; j < 7; ++j) { + this.b(world, j, 4, i, structureboundingbox); + this.b(world, Blocks.DIRT.getBlockData(), j, -1, i, structureboundingbox); + } + } + + return true; + } + } + + public static class WorldGenVillageBlacksmith extends WorldGenVillagePieces.WorldGenVillagePiece { + + private static final List a = Lists.newArrayList(new StructurePieceTreasure[] { new StructurePieceTreasure(Items.DIAMOND, 0, 1, 3, 3), new StructurePieceTreasure(Items.IRON_INGOT, 0, 1, 5, 10), new StructurePieceTreasure(Items.GOLD_INGOT, 0, 1, 3, 5), new StructurePieceTreasure(Items.BREAD, 0, 1, 3, 15), new StructurePieceTreasure(Items.APPLE, 0, 1, 3, 15), new StructurePieceTreasure(Items.IRON_PICKAXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.IRON_SWORD, 0, 1, 1, 5), new StructurePieceTreasure(Items.IRON_CHESTPLATE, 0, 1, 1, 5), new StructurePieceTreasure(Items.IRON_HELMET, 0, 1, 1, 5), new StructurePieceTreasure(Items.IRON_LEGGINGS, 0, 1, 1, 5), new StructurePieceTreasure(Items.IRON_BOOTS, 0, 1, 1, 5), new StructurePieceTreasure(Item.getItemOf(Blocks.OBSIDIAN), 0, 3, 7, 5), new StructurePieceTreasure(Item.getItemOf(Blocks.SAPLING), 0, 3, 7, 5), new StructurePieceTreasure(Items.SADDLE, 0, 1, 1, 3), new StructurePieceTreasure(Items.IRON_HORSE_ARMOR, 0, 1, 1, 1), new StructurePieceTreasure(Items.GOLDEN_HORSE_ARMOR, 0, 1, 1, 1), new StructurePieceTreasure(Items.DIAMOND_HORSE_ARMOR, 0, 1, 1, 1)}); + private boolean b; + + public WorldGenVillageBlacksmith() {} + + public WorldGenVillageBlacksmith(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + } + + public static WorldGenVillagePieces.WorldGenVillageBlacksmith a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 10, 6, 7, enumdirection); + + return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageBlacksmith(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setBoolean("Chest", this.b); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.b = nbttagcompound.getBoolean("Chest"); + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 6 - 1, 0); + } + + this.a(world, structureboundingbox, 0, 1, 0, 9, 4, 6, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 0, 0, 0, 9, 0, 6, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 4, 0, 9, 4, 6, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 5, 0, 9, 5, 6, Blocks.STONE_SLAB.getBlockData(), Blocks.STONE_SLAB.getBlockData(), false); + this.a(world, structureboundingbox, 1, 5, 1, 8, 5, 5, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 1, 1, 0, 2, 3, 0, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 1, 0, 0, 4, 0, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 3, 1, 0, 3, 4, 0, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 0, 1, 6, 0, 4, 6, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, Blocks.PLANKS.getBlockData(), 3, 3, 1, structureboundingbox); + this.a(world, structureboundingbox, 3, 1, 2, 3, 3, 2, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 4, 1, 3, 5, 3, 3, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 1, 1, 0, 3, 5, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 1, 6, 5, 3, 6, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 5, 1, 0, 5, 3, 0, Blocks.FENCE.getBlockData(), Blocks.FENCE.getBlockData(), false); + this.a(world, structureboundingbox, 9, 1, 0, 9, 3, 0, Blocks.FENCE.getBlockData(), Blocks.FENCE.getBlockData(), false); + this.a(world, structureboundingbox, 6, 1, 4, 9, 4, 6, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, Blocks.FLOWING_LAVA.getBlockData(), 7, 1, 5, structureboundingbox); + this.a(world, Blocks.FLOWING_LAVA.getBlockData(), 8, 1, 5, structureboundingbox); + this.a(world, Blocks.IRON_BARS.getBlockData(), 9, 2, 5, structureboundingbox); + this.a(world, Blocks.IRON_BARS.getBlockData(), 9, 2, 4, structureboundingbox); + this.a(world, structureboundingbox, 7, 2, 4, 8, 2, 5, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 6, 1, 3, structureboundingbox); + this.a(world, Blocks.FURNACE.getBlockData(), 6, 2, 3, structureboundingbox); + this.a(world, Blocks.FURNACE.getBlockData(), 6, 3, 3, structureboundingbox); + this.a(world, Blocks.DOUBLE_STONE_SLAB.getBlockData(), 8, 1, 1, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 4, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 2, 6, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 2, 6, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 2, 1, 4, structureboundingbox); + this.a(world, Blocks.WOODEN_PRESSURE_PLATE.getBlockData(), 2, 2, 4, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 1, 1, 5, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(this.a(Blocks.OAK_STAIRS, 3)), 2, 1, 5, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(this.a(Blocks.OAK_STAIRS, 1)), 1, 1, 4, structureboundingbox); + if (!this.b && structureboundingbox.b((BaseBlockPosition) (new BlockPosition(this.a(5, 5), this.d(1), this.b(5, 5))))) { + this.b = true; + this.a(world, structureboundingbox, random, 5, 1, 5, WorldGenVillagePieces.WorldGenVillageBlacksmith.a, 3 + random.nextInt(6)); + } + + int i; + + for (i = 6; i <= 8; ++i) { + if (this.a(world, i, 0, -1, structureboundingbox).getBlock().getMaterial() == Material.AIR && this.a(world, i, -1, -1, structureboundingbox).getBlock().getMaterial() != Material.AIR) { + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), i, 0, -1, structureboundingbox); + } + } + + for (i = 0; i < 7; ++i) { + for (int j = 0; j < 10; ++j) { + this.b(world, j, 6, i, structureboundingbox); + this.b(world, Blocks.COBBLESTONE.getBlockData(), j, -1, i, structureboundingbox); + } + } + + this.a(world, structureboundingbox, 7, 1, 1, 1); + return true; + } + + protected int c(int i, int j) { + return 3; + } + } + + public static class WorldGenVillageHouse2 extends WorldGenVillagePieces.WorldGenVillagePiece { + + public WorldGenVillageHouse2() {} + + public WorldGenVillageHouse2(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + } + + public static WorldGenVillagePieces.WorldGenVillageHouse2 a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 9, 7, 12, enumdirection); + + return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageHouse2(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 7 - 1, 0); + } + + this.a(world, structureboundingbox, 1, 1, 1, 7, 4, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 2, 1, 6, 8, 4, 10, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 2, 0, 5, 8, 0, 10, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 1, 7, 0, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 0, 0, 0, 3, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 8, 0, 0, 8, 3, 10, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 0, 7, 2, 0, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 5, 2, 1, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 2, 0, 6, 2, 3, 10, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 3, 0, 10, 7, 3, 10, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 2, 0, 7, 3, 0, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 2, 5, 2, 3, 5, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 4, 1, 8, 4, 1, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 4, 4, 3, 4, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 5, 2, 8, 5, 3, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, Blocks.PLANKS.getBlockData(), 0, 4, 2, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 0, 4, 3, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 8, 4, 2, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 8, 4, 3, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 8, 4, 4, structureboundingbox); + int i = this.a(Blocks.OAK_STAIRS, 3); + int j = this.a(Blocks.OAK_STAIRS, 2); + + int k; + int l; + + for (k = -1; k <= 2; ++k) { + for (l = 0; l <= 8; ++l) { + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(i), l, 4 + k, k, structureboundingbox); + if ((k > -1 || l <= 1) && (k > 0 || l <= 3) && (k > 1 || l <= 4 || l >= 6)) { + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(j), l, 4 + k, 5 - k, structureboundingbox); + } + } + } + + this.a(world, structureboundingbox, 3, 4, 5, 3, 4, 10, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 7, 4, 2, 7, 4, 10, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 4, 5, 4, 4, 5, 10, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 6, 5, 4, 6, 5, 10, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 5, 6, 3, 5, 6, 10, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + k = this.a(Blocks.OAK_STAIRS, 0); + + int i1; + + for (l = 4; l >= 1; --l) { + this.a(world, Blocks.PLANKS.getBlockData(), l, 2 + l, 7 - l, structureboundingbox); + + for (i1 = 8 - l; i1 <= 10; ++i1) { + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(k), l, 2 + l, i1, structureboundingbox); + } + } + + l = this.a(Blocks.OAK_STAIRS, 1); + this.a(world, Blocks.PLANKS.getBlockData(), 6, 6, 3, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 7, 5, 4, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(l), 6, 6, 4, structureboundingbox); + + int j1; + + for (i1 = 6; i1 <= 8; ++i1) { + for (j1 = 5; j1 <= 10; ++j1) { + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(l), i1, 12 - i1, j1, structureboundingbox); + } + } + + this.a(world, Blocks.LOG.getBlockData(), 0, 2, 1, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 0, 2, 4, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 3, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 4, 2, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 5, 2, 0, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 6, 2, 0, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 8, 2, 1, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 2, 3, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 8, 2, 4, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 8, 2, 5, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 8, 2, 6, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 2, 7, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 2, 8, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 8, 2, 9, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 2, 2, 6, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 2, 7, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 2, 8, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 2, 2, 9, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 4, 4, 10, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 5, 4, 10, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 6, 4, 10, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 5, 5, 10, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 2, 1, 0, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 2, 2, 0, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m), 2, 3, 1, structureboundingbox); + this.a(world, structureboundingbox, random, 2, 1, 0, EnumDirection.fromType2(this.a(Blocks.WOODEN_DOOR, 1))); + this.a(world, structureboundingbox, 1, 0, -1, 3, 2, -1, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + if (this.a(world, 2, 0, -1, structureboundingbox).getBlock().getMaterial() == Material.AIR && this.a(world, 2, -1, -1, structureboundingbox).getBlock().getMaterial() != Material.AIR) { + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 2, 0, -1, structureboundingbox); + } + + for (i1 = 0; i1 < 5; ++i1) { + for (j1 = 0; j1 < 9; ++j1) { + this.b(world, j1, 7, i1, structureboundingbox); + this.b(world, Blocks.COBBLESTONE.getBlockData(), j1, -1, i1, structureboundingbox); + } + } + + for (i1 = 5; i1 < 11; ++i1) { + for (j1 = 2; j1 < 9; ++j1) { + this.b(world, j1, 7, i1, structureboundingbox); + this.b(world, Blocks.COBBLESTONE.getBlockData(), j1, -1, i1, structureboundingbox); + } + } + + this.a(world, structureboundingbox, 4, 1, 2, 2); + return true; + } + } + + public static class WorldGenVillageButcher extends WorldGenVillagePieces.WorldGenVillagePiece { + + public WorldGenVillageButcher() {} + + public WorldGenVillageButcher(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + } + + public static WorldGenVillagePieces.WorldGenVillageButcher a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 9, 7, 11, enumdirection); + + return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageButcher(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 7 - 1, 0); + } + + this.a(world, structureboundingbox, 1, 1, 1, 7, 4, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 2, 1, 6, 8, 4, 10, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 2, 0, 6, 8, 0, 10, Blocks.DIRT.getBlockData(), Blocks.DIRT.getBlockData(), false); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 6, 0, 6, structureboundingbox); + this.a(world, structureboundingbox, 2, 1, 6, 2, 1, 10, Blocks.FENCE.getBlockData(), Blocks.FENCE.getBlockData(), false); + this.a(world, structureboundingbox, 8, 1, 6, 8, 1, 10, Blocks.FENCE.getBlockData(), Blocks.FENCE.getBlockData(), false); + this.a(world, structureboundingbox, 3, 1, 10, 7, 1, 10, Blocks.FENCE.getBlockData(), Blocks.FENCE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 1, 7, 0, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 0, 0, 0, 3, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 8, 0, 0, 8, 3, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 0, 7, 1, 0, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 5, 7, 1, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 2, 0, 7, 3, 0, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 2, 5, 7, 3, 5, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 4, 1, 8, 4, 1, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 4, 4, 8, 4, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 0, 5, 2, 8, 5, 3, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, Blocks.PLANKS.getBlockData(), 0, 4, 2, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 0, 4, 3, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 8, 4, 2, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 8, 4, 3, structureboundingbox); + int i = this.a(Blocks.OAK_STAIRS, 3); + int j = this.a(Blocks.OAK_STAIRS, 2); + + int k; + int l; + + for (k = -1; k <= 2; ++k) { + for (l = 0; l <= 8; ++l) { + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(i), l, 4 + k, k, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(j), l, 4 + k, 5 - k, structureboundingbox); + } + } + + this.a(world, Blocks.LOG.getBlockData(), 0, 2, 1, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 0, 2, 4, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 8, 2, 1, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 8, 2, 4, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 3, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 2, 3, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 2, 5, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 3, 2, 5, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 5, 2, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 6, 2, 5, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 2, 1, 3, structureboundingbox); + this.a(world, Blocks.WOODEN_PRESSURE_PLATE.getBlockData(), 2, 2, 3, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 1, 1, 4, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(this.a(Blocks.OAK_STAIRS, 3)), 2, 1, 4, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(this.a(Blocks.OAK_STAIRS, 1)), 1, 1, 3, structureboundingbox); + this.a(world, structureboundingbox, 5, 0, 1, 7, 0, 3, Blocks.DOUBLE_STONE_SLAB.getBlockData(), Blocks.DOUBLE_STONE_SLAB.getBlockData(), false); + this.a(world, Blocks.DOUBLE_STONE_SLAB.getBlockData(), 6, 1, 1, structureboundingbox); + this.a(world, Blocks.DOUBLE_STONE_SLAB.getBlockData(), 6, 1, 2, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 2, 1, 0, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 2, 2, 0, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m), 2, 3, 1, structureboundingbox); + this.a(world, structureboundingbox, random, 2, 1, 0, EnumDirection.fromType2(this.a(Blocks.WOODEN_DOOR, 1))); + if (this.a(world, 2, 0, -1, structureboundingbox).getBlock().getMaterial() == Material.AIR && this.a(world, 2, -1, -1, structureboundingbox).getBlock().getMaterial() != Material.AIR) { + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 2, 0, -1, structureboundingbox); + } + + this.a(world, Blocks.AIR.getBlockData(), 6, 1, 5, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 6, 2, 5, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m.opposite()), 6, 3, 4, structureboundingbox); + this.a(world, structureboundingbox, random, 6, 1, 5, EnumDirection.fromType2(this.a(Blocks.WOODEN_DOOR, 1))); + + for (k = 0; k < 5; ++k) { + for (l = 0; l < 9; ++l) { + this.b(world, l, 7, k, structureboundingbox); + this.b(world, Blocks.COBBLESTONE.getBlockData(), l, -1, k, structureboundingbox); + } + } + + this.a(world, structureboundingbox, 4, 1, 2, 2); + return true; + } + + protected int c(int i, int j) { + return i == 0 ? 4 : super.c(i, j); + } + } + + public static class WorldGenVillageHut extends WorldGenVillagePieces.WorldGenVillagePiece { + + private boolean a; + private int b; + + public WorldGenVillageHut() {} + + public WorldGenVillageHut(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + this.a = random.nextBoolean(); + this.b = random.nextInt(3); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setInt("T", this.b); + nbttagcompound.setBoolean("C", this.a); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.b = nbttagcompound.getInt("T"); + this.a = nbttagcompound.getBoolean("C"); + } + + public static WorldGenVillagePieces.WorldGenVillageHut a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 4, 6, 5, enumdirection); + + return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageHut(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 6 - 1, 0); + } + + this.a(world, structureboundingbox, 1, 1, 1, 3, 5, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 0, 0, 0, 3, 0, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 1, 2, 0, 3, Blocks.DIRT.getBlockData(), Blocks.DIRT.getBlockData(), false); + if (this.a) { + this.a(world, structureboundingbox, 1, 4, 1, 2, 4, 3, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + } else { + this.a(world, structureboundingbox, 1, 5, 1, 2, 5, 3, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + } + + this.a(world, Blocks.LOG.getBlockData(), 1, 4, 0, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 2, 4, 0, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 1, 4, 4, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 2, 4, 4, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 0, 4, 1, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 0, 4, 2, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 0, 4, 3, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 3, 4, 1, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 3, 4, 2, structureboundingbox); + this.a(world, Blocks.LOG.getBlockData(), 3, 4, 3, structureboundingbox); + this.a(world, structureboundingbox, 0, 1, 0, 0, 3, 0, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 3, 1, 0, 3, 3, 0, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 0, 1, 4, 0, 3, 4, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 3, 1, 4, 3, 3, 4, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 0, 1, 1, 0, 3, 3, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 3, 1, 1, 3, 3, 3, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 1, 0, 2, 3, 0, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 1, 4, 2, 3, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 3, 2, 2, structureboundingbox); + if (this.b > 0) { + this.a(world, Blocks.FENCE.getBlockData(), this.b, 1, 3, structureboundingbox); + this.a(world, Blocks.WOODEN_PRESSURE_PLATE.getBlockData(), this.b, 2, 3, structureboundingbox); + } + + this.a(world, Blocks.AIR.getBlockData(), 1, 1, 0, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 1, 2, 0, structureboundingbox); + this.a(world, structureboundingbox, random, 1, 1, 0, EnumDirection.fromType2(this.a(Blocks.WOODEN_DOOR, 1))); + if (this.a(world, 1, 0, -1, structureboundingbox).getBlock().getMaterial() == Material.AIR && this.a(world, 1, -1, -1, structureboundingbox).getBlock().getMaterial() != Material.AIR) { + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 1, 0, -1, structureboundingbox); + } + + for (int i = 0; i < 5; ++i) { + for (int j = 0; j < 4; ++j) { + this.b(world, j, 6, i, structureboundingbox); + this.b(world, Blocks.COBBLESTONE.getBlockData(), j, -1, i, structureboundingbox); + } + } + + this.a(world, structureboundingbox, 1, 1, 2, 1); + return true; + } + } + + public static class WorldGenVillageLibrary extends WorldGenVillagePieces.WorldGenVillagePiece { + + public WorldGenVillageLibrary() {} + + public WorldGenVillageLibrary(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + } + + public static WorldGenVillagePieces.WorldGenVillageLibrary a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 9, 9, 6, enumdirection); + + return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageLibrary(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 9 - 1, 0); + } + + this.a(world, structureboundingbox, 1, 1, 1, 7, 5, 4, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 0, 0, 0, 8, 0, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 5, 0, 8, 5, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 6, 1, 8, 6, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 7, 2, 8, 7, 3, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + int i = this.a(Blocks.OAK_STAIRS, 3); + int j = this.a(Blocks.OAK_STAIRS, 2); + + int k; + int l; + + for (k = -1; k <= 2; ++k) { + for (l = 0; l <= 8; ++l) { + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(i), l, 6 + k, k, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(j), l, 6 + k, 5 - k, structureboundingbox); + } + } + + this.a(world, structureboundingbox, 0, 1, 0, 0, 1, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 1, 5, 8, 1, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 8, 1, 0, 8, 1, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 2, 1, 0, 7, 1, 0, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 2, 0, 0, 4, 0, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 2, 5, 0, 4, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 8, 2, 5, 8, 4, 5, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 8, 2, 0, 8, 4, 0, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 2, 1, 0, 4, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 2, 5, 7, 4, 5, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 8, 2, 1, 8, 4, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 2, 0, 7, 4, 0, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 2, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 5, 2, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 6, 2, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 3, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 5, 3, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 6, 3, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 3, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 3, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 3, 3, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 2, 3, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 3, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 8, 3, 3, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 2, 5, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 3, 2, 5, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 5, 2, 5, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 6, 2, 5, structureboundingbox); + this.a(world, structureboundingbox, 1, 4, 1, 7, 4, 1, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 4, 4, 7, 4, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 3, 4, 7, 3, 4, Blocks.BOOKSHELF.getBlockData(), Blocks.BOOKSHELF.getBlockData(), false); + this.a(world, Blocks.PLANKS.getBlockData(), 7, 1, 4, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(this.a(Blocks.OAK_STAIRS, 0)), 7, 1, 3, structureboundingbox); + k = this.a(Blocks.OAK_STAIRS, 3); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(k), 6, 1, 4, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(k), 5, 1, 4, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(k), 4, 1, 4, structureboundingbox); + this.a(world, Blocks.OAK_STAIRS.fromLegacyData(k), 3, 1, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 6, 1, 3, structureboundingbox); + this.a(world, Blocks.WOODEN_PRESSURE_PLATE.getBlockData(), 6, 2, 3, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 1, 3, structureboundingbox); + this.a(world, Blocks.WOODEN_PRESSURE_PLATE.getBlockData(), 4, 2, 3, structureboundingbox); + this.a(world, Blocks.CRAFTING_TABLE.getBlockData(), 7, 1, 1, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 1, 1, 0, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 1, 2, 0, structureboundingbox); + this.a(world, structureboundingbox, random, 1, 1, 0, EnumDirection.fromType2(this.a(Blocks.WOODEN_DOOR, 1))); + if (this.a(world, 1, 0, -1, structureboundingbox).getBlock().getMaterial() == Material.AIR && this.a(world, 1, -1, -1, structureboundingbox).getBlock().getMaterial() != Material.AIR) { + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 1, 0, -1, structureboundingbox); + } + + for (l = 0; l < 6; ++l) { + for (int i1 = 0; i1 < 9; ++i1) { + this.b(world, i1, 9, l, structureboundingbox); + this.b(world, Blocks.COBBLESTONE.getBlockData(), i1, -1, l, structureboundingbox); + } + } + + this.a(world, structureboundingbox, 2, 1, 2, 1); + return true; + } + + protected int c(int i, int j) { + return 1; + } + } + + public static class WorldGenVillageTemple extends WorldGenVillagePieces.WorldGenVillagePiece { + + public WorldGenVillageTemple() {} + + public WorldGenVillageTemple(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + } + + public static WorldGenVillagePieces.WorldGenVillageTemple a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 5, 12, 9, enumdirection); + + return a(structureboundingbox) && StructurePiece.a(list, structureboundingbox) == null ? new WorldGenVillagePieces.WorldGenVillageTemple(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection) : null; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 12 - 1, 0); + } + + this.a(world, structureboundingbox, 1, 1, 1, 3, 3, 7, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 1, 5, 1, 3, 9, 3, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + this.a(world, structureboundingbox, 1, 0, 0, 3, 0, 8, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 1, 0, 3, 10, 0, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 1, 1, 0, 10, 3, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 4, 1, 1, 4, 10, 3, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 0, 4, 0, 4, 7, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 4, 0, 4, 4, 4, 7, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 1, 8, 3, 4, 8, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 5, 4, 3, 10, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 1, 5, 5, 3, 5, 7, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 9, 0, 4, 9, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 4, 0, 4, 4, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 0, 11, 2, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 4, 11, 2, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 2, 11, 0, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 2, 11, 4, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 1, 1, 6, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 1, 1, 7, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 2, 1, 7, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 3, 1, 6, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 3, 1, 7, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 1, 1, 5, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 2, 1, 6, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 3, 1, 5, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 1)), 1, 2, 7, structureboundingbox); + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 0)), 3, 2, 7, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 3, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 3, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 6, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 7, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 6, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 7, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 6, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 7, 0, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 6, 4, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 7, 4, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 3, 6, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 3, 6, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 3, 8, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m.opposite()), 2, 4, 7, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m.e()), 1, 4, 6, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m.f()), 3, 4, 6, structureboundingbox); + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m), 2, 4, 5, structureboundingbox); + int i = this.a(Blocks.LADDER, 4); + + int j; + + for (j = 1; j <= 9; ++j) { + this.a(world, Blocks.LADDER.fromLegacyData(i), 3, j, 3, structureboundingbox); + } + + this.a(world, Blocks.AIR.getBlockData(), 2, 1, 0, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 2, 2, 0, structureboundingbox); + this.a(world, structureboundingbox, random, 2, 1, 0, EnumDirection.fromType2(this.a(Blocks.WOODEN_DOOR, 1))); + if (this.a(world, 2, 0, -1, structureboundingbox).getBlock().getMaterial() == Material.AIR && this.a(world, 2, -1, -1, structureboundingbox).getBlock().getMaterial() != Material.AIR) { + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 2, 0, -1, structureboundingbox); + } + + for (j = 0; j < 9; ++j) { + for (int k = 0; k < 5; ++k) { + this.b(world, k, 12, j, structureboundingbox); + this.b(world, Blocks.COBBLESTONE.getBlockData(), k, -1, j, structureboundingbox); + } + } + + this.a(world, structureboundingbox, 2, 1, 2, 1); + return true; + } + + protected int c(int i, int j) { + return 2; + } + } + + public static class WorldGenVillageHouse extends WorldGenVillagePieces.WorldGenVillagePiece { + + private boolean a; + + public WorldGenVillageHouse() {} + + public WorldGenVillageHouse(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + this.a = random.nextBoolean(); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setBoolean("Terrace", this.a); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.a = nbttagcompound.getBoolean("Terrace"); + } + + public static WorldGenVillagePieces.WorldGenVillageHouse a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection, int l) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 5, 6, 5, enumdirection); + + return StructurePiece.a(list, structureboundingbox) != null ? null : new WorldGenVillagePieces.WorldGenVillageHouse(worldgenvillagepieces_worldgenvillagestartpiece, l, random, structureboundingbox, enumdirection); + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 6 - 1, 0); + } + + this.a(world, structureboundingbox, 0, 0, 0, 4, 0, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + this.a(world, structureboundingbox, 0, 4, 0, 4, 4, 4, Blocks.LOG.getBlockData(), Blocks.LOG.getBlockData(), false); + this.a(world, structureboundingbox, 1, 4, 1, 3, 4, 3, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 0, 1, 0, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 0, 2, 0, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 0, 3, 0, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 4, 1, 0, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 4, 2, 0, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 4, 3, 0, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 0, 1, 4, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 0, 2, 4, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 0, 3, 4, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 4, 1, 4, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 4, 2, 4, structureboundingbox); + this.a(world, Blocks.COBBLESTONE.getBlockData(), 4, 3, 4, structureboundingbox); + this.a(world, structureboundingbox, 0, 1, 1, 0, 3, 3, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 4, 1, 1, 4, 3, 3, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, structureboundingbox, 1, 1, 4, 3, 3, 4, Blocks.PLANKS.getBlockData(), Blocks.PLANKS.getBlockData(), false); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 0, 2, 2, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 2, 2, 4, structureboundingbox); + this.a(world, Blocks.GLASS_PANE.getBlockData(), 4, 2, 2, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 1, 1, 0, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 1, 2, 0, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 1, 3, 0, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 2, 3, 0, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 3, 3, 0, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 3, 2, 0, structureboundingbox); + this.a(world, Blocks.PLANKS.getBlockData(), 3, 1, 0, structureboundingbox); + if (this.a(world, 2, 0, -1, structureboundingbox).getBlock().getMaterial() == Material.AIR && this.a(world, 2, -1, -1, structureboundingbox).getBlock().getMaterial() != Material.AIR) { + this.a(world, Blocks.STONE_STAIRS.fromLegacyData(this.a(Blocks.STONE_STAIRS, 3)), 2, 0, -1, structureboundingbox); + } + + this.a(world, structureboundingbox, 1, 1, 1, 3, 3, 3, Blocks.AIR.getBlockData(), Blocks.AIR.getBlockData(), false); + if (this.a) { + this.a(world, Blocks.FENCE.getBlockData(), 0, 5, 0, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 5, 0, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 2, 5, 0, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 3, 5, 0, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 5, 0, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 0, 5, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 5, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 2, 5, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 3, 5, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 5, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 5, 1, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 5, 2, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 5, 3, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 0, 5, 1, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 0, 5, 2, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 0, 5, 3, structureboundingbox); + } + + int i; + + if (this.a) { + i = this.a(Blocks.LADDER, 3); + this.a(world, Blocks.LADDER.fromLegacyData(i), 3, 1, 3, structureboundingbox); + this.a(world, Blocks.LADDER.fromLegacyData(i), 3, 2, 3, structureboundingbox); + this.a(world, Blocks.LADDER.fromLegacyData(i), 3, 3, 3, structureboundingbox); + this.a(world, Blocks.LADDER.fromLegacyData(i), 3, 4, 3, structureboundingbox); + } + + this.a(world, Blocks.TORCH.getBlockData().set(BlockTorch.FACING, this.m), 2, 3, 1, structureboundingbox); + + for (i = 0; i < 5; ++i) { + for (int j = 0; j < 5; ++j) { + this.b(world, j, 6, i, structureboundingbox); + this.b(world, Blocks.COBBLESTONE.getBlockData(), j, -1, i, structureboundingbox); + } + } + + this.a(world, structureboundingbox, 1, 1, 2, 1); + return true; + } + } + + public static class WorldGenVillageRoad extends WorldGenVillagePieces.WorldGenVillageRoadPiece { + + private int a; + + public WorldGenVillageRoad() {} + + public WorldGenVillageRoad(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, StructureBoundingBox structureboundingbox, EnumDirection enumdirection) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = enumdirection; + this.l = structureboundingbox; + this.a = Math.max(structureboundingbox.c(), structureboundingbox.e()); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + nbttagcompound.setInt("Length", this.a); + } + + protected void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + this.a = nbttagcompound.getInt("Length"); + } + + public void a(StructurePiece structurepiece, List list, Random random) { + boolean flag = false; + + int i; + StructurePiece structurepiece1; + + for (i = random.nextInt(5); i < this.a - 8; i += 2 + random.nextInt(5)) { + structurepiece1 = this.a((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, 0, i); + if (structurepiece1 != null) { + i += Math.max(structurepiece1.l.c(), structurepiece1.l.e()); + flag = true; + } + } + + for (i = random.nextInt(5); i < this.a - 8; i += 2 + random.nextInt(5)) { + structurepiece1 = this.b((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, 0, i); + if (structurepiece1 != null) { + i += Math.max(structurepiece1.l.c(), structurepiece1.l.e()); + flag = true; + } + } + + if (flag && random.nextInt(3) > 0 && this.m != null) { + switch (WorldGenVillagePieces.SyntheticClass_1.a[this.m.ordinal()]) { + case 1: + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.a - 1, this.l.b, this.l.c, EnumDirection.WEST, this.d()); + break; + + case 2: + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.a - 1, this.l.b, this.l.f - 2, EnumDirection.WEST, this.d()); + break; + + case 3: + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.a, this.l.b, this.l.c - 1, EnumDirection.NORTH, this.d()); + break; + + case 4: + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.d - 2, this.l.b, this.l.c - 1, EnumDirection.NORTH, this.d()); + } + } + + if (flag && random.nextInt(3) > 0 && this.m != null) { + switch (WorldGenVillagePieces.SyntheticClass_1.a[this.m.ordinal()]) { + case 1: + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.d + 1, this.l.b, this.l.c, EnumDirection.EAST, this.d()); + break; + + case 2: + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.d + 1, this.l.b, this.l.f - 2, EnumDirection.EAST, this.d()); + break; + + case 3: + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.a, this.l.b, this.l.f + 1, EnumDirection.SOUTH, this.d()); + break; + + case 4: + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.d - 2, this.l.b, this.l.f + 1, EnumDirection.SOUTH, this.d()); + } + } + + } + + public static StructureBoundingBox a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j, int k, EnumDirection enumdirection) { + for (int l = 7 * MathHelper.nextInt(random, 3, 5); l >= 7; l -= 7) { + StructureBoundingBox structureboundingbox = StructureBoundingBox.a(i, j, k, 0, 0, 0, 3, 3, l, enumdirection); + + if (StructurePiece.a(list, structureboundingbox) == null) { + return structureboundingbox; + } + } + + return null; + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + IBlockData iblockdata = this.a(Blocks.GRAVEL.getBlockData()); + IBlockData iblockdata1 = this.a(Blocks.COBBLESTONE.getBlockData()); + + for (int i = this.l.a; i <= this.l.d; ++i) { + for (int j = this.l.c; j <= this.l.f; ++j) { + BlockPosition blockposition = new BlockPosition(i, 64, j); + + if (structureboundingbox.b((BaseBlockPosition) blockposition)) { + blockposition = world.r(blockposition).down(); + world.setTypeAndData(blockposition, iblockdata, 2); + world.setTypeAndData(blockposition.down(), iblockdata1, 2); + } + } + } + + return true; + } + } + + public abstract static class WorldGenVillageRoadPiece extends WorldGenVillagePieces.WorldGenVillagePiece { + + public WorldGenVillageRoadPiece() {} + + protected WorldGenVillageRoadPiece(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + } + } + + public static class WorldGenVillageStartPiece extends WorldGenVillagePieces.WorldGenVillageWell { + + public WorldChunkManager a; + public boolean b; + public int c; + public WorldGenVillagePieces.WorldGenVillagePieceWeight d; + public List e; + public List f = Lists.newArrayList(); + public List g = Lists.newArrayList(); + + public WorldGenVillageStartPiece() {} + + public WorldGenVillageStartPiece(WorldChunkManager worldchunkmanager, int i, Random random, int j, int k, List list, int l) { + super((WorldGenVillagePieces.WorldGenVillageStartPiece) null, 0, random, j, k); + this.a = worldchunkmanager; + this.e = list; + this.c = l; + BiomeBase biomebase = worldchunkmanager.getBiome(new BlockPosition(j, 0, k), BiomeBase.ad); + + this.b = biomebase == BiomeBase.DESERT || biomebase == BiomeBase.DESERT_HILLS; + this.a(this.b); + } + + public WorldChunkManager e() { + return this.a; + } + } + + public static class WorldGenVillageWell extends WorldGenVillagePieces.WorldGenVillagePiece { + + public WorldGenVillageWell() {} + + public WorldGenVillageWell(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i, Random random, int j, int k) { + super(worldgenvillagepieces_worldgenvillagestartpiece, i); + this.m = EnumDirection.EnumDirectionLimit.HORIZONTAL.a(random); + switch (WorldGenVillagePieces.SyntheticClass_1.a[this.m.ordinal()]) { + case 1: + case 2: + this.l = new StructureBoundingBox(j, 64, k, j + 6 - 1, 78, k + 6 - 1); + break; + + default: + this.l = new StructureBoundingBox(j, 64, k, j + 6 - 1, 78, k + 6 - 1); + } + + } + + public void a(StructurePiece structurepiece, List list, Random random) { + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.a - 1, this.l.e - 4, this.l.c + 1, EnumDirection.WEST, this.d()); + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.d + 1, this.l.e - 4, this.l.c + 1, EnumDirection.EAST, this.d()); + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.a + 1, this.l.e - 4, this.l.c - 1, EnumDirection.NORTH, this.d()); + WorldGenVillagePieces.e((WorldGenVillagePieces.WorldGenVillageStartPiece) structurepiece, list, random, this.l.a + 1, this.l.e - 4, this.l.f + 1, EnumDirection.SOUTH, this.d()); + } + + public boolean a(World world, Random random, StructureBoundingBox structureboundingbox) { + if (this.h < 0) { + this.h = this.b(world, structureboundingbox); + if (this.h < 0) { + return true; + } + + this.l.a(0, this.h - this.l.e + 3, 0); + } + + this.a(world, structureboundingbox, 1, 0, 1, 4, 12, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.FLOWING_WATER.getBlockData(), false); + this.a(world, Blocks.AIR.getBlockData(), 2, 12, 2, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 3, 12, 2, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 2, 12, 3, structureboundingbox); + this.a(world, Blocks.AIR.getBlockData(), 3, 12, 3, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 13, 1, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 14, 1, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 13, 1, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 14, 1, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 13, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 1, 14, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 13, 4, structureboundingbox); + this.a(world, Blocks.FENCE.getBlockData(), 4, 14, 4, structureboundingbox); + this.a(world, structureboundingbox, 1, 15, 1, 4, 15, 4, Blocks.COBBLESTONE.getBlockData(), Blocks.COBBLESTONE.getBlockData(), false); + + for (int i = 0; i <= 5; ++i) { + for (int j = 0; j <= 5; ++j) { + if (j == 0 || j == 5 || i == 0 || i == 5) { + this.a(world, Blocks.GRAVEL.getBlockData(), j, 11, i, structureboundingbox); + this.b(world, j, 12, i, structureboundingbox); + } + } + } + + return true; + } + } + + abstract static class WorldGenVillagePiece extends StructurePiece { + + protected int h = -1; + private int a; + private boolean b; + + public WorldGenVillagePiece() {} + + protected WorldGenVillagePiece(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, int i) { + super(i); + if (worldgenvillagepieces_worldgenvillagestartpiece != null) { + this.b = worldgenvillagepieces_worldgenvillagestartpiece.b; + } + + } + + protected void a(NBTTagCompound nbttagcompound) { + nbttagcompound.setInt("HPos", this.h); + nbttagcompound.setInt("VCount", this.a); + nbttagcompound.setBoolean("Desert", this.b); + } + + protected void b(NBTTagCompound nbttagcompound) { + this.h = nbttagcompound.getInt("HPos"); + this.a = nbttagcompound.getInt("VCount"); + this.b = nbttagcompound.getBoolean("Desert"); + } + + protected StructurePiece a(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j) { + if (this.m != null) { + switch (WorldGenVillagePieces.SyntheticClass_1.a[this.m.ordinal()]) { + case 1: + return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.l.a - 1, this.l.b + i, this.l.c + j, EnumDirection.WEST, this.d()); + + case 2: + return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.l.a - 1, this.l.b + i, this.l.c + j, EnumDirection.WEST, this.d()); + + case 3: + return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.l.a + j, this.l.b + i, this.l.c - 1, EnumDirection.NORTH, this.d()); + + case 4: + return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.l.a + j, this.l.b + i, this.l.c - 1, EnumDirection.NORTH, this.d()); + } + } + + return null; + } + + protected StructurePiece b(WorldGenVillagePieces.WorldGenVillageStartPiece worldgenvillagepieces_worldgenvillagestartpiece, List list, Random random, int i, int j) { + if (this.m != null) { + switch (WorldGenVillagePieces.SyntheticClass_1.a[this.m.ordinal()]) { + case 1: + return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.l.d + 1, this.l.b + i, this.l.c + j, EnumDirection.EAST, this.d()); + + case 2: + return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.l.d + 1, this.l.b + i, this.l.c + j, EnumDirection.EAST, this.d()); + + case 3: + return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.l.a + j, this.l.b + i, this.l.f + 1, EnumDirection.SOUTH, this.d()); + + case 4: + return WorldGenVillagePieces.d(worldgenvillagepieces_worldgenvillagestartpiece, list, random, this.l.a + j, this.l.b + i, this.l.f + 1, EnumDirection.SOUTH, this.d()); + } + } + + return null; + } + + protected int b(World world, StructureBoundingBox structureboundingbox) { + int i = 0; + int j = 0; + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + + for (int k = this.l.c; k <= this.l.f; ++k) { + for (int l = this.l.a; l <= this.l.d; ++l) { + blockposition_mutableblockposition.c(l, 64, k); + if (structureboundingbox.b((BaseBlockPosition) blockposition_mutableblockposition)) { + i += Math.max(world.r(blockposition_mutableblockposition).getY(), world.worldProvider.getSeaLevel()); + ++j; + } + } + } + + if (j == 0) { + return -1; + } else { + return i / j; + } + } + + protected static boolean a(StructureBoundingBox structureboundingbox) { + return structureboundingbox != null && structureboundingbox.b > 10; + } + + protected void a(World world, StructureBoundingBox structureboundingbox, int i, int j, int k, int l) { + if (this.a < l) { + for (int i1 = this.a; i1 < l; ++i1) { + int j1 = this.a(i + i1, k); + int k1 = this.d(j); + int l1 = this.b(i + i1, k); + + if (!structureboundingbox.b((BaseBlockPosition) (new BlockPosition(j1, k1, l1)))) { + break; + } + + ++this.a; + EntityVillager entityvillager = new EntityVillager(world); + + entityvillager.setPositionRotation((double) j1 + 0.5D, (double) k1, (double) l1 + 0.5D, 0.0F, 0.0F); + entityvillager.prepare(world.E(new BlockPosition(entityvillager)), (GroupDataEntity) null); + entityvillager.setProfession(this.c(i1, entityvillager.getProfession())); + world.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN); // CraftBukkit - add SpawnReason + } + + } + } + + protected int c(int i, int j) { + return j; + } + + protected IBlockData a(IBlockData iblockdata) { + if (this.b) { + if (iblockdata.getBlock() == Blocks.LOG || iblockdata.getBlock() == Blocks.LOG2) { + return Blocks.SANDSTONE.getBlockData(); + } + + if (iblockdata.getBlock() == Blocks.COBBLESTONE) { + return Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.DEFAULT.a()); + } + + if (iblockdata.getBlock() == Blocks.PLANKS) { + return Blocks.SANDSTONE.fromLegacyData(BlockSandStone.EnumSandstoneVariant.SMOOTH.a()); + } + + if (iblockdata.getBlock() == Blocks.OAK_STAIRS) { + return Blocks.SANDSTONE_STAIRS.getBlockData().set(BlockStairs.FACING, iblockdata.get(BlockStairs.FACING)); + } + + if (iblockdata.getBlock() == Blocks.STONE_STAIRS) { + return Blocks.SANDSTONE_STAIRS.getBlockData().set(BlockStairs.FACING, iblockdata.get(BlockStairs.FACING)); + } + + if (iblockdata.getBlock() == Blocks.GRAVEL) { + return Blocks.SANDSTONE.getBlockData(); + } + } + + return iblockdata; + } + + protected void a(World world, IBlockData iblockdata, int i, int j, int k, StructureBoundingBox structureboundingbox) { + IBlockData iblockdata1 = this.a(iblockdata); + + super.a(world, iblockdata1, i, j, k, structureboundingbox); + } + + protected void a(World world, StructureBoundingBox structureboundingbox, int i, int j, int k, int l, int i1, int j1, IBlockData iblockdata, IBlockData iblockdata1, boolean flag) { + IBlockData iblockdata2 = this.a(iblockdata); + IBlockData iblockdata3 = this.a(iblockdata1); + + super.a(world, structureboundingbox, i, j, k, l, i1, j1, iblockdata2, iblockdata3, flag); + } + + protected void b(World world, IBlockData iblockdata, int i, int j, int k, StructureBoundingBox structureboundingbox) { + IBlockData iblockdata1 = this.a(iblockdata); + + super.b(world, iblockdata1, i, j, k, structureboundingbox); + } + + protected void a(boolean flag) { + this.b = flag; + } + } + + public static class WorldGenVillagePieceWeight { + + public Class a; + public final int b; + public int c; + public int d; + + public WorldGenVillagePieceWeight(Class oclass, int i, int j) { + this.a = oclass; + this.b = i; + this.d = j; + } + + public boolean a(int i) { + return this.d == 0 || this.c < this.d; + } + + public boolean a() { + return this.d == 0 || this.c < this.d; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldManager.java new file mode 100644 index 0000000..04220b8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldManager.java @@ -0,0 +1,95 @@ +package net.minecraft.server; + +import java.util.Iterator; + +public class WorldManager implements IWorldAccess { + + private MinecraftServer a; + private WorldServer world; + + public WorldManager(MinecraftServer minecraftserver, WorldServer worldserver) { + this.a = minecraftserver; + this.world = worldserver; + } + + public void a(int i, boolean flag, double d0, double d1, double d2, double d3, double d4, double d5, int... aint) {} + + public void a(Entity entity) { + this.world.getTracker().track(entity); + } + + public void b(Entity entity) { + this.world.getTracker().untrackEntity(entity); + this.world.getScoreboard().a(entity); + } + + public void a(String s, double d0, double d1, double d2, float f, float f1) { + // CraftBukkit - this.world.dimension + this.a.getPlayerList().sendPacketNearby(d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.dimension, new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1)); + } + + public void a(EntityHuman entityhuman, String s, double d0, double d1, double d2, float f, float f1) { + // CraftBukkit - this.world.dimension + // Paper start - fix invisible players hearing other sounds + if (s.equals("random.drink") || s.contains("step") || s.contains("player") || s.equals("random.eat")) { + this.a.getPlayerList().sendPacketNearby(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.dimension, new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1)); + } else { + this.a.getPlayerList().sendPacketNearbyIncludingSelf(entityhuman, d0, d1, d2, f > 1.0F ? (double) (16.0F * f) : 16.0D, this.world.dimension, new PacketPlayOutNamedSoundEffect(s, d0, d1, d2, f, f1)); + } + // Paper end + } + + public void a(int i, int j, int k, int l, int i1, int j1) {} + + public void a(BlockPosition blockposition) { + this.world.getPlayerChunkMap().flagDirty(blockposition); + } + + public void b(BlockPosition blockposition) {} + + public void a(String s, BlockPosition blockposition) {} + + public void a(EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { + // CraftBukkit - this.world.dimension + if (i == 2001) { + this.a.getPlayerList().sendPacketNearby(entityhuman, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 64.0D, this.world.dimension, new PacketPlayOutWorldEvent(i, blockposition, j, false)); + } else { + this.a.getPlayerList().sendPacketNearbyIncludingSelf(entityhuman, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), 64.0D, this.world.dimension, new PacketPlayOutWorldEvent(i, blockposition, j, false)); + } + } + + public void a(int i, BlockPosition blockposition, int j) { + this.a.getPlayerList().sendAll(new PacketPlayOutWorldEvent(i, blockposition, j, true)); + } + + public void b(int i, BlockPosition blockposition, int j) { + Iterator iterator = this.a.getPlayerList().v().iterator(); + + // CraftBukkit start + EntityHuman entityhuman = null; + Entity entity = world.a(i); // PAIL Rename getEntity + if (entity instanceof EntityHuman) entityhuman = (EntityHuman) entity; + // CraftBukkit end + + while (iterator.hasNext()) { + EntityPlayer entityplayer = (EntityPlayer) iterator.next(); + + if (entityplayer != null && entityplayer.world == this.world && entityplayer.getId() != i) { + double d0 = (double) blockposition.getX() - entityplayer.locX; + double d1 = (double) blockposition.getY() - entityplayer.locY; + double d2 = (double) blockposition.getZ() - entityplayer.locZ; + + if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D) { + // Mythic - Move CraftPlayer#canSee down + // CraftBukkit start + if (entityhuman instanceof EntityPlayer && !entityplayer.getBukkitEntity().canSee(((EntityPlayer) entityhuman).getBukkitEntity())) { + continue; + } + // CraftBukkit end + entityplayer.playerConnection.sendPacket(new PacketPlayOutBlockBreakAnimation(i, blockposition, j)); + } + } + } + + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldMap.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldMap.java new file mode 100644 index 0000000..162b3a3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldMap.java @@ -0,0 +1,316 @@ +package net.minecraft.server; + +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +// CraftBukkit start +import java.util.UUID; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.map.CraftMapView; +// CraftBukkit end + +public class WorldMap extends PersistentBase { + + public int centerX; + public int centerZ; + public byte map; + public byte scale; + public byte[] colors = new byte[16384]; + public List g = Lists.newArrayList(); + public Map i = Maps.newHashMap(); // Spigot + public Map decorations = Maps.newLinkedHashMap(); // Spigot + + // CraftBukkit start + public final CraftMapView mapView; + private CraftServer server; + private UUID uniqueId = null; + // CraftBukkit end + + public WorldMap(String s) { + super(s); + // CraftBukkit start + mapView = new CraftMapView(this); + server = (CraftServer) org.bukkit.Bukkit.getServer(); + // CraftBukkit end + } + + public void a(double d0, double d1, int i) { + int j = 128 * (1 << i); + int k = MathHelper.floor((d0 + 64.0D) / (double) j); + int l = MathHelper.floor((d1 + 64.0D) / (double) j); + + this.centerX = k * j + j / 2 - 64; + this.centerZ = l * j + j / 2 - 64; + } + + public void a(NBTTagCompound nbttagcompound) { + // CraftBukkit start + byte dimension = nbttagcompound.getByte("dimension"); + + if (dimension >= 10) { + long least = nbttagcompound.getLong("UUIDLeast"); + long most = nbttagcompound.getLong("UUIDMost"); + + if (least != 0L && most != 0L) { + this.uniqueId = new UUID(most, least); + + CraftWorld world = (CraftWorld) server.getWorld(this.uniqueId); + // Check if the stored world details are correct. + if (world == null) { + /* All Maps which do not have their valid world loaded are set to a dimension which hopefully won't be reached. + This is to prevent them being corrupted with the wrong map data. */ + dimension = 127; + } else { + dimension = (byte) world.getHandle().dimension; + } + } + } + + this.map = dimension; + // CraftBukkit end + this.centerX = nbttagcompound.getInt("xCenter"); + this.centerZ = nbttagcompound.getInt("zCenter"); + this.scale = nbttagcompound.getByte("scale"); + this.scale = (byte) MathHelper.clamp(this.scale, 0, 4); + short short0 = nbttagcompound.getShort("width"); + short short1 = nbttagcompound.getShort("height"); + + if (short0 == 128 && short1 == 128) { + this.colors = nbttagcompound.getByteArray("colors"); + } else { + byte[] abyte = nbttagcompound.getByteArray("colors"); + + this.colors = new byte[16384]; + int i = (128 - short0) / 2; + int j = (128 - short1) / 2; + + for (int k = 0; k < short1; ++k) { + int l = k + j; + + if (l >= 0 || l < 128) { + for (int i1 = 0; i1 < short0; ++i1) { + int j1 = i1 + i; + + if (j1 >= 0 || j1 < 128) { + this.colors[j1 + l * 128] = abyte[i1 + k * short0]; + } + } + } + } + } + + } + + public void b(NBTTagCompound nbttagcompound) { + // CraftBukkit start + if (this.map >= 10) { + if (this.uniqueId == null) { + for (org.bukkit.World world : server.getWorlds()) { + CraftWorld cWorld = (CraftWorld) world; + if (cWorld.getHandle().dimension == this.map) { + this.uniqueId = cWorld.getUID(); + break; + } + } + } + /* Perform a second check to see if a matching world was found, this is a necessary + change incase Maps are forcefully unlinked from a World and lack a UID.*/ + if (this.uniqueId != null) { + nbttagcompound.setLong("UUIDLeast", this.uniqueId.getLeastSignificantBits()); + nbttagcompound.setLong("UUIDMost", this.uniqueId.getMostSignificantBits()); + } + } + // CraftBukkit end + nbttagcompound.setByte("dimension", this.map); + nbttagcompound.setInt("xCenter", this.centerX); + nbttagcompound.setInt("zCenter", this.centerZ); + nbttagcompound.setByte("scale", this.scale); + nbttagcompound.setShort("width", (short) 128); + nbttagcompound.setShort("height", (short) 128); + nbttagcompound.setByteArray("colors", this.colors); + } + + public void a(EntityHuman entityhuman, ItemStack itemstack) { + if (!this.i.containsKey(entityhuman)) { + WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker = new WorldMap.WorldMapHumanTracker(entityhuman); + + this.i.put(entityhuman, worldmap_worldmaphumantracker); + this.g.add(worldmap_worldmaphumantracker); + } + + if (!entityhuman.inventory.c(itemstack)) { + this.decorations.remove(entityhuman.getUniqueID()); // Spigot + } + + for (int i = 0; i < this.g.size(); ++i) { + WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker1 = (WorldMap.WorldMapHumanTracker) this.g.get(i); + + if (!worldmap_worldmaphumantracker1.trackee.dead && (worldmap_worldmaphumantracker1.trackee.inventory.c(itemstack) || itemstack.y())) { + if (!itemstack.y() && worldmap_worldmaphumantracker1.trackee.dimension == this.map) { + this.a(0, worldmap_worldmaphumantracker1.trackee.world, worldmap_worldmaphumantracker1.trackee.getUniqueID(), worldmap_worldmaphumantracker1.trackee.locX, worldmap_worldmaphumantracker1.trackee.locZ, (double) worldmap_worldmaphumantracker1.trackee.yaw); // Spigot + } + } else { + this.i.remove(worldmap_worldmaphumantracker1.trackee); + this.g.remove(worldmap_worldmaphumantracker1); + } + } + + if (itemstack.y()) { + EntityItemFrame entityitemframe = itemstack.z(); + BlockPosition blockposition = entityitemframe.getBlockPosition(); + + this.a(1, entityhuman.world, UUID.nameUUIDFromBytes(("frame-" + entityitemframe.getId()).getBytes(Charsets.US_ASCII)), (double) blockposition.getX(), (double) blockposition.getZ(), (double) (entityitemframe.direction.b() * 90)); // Spigot + } + + if (itemstack.hasTag() && itemstack.getTag().hasKeyOfType("Decorations", 9)) { + NBTTagList nbttaglist = itemstack.getTag().getList("Decorations", 10); + + for (int j = 0; j < nbttaglist.size(); ++j) { + NBTTagCompound nbttagcompound = nbttaglist.get(j); + + // Spigot - start + UUID uuid = UUID.nameUUIDFromBytes(nbttagcompound.getString("id").getBytes(Charsets.US_ASCII)); + if (!this.decorations.containsKey(uuid)) { + this.a(nbttagcompound.getByte("type"), entityhuman.world, uuid, nbttagcompound.getDouble("x"), nbttagcompound.getDouble("z"), nbttagcompound.getDouble("rot")); + // Spigot - end + } + } + } + + } + + private void a(int i, World world, UUID s, double d0, double d1, double d2) { + int j = 1 << this.scale; + float f = (float) (d0 - (double) this.centerX) / (float) j; + float f1 = (float) (d1 - (double) this.centerZ) / (float) j; + byte b0 = (byte) ((int) ((double) (f * 2.0F) + 0.5D)); + byte b1 = (byte) ((int) ((double) (f1 * 2.0F) + 0.5D)); + byte b2 = 63; + byte b3; + + if (f >= (float) (-b2) && f1 >= (float) (-b2) && f <= (float) b2 && f1 <= (float) b2) { + d2 += d2 < 0.0D ? -8.0D : 8.0D; + b3 = (byte) ((int) (d2 * 16.0D / 360.0D)); + if (this.map < 0) { + int k = (int) (world.getWorldData().getDayTime() / 10L); + + b3 = (byte) (k * k * 34187121 + k * 121 >> 15 & 15); + } + } else { + if (Math.abs(f) >= 320.0F || Math.abs(f1) >= 320.0F) { + this.decorations.remove(s); + return; + } + + i = 6; + b3 = 0; + if (f <= (float) (-b2)) { + b0 = (byte) ((int) ((double) (b2 * 2) + 2.5D)); + } + + if (f1 <= (float) (-b2)) { + b1 = (byte) ((int) ((double) (b2 * 2) + 2.5D)); + } + + if (f >= (float) b2) { + b0 = (byte) (b2 * 2 + 1); + } + + if (f1 >= (float) b2) { + b1 = (byte) (b2 * 2 + 1); + } + } + + this.decorations.put(s, new MapIcon((byte) i, b0, b1, b3)); + } + + public Packet a(ItemStack itemstack, World world, EntityHuman entityhuman) { + WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker = (WorldMap.WorldMapHumanTracker) this.i.get(entityhuman); + + return worldmap_worldmaphumantracker == null ? null : worldmap_worldmaphumantracker.a(itemstack); + } + + public void flagDirty(int i, int j) { + super.c(); + Iterator iterator = this.g.iterator(); + + while (iterator.hasNext()) { + WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker = (WorldMap.WorldMapHumanTracker) iterator.next(); + + worldmap_worldmaphumantracker.a(i, j); + } + + } + + public WorldMap.WorldMapHumanTracker a(EntityHuman entityhuman) { + WorldMap.WorldMapHumanTracker worldmap_worldmaphumantracker = (WorldMap.WorldMapHumanTracker) this.i.get(entityhuman); + + if (worldmap_worldmaphumantracker == null) { + worldmap_worldmaphumantracker = new WorldMap.WorldMapHumanTracker(entityhuman); + this.i.put(entityhuman, worldmap_worldmaphumantracker); + this.g.add(worldmap_worldmaphumantracker); + } + + return worldmap_worldmaphumantracker; + } + + public class WorldMapHumanTracker { + + public final EntityHuman trackee; + private boolean d = true; + private int e = 0; + private int f = 0; + private int g = 127; + private int h = 127; + private int i; + public int b; + + public WorldMapHumanTracker(EntityHuman entityhuman) { + this.trackee = entityhuman; + } + + public Packet a(ItemStack itemstack) { + // CraftBukkit start + org.bukkit.craftbukkit.map.RenderData render = WorldMap.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.trackee.getBukkitEntity()); // CraftBukkit + + java.util.Collection icons = new java.util.ArrayList(); + + for ( org.bukkit.map.MapCursor cursor : render.cursors) { + + if (cursor.isVisible()) { + icons.add(new MapIcon(cursor.getRawType(), cursor.getX(), cursor.getY(), cursor.getDirection())); + } + } + + if (this.d) { + this.d = false; + return new PacketPlayOutMap(itemstack.getData(), WorldMap.this.scale, icons, render.buffer, this.e, this.f, this.g + 1 - this.e, this.h + 1 - this.f); + } else { + return this.i++ % 5 == 0 ? new PacketPlayOutMap(itemstack.getData(), WorldMap.this.scale, icons, render.buffer, 0, 0, 0, 0) : null; + } + // CraftBukkit end + } + + public void a(int i, int j) { + if (this.d) { + this.e = Math.min(this.e, i); + this.f = Math.min(this.f, j); + this.g = Math.max(this.g, i); + this.h = Math.max(this.h, j); + } else { + this.d = true; + this.e = i; + this.f = j; + this.g = i; + this.h = j; + } + + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldNBTStorage.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldNBTStorage.java new file mode 100644 index 0000000..e5124af --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldNBTStorage.java @@ -0,0 +1,338 @@ +package net.minecraft.server; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +// CraftBukkit start +import java.util.UUID; + +import org.bukkit.craftbukkit.entity.CraftPlayer; +// CraftBukkit end + +public class WorldNBTStorage implements IDataManager, IPlayerFileData { + + private static final Logger a = LogManager.getLogger(); + private final File baseDir; + private final File playerDir; + private final File dataDir; + private final long sessionId = MinecraftServer.az(); + private final String f; + private UUID uuid = null; // CraftBukkit + + public WorldNBTStorage(File file, String s, boolean flag) { + this.baseDir = new File(file, s); + this.baseDir.mkdirs(); + this.playerDir = new File(this.baseDir, "playerdata"); + this.dataDir = new File(this.baseDir, "data"); + this.dataDir.mkdirs(); + this.f = s; + if (flag) { + this.playerDir.mkdirs(); + } + + this.h(); + } + + private void h() { + try { + File file = new File(this.baseDir, "session.lock"); + DataOutputStream dataoutputstream = new DataOutputStream(new FileOutputStream(file)); + + try { + dataoutputstream.writeLong(this.sessionId); + } finally { + dataoutputstream.close(); + } + + } catch (IOException ioexception) { + ioexception.printStackTrace(); + throw new RuntimeException("Failed to check session lock for world located at " + this.baseDir + ", aborting. Stop the server and delete the session.lock in this world to prevent further issues."); // Spigot + } + } + + public File getDirectory() { + return this.baseDir; + } + + public void checkSession() throws ExceptionWorldConflict { + try { + File file = new File(this.baseDir, "session.lock"); + DataInputStream datainputstream = new DataInputStream(new FileInputStream(file)); + + try { + if (datainputstream.readLong() != this.sessionId) { + throw new ExceptionWorldConflict("The save for world located at " + this.baseDir + " is being accessed from another location, aborting"); // Spigot + } + } finally { + datainputstream.close(); + } + + } catch (IOException ioexception) { + throw new ExceptionWorldConflict("Failed to check session lock for world located at " + this.baseDir + ", aborting. Stop the server and delete the session.lock in this world to prevent further issues."); // Spigot + } + } + + public IChunkLoader createChunkLoader(WorldProvider worldprovider) { + throw new RuntimeException("Old Chunk Storage is no longer supported."); + } + + public WorldData getWorldData() { + File file = new File(this.baseDir, "level.dat"); + NBTTagCompound nbttagcompound; + NBTTagCompound nbttagcompound1; + + if (file.exists()) { + try { + nbttagcompound = NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file))); + nbttagcompound1 = nbttagcompound.getCompound("Data"); + return new WorldData(nbttagcompound1); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + + file = new File(this.baseDir, "level.dat_old"); + if (file.exists()) { + try { + nbttagcompound = NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file))); + nbttagcompound1 = nbttagcompound.getCompound("Data"); + return new WorldData(nbttagcompound1); + } catch (Exception exception1) { + exception1.printStackTrace(); + } + } + + return null; + } + + public void saveWorldData(WorldData worlddata, NBTTagCompound nbttagcompound) { + NBTTagCompound nbttagcompound1 = worlddata.a(nbttagcompound); + NBTTagCompound nbttagcompound2 = new NBTTagCompound(); + + nbttagcompound2.set("Data", nbttagcompound1); + + try { + File file = new File(this.baseDir, "level.dat_new"); + File file1 = new File(this.baseDir, "level.dat_old"); + File file2 = new File(this.baseDir, "level.dat"); + + NBTCompressedStreamTools.a(nbttagcompound2, (OutputStream) (new FileOutputStream(file))); + if (file1.exists()) { + file1.delete(); + } + + file2.renameTo(file1); + if (file2.exists()) { + file2.delete(); + } + + file.renameTo(file2); + if (file.exists()) { + file.delete(); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + + } + + public void saveWorldData(WorldData worlddata) { + NBTTagCompound nbttagcompound = worlddata.a(); + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + + nbttagcompound1.set("Data", nbttagcompound); + + try { + File file = new File(this.baseDir, "level.dat_new"); + File file1 = new File(this.baseDir, "level.dat_old"); + File file2 = new File(this.baseDir, "level.dat"); + + NBTCompressedStreamTools.a(nbttagcompound1, (OutputStream) (new FileOutputStream(file))); + if (file1.exists()) { + file1.delete(); + } + + file2.renameTo(file1); + if (file2.exists()) { + file2.delete(); + } + + file.renameTo(file2); + if (file.exists()) { + file.delete(); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + + } + + public void save(EntityHuman entityhuman) { + try { + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + entityhuman.e(nbttagcompound); + File file = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat.tmp"); + File file1 = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat"); + + NBTCompressedStreamTools.a(nbttagcompound, (OutputStream) (new FileOutputStream(file))); + if (file1.exists()) { + file1.delete(); + } + + file.renameTo(file1); + } catch (Exception exception) { + WorldNBTStorage.a.warn("Failed to save player data for " + entityhuman.getName()); + } + + } + + public NBTTagCompound load(EntityHuman entityhuman) { + NBTTagCompound nbttagcompound = null; + + try { + File file = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat"); + // Spigot Start + boolean usingWrongFile = false; + if ( org.bukkit.Bukkit.getOnlineMode() && !file.exists() ) // PaperSpigot - Check online mode first + { + file = new File( this.playerDir, UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + entityhuman.getName() ).getBytes( "UTF-8" ) ).toString() + ".dat"); + if ( file.exists() ) + { + usingWrongFile = true; + org.bukkit.Bukkit.getServer().getLogger().warning( "Using offline mode UUID file for player " + entityhuman.getName() + " as it is the only copy we can find." ); + } + } + // Spigot End + + if (file.exists() && file.isFile()) { + nbttagcompound = NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file))); + } + // Spigot Start + if ( usingWrongFile ) + { + file.renameTo( new File( file.getPath() + ".offline-read" ) ); + } + // Spigot End + } catch (Exception exception) { + WorldNBTStorage.a.warn("Failed to load player data for " + entityhuman.getName()); + } + + if (nbttagcompound != null) { + // CraftBukkit start + if (entityhuman instanceof EntityPlayer) { + CraftPlayer player = (CraftPlayer) entityhuman.getBukkitEntity(); + // Only update first played if it is older than the one we have + long modified = new File(this.playerDir, entityhuman.getUniqueID().toString() + ".dat").lastModified(); + if (modified < player.getFirstPlayed()) { + player.setFirstPlayed(modified); + } + } + // CraftBukkit end + + entityhuman.f(nbttagcompound); + } + + return nbttagcompound; + } + + // CraftBukkit start + public NBTTagCompound getPlayerData(String s) { + try { + File file1 = new File(this.playerDir, s + ".dat"); + + if (file1.exists()) { + return NBTCompressedStreamTools.a((InputStream) (new FileInputStream(file1))); + } + } catch (Exception exception) { + a.warn("Failed to load player data for " + s); + } + + return null; + } + // CraftBukkit end + + public IPlayerFileData getPlayerFileData() { + return this; + } + + public String[] getSeenPlayers() { + String[] astring = this.playerDir.list(); + + if (astring == null) { + astring = new String[0]; + } + + for (int i = 0; i < astring.length; ++i) { + if (astring[i].endsWith(".dat")) { + astring[i] = astring[i].substring(0, astring[i].length() - 4); + } + } + + return astring; + } + + public void a() {} + + public File getDataFile(String s) { + return new File(this.dataDir, s + ".dat"); + } + + public String g() { + return this.f; + } + + // CraftBukkit start + public UUID getUUID() { + if (uuid != null) return uuid; + File file1 = new File(this.baseDir, "uid.dat"); + if (file1.exists()) { + DataInputStream dis = null; + try { + dis = new DataInputStream(new FileInputStream(file1)); + return uuid = new UUID(dis.readLong(), dis.readLong()); + } catch (IOException ex) { + a.warn("Failed to read " + file1 + ", generating new random UUID", ex); + } finally { + if (dis != null) { + try { + dis.close(); + } catch (IOException ex) { + // NOOP + } + } + } + } + uuid = UUID.randomUUID(); + DataOutputStream dos = null; + try { + dos = new DataOutputStream(new FileOutputStream(file1)); + dos.writeLong(uuid.getMostSignificantBits()); + dos.writeLong(uuid.getLeastSignificantBits()); + } catch (IOException ex) { + a.warn("Failed to write " + file1, ex); + } finally { + if (dos != null) { + try { + dos.close(); + } catch (IOException ex) { + // NOOP + } + } + } + return uuid; + } + + public File getPlayerDir() { + return playerDir; + } + // CraftBukkit end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java new file mode 100644 index 0000000..2b3f0ba --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/minecraft/server/WorldServer.java @@ -0,0 +1,1277 @@ +package net.minecraft.server; + +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.util.concurrent.ListenableFuture; +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.WeatherType; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.util.HashTreeSet; +import org.bukkit.craftbukkit.util.LongHash; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.weather.LightningStrikeEvent; + +import java.util.*; +import java.util.logging.Level; + +// CraftBukkit start +// CraftBukkit end + +public class WorldServer extends World implements IAsyncTaskHandler { + + private static final Logger a = LogManager.getLogger(); + private final MinecraftServer server; + public EntityTracker tracker; + private final PlayerChunkMap manager; + // private final Set L = Sets.newHashSet(); // PAIL: Rename nextTickListHash + private final HashTreeSet M = new HashTreeSet(); // CraftBukkit - HashTreeSet // PAIL: Rename nextTickList + private final Map entitiesByUUID = Maps.newHashMap(); + public ChunkProviderServer chunkProviderServer; + public boolean savingDisabled; + private boolean O; + private int emptyTime; + private final PortalTravelAgent Q; + private final SpawnerCreature R = new SpawnerCreature(); + protected final VillageSiege siegeManager = new VillageSiege(this); + private WorldServer.BlockActionDataList[] S = new WorldServer.BlockActionDataList[] { new WorldServer.BlockActionDataList(null), new WorldServer.BlockActionDataList(null)}; + private int T; + private static final List U = Lists.newArrayList(new StructurePieceTreasure(Items.STICK, 0, 1, 3, 10), new StructurePieceTreasure(Item.getItemOf(Blocks.PLANKS), 0, 1, 3, 10), new StructurePieceTreasure(Item.getItemOf(Blocks.LOG), 0, 1, 3, 10), new StructurePieceTreasure(Items.STONE_AXE, 0, 1, 1, 3), new StructurePieceTreasure(Items.WOODEN_AXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.STONE_PICKAXE, 0, 1, 1, 3), new StructurePieceTreasure(Items.WOODEN_PICKAXE, 0, 1, 1, 5), new StructurePieceTreasure(Items.APPLE, 0, 2, 3, 5), new StructurePieceTreasure(Items.BREAD, 0, 2, 3, 3), new StructurePieceTreasure(Item.getItemOf(Blocks.LOG2), 0, 1, 3, 10)); + private List V = Lists.newArrayList(); + + // CraftBukkit start + public final int dimension; + + // Add env and gen to constructor + public WorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, WorldData worlddata, int i, MethodProfiler methodprofiler, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + super(idatamanager, worlddata, WorldProvider.byDimension(env.getId()), methodprofiler, false, gen, env); + this.dimension = i; + this.pvpMode = minecraftserver.getPVP(); + worlddata.world = this; + // CraftBukkit end + this.server = minecraftserver; + this.tracker = new EntityTracker(this); + this.manager = new PlayerChunkMap(this, spigotConfig.viewDistance); // Spigot + this.worldProvider.a(this); + this.chunkProvider = this.k(); + this.Q = ((org.bukkit.craftbukkit.CraftTravelAgent) new org.bukkit.craftbukkit.CraftTravelAgent(this).setSearchRadius(paperSpigotConfig.portalSearchRadius)); // CraftBukkit // Paper - configurable search radius + this.B(); + this.C(); + this.getWorldBorder().a(minecraftserver.aI()); + } + + public ChunkProviderServer getChunkProviderServer() { + return chunkProviderServer; + } + + public World b() { + this.worldMaps = new PersistentCollection(this.dataManager); + String s = PersistentVillage.a(this.worldProvider); + PersistentVillage persistentvillage = (PersistentVillage) this.worldMaps.get(PersistentVillage.class, s); + + if (persistentvillage == null) { + this.villages = new PersistentVillage(this); + this.worldMaps.a(s, this.villages); + } else { + this.villages = persistentvillage; + this.villages.a(this); + } + + if (getServer().getScoreboardManager() == null) { // CraftBukkit + this.scoreboard = new ScoreboardServer(this.server); + PersistentScoreboard persistentscoreboard = (PersistentScoreboard) this.worldMaps.get(PersistentScoreboard.class, "scoreboard"); + + if (persistentscoreboard == null) { + persistentscoreboard = new PersistentScoreboard(); + this.worldMaps.a("scoreboard", persistentscoreboard); + } + + persistentscoreboard.a(this.scoreboard); + ((ScoreboardServer) this.scoreboard).a(persistentscoreboard); + // CraftBukkit start + } else { + this.scoreboard = getServer().getScoreboardManager().getMainScoreboard().getHandle(); + } + // CraftBukkit end + this.getWorldBorder().setCenter(this.worldData.C(), this.worldData.D()); + this.getWorldBorder().setDamageAmount(this.worldData.I()); + this.getWorldBorder().setDamageBuffer(this.worldData.H()); + this.getWorldBorder().setWarningDistance(this.worldData.J()); + this.getWorldBorder().setWarningTime(this.worldData.K()); + if (this.worldData.F() > 0L) { + this.getWorldBorder().transitionSizeBetween(this.worldData.E(), this.worldData.G(), this.worldData.F()); + } else { + this.getWorldBorder().setSize(this.worldData.E()); + } + + // CraftBukkit start + if (generator != null) { + getWorld().getPopulators().addAll(generator.getDefaultPopulators(getWorld())); + } + // CraftBukkit end + + return this; + } + + // CraftBukkit start + @Override + public TileEntity getTileEntity(BlockPosition pos) { + TileEntity result = super.getTileEntity(pos); + Block type = getType(pos).getBlock(); + + if (type == Blocks.CHEST || type == Blocks.TRAPPED_CHEST) { // Spigot + if (!(result instanceof TileEntityChest)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.FURNACE) { + if (!(result instanceof TileEntityFurnace)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.DROPPER) { + if (!(result instanceof TileEntityDropper)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.DISPENSER) { + if (!(result instanceof TileEntityDispenser)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.JUKEBOX) { + if (!(result instanceof BlockJukeBox.TileEntityRecordPlayer)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.NOTEBLOCK) { + if (!(result instanceof TileEntityNote)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.MOB_SPAWNER) { + if (!(result instanceof TileEntityMobSpawner)) { + result = fixTileEntity(pos, type, result); + } + } else if ((type == Blocks.STANDING_SIGN) || (type == Blocks.WALL_SIGN)) { + if (!(result instanceof TileEntitySign)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.ENDER_CHEST) { + if (!(result instanceof TileEntityEnderChest)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.BREWING_STAND) { + if (!(result instanceof TileEntityBrewingStand)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.BEACON) { + if (!(result instanceof TileEntityBeacon)) { + result = fixTileEntity(pos, type, result); + } + } else if (type == Blocks.HOPPER) { + if (!(result instanceof TileEntityHopper)) { + result = fixTileEntity(pos, type, result); + } + } + + return result; + } + + private TileEntity fixTileEntity(BlockPosition pos, Block type, TileEntity found) { + this.getServer().getLogger().log(Level.SEVERE, "Block at {0},{1},{2} is {3} but has {4}" + ". " + + "Bukkit will attempt to fix this, but there may be additional damage that we cannot recover.", new Object[]{pos.getX(), pos.getY(), pos.getZ(), org.bukkit.Material.getMaterial(Block.getId(type)).toString(), found}); + + if (type instanceof IContainer) { + TileEntity replacement = ((IContainer) type).a(this, type.toLegacyData(this.getType(pos))); + replacement.world = this; + this.setTileEntity(pos, replacement); + return replacement; + } else { + this.getServer().getLogger().severe("Don't know how to fix for this type... Can't do anything! :("); + return found; + } + } + + private boolean canSpawn(int x, int z) { + if (this.generator != null) { + return this.generator.canSpawn(this.getWorld(), x, z); + } else { + return this.worldProvider.canSpawn(x, z); + } + } + // CraftBukkit end + + public void doTick() { + super.doTick(); + if(MythicConfiguration.Options.World.checkDifficulty) { + if (this.getWorldData().isHardcore() && this.getDifficulty() != EnumDifficulty.HARD) { + this.getWorldData().setDifficulty(EnumDifficulty.HARD); + } + } + + this.worldProvider.m().b(); + if(MythicConfiguration.Options.World.daylightCycle) { + if (this.everyoneDeeplySleeping()) { + if (this.getGameRules().getBoolean("doDaylightCycle")) { + long i = this.worldData.getDayTime() + 24000L; + + this.worldData.setDayTime(i - i % 24000L); + } + + this.e(); + } + } + + if(MythicConfiguration.Options.World.Mobs.spawn) { + // 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)) { + timings.mobSpawn.startTiming(); // Spigot + this.R.a(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L); + timings.mobSpawn.stopTiming(); // Spigot + // CraftBukkit end + } + } + + // CraftBukkit end + timings.doChunkUnload.startTiming(); // Spigot + this.methodProfiler.c("chunkSource"); + if(MythicConfiguration.Options.World.Chunks.unload) { + this.chunkProvider.unloadChunks(); + } + if(MythicConfiguration.Options.World.daylightCycle) { + int j = this.a(1.0F); + + if (j != this.ab()) { + this.c(j); + } + } + + if(MythicConfiguration.Options.World.time) { + this.worldData.setTime(this.worldData.getTime() + 1L); + } + + if(MythicConfiguration.Options.World.daylightCycle) { + if (this.getGameRules().getBoolean("doDaylightCycle")) { + this.worldData.setDayTime(this.worldData.getDayTime() + 1L); + } + } + + timings.doChunkUnload.stopTiming(); // Spigot + this.methodProfiler.c("tickPending"); + timings.scheduledBlocks.startTiming(); // Spigot + if(MythicConfiguration.Options.World.tickPending) { + this.a(false); + } + timings.scheduledBlocks.stopTiming(); // Spigot + this.methodProfiler.c("tickBlocks"); + timings.chunkTicks.startTiming(); // Spigot + if(MythicConfiguration.Options.World.tickBlocks) { + this.h(); + } + timings.chunkTicks.stopTiming(); // Spigot + if(MythicConfiguration.Options.World.antiXray) { + spigotConfig.antiXrayInstance.flushUpdates(this); // PaperSpigot + } + this.methodProfiler.c("chunkMap"); + timings.doChunkMap.startTiming(); // Spigot + this.manager.flush(); + timings.doChunkMap.stopTiming(); // Spigot + this.methodProfiler.c("village"); + timings.doVillages.startTiming(); // Spigot + if(MythicConfiguration.Options.World.tickVillage) { + this.villages.tick(); + this.siegeManager.a(); + } + timings.doVillages.stopTiming(); // Spigot + this.methodProfiler.c("portalForcer"); + timings.doPortalForcer.startTiming(); // Spigot + if(MythicConfiguration.Options.World.tickPortals) { + this.Q.a(this.getTime()); + } + timings.doPortalForcer.stopTiming(); // Spigot + this.methodProfiler.b(); + timings.doSounds.startTiming(); // Spigot + if(MythicConfiguration.Options.World.blockActions) { + this.ak(); + } + + if(MythicConfiguration.Options.World.Chunks.unload) { + this.getWorld().processChunkGC(); // CraftBukkit + } + timings.doChunkGC.stopTiming(); // Spigot + } + + public BiomeBase.BiomeMeta a(EnumCreatureType enumcreaturetype, BlockPosition blockposition) { + List list = this.N().getMobsFor(enumcreaturetype, blockposition); + + return list != null && !list.isEmpty() ? (BiomeBase.BiomeMeta) WeightedRandom.a(this.random, list) : null; + } + + public boolean a(EnumCreatureType enumcreaturetype, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition blockposition) { + List list = this.N().getMobsFor(enumcreaturetype, blockposition); + + return (list != null && !list.isEmpty()) && list.contains(biomebase_biomemeta); + } + + public void everyoneSleeping() { + this.O = false; + if (!this.players.isEmpty()) { + int i = 0; + int j = 0; + Iterator iterator = this.players.iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (entityhuman.isSpectator()) { + ++i; + } else if (entityhuman.isSleeping() || entityhuman.fauxSleeping) { + ++j; + } + } + + this.O = j > 0 && j >= this.players.size() - i; + } + + } + + protected void e() { + this.O = false; + Iterator iterator = this.players.iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (entityhuman.isSleeping()) { + entityhuman.a(false, false, true); + } + } + + this.ag(); + } + + private void ag() { + this.worldData.setStorm(false); + // CraftBukkit start + // If we stop due to everyone sleeping we should reset the weather duration to some other random value. + // Not that everyone ever manages to get the whole server to sleep at the same time.... + if (!this.worldData.hasStorm()) { + this.worldData.setWeatherDuration(0); + } + // CraftBukkit end + this.worldData.setThundering(false); + // CraftBukkit start + // If we stop due to everyone sleeping we should reset the weather duration to some other random value. + // Not that everyone ever manages to get the whole server to sleep at the same time.... + if (!this.worldData.isThundering()) { + this.worldData.setThunderDuration(0); + } + // CraftBukkit end + } + + public boolean everyoneDeeplySleeping() { + if (this.O && !this.isClientSide) { + Iterator iterator = this.players.iterator(); + + // CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers + boolean foundActualSleepers = false; + + EntityHuman entityhuman; + + do { + if (!iterator.hasNext()) { + return foundActualSleepers; + } + + entityhuman = (EntityHuman) iterator.next(); + + // CraftBukkit start + if (entityhuman.isDeeplySleeping()) { + foundActualSleepers = true; + } + } while (!entityhuman.isSpectator() || entityhuman.isDeeplySleeping() || entityhuman.fauxSleeping); + // CraftBukkit end + + return false; + } else { + return false; + } + } + + protected void h() { + super.h(); + if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + // Spigot start + gnu.trove.iterator.TLongShortIterator iterator = this.chunkTickList.iterator(); + + while (iterator.hasNext()) { + iterator.advance(); + long chunkCoord = iterator.key(); + + this.getChunkAt(World.keyToX( chunkCoord ), World.keyToZ( chunkCoord )).b(false); + // Spigot end + } + + } else { + int i = 0; + int j = 0; + + // CraftBukkit start + //for (Iterator iterator1 = this.chunkTickList.iterator(); iterator1.hasNext(); this.methodProfiler.b()) { + // ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair) iterator1.next(); + // int k = chunkcoordintpair1.x * 16; + // int l = chunkcoordintpair1.z * 16; + // Spigot start + + // Mythic - Configurable maximum random tick speed + int randomTickSpeed = Math.min(MythicConfiguration.Options.World.maxRandomTick, this.getGameRules().c("randomTickSpeed")); + + for (gnu.trove.iterator.TLongShortIterator iter = chunkTickList.iterator(); iter.hasNext(); ) + { + iter.advance(); + long chunkCoord = iter.key(); + int chunkX = World.keyToX( chunkCoord ); + int chunkZ = World.keyToZ( chunkCoord ); + // If unloaded, or in procedd of being unloaded, drop it + if ( ( !this.chunkProvider.isChunkLoaded( chunkX, chunkZ ) ) || ( this.chunkProviderServer.unloadQueue.contains( LongHash.toLong(chunkX, chunkZ) ) ) ) // TacoSpigot - invoke LongHash directly + { + iter.remove(); + continue; + } + // Spigot end + // ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next(); + int k = chunkX * 16; + int l = chunkZ * 16; + + this.methodProfiler.a("getChunk"); + Chunk chunk = this.getChunkAt(chunkX, chunkZ); + // CraftBukkit end + + // Mythic - Only tick when nearby chunks are loaded + if(MythicConfiguration.Options.World.nearbyChunkRadius > 0 && !chunk.areNeighborsLoaded(Math.min(MythicConfiguration.Options.World.nearbyChunkRadius, 2))) continue; + + this.a(k, l, chunk); + this.methodProfiler.c("tickChunk"); + chunk.b(false); + this.methodProfiler.c("thunder"); + int i1; + BlockPosition blockposition; + + if (!this.paperSpigotConfig.disableThunder && this.random.nextInt(100000) == 0 && this.S() && this.R()) { // PaperSpigot - Disable thunder + this.m = this.m * 3 + 1013904223; + i1 = this.m >> 2; + blockposition = this.a(new BlockPosition(k + (i1 & 15), 0, l + (i1 >> 8 & 15))); + if (this.isRainingAt(blockposition)) { + this.strikeLightning(new EntityLightning(this, blockposition.getX(), blockposition.getY(), blockposition.getZ())); + } + } + + this.methodProfiler.c("iceandsnow"); + if (!this.paperSpigotConfig.disableIceAndSnow && this.random.nextInt(16) == 0) { // PaperSpigot - Disable ice and snow + this.m = this.m * 3 + 1013904223; + i1 = this.m >> 2; + blockposition = this.q(new BlockPosition(k + (i1 & 15), 0, l + (i1 >> 8 & 15))); + BlockPosition blockposition1 = blockposition.down(); + + if (this.w(blockposition1)) { + // CraftBukkit start + BlockState blockState = this.getWorld().getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()).getState(); + blockState.setTypeId(Block.getId(Blocks.ICE)); + + BlockFormEvent iceBlockForm = new BlockFormEvent(blockState.getBlock(), blockState); + this.getServer().getPluginManager().callEvent(iceBlockForm); + if (!iceBlockForm.isCancelled()) { + blockState.update(true); + } + // CraftBukkit end + } + + if (this.S() && this.f(blockposition, true)) { + // CraftBukkit start + BlockState blockState = this.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()).getState(); + blockState.setTypeId(Block.getId(Blocks.SNOW_LAYER)); + + BlockFormEvent snow = new BlockFormEvent(blockState.getBlock(), blockState); + this.getServer().getPluginManager().callEvent(snow); + if (!snow.isCancelled()) { + blockState.update(true); + } + // CraftBukkit end + } + + if (this.S() && this.getBiome(blockposition1).e()) { + this.getType(blockposition1).getBlock().k(this, blockposition1); + } + } + + this.methodProfiler.c("tickBlocks"); + timings.chunkTicksBlocks.startTiming(); // Spigot + i1 = randomTickSpeed; + if (i1 > 0) { + ChunkSection[] achunksection = chunk.getSections(); + int j1 = achunksection.length; + + for (int k1 = 0; k1 < j1; ++k1) { + ChunkSection chunksection = achunksection[k1]; + + if (chunksection != null && chunksection.shouldTick()) { + for (int l1 = 0; l1 < i1; ++l1) { + this.m = this.m * 3 + 1013904223; + int i2 = this.m >> 2; + int j2 = i2 & 15; + int k2 = i2 >> 8 & 15; + int l2 = i2 >> 16 & 15; + + ++j; + IBlockData iblockdata = chunksection.getType(j2, l2, k2); + Block block = iblockdata.getBlock(); + + if (block.isTicking()) { + ++i; + block.a(this, new BlockPosition(j2 + k, l2 + chunksection.getYPosition(), k2 + l), iblockdata, this.random); + } + } + } + } + } + timings.chunkTicksBlocks.stopTiming(); // Spigot + } + + } + // Spigot Start + if ( spigotConfig.clearChunksOnTick ) + { + chunkTickList.clear(); + } + // Spigot End + } + + protected BlockPosition a(BlockPosition blockposition) { + BlockPosition blockposition1 = this.q(blockposition); + AxisAlignedBB axisalignedbb = (new AxisAlignedBB(blockposition1, new BlockPosition(blockposition1.getX(), this.getHeight(), blockposition1.getZ()))).grow(3.0D, 3.0D, 3.0D); + List list = this.a(EntityLiving.class, axisalignedbb, new Predicate() { + public boolean a(EntityLiving entityliving) { + return entityliving != null && entityliving.isAlive() && WorldServer.this.i(entityliving.getChunkCoordinates()); + } + + public boolean apply(Object object) { + return this.a((EntityLiving) object); + } + }); + + return !list.isEmpty() ? ((EntityLiving) list.get(this.random.nextInt(list.size()))).getChunkCoordinates() : blockposition1; + } + + public boolean a(BlockPosition blockposition, Block block) { + NextTickListEntry nextticklistentry = new NextTickListEntry(blockposition, block); + + return this.V.contains(nextticklistentry); + } + + public void a(BlockPosition blockposition, Block block, int i) { + this.a(blockposition, block, i, 0); + } + + public void a(BlockPosition blockposition, Block block, int i, int j) { + NextTickListEntry nextticklistentry = new NextTickListEntry(blockposition, block); + byte b0 = 0; + + if (this.e && block.getMaterial() != Material.AIR) { + if (block.N()) { + b0 = 8; + if (this.areChunksLoadedBetween(nextticklistentry.a.a(-b0, -b0, -b0), nextticklistentry.a.a(b0, b0, b0))) { + IBlockData iblockdata = this.getType(nextticklistentry.a); + + if (iblockdata.getBlock().getMaterial() != Material.AIR && iblockdata.getBlock() == nextticklistentry.a()) { + iblockdata.getBlock().b(this, nextticklistentry.a, iblockdata, this.random); + } + } + + return; + } + + i = 1; + } + + if (this.areChunksLoadedBetween(blockposition.a(-b0, -b0, -b0), blockposition.a(b0, b0, b0))) { + if (block.getMaterial() != Material.AIR) { + nextticklistentry.a((long) i + this.worldData.getTime()); + nextticklistentry.a(j); + } + + // CraftBukkit - use M, PAIL: Rename nextTickList + if (!this.M.contains(nextticklistentry)) { + this.M.add(nextticklistentry); + } + } + + } + + public void b(BlockPosition blockposition, Block block, int i, int j) { + NextTickListEntry nextticklistentry = new NextTickListEntry(blockposition, block); + + nextticklistentry.a(j); + if (block.getMaterial() != Material.AIR) { + nextticklistentry.a((long) i + this.worldData.getTime()); + } + + // CraftBukkit - use M, PAIL: Rename nextTickList + if (!this.M.contains(nextticklistentry)) { + this.M.add(nextticklistentry); + } + + } + + public void tickEntities() { + if (false && this.players.isEmpty()) { // CraftBukkit - this prevents entity cleanup, other issues on servers with no players + if (this.emptyTime++ >= 1200) { + return; + } + } else { + this.j(); + } + + super.tickEntities(); + spigotConfig.currentPrimedTnt = 0; // Spigot + } + + public void j() { + this.emptyTime = 0; + } + + public boolean a(boolean flag) { + if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + return false; + } else { + int i = this.M.size(); + + if (false) { // CraftBukkit + throw new IllegalStateException("TickNextTick list out of synch"); + } else { + // PaperSpigot start - No, stop doing this, it affects things like redstone + /* + if (i > 1000) { + // CraftBukkit start - If the server has too much to process over time, try to alleviate that + if (i > 20 * 1000) { + i = i / 20; + } else { + i = 1000; + } + // CraftBukkit end + */ + if (i > paperSpigotConfig.tickNextTickCap) { + i = paperSpigotConfig.tickNextTickCap; + } + // PaperSpigot end + + this.methodProfiler.a("cleaning"); + + timings.scheduledBlocksCleanup.startTiming(); // Spigot + NextTickListEntry nextticklistentry; + + for (int j = 0; j < i; ++j) { + nextticklistentry = this.M.first(); + if (!flag && nextticklistentry.b > this.worldData.getTime()) { + break; + } + + // CraftBukkit - use M, PAIL: Rename nextTickList + this.M.remove(nextticklistentry); + this.V.add(nextticklistentry); + } + timings.scheduledBlocksCleanup.stopTiming(); // Spigot + + // PaperSpigot start - Allow redstone ticks to bypass the tickNextTickListCap + if (paperSpigotConfig.tickNextTickListCapIgnoresRedstone) { + Iterator iterator = this.M.iterator(); + while (iterator.hasNext()) { + NextTickListEntry next = iterator.next(); + if (!flag && next.b > this.worldData.getTime()) { + break; + } + + if (next.a().isPowerSource() || next.a() instanceof IContainer) { + iterator.remove(); + this.V.add(next); + } + } + } + // PaperSpigot end + + this.methodProfiler.b(); + this.methodProfiler.a("ticking"); + timings.scheduledBlocksTicking.startTiming(); // Spigot + Iterator iterator = this.V.iterator(); + + while (iterator.hasNext()) { + nextticklistentry = (NextTickListEntry) iterator.next(); + iterator.remove(); + byte b0 = 0; + + if (this.areChunksLoadedBetween(nextticklistentry.a.a(-b0, -b0, -b0), nextticklistentry.a.a(b0, b0, b0))) { + IBlockData iblockdata = this.getType(nextticklistentry.a); + co.aikar.timings.Timing timing = iblockdata.getBlock().getTiming(); // Spigot + timing.startTiming(); // Spigot + + if (iblockdata.getBlock().getMaterial() != Material.AIR && Block.a(iblockdata.getBlock(), nextticklistentry.a())) { + try { + iblockdata.getBlock().b(this, nextticklistentry.a, iblockdata, this.random); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Exception while ticking a block"); + CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being ticked"); + + CrashReportSystemDetails.a(crashreportsystemdetails, nextticklistentry.a, iblockdata); + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + } + timing.stopTiming(); // Spigot + } else { + this.a(nextticklistentry.a, nextticklistentry.a(), 0); + } + } + timings.scheduledBlocksTicking.stopTiming(); // Spigot + + this.methodProfiler.b(); + this.V.clear(); + return !this.M.isEmpty(); + } + } + } + + public List a(Chunk chunk, boolean flag) { + ChunkCoordIntPair chunkcoordintpair = chunk.j(); + int i = (chunkcoordintpair.x << 4) - 2; + int j = i + 16 + 2; + int k = (chunkcoordintpair.z << 4) - 2; + int l = k + 16 + 2; + + return this.a(new StructureBoundingBox(i, 0, k, j, 256, l), flag); + } + + public List a(StructureBoundingBox structureboundingbox, boolean flag) { + ArrayList arraylist = null; + + for (int i = 0; i < 2; ++i) { + Iterator iterator; + + if (i == 0) { + iterator = this.M.iterator(); + } else { + iterator = this.V.iterator(); + } + + while (iterator.hasNext()) { + NextTickListEntry nextticklistentry = (NextTickListEntry) iterator.next(); + BlockPosition blockposition = nextticklistentry.a; + + if (blockposition.getX() >= structureboundingbox.a && blockposition.getX() < structureboundingbox.d && blockposition.getZ() >= structureboundingbox.c && blockposition.getZ() < structureboundingbox.f) { + if (flag) { + // CraftBukkit - use M + iterator.remove(); + } + + if (arraylist == null) { + arraylist = Lists.newArrayList(); + } + + arraylist.add(nextticklistentry); + } + } + } + + return arraylist; + } + + /* CraftBukkit start - We prevent spawning in general, so this butchering is not needed + public void entityJoinedWorld(Entity entity, boolean flag) { + if (!this.getSpawnAnimals() && (entity instanceof EntityAnimal || entity instanceof EntityWaterAnimal)) { + entity.die(); + } + + if (!this.getSpawnNPCs() && entity instanceof NPC) { + entity.die(); + } + + super.entityJoinedWorld(entity, flag); + } + // CraftBukkit end */ + + private boolean getSpawnNPCs() { + return this.server.getSpawnNPCs(); + } + + private boolean getSpawnAnimals() { + return this.server.getSpawnAnimals(); + } + + protected IChunkProvider k() { + IChunkLoader ichunkloader = this.dataManager.createChunkLoader(this.worldProvider); + + // CraftBukkit start + org.bukkit.craftbukkit.generator.InternalChunkGenerator gen; + + if (this.generator != null) { + gen = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, this.getSeed(), this.generator); + } else if (this.worldProvider instanceof WorldProviderHell) { + gen = new org.bukkit.craftbukkit.generator.NetherChunkGenerator(this, this.getSeed()); + } else if (this.worldProvider instanceof WorldProviderTheEnd) { + gen = new org.bukkit.craftbukkit.generator.SkyLandsChunkGenerator(this, this.getSeed()); + } else { + gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed()); + } + + this.chunkProviderServer = new ChunkProviderServer(this, ichunkloader, gen); + // CraftBukkit end + return this.chunkProviderServer; + } + + public List getTileEntities(int i, int j, int k, int l, int i1, int j1) { + ArrayList arraylist = Lists.newArrayList(); + + // CraftBukkit start - Get tile entities from chunks instead of world + for (int chunkX = (i >> 4); chunkX <= ((l - 1) >> 4); chunkX++) { + for (int chunkZ = (k >> 4); chunkZ <= ((j1 - 1) >> 4); chunkZ++) { + Chunk chunk = getChunkAt(chunkX, chunkZ); + if (chunk == null) { + continue; + } + for (Object te : chunk.tileEntities.values()) { + TileEntity tileentity = (TileEntity) te; + if ((tileentity.position.getX() >= i) && (tileentity.position.getY() >= j) && (tileentity.position.getZ() >= k) && (tileentity.position.getX() < l) && (tileentity.position.getY() < i1) && (tileentity.position.getZ() < j1)) { + arraylist.add(tileentity); + } + } + } + } + /* + for (int k1 = 0; k1 < this.h.size(); ++k1) { + TileEntity tileentity = (TileEntity) this.h.get(k1); + BlockPosition blockposition = tileentity.getPosition(); + + if (blockposition.getX() >= i && blockposition.getY() >= j && blockposition.getZ() >= k && blockposition.getX() < l && blockposition.getY() < i1 && blockposition.getZ() < j1) { + arraylist.add(tileentity); + } + } + */ + // CraftBukkit end + + return arraylist; + } + + public boolean a(EntityHuman entityhuman, BlockPosition blockposition) { + return !this.server.a(this, blockposition, entityhuman) && this.getWorldBorder().a(blockposition); + } + + public void a(WorldSettings worldsettings) { + if (!this.worldData.w()) { + try { + this.b(worldsettings); + if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + this.aj(); + } + + super.a(worldsettings); + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.a(throwable, "Exception initializing level"); + + try { + this.a(crashreport); + } catch (Throwable throwable1) { + } + + if(MythicConfiguration.Options.Server.preventCrash) { // Mythic - prevent crash + MythicCore.getLogger().log(Level.SEVERE, "Prevented server crash, ", crashreport); + } + else throw new ReportedException(crashreport); + } + + this.worldData.d(true); + } + + } + + private void aj() { + this.worldData.f(false); + this.worldData.c(true); + this.worldData.setStorm(false); + this.worldData.setThundering(false); + this.worldData.i(1000000000); + this.worldData.setDayTime(6000L); + this.worldData.setGameType(WorldSettings.EnumGamemode.SPECTATOR); + this.worldData.g(false); + this.worldData.setDifficulty(EnumDifficulty.PEACEFUL); + this.worldData.e(true); + this.getGameRules().set("doDaylightCycle", "false"); + } + + private void b(WorldSettings worldsettings) { + if (!this.worldProvider.e()) { + this.worldData.setSpawn(BlockPosition.ZERO.up(this.worldProvider.getSeaLevel())); + } else if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + this.worldData.setSpawn(BlockPosition.ZERO.up()); + } else { + this.isLoading = true; + WorldChunkManager worldchunkmanager = this.worldProvider.m(); + List list = worldchunkmanager.a(); + Random random = new Random(this.getSeed()); + BlockPosition blockposition = worldchunkmanager.a(0, 0, 256, list, random); + int i = 0; + int j = this.worldProvider.getSeaLevel(); + int k = 0; + + // CraftBukkit start + if (this.generator != null) { + Random rand = new Random(this.getSeed()); + org.bukkit.Location spawn = this.generator.getFixedSpawnLocation(this.getWorld(), rand); + + if (spawn != null) { + if (spawn.getWorld() != this.getWorld()) { + throw new IllegalStateException("Cannot set spawn point for " + this.worldData.getName() + " to be in another world (" + spawn.getWorld().getName() + ")"); + } else { + this.worldData.setSpawn(new BlockPosition(spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ())); + this.isLoading = false; + return; + } + } + } + // CraftBukkit end + + if (blockposition != null) { + i = blockposition.getX(); + k = blockposition.getZ(); + } else { + WorldServer.a.warn("Unable to find spawn biome"); + } + + int l = 0; + + while (!this.canSpawn(i, k)) { // CraftBukkit - use our own canSpawn + i += random.nextInt(64) - random.nextInt(64); + k += random.nextInt(64) - random.nextInt(64); + ++l; + if (l == 1000) { + break; + } + } + + this.worldData.setSpawn(new BlockPosition(i, j, k)); + this.isLoading = false; + if (worldsettings.c()) { + this.l(); + } + + } + } + + protected void l() { + WorldGenBonusChest worldgenbonuschest = new WorldGenBonusChest(WorldServer.U, 10); + + for (int i = 0; i < 10; ++i) { + int j = this.worldData.c() + this.random.nextInt(6) - this.random.nextInt(6); + int k = this.worldData.e() + this.random.nextInt(6) - this.random.nextInt(6); + BlockPosition blockposition = this.r(new BlockPosition(j, 0, k)).up(); + + if (worldgenbonuschest.generate(this, this.random, blockposition)) { + break; + } + } + + } + + public BlockPosition getDimensionSpawn() { + return this.worldProvider.h(); + } + + public void save(boolean flag, IProgressUpdate iprogressupdate) throws ExceptionWorldConflict { + if (this.chunkProvider.canSave()) { + org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit + if (iprogressupdate != null) { + iprogressupdate.a("Saving level"); + } + + this.a(); + if (iprogressupdate != null) { + iprogressupdate.c("Saving chunks"); + } + + this.chunkProvider.saveChunks(flag, iprogressupdate); + // CraftBukkit - ArrayList -> Collection + Collection arraylist = this.chunkProviderServer.a(); + Iterator iterator = arraylist.iterator(); + + while (iterator.hasNext()) { + Chunk chunk = (Chunk) iterator.next(); + + if (chunk != null && !this.manager.a(chunk.locX, chunk.locZ)) { + this.chunkProviderServer.queueUnload(chunk.locX, chunk.locZ); + } + } + + } + } + + public void flushSave() { + if (this.chunkProvider.canSave()) { + this.chunkProvider.c(); + } + } + + protected void a() throws ExceptionWorldConflict { + this.checkSession(); + this.worldData.a(this.getWorldBorder().getSize()); + this.worldData.d(this.getWorldBorder().getCenterX()); + this.worldData.c(this.getWorldBorder().getCenterZ()); + this.worldData.e(this.getWorldBorder().getDamageBuffer()); + this.worldData.f(this.getWorldBorder().getDamageAmount()); + this.worldData.j(this.getWorldBorder().getWarningDistance()); + this.worldData.k(this.getWorldBorder().getWarningTime()); + this.worldData.b(this.getWorldBorder().j()); + this.worldData.e(this.getWorldBorder().i()); + // CraftBukkit start - save worldMaps once, rather than once per shared world + if (!(this instanceof SecondaryWorldServer)) { + this.worldMaps.a(); + } + this.dataManager.saveWorldData(this.worldData, this.server.getPlayerList().t()); + // CraftBukkit end + } + + protected void a(Entity entity) { + super.a(entity); + this.entitiesById.a(entity.getId(), entity); + this.entitiesByUUID.put(entity.getUniqueID(), entity); + Entity[] aentity = entity.aB(); + + if (aentity != null) { + for (int i = 0; i < aentity.length; ++i) { + this.entitiesById.a(aentity[i].getId(), aentity[i]); + } + } + + } + + protected void b(Entity entity) { + super.b(entity); + this.entitiesById.d(entity.getId()); + this.entitiesByUUID.remove(entity.getUniqueID()); + Entity[] aentity = entity.aB(); + + if (aentity != null) { + for (int i = 0; i < aentity.length; ++i) { + this.entitiesById.d(aentity[i].getId()); + } + } + + } + + public boolean strikeLightning(Entity entity) { + // CraftBukkit start + LightningStrikeEvent lightning = new LightningStrikeEvent(this.getWorld(), (org.bukkit.entity.LightningStrike) entity.getBukkitEntity()); + this.getServer().getPluginManager().callEvent(lightning); + + if (lightning.isCancelled()) { + return false; + } + if (super.strikeLightning(entity)) { + this.server.getPlayerList().sendPacketNearby(entity.locX, entity.locY, entity.locZ, 512.0D, dimension, new PacketPlayOutSpawnEntityWeather(entity)); + // CraftBukkit end + return true; + } else { + return false; + } + } + + public void broadcastEntityEffect(Entity entity, byte b0) { + this.getTracker().sendPacketToEntity(entity, new PacketPlayOutEntityStatus(entity, b0)); + } + + public Explosion createExplosion(Entity entity, double d0, double d1, double d2, float f, boolean flag, boolean flag1) { + // CraftBukkit start + Explosion explosion = super.createExplosion(entity, d0, d1, d2, f, flag, flag1); + + if (explosion.wasCanceled) { + return explosion; + } + + /* Remove + Explosion explosion = new Explosion(this, entity, d0, d1, d2, f, flag, flag1); + + explosion.a(); + explosion.a(false); + */ + // CraftBukkit end - TODO: Check if explosions are still properly implemented + if (!flag1) { + explosion.clearBlocks(); + } + + Iterator iterator = this.players.iterator(); + + while (iterator.hasNext()) { + EntityHuman entityhuman = (EntityHuman) iterator.next(); + + if (entityhuman.e(d0, d1, d2) < 4096.0D) { + ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutExplosion(d0, d1, d2, f, explosion.getBlocks(), explosion.b().get(entityhuman))); + } + } + + return explosion; + } + + public void playBlockAction(BlockPosition blockposition, Block block, int i, int j) { + BlockActionData blockactiondata = new BlockActionData(blockposition, block, i, j); + Iterator iterator = this.S[this.T].iterator(); + + BlockActionData blockactiondata1; + + do { + if (!iterator.hasNext()) { + this.S[this.T].add(blockactiondata); + return; + } + + blockactiondata1 = (BlockActionData) iterator.next(); + } while (!blockactiondata1.equals(blockactiondata)); + + } + + private void ak() { + while (!this.S[this.T].isEmpty()) { + int i = this.T; + + this.T ^= 1; + Iterator iterator = this.S[i].iterator(); + + while (iterator.hasNext()) { + BlockActionData blockactiondata = (BlockActionData) iterator.next(); + + if (this.a(blockactiondata)) { + // CraftBukkit - this.worldProvider.dimension -> this.dimension + this.server.getPlayerList().sendPacketNearby(blockactiondata.a().getX(), blockactiondata.a().getY(), blockactiondata.a().getZ(), 64.0D, dimension, new PacketPlayOutBlockAction(blockactiondata.a(), blockactiondata.d(), blockactiondata.b(), blockactiondata.c())); + } + } + + this.S[i].clear(); + } + + } + + private boolean a(BlockActionData blockactiondata) { + IBlockData iblockdata = this.getType(blockactiondata.a()); + + return iblockdata.getBlock() == blockactiondata.d() && iblockdata.getBlock().a(this, blockactiondata.a(), iblockdata, blockactiondata.b(), blockactiondata.c()); + } + + public void saveLevel() { + this.dataManager.a(); + } + + protected void p() { + if(!MythicConfiguration.Options.World.weather) return; + boolean flag = this.S(); + + super.p(); + /* CraftBukkit start + if (this.o != this.p) { + this.server.getPlayerList().a(new PacketPlayOutGameStateChange(7, this.p), this.worldProvider.getDimension()); + } + + if (this.q != this.r) { + this.server.getPlayerList().a(new PacketPlayOutGameStateChange(8, this.r), this.worldProvider.getDimension()); + } + + if (flag != this.S()) { + if (flag) { + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(2, 0.0F)); + } else { + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(1, 0.0F)); + } + + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(7, this.p)); + this.server.getPlayerList().sendAll(new PacketPlayOutGameStateChange(8, this.r)); + } + // */ + if (flag != this.S()) { + // Only send weather packets to those affected + for (int i = 0; i < this.players.size(); ++i) { + if (((EntityPlayer) this.players.get(i)).world == this) { + ((EntityPlayer) this.players.get(i)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); + } + } + } + for (int i = 0; i < this.players.size(); ++i) { + if (((EntityPlayer) this.players.get(i)).world == this) { + ((EntityPlayer) this.players.get(i)).updateWeather(this.o, this.p, this.q, this.r); + } + } + // CraftBukkit end + + } + + protected int q() { + return this.server.getPlayerList().s(); + } + + public MinecraftServer getMinecraftServer() { + return this.server; + } + + public EntityTracker getTracker() { + return this.tracker; + } + + public PlayerChunkMap getPlayerChunkMap() { + return this.manager; + } + + public PortalTravelAgent getTravelAgent() { + return this.Q; + } + + public void a(EnumParticle enumparticle, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, int... aint) { + this.a(enumparticle, false, d0, d1, d2, i, d3, d4, d5, d6, aint); + } + + public void a(EnumParticle enumparticle, boolean flag, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, int... aint) { + // CraftBukkit - visibility api support + sendParticles(null, enumparticle, flag, d0, d1, d2, i, d3, d4, d5, d6, aint); + } + + public void sendParticles(EntityPlayer sender, EnumParticle enumparticle, boolean flag, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, int... aint) { + // CraftBukkit end + PacketPlayOutWorldParticles packetplayoutworldparticles = new PacketPlayOutWorldParticles(enumparticle, flag, (float) d0, (float) d1, (float) d2, (float) d3, (float) d4, (float) d5, (float) d6, i, aint); + + for (int j = 0; j < this.players.size(); ++j) { + EntityPlayer entityplayer = (EntityPlayer) this.players.get(j); + if (sender != null && !entityplayer.getBukkitEntity().canSee(sender.getBukkitEntity())) continue; // CraftBukkit + BlockPosition blockposition = entityplayer.getChunkCoordinates(); + double d7 = blockposition.c(d0, d1, d2); + + if (d7 <= 256.0D || flag && d7 <= 65536.0D) { + entityplayer.playerConnection.sendPacket(packetplayoutworldparticles); + } + } + + } + + public Entity getEntity(UUID uuid) { + return this.entitiesByUUID.get(uuid); + } + + public ListenableFuture postToMainThread(Runnable runnable) { + return this.server.postToMainThread(runnable); + } + + public boolean isMainThread() { + return this.server.isMainThread(); + } + + static class BlockActionDataList extends ArrayList { + + private BlockActionDataList() {} + + BlockActionDataList(Object object) { + this(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/BlockStateRegistry.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/BlockStateRegistry.java new file mode 100644 index 0000000..5678ed3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/BlockStateRegistry.java @@ -0,0 +1,41 @@ +package net.techcable.tacospigot; + +import gnu.trove.map.TObjectIntMap; +import gnu.trove.map.hash.TObjectIntHashMap; + +import java.util.Arrays; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicInteger; + +import net.minecraft.server.IBlockState; + +public class BlockStateRegistry { + private BlockStateRegistry() {} // Utility class + private static final ConcurrentMap, Integer> idsByObj = new ConcurrentHashMap<>(); + private static volatile IBlockState[] byId = new IBlockState[0]; + private static final AtomicInteger nextId = new AtomicInteger(); + + public static int getId(IBlockState s) { + return idsByObj.computeIfAbsent(s, (state) -> { + int id = nextId.getAndIncrement(); + synchronized (BlockStateRegistry.class) { + if (id >= byId.length) { + byId = Arrays.copyOf(byId, id + 1); + } + byId[id] = state; + } + return id; + }); + } + + public static IBlockState getById(int id) { + if (id < 0) { + throw new IllegalArgumentException("Negative id: " + id); + } else if (id < byId.length) { + return byId[id]; + } else { + return null; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/CompatHacks.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/CompatHacks.java new file mode 100644 index 0000000..6ebc9c8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/CompatHacks.java @@ -0,0 +1,10 @@ +package net.techcable.tacospigot; + +import org.bukkit.Bukkit; + +public class CompatHacks { + private CompatHacks() {} + public static boolean hasProtocolSupport() { + return Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport"); + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/HopperHelper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/HopperHelper.java new file mode 100644 index 0000000..630a81b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/HopperHelper.java @@ -0,0 +1,41 @@ +package net.techcable.tacospigot; + +import net.minecraft.server.Block; +import net.minecraft.server.BlockChest; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.Blocks; +import net.minecraft.server.IHopper; +import net.minecraft.server.IInventory; +import net.minecraft.server.TileEntity; +import net.minecraft.server.TileEntityHopper; +import net.minecraft.server.World; + +import org.bukkit.event.inventory.InventoryMoveItemEvent; + +public class HopperHelper { + + public static TileEntityHopper getHopper(World world, BlockPosition pos) { + if (world.getType(pos).getBlock() != Blocks.HOPPER) return null; + TileEntity tileEntity = world.getTileEntity(pos); + if (tileEntity instanceof TileEntityHopper) { + return (TileEntityHopper) tileEntity; + } + return null; + } + + public static IInventory getInventory(World world, BlockPosition position) { + Block block = world.getType(position).getBlock(); + if (block instanceof BlockChest) { + return ((BlockChest) block).f(world, position); + } + if (block.isTileEntity()) { + TileEntity tile = world.getTileEntity(position); + if (tile instanceof IInventory) return (IInventory) tile; + } + return null; + } + + public static boolean isFireInventoryMoveItemEvent(IHopper hopper) { + return hopper.getWorld().tacoSpigotConfig.isHopperFireIMIE && InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length > 0; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/HopperPusher.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/HopperPusher.java new file mode 100644 index 0000000..21d5a11 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/HopperPusher.java @@ -0,0 +1,65 @@ +package net.techcable.tacospigot; + +import net.minecraft.server.AxisAlignedBB; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.Entity; +import net.minecraft.server.IHopper; +import net.minecraft.server.TileEntityHopper; +import net.minecraft.server.World; + +public interface HopperPusher { + + public default TileEntityHopper findHopper() { + BlockPosition pos = new BlockPosition(getX(), getY(), getZ()); + int startX = pos.getX() - 1; + int endX = pos.getX() + 1; + int startY = Math.max(0, pos.getY() - 1); + int endY = Math.min(255, pos.getY() + 1); + int startZ = pos.getZ() - 1; + int endZ = pos.getZ() + 1; + for (int x = startX; x <= endX; x++) { + for (int y = startY; y <= endY; y++) { + for (int z = startZ; z <= endZ; z++) { + BlockPosition adjacentPos = new BlockPosition(x, y, z); + TileEntityHopper hopper = HopperHelper.getHopper(getWorld(), adjacentPos); + if (hopper == null) continue; // Avoid playing with the bounding boxes, if at all possible + /** + * We add one to getY(), just like {@link TileEntityHopper#b(IHopper)} + */ + AxisAlignedBB hopperBoundingBox = hopper.getHopperLookupBoundingBox(); + if (hopperBoundingBox.b(this.getBoundingBox())) { // AxisAlignedBB.b(AxisAlignedBB) -> isIntersect() + return hopper; + } + } + } + } + return null; + } + + public boolean acceptItem(TileEntityHopper hopper); + + public default boolean tryPutInHopper() { + if (!getWorld().tacoSpigotConfig.isHopperPushBased) return false; + TileEntityHopper hopper = findHopper(); + return hopper != null && hopper.canAcceptItems() && acceptItem(hopper); + } + + public AxisAlignedBB getBoundingBox(); + + public World getWorld(); + + // Default implementations for entities + + public default double getX() { + return ((Entity) this).locX; + } + + public default double getY() { + return ((Entity) this).locY; + } + + public default double getZ() { + return ((Entity) this).locZ; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/ImmutableArrayMap.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/ImmutableArrayMap.java new file mode 100644 index 0000000..16a370c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/ImmutableArrayMap.java @@ -0,0 +1,170 @@ +package net.techcable.tacospigot; + +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; + +public class ImmutableArrayMap extends AbstractMap implements Map { + private final Indexer indexer; + private final int offset; + private final Object[] data; + private final Object[] outlyingData; + private final Entry[] entries; + private final int[] outlyingIds; + + private final int size; + + @SuppressWarnings("Convert2Lambda") // The comparator is anonomous for performance reasons + public ImmutableArrayMap(Indexer getId, Map map) { + Preconditions.checkNotNull(getId, "Null getId function"); + Preconditions.checkNotNull(map, "Null map"); + this.indexer = getId; + this.size = map.size(); + this.keyComparator = new Comparator() { + @Override + public int compare(K o1, K o2) { + return Integer.compare(indexer.getId(o1), indexer.getId(o2)); + } + }; + @SuppressWarnings("unchecked") + Entry[] entries = new Entry[size]; + Iterator> iterator = map.entrySet().iterator(); + for (int i = 0; i < entries.length; i++) { + Preconditions.checkArgument(iterator.hasNext(), "Expected %s entries but only got %s", size, i + 1); + Entry entry = iterator.next(); + entries[i] = Maps.immutableEntry(entry.getKey(), entry.getValue()); + } + Arrays.sort(entries, (entry1, entry2) -> keyComparator.compare(entry1.getKey(), entry2.getKey())); + Preconditions.checkArgument(!iterator.hasNext(), "Got more than expected %s entries", size); + int[] ids = Arrays.stream(entries).map(Entry::getKey).mapToInt(indexer::getId).toArray(); // Don't worry, its sorted by key id ;) + int[] largestRangeOfSequentialValues = calculateLargestRangeOfSequentialValues(ids); + int minIndex = largestRangeOfSequentialValues == null ? -1 : largestRangeOfSequentialValues[0]; + int maxIndex = largestRangeOfSequentialValues == null ? -1 : largestRangeOfSequentialValues[1]; + int sequentalRangeSize = largestRangeOfSequentialValues == null ? 0 : largestRangeOfSequentialValues[2]; +// if (sequentalRangeSize < size / 2) { +// System.err.println("Less than 50% of values are sequential"); +// System.err.print(sequentalRangeSize); +// System.err.print(" out of "); +// System.err.println(size); +// System.err.println("Expect reduced performance"); +// } + this.data = new Object[sequentalRangeSize]; + this.outlyingIds = new int[size - sequentalRangeSize]; + this.outlyingData = new Object[size - sequentalRangeSize]; + this.offset = sequentalRangeSize == 0 ? 0 : ids[minIndex]; + this.entries = entries; + int outlyingIndex = 0; + for (int i = 0; i < entries.length; i++) { + Entry entry = entries[i]; + K key = entry.getKey(); + V value = entry.getValue(); + int id = indexer.getId(key); + Preconditions.checkArgument(id >= 0, "Negative id for %s: %s", key, id); + if (i >= minIndex && i < maxIndex) { + int index = id - offset; + data[index] = value; + } else { + int index = outlyingIndex++; + outlyingIds[index] = id; + outlyingData[index] = value; + } + } + } + + private final Comparator keyComparator; + + @Override + public int size() { + return size; + } + + @Override + public boolean containsKey(Object key) { + return get(key) != null; + } + + @Override + @SuppressWarnings("unchecked") + public V get(Object key) { + int id = indexer.getId((K) key); + int index = id - offset; + if (index >= 0 && index < data.length) { + return (V) data[index]; + } + int outlyingIndex = Arrays.binarySearch(outlyingIds, id); + if (outlyingIndex >= 0 && outlyingIndex < outlyingData.length) { + return (V) outlyingData[outlyingIndex]; + } else { + return null; + } + } + + @Override + public Set> entrySet() { + return new AbstractSet>() { + @SuppressWarnings("unchecked") + @Override + public Iterator> iterator() { + return Arrays.asList(entries).iterator(); + } + + @Override + public int size() { + return size; + } + }; + } + + @Override + public void forEach(BiConsumer action) { + for (Entry entry : entries) { + action.accept(entry.getKey(), entry.getValue()); + } + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public V put(K key, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public V remove(Object key) { + throw new UnsupportedOperationException(); + } + + private static int[] calculateLargestRangeOfSequentialValues(int[] ids) { + int largestRangeSize = 0; + int[] largestRange = new int[3]; + for (int minIndex = 0; minIndex < ids.length; minIndex++) { + final int min = ids[minIndex]; + int lastNum = min; + int maxIndex; + for (maxIndex = minIndex + 1; maxIndex < ids.length; maxIndex++) { + final int max = ids[maxIndex]; + if (lastNum + 1 != max) break; // The number is not sequential + lastNum = max; + } + int rangeSize = maxIndex - minIndex; + if (rangeSize > largestRangeSize) { + largestRange[0] = minIndex; + largestRange[1] = maxIndex; + largestRange[2] = rangeSize; + largestRangeSize = rangeSize; + } + } + return largestRangeSize == 0 ? null : largestRange; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/ImmutableArrayTable.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/ImmutableArrayTable.java new file mode 100644 index 0000000..f532fe2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/ImmutableArrayTable.java @@ -0,0 +1,196 @@ +package net.techcable.tacospigot; + +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.function.ToIntBiFunction; +import javax.annotation.Nullable; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Table; +import com.google.common.collect.Tables; + +public class ImmutableArrayTable implements Table { + private final Indexer rowIndexer; + private final ToIntBiFunction columnGetId; + private final ImmutableArrayMap> rowMap; + private final ImmutableMap> columnMap; + private final int size; + + public ImmutableArrayTable(Indexer rowIndexer, ToIntBiFunction columnGetId, Table table) { + this.rowIndexer = Preconditions.checkNotNull(rowIndexer, "Null indexer for row"); + this.columnGetId = Preconditions.checkNotNull(columnGetId, "Null getId function for column"); + Preconditions.checkNotNull(table, "Null table"); + ImmutableMap.Builder> rowMapBuilder = ImmutableMap.builder(); + for (Map.Entry> rowEntry : table.rowMap().entrySet()) { + R row = rowEntry.getKey(); + Preconditions.checkNotNull(row, "Null row"); + ImmutableMap.Builder rowMapEntryBuilder = ImmutableMap.builder(); + for (Map.Entry rowEntryEntry : rowEntry.getValue().entrySet()) { + rowMapEntryBuilder.put(rowEntryEntry); + } + rowMapBuilder.put(row, new ImmutableArrayMap<>((c) -> columnGetId.applyAsInt(row, c), rowMapEntryBuilder.build())); + } + this.rowMap = new ImmutableArrayMap<>(rowIndexer, rowMapBuilder.build()); + Map> columnMapBuilder = new HashMap<>(); + int size = 0; + for (Cell cell : cellSet()) { + R row = cell.getRowKey(); + C column = cell.getColumnKey(); + V value = cell.getValue(); + Preconditions.checkNotNull(column, "Null column"); + Preconditions.checkNotNull(value, "Null value"); + Map columnEntry = columnMapBuilder.computeIfAbsent(column, (c) -> new HashMap<>()); + columnEntry.put(cell.getRowKey(), cell.getValue()); + size++; + } + this.size = size; + this.columnMap = ImmutableMap.copyOf(columnMapBuilder); + } + + @Override + public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) { + Map rowEntry = rowMap.get(rowKey); + return rowEntry != null && rowEntry.containsKey(columnKey); + } + + @Override + public boolean containsRow(@Nullable Object rowKey) { + return rowMap.containsKey(rowKey); + } + + @Override + public boolean containsColumn(@Nullable Object columnKey) { + return columnMap.containsKey(columnKey); + } + + @Override + public boolean containsValue(@Nullable Object value) { + Preconditions.checkNotNull(value, "Null value"); + for (V v : values()) { + if (v.equals(value)) return true; + } + return false; + } + + @Override + public V get(@Nullable Object rowKey, @Nullable Object columnKey) { + Map rowEntry = rowMap.get(rowKey); + return rowEntry != null ? rowEntry.get(columnKey) : null; + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public int size() { + return size; + } + + @Override + public Map row(R rowKey) { + return rowMap.get(rowKey); + } + + @Override + public Map column(C columnKey) { + return columnMap.get(columnKey); + } + + @Override + public Set> cellSet() { + return new AbstractSet>() { + @Override + public Iterator> iterator() { + return new CellIterator(); + } + + @Override + public int size() { + return ImmutableArrayTable.this.size(); + } + }; + } + + @Override + public Set rowKeySet() { + return rowMap.keySet(); + } + + @Override + public Set columnKeySet() { + return columnMap.keySet(); + } + + @Override + public Collection values() { + return Collections2.transform(cellSet(), Cell::getValue); + } + + @Override + public Map> rowMap() { + return rowMap; + } + + @Override + public Map> columnMap() { + return columnMap; + } + + private class CellIterator implements Iterator> { + final Iterator>> rowIterator = rowMap.entrySet().iterator(); + Map.Entry> rowEntry; + Iterator> columnIterator = Collections.emptyIterator(); + + @Override + public boolean hasNext() { + return rowIterator.hasNext() || columnIterator.hasNext(); + } + + @Override + public Cell next() { + if (!columnIterator.hasNext()) { + rowEntry = rowIterator.next(); + columnIterator = rowEntry.getValue().entrySet().iterator(); + } + Map.Entry columnEntry = columnIterator.next(); + return Tables.immutableCell(rowEntry.getKey(), columnEntry.getKey(), columnEntry.getValue()); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + // Mutators + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + + @Override + public V put(R rowKey, C columnKey, V value) { + throw new UnsupportedOperationException(); + } + + @Override + public void putAll(Table table) { + throw new UnsupportedOperationException(); + } + + @Override + public V remove(@Nullable Object rowKey, @Nullable Object columnKey) { + throw new UnsupportedOperationException(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/Indexer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/Indexer.java new file mode 100644 index 0000000..f6fec82 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/Indexer.java @@ -0,0 +1,5 @@ +package net.techcable.tacospigot; + +public interface Indexer { + public int getId(T t); +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotConfig.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotConfig.java new file mode 100644 index 0000000..c0a7160 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotConfig.java @@ -0,0 +1,111 @@ +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.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +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 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 ex) { + } 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 (List) 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/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotWorldConfig.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotWorldConfig.java new file mode 100644 index 0000000..8c1f1a7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/TacoSpigotWorldConfig.java @@ -0,0 +1,113 @@ +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 (List) 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/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/function/ObjIntFunction.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/function/ObjIntFunction.java new file mode 100644 index 0000000..b5adb4e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/function/ObjIntFunction.java @@ -0,0 +1,6 @@ +package net.techcable.tacospigot.function; + +@FunctionalInterface +public interface ObjIntFunction { + public R apply(T t, int i); +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/utils/BlockHelper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/utils/BlockHelper.java new file mode 100644 index 0000000..e98fa4d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/net/techcable/tacospigot/utils/BlockHelper.java @@ -0,0 +1,64 @@ +package net.techcable.tacospigot.utils; + +import java.util.AbstractSet; +import java.util.Iterator; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.BiConsumer; +import java.util.function.BiPredicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import com.google.common.base.Preconditions; +import com.google.common.collect.AbstractIterator; + +import net.minecraft.server.Block; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.World; + +public class BlockHelper { + private BlockHelper() {} + + public static void forEachAdjacentBlock(World w, BlockPosition position, int radius, BiConsumer action) { + isAllAdjacentBlocksFillPredicate(w, position, radius, (world, adjacentPos) -> { + action.accept(world, adjacentPos); + return true; + }); + } + + public static boolean isAllAdjacentBlocksLoaded(World world, BlockPosition pos, int radius) { + return isAllAdjacentBlocksFillPredicate(world, pos, radius, World::isLoaded); + } + + public static boolean isAllAdjacentBlocksFillPredicate(World world, BlockPosition pos, int radius, BiPredicate predicate) { + // Make sure to keep this below the inline threshold!!! + int startX = pos.getX() - radius; + int endX = pos.getX() + radius; + int startY = Math.max(0, pos.getY() - radius); + int endY = Math.min(255, pos.getY() + radius); + int startZ = pos.getZ() - radius; + int endZ = pos.getZ() + radius; + BlockPosition.MutableBlockPosition adjacent = new BlockPosition.MutableBlockPosition(); + for (int x = startX; x <= endX; x++) { + for (int y = startY; y <= endY; y++) { + for (int z = startZ; z <= endZ; z++) { + adjacent.setValues(x, y, z); + if (!predicate.test(world, adjacent)) return false; + } + } + } + return true; + } + + private static final Block[] blockById = new Block[256]; + + static { + for (int i = 0; i < blockById.length; i++) { + blockById[i] = Block.getById(i); + } + } + + public static Block getBlock(int id) { + return id < 256 ? blockById[id] : Block.getById(id); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java new file mode 100644 index 0000000..341eaa3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java @@ -0,0 +1,245 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +package org.apache.logging.log4j.core.appender; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Constructor; +import java.nio.charset.Charset; + +import org.apache.logging.log4j.core.Filter; +import org.apache.logging.log4j.core.Layout; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.plugins.PluginAttribute; +import org.apache.logging.log4j.core.config.plugins.PluginElement; +import org.apache.logging.log4j.core.config.plugins.PluginFactory; +import org.apache.logging.log4j.core.helpers.Booleans; +import org.apache.logging.log4j.core.helpers.Loader; +import org.apache.logging.log4j.core.layout.PatternLayout; +import org.apache.logging.log4j.util.PropertiesUtil; + +/** + * ConsoleAppender appends log events to System.out or + * System.err using a layout specified by the user. The + * default target is System.out. + * @doubt accessing System.out or .err as a byte stream instead of a writer + * bypasses the JVM's knowledge of the proper encoding. (RG) Encoding + * is handled within the Layout. Typically, a Layout will generate a String + * and then call getBytes which may use a configured encoding or the system + * default. OTOH, a Writer cannot print byte streams. + */ +@Plugin(name = "Console", category = "Core", elementType = "appender", printObject = true) +public final class ConsoleAppender extends AbstractOutputStreamAppender { + + private static final String JANSI_CLASS = "org.fusesource.jansi.WindowsAnsiOutputStream"; + private static ConsoleManagerFactory factory = new ConsoleManagerFactory(); + + /** + * Enumeration of console destinations. + */ + public enum Target { + /** Standard output. */ + SYSTEM_OUT, + /** Standard error output. */ + SYSTEM_ERR + } + + private ConsoleAppender(final String name, final Layout layout, final Filter filter, + final OutputStreamManager manager, + final boolean ignoreExceptions) { + super(name, layout, filter, ignoreExceptions, true, manager); + } + + /** + * Create a Console Appender. + * @param layout The layout to use (required). + * @param filter The Filter or null. + * @param t The target ("SYSTEM_OUT" or "SYSTEM_ERR"). The default is "SYSTEM_OUT". + * @param follow If true will follow changes to the underlying output stream. + * @param name The name of the Appender (required). + * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise + * they are propagated to the caller. + * @return The ConsoleAppender. + */ + @PluginFactory + public static ConsoleAppender createAppender( + @PluginElement("Layout") Layout layout, + @PluginElement("Filters") final Filter filter, + @PluginAttribute("target") final String t, + @PluginAttribute("name") final String name, + @PluginAttribute("follow") final String follow, + @PluginAttribute("ignoreExceptions") final String ignore) { + if (name == null) { + LOGGER.error("No name provided for ConsoleAppender"); + return null; + } + if (layout == null) { + layout = PatternLayout.createLayout(null, null, null, null, null); + } + final boolean isFollow = Boolean.parseBoolean(follow); + final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true); + final Target target = t == null ? Target.SYSTEM_OUT : Target.valueOf(t); + return new ConsoleAppender(name, layout, filter, getManager(isFollow, target, layout), ignoreExceptions); + } + + private static OutputStreamManager getManager(final boolean follow, final Target target, final Layout layout) { + final String type = target.name(); + final OutputStream os = getOutputStream(follow, target); + return OutputStreamManager.getManager(target.name() + "." + follow, new FactoryData(os, type, layout), factory); + } + + private static OutputStream getOutputStream(final boolean follow, final Target target) { + final String enc = Charset.defaultCharset().name(); + PrintStream printStream = null; + try { + printStream = target == Target.SYSTEM_OUT ? + follow ? new PrintStream(new SystemOutStream(), true, enc) : System.out : + follow ? new PrintStream(new SystemErrStream(), true, enc) : System.err; + } catch (final UnsupportedEncodingException ex) { // should never happen + throw new IllegalStateException("Unsupported default encoding " + enc, ex); + } + final PropertiesUtil propsUtil = PropertiesUtil.getProperties(); + if (!propsUtil.getStringProperty("os.name").startsWith("Windows") || + propsUtil.getBooleanProperty("log4j.skipJansi")) { + return printStream; + } + try { + final ClassLoader loader = Loader.getClassLoader(); + // We type the parameter as a wildcard to avoid a hard reference to Jansi. + final Class clazz = loader.loadClass(JANSI_CLASS); + final Constructor constructor = clazz.getConstructor(OutputStream.class); + return (OutputStream) constructor.newInstance(printStream); + } catch (final ClassNotFoundException cnfe) { + LOGGER.debug("Jansi is not installed, cannot find {}", JANSI_CLASS); + } catch (final NoSuchMethodException nsme) { + LOGGER.warn("{} is missing the proper constructor", JANSI_CLASS); + } catch (final Throwable ex) { // CraftBukkit - Exception -> Throwable + LOGGER.warn("Unable to instantiate {}", JANSI_CLASS); + } + return printStream; + } + + /** + * An implementation of OutputStream that redirects to the current System.err. + */ + private static class SystemErrStream extends OutputStream { + public SystemErrStream() { + } + + @Override + public void close() { + // do not close sys err! + } + + @Override + public void flush() { + System.err.flush(); + } + + @Override + public void write(final byte[] b) throws IOException { + System.err.write(b); + } + + @Override + public void write(final byte[] b, final int off, final int len) + throws IOException { + System.err.write(b, off, len); + } + + @Override + public void write(final int b) { + System.err.write(b); + } + } + + /** + * An implementation of OutputStream that redirects to the current System.out. + */ + private static class SystemOutStream extends OutputStream { + public SystemOutStream() { + } + + @Override + public void close() { + // do not close sys out! + } + + @Override + public void flush() { + System.out.flush(); + } + + @Override + public void write(final byte[] b) throws IOException { + System.out.write(b); + } + + @Override + public void write(final byte[] b, final int off, final int len) + throws IOException { + System.out.write(b, off, len); + } + + @Override + public void write(final int b) throws IOException { + System.out.write(b); + } + } + + /** + * Data to pass to factory method. + */ + private static class FactoryData { + private final OutputStream os; + private final String type; + private final Layout layout; + + /** + * Constructor. + * @param os The OutputStream. + * @param type The name of the target. + * @param layout A Serializable layout + */ + public FactoryData(final OutputStream os, final String type, final Layout layout) { + this.os = os; + this.type = type; + this.layout = layout; + } + } + + /** + * Factory to create the Appender. + */ + private static class ConsoleManagerFactory implements ManagerFactory { + + /** + * Create an OutputStreamManager. + * @param name The name of the entity to manage. + * @param data The data required to create the entity. + * @return The OutputStreamManager + */ + @Override + public OutputStreamManager createManager(final String name, final FactoryData data) { + return new OutputStreamManager(data.os, data.type, data.layout); + } + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftArt.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftArt.java new file mode 100644 index 0000000..6f94348 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftArt.java @@ -0,0 +1,74 @@ +package org.bukkit.craftbukkit; + +import net.minecraft.server.EntityPainting.EnumArt; +import org.bukkit.Art; + +// Safety class, will break if either side changes +public class CraftArt { + + public static Art NotchToBukkit(EnumArt art) { + switch (art) { + case KEBAB: return Art.KEBAB; + case AZTEC: return Art.AZTEC; + case ALBAN: return Art.ALBAN; + case AZTEC_2: return Art.AZTEC2; + case BOMB: return Art.BOMB; + case PLANT: return Art.PLANT; + case WASTELAND: return Art.WASTELAND; + case POOL: return Art.POOL; + case COURBET: return Art.COURBET; + case SEA: return Art.SEA; + case SUNSET: return Art.SUNSET; + case CREEBET: return Art.CREEBET; + case WANDERER: return Art.WANDERER; + case GRAHAM: return Art.GRAHAM; + case MATCH: return Art.MATCH; + case BUST: return Art.BUST; + case STAGE: return Art.STAGE; + case VOID: return Art.VOID; + case SKULL_AND_ROSES: return Art.SKULL_AND_ROSES; + case FIGHTERS: return Art.FIGHTERS; + case POINTER: return Art.POINTER; + case PIGSCENE: return Art.PIGSCENE; + case BURNING_SKULL: return Art.BURNINGSKULL; + case SKELETON: return Art.SKELETON; + case DONKEY_KONG: return Art.DONKEYKONG; + case WITHER: return Art.WITHER; + default: + throw new AssertionError(art); + } + } + + public static EnumArt BukkitToNotch(Art art) { + switch (art) { + case KEBAB: return EnumArt.KEBAB; + case AZTEC: return EnumArt.AZTEC; + case ALBAN: return EnumArt.ALBAN; + case AZTEC2: return EnumArt.AZTEC_2; + case BOMB: return EnumArt.BOMB; + case PLANT: return EnumArt.PLANT; + case WASTELAND: return EnumArt.WASTELAND; + case POOL: return EnumArt.POOL; + case COURBET: return EnumArt.COURBET; + case SEA: return EnumArt.SEA; + case SUNSET: return EnumArt.SUNSET; + case CREEBET: return EnumArt.CREEBET; + case WANDERER: return EnumArt.WANDERER; + case GRAHAM: return EnumArt.GRAHAM; + case MATCH: return EnumArt.MATCH; + case BUST: return EnumArt.BUST; + case STAGE: return EnumArt.STAGE; + case VOID: return EnumArt.VOID; + case SKULL_AND_ROSES: return EnumArt.SKULL_AND_ROSES; + case FIGHTERS: return EnumArt.FIGHTERS; + case POINTER: return EnumArt.POINTER; + case PIGSCENE: return EnumArt.PIGSCENE; + case BURNINGSKULL: return EnumArt.BURNING_SKULL; + case SKELETON: return EnumArt.SKELETON; + case DONKEYKONG: return EnumArt.DONKEY_KONG; + case WITHER: return EnumArt.WITHER; + default: + throw new AssertionError(art); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftChunk.java new file mode 100644 index 0000000..8a33e28 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -0,0 +1,311 @@ +package org.bukkit.craftbukkit; + +import java.lang.ref.WeakReference; +import java.util.Arrays; + +import net.minecraft.server.*; + +import org.bukkit.Chunk; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.entity.Entity; +import org.bukkit.ChunkSnapshot; + +public class CraftChunk implements Chunk { + private WeakReference weakChunk; + private final WorldServer worldServer; + private final int x; + private final int z; + private static final byte[] emptyData = new byte[2048]; + private static final short[] emptyBlockIDs = new short[4096]; + private static final byte[] emptySkyLight = new byte[2048]; + + public CraftChunk(net.minecraft.server.Chunk chunk) { + if (!(chunk instanceof EmptyChunk)) { + this.weakChunk = new WeakReference(chunk); + } + + worldServer = (WorldServer) getHandle().world; + x = getHandle().locX; + z = getHandle().locZ; + } + + public World getWorld() { + return worldServer.getWorld(); + } + + public CraftWorld getCraftWorld() { + return (CraftWorld) getWorld(); + } + + public net.minecraft.server.Chunk getHandle() { + net.minecraft.server.Chunk c = weakChunk.get(); + + if (c == null) { + c = worldServer.getChunkAt(x, z); + + if (!(c instanceof EmptyChunk)) { + weakChunk = new WeakReference(c); + } + } + + return c; + } + + void breakLink() { + weakChunk.clear(); + } + + public int getX() { + return x; + } + + public int getZ() { + return z; + } + + @Override + public String toString() { + return "CraftChunk{" + "x=" + getX() + "z=" + getZ() + '}'; + } + + public Block getBlock(int x, int y, int z) { + return new CraftBlock(this, (getX() << 4) | (x & 0xF), y, (getZ() << 4) | (z & 0xF)); + } + + public Entity[] getEntities() { + int count = 0, index = 0; + net.minecraft.server.Chunk chunk = getHandle(); + + for (int i = 0; i < 16; i++) { + count += chunk.entitySlices[i].size(); + } + + Entity[] entities = new Entity[count]; + + for (int i = 0; i < 16; i++) { + + for (Object obj : chunk.entitySlices[i].toArray()) { + if (!(obj instanceof net.minecraft.server.Entity)) { + continue; + } + + entities[index++] = ((net.minecraft.server.Entity) obj).getBukkitEntity(); + } + } + + return entities; + } + + public BlockState[] getTileEntities() { + int index = 0; + net.minecraft.server.Chunk chunk = getHandle(); + + BlockState[] entities = new BlockState[chunk.tileEntities.size()]; + + for (Object obj : chunk.tileEntities.keySet().toArray()) { + if (!(obj instanceof BlockPosition)) { + continue; + } + + BlockPosition position = (BlockPosition) obj; + entities[index++] = worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(); + } + + return entities; + } + + public boolean isLoaded() { + return getWorld().isChunkLoaded(this); + } + + public boolean load() { + return getWorld().loadChunk(getX(), getZ(), true); + } + + public boolean load(boolean generate) { + return getWorld().loadChunk(getX(), getZ(), generate); + } + + public boolean unload() { + return getWorld().unloadChunk(getX(), getZ()); + } + + public boolean unload(boolean save) { + return getWorld().unloadChunk(getX(), getZ(), save); + } + + public boolean unload(boolean save, boolean safe) { + return getWorld().unloadChunk(getX(), getZ(), save, safe); + } + + public ChunkSnapshot getChunkSnapshot() { + return getChunkSnapshot(true, false, false); + } + + public ChunkSnapshot getChunkSnapshot(boolean includeMaxBlockY, boolean includeBiome, boolean includeBiomeTempRain) { + net.minecraft.server.Chunk chunk = getHandle(); + + ChunkSection[] cs = chunk.getSections(); + short[][] sectionBlockIDs = new short[cs.length][]; + byte[][] sectionBlockData = new byte[cs.length][]; + byte[][] sectionSkyLights = new byte[cs.length][]; + byte[][] sectionEmitLights = new byte[cs.length][]; + boolean[] sectionEmpty = new boolean[cs.length]; + + for (int i = 0; i < cs.length; i++) { + if (cs[i] == null) { // Section is empty? + sectionBlockIDs[i] = emptyBlockIDs; + sectionBlockData[i] = emptyData; + sectionSkyLights[i] = emptySkyLight; + sectionEmitLights[i] = emptyData; + sectionEmpty[i] = true; + } else { // Not empty + short[] blockids = new short[4096]; + char[] baseids = cs[i].getIdArray(); + byte[] dataValues = sectionBlockData[i] = new byte[2048]; + + // Copy base IDs + for (int j = 0; j < 4096; j++) { + if (baseids[j] == 0) continue; + IBlockData blockData = (IBlockData) net.minecraft.server.Block.d.a(baseids[j]); + if (blockData == null) continue; + blockids[j] = (short) net.minecraft.server.Block.getId(blockData.getBlock()); + int data = blockData.getBlock().toLegacyData(blockData); + int jj = j >> 1; + if ((j & 1) == 0) { + dataValues[jj] = (byte) ((dataValues[jj] & 0xF0) | (data & 0xF)); + } else { + dataValues[jj] = (byte) ((dataValues[jj] & 0xF) | ((data & 0xF) << 4)); + } + } + + sectionBlockIDs[i] = blockids; + + if (cs[i].getSkyLightArray() == null) { + sectionSkyLights[i] = emptyData; + } else { + sectionSkyLights[i] = new byte[2048]; + System.arraycopy(cs[i].getSkyLightArray().a(), 0, sectionSkyLights[i], 0, 2048); + } + sectionEmitLights[i] = new byte[2048]; + System.arraycopy(cs[i].getEmittedLightArray().a(), 0, sectionEmitLights[i], 0, 2048); + } + } + + int[] hmap = null; + + if (includeMaxBlockY) { + hmap = new int[256]; // Get copy of height map + System.arraycopy(chunk.heightMap, 0, hmap, 0, 256); + } + + BiomeBase[] biome = null; + double[] biomeTemp = null; + double[] biomeRain = null; + + if (includeBiome || includeBiomeTempRain) { + WorldChunkManager wcm = chunk.world.getWorldChunkManager(); + + if (includeBiome) { + biome = new BiomeBase[256]; + for (int i = 0; i < 256; i++) { + biome[i] = chunk.getBiome(new BlockPosition(i & 0xF, 0, i >> 4), wcm); + } + } + + if (includeBiomeTempRain) { + biomeTemp = new double[256]; + biomeRain = new double[256]; + float[] dat = getTemperatures(wcm, getX() << 4, getZ() << 4); + + for (int i = 0; i < 256; i++) { + biomeTemp[i] = dat[i]; + } + + dat = wcm.getWetness(null, getX() << 4, getZ() << 4, 16, 16); + + for (int i = 0; i < 256; i++) { + biomeRain[i] = dat[i]; + } + } + } + + World world = getWorld(); + return new CraftChunkSnapshot(getX(), getZ(), world.getName(), world.getFullTime(), sectionBlockIDs, sectionBlockData, sectionSkyLights, sectionEmitLights, sectionEmpty, hmap, biome, biomeTemp, biomeRain); + } + + public static ChunkSnapshot getEmptyChunkSnapshot(int x, int z, CraftWorld world, boolean includeBiome, boolean includeBiomeTempRain) { + BiomeBase[] biome = null; + double[] biomeTemp = null; + double[] biomeRain = null; + + if (includeBiome || includeBiomeTempRain) { + WorldChunkManager wcm = world.getHandle().getWorldChunkManager(); + + if (includeBiome) { + biome = new BiomeBase[256]; + for (int i = 0; i < 256; i++) { + biome[i] = world.getHandle().getBiome(new BlockPosition((x << 4) + (i & 0xF), 0, (z << 4) + (i >> 4))); + } + } + + if (includeBiomeTempRain) { + biomeTemp = new double[256]; + biomeRain = new double[256]; + float[] dat = getTemperatures(wcm, x << 4, z << 4); + + for (int i = 0; i < 256; i++) { + biomeTemp[i] = dat[i]; + } + + dat = wcm.getWetness(null, x << 4, z << 4, 16, 16); + + for (int i = 0; i < 256; i++) { + biomeRain[i] = dat[i]; + } + } + } + + /* Fill with empty data */ + int hSection = world.getMaxHeight() >> 4; + short[][] blockIDs = new short[hSection][]; + byte[][] skyLight = new byte[hSection][]; + byte[][] emitLight = new byte[hSection][]; + byte[][] blockData = new byte[hSection][]; + boolean[] empty = new boolean[hSection]; + + for (int i = 0; i < hSection; i++) { + blockIDs[i] = emptyBlockIDs; + skyLight[i] = emptySkyLight; + emitLight[i] = emptyData; + blockData[i] = emptyData; + empty[i] = true; + } + + return new CraftChunkSnapshot(x, z, world.getName(), world.getFullTime(), blockIDs, blockData, skyLight, emitLight, empty, new int[256], biome, biomeTemp, biomeRain); + } + + private static float[] getTemperatures(WorldChunkManager chunkmanager, int chunkX, int chunkZ) { + BiomeBase[] biomes = chunkmanager.getBiomes(null, chunkX, chunkZ, 16, 16); + float[] temps = new float[biomes.length]; + + for (int i = 0; i < biomes.length; i++) { + float temp = biomes[i].temperature; // Vanilla of olde: ((int) biomes[i].temperature * 65536.0F) / 65536.0F + + if (temp > 1F) { + temp = 1F; + } + + temps[i] = temp; + } + + return temps; + } + + static { + Arrays.fill(emptySkyLight, (byte) 0xFF); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java new file mode 100644 index 0000000..edf701b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java @@ -0,0 +1,97 @@ +package org.bukkit.craftbukkit; + +import org.bukkit.ChunkSnapshot; +import org.bukkit.block.Biome; +import org.bukkit.craftbukkit.block.CraftBlock; + +import net.minecraft.server.BiomeBase; + +/** + * Represents a static, thread-safe snapshot of chunk of blocks + * Purpose is to allow clean, efficient copy of a chunk data to be made, and then handed off for processing in another thread (e.g. map rendering) + */ +public class CraftChunkSnapshot implements ChunkSnapshot { + private final int x, z; + private final String worldname; + private final short[][] blockids; /* Block IDs, by section */ + private final byte[][] blockdata; + private final byte[][] skylight; + private final byte[][] emitlight; + private final boolean[] empty; + private final int[] hmap; // Height map + private final long captureFulltime; + private final BiomeBase[] biome; + private final double[] biomeTemp; + private final double[] biomeRain; + + CraftChunkSnapshot(int x, int z, String wname, long wtime, short[][] sectionBlockIDs, byte[][] sectionBlockData, byte[][] sectionSkyLights, byte[][] sectionEmitLights, boolean[] sectionEmpty, int[] hmap, BiomeBase[] biome, double[] biomeTemp, double[] biomeRain) { + this.x = x; + this.z = z; + this.worldname = wname; + this.captureFulltime = wtime; + this.blockids = sectionBlockIDs; + this.blockdata = sectionBlockData; + this.skylight = sectionSkyLights; + this.emitlight = sectionEmitLights; + this.empty = sectionEmpty; + this.hmap = hmap; + this.biome = biome; + this.biomeTemp = biomeTemp; + this.biomeRain = biomeRain; + } + + public int getX() { + return x; + } + + public int getZ() { + return z; + } + + public String getWorldName() { + return worldname; + } + + public final int getBlockTypeId(int x, int y, int z) { + return blockids[y >> 4][((y & 0xF) << 8) | (z << 4) | x]; + } + + public final int getBlockData(int x, int y, int z) { + int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1); + return (blockdata[y >> 4][off] >> ((x & 1) << 2)) & 0xF; + } + + public final int getBlockSkyLight(int x, int y, int z) { + int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1); + return (skylight[y >> 4][off] >> ((x & 1) << 2)) & 0xF; + } + + public final int getBlockEmittedLight(int x, int y, int z) { + int off = ((y & 0xF) << 7) | (z << 3) | (x >> 1); + return (emitlight[y >> 4][off] >> ((x & 1) << 2)) & 0xF; + } + + public final int getHighestBlockYAt(int x, int z) { + return hmap[z << 4 | x]; + } + + public final Biome getBiome(int x, int z) { + return CraftBlock.biomeBaseToBiome(biome[z << 4 | x]); + } + + public final double getRawBiomeTemperature(int x, int z) { + return biomeTemp[z << 4 | x]; + } + + public final double getRawBiomeRainfall(int x, int z) { + return biomeRain[z << 4 | x]; + } + + public final long getCaptureFullTime() { + return captureFulltime; + } + + public final boolean isSectionEmpty(int sy) { + return empty[sy]; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java new file mode 100644 index 0000000..8998372 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java @@ -0,0 +1,42 @@ +package org.bukkit.craftbukkit; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.Callable; + +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; + +import net.minecraft.server.MinecraftServer; + +public class CraftCrashReport implements Callable { + + public Object call() throws Exception { + StringWriter value = new StringWriter(); + try { + value.append("\n Running: ").append(Bukkit.getName()).append(" version ").append(Bukkit.getVersion()).append(" (Implementing API version ").append(Bukkit.getBukkitVersion()).append(") ").append(String.valueOf(MinecraftServer.getServer().getOnlineMode())); + value.append("\n Plugins: {"); + for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { + PluginDescriptionFile description = plugin.getDescription(); + 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(','); + } + value.append("}\n ").append(Bukkit.getScheduler().toString()); + } catch (Throwable t) { + value.append("\n Failed to handle CraftCrashReport:\n"); + PrintWriter writer = new PrintWriter(value); + t.printStackTrace(writer); + writer.flush(); + } + return value.toString(); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftEffect.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftEffect.java new file mode 100644 index 0000000..13f9e9d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftEffect.java @@ -0,0 +1,66 @@ +package org.bukkit.craftbukkit; + +import org.apache.commons.lang.Validate; +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.potion.Potion; + +public class CraftEffect { + public static int getDataValue(Effect effect, T data) { + int datavalue; + switch(effect) { + case POTION_BREAK: + datavalue = ((Potion) data).toDamageValue() & 0x3F; + break; + case RECORD_PLAY: + Validate.isTrue(((Material) data).isRecord(), "Invalid record type!"); + datavalue = ((Material) data).getId(); + break; + case SMOKE: + switch((BlockFace) data) { // TODO: Verify (Where did these values come from...?) + case SOUTH_EAST: + datavalue = 0; + break; + case SOUTH: + datavalue = 1; + break; + case SOUTH_WEST: + datavalue = 2; + break; + case EAST: + datavalue = 3; + break; + case UP: + case SELF: + datavalue = 4; + break; + case WEST: + datavalue = 5; + break; + case NORTH_EAST: + datavalue = 6; + break; + case NORTH: + datavalue = 7; + break; + case NORTH_WEST: + datavalue = 8; + break; + default: + throw new IllegalArgumentException("Bad smoke direction!"); + } + break; + case STEP_SOUND: + Validate.isTrue(((Material) data).isBlock(), "Material is not a block!"); + datavalue = ((Material) data).getId(); + break; + case ITEM_BREAK: + datavalue = ((Material) data).getId(); + break; + default: + datavalue = 0; + } + return datavalue; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java new file mode 100644 index 0000000..a33f446 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java @@ -0,0 +1,35 @@ +package org.bukkit.craftbukkit; + +import org.bukkit.inventory.EquipmentSlot; + +public class CraftEquipmentSlot { + + private static final int[] slots = new int[EquipmentSlot.values().length]; + private static final EquipmentSlot[] enums = new EquipmentSlot[EquipmentSlot.values().length]; + + static { + set(EquipmentSlot.HAND, 0); + set(EquipmentSlot.FEET, 1); + set(EquipmentSlot.LEGS, 2); + set(EquipmentSlot.CHEST, 3); + set(EquipmentSlot.HEAD, 4); + } + + private static void set(EquipmentSlot type, int value) { + slots[type.ordinal()] = value; + if (value < enums.length) { + enums[value] = type; + } + } + + public static EquipmentSlot getSlot(int magic) { + if (magic > 0 && magic < enums.length) { + return enums[magic]; + } + return null; + } + + public static int getSlotIndex(EquipmentSlot slot) { + return slots[slot.ordinal()]; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java new file mode 100644 index 0000000..7a8ea3b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java @@ -0,0 +1,88 @@ +package org.bukkit.craftbukkit; + +import net.minecraft.server.IpBanEntry; +import net.minecraft.server.IpBanList; +import net.minecraft.server.MinecraftServer; + +import java.io.IOException; +import java.util.Date; +import java.util.logging.Level; +import org.bukkit.Bukkit; + +public final class CraftIpBanEntry implements org.bukkit.BanEntry { + private final IpBanList list; + private final String target; + private Date created; + private String source; + private Date expiration; + private String reason; + + public CraftIpBanEntry(String target, IpBanEntry entry, IpBanList list) { + this.list = list; + this.target = target; + this.created = entry.getCreated() != null ? new Date(entry.getCreated().getTime()) : null; + this.source = entry.getSource(); + this.expiration = entry.getExpires() != null ? new Date(entry.getExpires().getTime()) : null; + this.reason = entry.getReason(); + } + + @Override + public String getTarget() { + return this.target; + } + + @Override + public Date getCreated() { + return this.created == null ? null : (Date) this.created.clone(); + } + + @Override + public void setCreated(Date created) { + this.created = created; + } + + @Override + public String getSource() { + return this.source; + } + + @Override + public void setSource(String source) { + this.source = source; + } + + @Override + public Date getExpiration() { + return this.expiration == null ? null : (Date) this.expiration.clone(); + } + + @Override + public void setExpiration(Date expiration) { + if (expiration != null && expiration.getTime() == new Date(0, 0, 0, 0, 0, 0).getTime()) { + expiration = null; // Forces "forever" + } + + this.expiration = expiration; + } + + @Override + public String getReason() { + return this.reason; + } + + @Override + public void setReason(String reason) { + this.reason = reason; + } + + @Override + public void save() { + IpBanEntry entry = new IpBanEntry(target, this.created, this.source, this.expiration, this.reason); + this.list.add(entry); + try { + this.list.save(); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Failed to save banned-ips.json, {0}", ex.getMessage()); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java new file mode 100644 index 0000000..80832f7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java @@ -0,0 +1,79 @@ +package org.bukkit.craftbukkit; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Date; +import java.util.Set; + +import net.minecraft.server.IpBanEntry; +import net.minecraft.server.IpBanList; +import net.minecraft.server.MinecraftServer; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; + +import com.google.common.collect.ImmutableSet; +import java.util.logging.Level; +import org.bukkit.Bukkit; + +public class CraftIpBanList implements org.bukkit.BanList { + private final IpBanList list; + + public CraftIpBanList(IpBanList list) { + this.list = list; + } + + @Override + public org.bukkit.BanEntry getBanEntry(String target) { + Validate.notNull(target, "Target cannot be null"); + + IpBanEntry entry = (IpBanEntry) list.get(target); + if (entry == null) { + return null; + } + + return new CraftIpBanEntry(target, entry, list); + } + + @Override + public org.bukkit.BanEntry addBan(String target, String reason, Date expires, String source) { + Validate.notNull(target, "Ban target cannot be null"); + + IpBanEntry entry = new IpBanEntry(target, new Date(), + StringUtils.isBlank(source) ? null : source, expires, + StringUtils.isBlank(reason) ? null : reason); + + list.add(entry); + + try { + list.save(); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Failed to save banned-ips.json, {0}", ex.getMessage()); + } + + return new CraftIpBanEntry(target, entry, list); + } + + @Override + public Set getBanEntries() { + ImmutableSet.Builder builder = ImmutableSet.builder(); + for (String target : list.getEntries()) { + builder.add(new CraftIpBanEntry(target, (IpBanEntry) list.get(target), list)); + } + + return builder.build(); + } + + @Override + public boolean isBanned(String target) { + Validate.notNull(target, "Target cannot be null"); + + return list.isBanned(InetSocketAddress.createUnresolved(target, 0)); + } + + @Override + public void pardon(String target) { + Validate.notNull(target, "Target cannot be null"); + + list.remove(target); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java new file mode 100644 index 0000000..4521786 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -0,0 +1,261 @@ +package org.bukkit.craftbukkit; + +import com.mojang.authlib.GameProfile; +import java.io.File; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.WorldNBTStorage; + +import org.bukkit.BanList; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.Server; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.SerializableAs; +import org.bukkit.entity.Player; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.Plugin; + +@SerializableAs("Player") +public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializable { + private final GameProfile profile; + private final CraftServer server; + private final WorldNBTStorage storage; + + protected CraftOfflinePlayer(CraftServer server, GameProfile profile) { + this.server = server; + this.profile = profile; + this.storage = (WorldNBTStorage) (server.console.worlds.get(0).getDataManager()); + + } + + public GameProfile getProfile() { + return profile; + } + + public boolean isOnline() { + return getPlayer() != null; + } + + public String getName() { + Player player = getPlayer(); + if (player != null) { + return player.getName(); + } + + // This might not match lastKnownName but if not it should be more correct + if (profile.getName() != null) { + return profile.getName(); + } + + NBTTagCompound data = getBukkitData(); + + if (data != null) { + if (data.hasKey("lastKnownName")) { + return data.getString("lastKnownName"); + } + } + + return null; + } + + public UUID getUniqueId() { + return profile.getId(); + } + + public Server getServer() { + return server; + } + + public boolean isOp() { + return server.getHandle().isOp(profile); + } + + public void setOp(boolean value) { + if (value == isOp()) { + return; + } + + if (value) { + server.getHandle().addOp(profile); + } else { + server.getHandle().removeOp(profile); + } + } + + public boolean isBanned() { + if (getName() == null) { + return false; + } + + return server.getBanList(BanList.Type.NAME).isBanned(getName()); + } + + public void setBanned(boolean value) { + if (getName() == null) { + return; + } + + if (value) { + server.getBanList(BanList.Type.NAME).addBan(getName(), null, null, null); + } else { + server.getBanList(BanList.Type.NAME).pardon(getName()); + } + } + + public boolean isWhitelisted() { + return server.getHandle().getWhitelist().isWhitelisted(profile); + } + + public void setWhitelisted(boolean value) { + if (value) { + server.getHandle().addWhitelist(profile); + } else { + server.getHandle().removeWhitelist(profile); + } + } + + public Map serialize() { + Map result = new LinkedHashMap(); + + result.put("UUID", profile.getId().toString()); + + return result; + } + + public static OfflinePlayer deserialize(Map args) { + // Backwards comparability + if (args.get("name") != null) { + return Bukkit.getServer().getOfflinePlayer((String) args.get("name")); + } + + return Bukkit.getServer().getOfflinePlayer(UUID.fromString((String) args.get("UUID"))); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "[UUID=" + profile.getId() + "]"; + } + + public Player getPlayer() { + return server.getPlayer(getUniqueId()); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof OfflinePlayer)) { + return false; + } + + OfflinePlayer other = (OfflinePlayer) obj; + if ((this.getUniqueId() == null) || (other.getUniqueId() == null)) { + return false; + } + + return this.getUniqueId().equals(other.getUniqueId()); + } + + @Override + public int hashCode() { + int hash = 5; + hash = 97 * hash + (this.getUniqueId() != null ? this.getUniqueId().hashCode() : 0); + return hash; + } + + private NBTTagCompound getData() { + return storage.getPlayerData(getUniqueId().toString()); + } + + private NBTTagCompound getBukkitData() { + NBTTagCompound result = getData(); + + if (result != null) { + if (!result.hasKey("bukkit")) { + result.set("bukkit", new NBTTagCompound()); + } + result = result.getCompound("bukkit"); + } + + return result; + } + + private File getDataFile() { + return new File(storage.getPlayerDir(), getUniqueId() + ".dat"); + } + + public long getFirstPlayed() { + Player player = getPlayer(); + if (player != null) return player.getFirstPlayed(); + + NBTTagCompound data = getBukkitData(); + + if (data != null) { + if (data.hasKey("firstPlayed")) { + return data.getLong("firstPlayed"); + } else { + File file = getDataFile(); + return file.lastModified(); + } + } else { + return 0; + } + } + + public long getLastPlayed() { + Player player = getPlayer(); + if (player != null) return player.getLastPlayed(); + + NBTTagCompound data = getBukkitData(); + + if (data != null) { + if (data.hasKey("lastPlayed")) { + return data.getLong("lastPlayed"); + } else { + File file = getDataFile(); + return file.lastModified(); + } + } else { + return 0; + } + } + + public boolean hasPlayedBefore() { + return getData() != null; + } + + public Location getBedSpawnLocation() { + NBTTagCompound data = getData(); + if (data == null) return null; + + if (data.hasKey("SpawnX") && data.hasKey("SpawnY") && data.hasKey("SpawnZ")) { + String spawnWorld = data.getString("SpawnWorld"); + if (spawnWorld.equals("")) { + spawnWorld = server.getWorlds().get(0).getName(); + } + return new Location(server.getWorld(spawnWorld), data.getInt("SpawnX"), data.getInt("SpawnY"), data.getInt("SpawnZ")); + } + return null; + } + + public void setMetadata(String metadataKey, MetadataValue metadataValue) { + server.getPlayerMetadata().setMetadata(this, metadataKey, metadataValue); + } + + public List getMetadata(String metadataKey) { + return server.getPlayerMetadata().getMetadata(this, metadataKey); + } + + public boolean hasMetadata(String metadataKey) { + return server.getPlayerMetadata().hasMetadata(this, metadataKey); + } + + public void removeMetadata(String metadataKey, Plugin plugin) { + server.getPlayerMetadata().removeMetadata(this, metadataKey, plugin); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftProfileBanEntry.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftProfileBanEntry.java new file mode 100644 index 0000000..3c6f922 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftProfileBanEntry.java @@ -0,0 +1,89 @@ +package org.bukkit.craftbukkit; + +import com.mojang.authlib.GameProfile; +import net.minecraft.server.GameProfileBanEntry; +import net.minecraft.server.GameProfileBanList; +import net.minecraft.server.MinecraftServer; + +import java.io.IOException; +import java.util.Date; +import java.util.logging.Level; +import org.bukkit.Bukkit; + +public final class CraftProfileBanEntry implements org.bukkit.BanEntry { + private final GameProfileBanList list; + private final GameProfile profile; + private Date created; + private String source; + private Date expiration; + private String reason; + + public CraftProfileBanEntry(GameProfile profile, GameProfileBanEntry entry, GameProfileBanList list) { + this.list = list; + this.profile = profile; + this.created = entry.getCreated() != null ? new Date(entry.getCreated().getTime()) : null; + this.source = entry.getSource(); + this.expiration = entry.getExpires() != null ? new Date(entry.getExpires().getTime()) : null; + this.reason = entry.getReason(); + } + + @Override + public String getTarget() { + return this.profile.getName(); + } + + @Override + public Date getCreated() { + return this.created == null ? null : (Date) this.created.clone(); + } + + @Override + public void setCreated(Date created) { + this.created = created; + } + + @Override + public String getSource() { + return this.source; + } + + @Override + public void setSource(String source) { + this.source = source; + } + + @Override + public Date getExpiration() { + return this.expiration == null ? null : (Date) this.expiration.clone(); + } + + @Override + public void setExpiration(Date expiration) { + if (expiration != null && expiration.getTime() == new Date(0, 0, 0, 0, 0, 0).getTime()) { + expiration = null; // Forces "forever" + } + + this.expiration = expiration; + } + + @Override + public String getReason() { + return this.reason; + } + + @Override + public void setReason(String reason) { + this.reason = reason; + } + + @Override + public void save() { + GameProfileBanEntry entry = new GameProfileBanEntry(profile, this.created, this.source, this.expiration, this.reason); + this.list.add(entry); + try { + this.list.save(); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Failed to save banned-players.json, {0}", ex.getMessage()); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftProfileBanList.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftProfileBanList.java new file mode 100644 index 0000000..84a1f9c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftProfileBanList.java @@ -0,0 +1,99 @@ +package org.bukkit.craftbukkit; + +import java.io.IOException; +import java.util.Date; +import java.util.Set; + +import net.minecraft.server.GameProfileBanEntry; +import net.minecraft.server.GameProfileBanList; +import net.minecraft.server.JsonListEntry; +import net.minecraft.server.MinecraftServer; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; + +import com.google.common.collect.ImmutableSet; +import com.mojang.authlib.GameProfile; +import java.util.logging.Level; +import org.bukkit.Bukkit; + +public class CraftProfileBanList implements org.bukkit.BanList { + private final GameProfileBanList list; + + public CraftProfileBanList(GameProfileBanList list){ + this.list = list; + } + + @Override + public org.bukkit.BanEntry getBanEntry(String target) { + Validate.notNull(target, "Target cannot be null"); + + GameProfile profile = MinecraftServer.getServer().getUserCache().getProfile(target); + if (profile == null) { + return null; + } + + GameProfileBanEntry entry = (GameProfileBanEntry) list.get(profile); + if (entry == null) { + return null; + } + + return new CraftProfileBanEntry(profile, entry, list); + } + + @Override + public org.bukkit.BanEntry addBan(String target, String reason, Date expires, String source) { + Validate.notNull(target, "Ban target cannot be null"); + + GameProfile profile = MinecraftServer.getServer().getUserCache().getProfile(target); + if (profile == null) { + return null; + } + + GameProfileBanEntry entry = new GameProfileBanEntry(profile, new Date(), + StringUtils.isBlank(source) ? null : source, expires, + StringUtils.isBlank(reason) ? null : reason); + + list.add(entry); + + try { + list.save(); + } catch (IOException ex) { + Bukkit.getLogger().log(Level.SEVERE, "Failed to save banned-players.json, {0}", ex.getMessage()); + } + + return new CraftProfileBanEntry(profile, entry, list); + } + + @Override + public Set getBanEntries() { + ImmutableSet.Builder builder = ImmutableSet.builder(); + + for (JsonListEntry entry : list.getValues()) { + GameProfile profile = (GameProfile) entry.getKey(); + builder.add(new CraftProfileBanEntry(profile, (GameProfileBanEntry) entry, list)); + } + + return builder.build(); + } + + @Override + public boolean isBanned(String target) { + Validate.notNull(target, "Target cannot be null"); + + GameProfile profile = MinecraftServer.getServer().getUserCache().getProfile(target); + if (profile == null) { + return false; + } + + return list.isBanned(profile); + } + + @Override + public void pardon(String target) { + Validate.notNull(target, "Target cannot be null"); + + GameProfile profile = MinecraftServer.getServer().getUserCache().getProfile(target); + list.remove(profile); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftServer.java new file mode 100644 index 0000000..5fdf4e7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -0,0 +1,1791 @@ +package org.bukkit.craftbukkit; + +import com.avaje.ebean.config.DataSourceConfig; +import com.avaje.ebean.config.ServerConfig; +import com.avaje.ebean.config.dbplatform.SQLitePlatform; +import com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation; +import com.google.common.base.Charsets; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.MapMaker; +import com.mojang.authlib.GameProfile; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.Unpooled; +import io.netty.handler.codec.base64.Base64; +import jline.console.ConsoleReader; +import me.levansj01.mythicspigot.MythicCore; +import net.md_5.bungee.api.chat.BaseComponent; +import net.minecraft.server.WorldType; +import net.minecraft.server.*; +import org.apache.commons.lang.Validate; +import org.bukkit.*; +import org.bukkit.World; +import org.bukkit.Warning.WarningState; +import org.bukkit.World.Environment; +import org.bukkit.command.CommandException; +import org.bukkit.command.*; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.conversations.Conversable; +import org.bukkit.craftbukkit.command.VanillaCommandWrapper; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.generator.CraftChunkData; +import org.bukkit.craftbukkit.help.SimpleHelpMap; +import org.bukkit.craftbukkit.inventory.*; +import org.bukkit.craftbukkit.map.CraftMapView; +import org.bukkit.craftbukkit.metadata.EntityMetadataStore; +import org.bukkit.craftbukkit.metadata.PlayerMetadataStore; +import org.bukkit.craftbukkit.metadata.WorldMetadataStore; +import org.bukkit.craftbukkit.potion.CraftPotionBrewer; +import org.bukkit.craftbukkit.scheduler.CraftScheduler; +import org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager; +import org.bukkit.craftbukkit.util.CraftIconCache; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.craftbukkit.util.DatFileFilter; +import org.bukkit.craftbukkit.util.Versioning; +import org.bukkit.craftbukkit.util.permissions.CraftDefaultPermissions; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerChatTabCompleteEvent; +import org.bukkit.event.world.WorldInitEvent; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.help.HelpMap; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.*; +import org.bukkit.permissions.Permissible; +import org.bukkit.permissions.Permission; +import org.bukkit.plugin.*; +import org.bukkit.plugin.java.JavaPluginLoader; +import org.bukkit.plugin.messaging.Messenger; +import org.bukkit.plugin.messaging.StandardMessenger; +import org.bukkit.potion.Potion; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitWorker; +import org.bukkit.util.StringUtil; +import org.bukkit.util.permissions.DefaultPermissions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; +import org.yaml.snakeyaml.error.MarkedYAMLException; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.*; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +public final class CraftServer implements Server { + private static final Player[] EMPTY_PLAYER_ARRAY = new Player[0]; + private final String serverName = "CraftBukkit"; + private final String serverVersion; + private final String bukkitVersion = Versioning.getBukkitVersion(); + private final Logger logger = Logger.getLogger("Minecraft"); + private final ServicesManager servicesManager = new SimpleServicesManager(); + private final CraftScheduler scheduler = new CraftScheduler(); + private final SimpleCommandMap commandMap = new SimpleCommandMap(this); + private final SimpleHelpMap helpMap = new SimpleHelpMap(this); + private final StandardMessenger messenger = new StandardMessenger(); + private final PluginManager pluginManager = new SimplePluginManager(this, commandMap); + protected final MinecraftServer console; + protected final DedicatedPlayerList playerList; + private final Map worlds = new LinkedHashMap(); + private YamlConfiguration configuration; + private YamlConfiguration commandsConfiguration; + private final Yaml yaml = new Yaml(new SafeConstructor()); + private final Map offlinePlayers = new MapMaker().softValues().makeMap(); + private final EntityMetadataStore entityMetadata = new EntityMetadataStore(); + private final PlayerMetadataStore playerMetadata = new PlayerMetadataStore(); + private final WorldMetadataStore worldMetadata = new WorldMetadataStore(); + private int monsterSpawn = -1; + private int animalSpawn = -1; + private int waterAnimalSpawn = -1; + private int ambientSpawn = -1; + public int chunkGCPeriod = -1; + public int chunkGCLoadThresh = 0; + private File container; + private WarningState warningState = WarningState.DEFAULT; + private final BooleanWrapper online = new BooleanWrapper(); + public CraftScoreboardManager scoreboardManager; + public boolean playerCommandState; + private boolean printSaveWarning; + private CraftIconCache icon; + private boolean overrideAllCommandBlockCommands = false; + 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 class BooleanWrapper { + private boolean value = true; + } + + static { + ConfigurationSerialization.registerClass(CraftOfflinePlayer.class); + CraftItemFactory.instance(); + } + + public CraftServer(MinecraftServer console, PlayerList playerList) { + this.console = console; + this.playerList = (DedicatedPlayerList) playerList; + this.playerView = Collections.unmodifiableList(Lists.transform(playerList.players, new Function() { + @Override + public CraftPlayer apply(EntityPlayer player) { + return player.getBukkitEntity(); + } + })); + this.serverVersion = CraftServer.class.getPackage().getImplementationVersion(); + online.value = console.getPropertyManager().getBoolean("online-mode", true); + + Bukkit.setServer(this); + + // Register all the Enchantments and PotionTypes now so we can stop new registration immediately after + Enchantment.DAMAGE_ALL.getClass(); + org.bukkit.enchantments.Enchantment.stopAcceptingRegistrations(); + + Potion.setPotionBrewer(new CraftPotionBrewer()); + MobEffectList.BLINDNESS.getClass(); + PotionEffectType.stopAcceptingRegistrations(); + // Ugly hack :( + + if (!Main.useConsole) { + getLogger().info("Console 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(); + + // 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"); + loadIcon(); + + // Spigot Start - Moved to old location of new DedicatedPlayerList in DedicatedServer + // loadPlugins(); + // enablePlugins(PluginLoadOrder.STARTUP); + // Spigot End + } + + 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); + } + } + + public void loadPlugins() { + pluginManager.registerInterface(JavaPluginLoader.class); + + File pluginFolder = (File) console.options.valueOf("plugins"); + + if (pluginFolder.exists()) { + Plugin[] plugins = pluginManager.loadPlugins(pluginFolder); + for (Plugin plugin : plugins) { + try { + String message = String.format("Loading %s", plugin.getDescription().getFullName()); + plugin.getLogger().info(message); + plugin.onLoad(); + } catch (Throwable ex) { + Logger.getLogger(CraftServer.class.getName()).log(Level.SEVERE, ex.getMessage() + " initializing " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + } + } else { + pluginFolder.mkdir(); + } + } + + public void enablePlugins(PluginLoadOrder type) { + if (type == PluginLoadOrder.STARTUP) { + helpMap.clear(); + helpMap.initializeGeneralTopics(); + } + + Plugin[] plugins = pluginManager.getPlugins(); + + for (Plugin plugin : plugins) { + if ((!plugin.isEnabled()) && (plugin.getDescription().getLoad() == type)) { + loadPlugin(plugin); + } + } + + if (type == PluginLoadOrder.POSTWORLD) { + // Spigot start - Allow vanilla commands to be forced to be the main command + setVanillaCommands(true); + commandMap.setFallbackCommands(); + setVanillaCommands(false); + // Spigot end + commandMap.registerServerAliases(); + loadCustomPermissions(); + DefaultPermissions.registerCorePermissions(); + CraftDefaultPermissions.registerCorePermissions(); + helpMap.initializeCommands(); + co.aikar.timings.Timings.reset(); // Spigot + } + } + + public void disablePlugins() { + pluginManager.disablePlugins(); + } + + private void setVanillaCommands(boolean first) { // Spigot + Map commands = new CommandDispatcher().getCommands(); + for (ICommand cmd : commands.values()) { + // Spigot start + VanillaCommandWrapper wrapper = new VanillaCommandWrapper((CommandAbstract) cmd, LocaleI18n.get(cmd.getUsage(null))); + if (org.spigotmc.SpigotConfig.replaceCommands.contains( wrapper.getName() ) ) { + if (first) { + commandMap.register("minecraft", wrapper); + } + } else if (!first) { + commandMap.register("minecraft", wrapper); + } + // Spigot end + } + } + + private void loadPlugin(Plugin plugin) { + try { + pluginManager.enablePlugin(plugin); + + List perms = plugin.getDescription().getPermissions(); + + for (Permission perm : perms) { + try { + pluginManager.addPermission(perm); + } catch (IllegalArgumentException ex) { + getLogger().log(Level.WARNING, "Plugin " + plugin.getDescription().getFullName() + " tried to register permission '" + perm.getName() + "' but it's already registered", ex); + } + } + } catch (Throwable ex) { + Logger.getLogger(CraftServer.class.getName()).log(Level.SEVERE, ex.getMessage() + " loading " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex); + } + } + + @Override + public String getName() { + return serverName; + } + + @Override + public String getVersion() { + return serverVersion + " (MC: " + console.getVersion() + ")"; + } + + @Override + public String getBukkitVersion() { + return bukkitVersion; + } + + @Override + @Deprecated + @SuppressWarnings("unchecked") + public Player[] _INVALID_getOnlinePlayers() { + return getOnlinePlayers().toArray(EMPTY_PLAYER_ARRAY); + } + + @Override + public List getOnlinePlayers() { + return this.playerView; + } + + @Override + @Deprecated + public Player getPlayer(final String name) { + Validate.notNull(name, "Name cannot be null"); + + Player found = getPlayerExact(name); + // Try for an exact match first. + if (found != null) { + return found; + } + + String lowerName = name.toLowerCase(); + int delta = Integer.MAX_VALUE; + for (Player player : getOnlinePlayers()) { + if (player.getName().toLowerCase().startsWith(lowerName)) { + int curDelta = Math.abs(player.getName().length() - lowerName.length()); + if (curDelta < delta) { + found = player; + delta = curDelta; + } + if (curDelta == 0) break; + } + } + return found; + } + + @Override + @Deprecated + public Player getPlayerExact(String name) { + Validate.notNull(name, "Name cannot be null"); + + EntityPlayer player = playerList.getPlayer(name); + return (player != null) ? player.getBukkitEntity() : null; + } + + @Override + public Player getPlayer(UUID id) { + EntityPlayer player = playerList.a(id); + + if (player != null) { + return player.getBukkitEntity(); + } + + return null; + } + + @Override + public int broadcastMessage(String message) { + return broadcast(message, BROADCAST_CHANNEL_USERS); + } + + public Player getPlayer(final EntityPlayer entity) { + return entity.getBukkitEntity(); + } + + @Override + @Deprecated + public List matchPlayer(String partialName) { + Validate.notNull(partialName, "PartialName cannot be null"); + + List matchedPlayers = new ArrayList(); + + for (Player iterPlayer : this.getOnlinePlayers()) { + String iterPlayerName = iterPlayer.getName(); + + if (partialName.equalsIgnoreCase(iterPlayerName)) { + // Exact match + matchedPlayers.clear(); + matchedPlayers.add(iterPlayer); + break; + } + if (iterPlayerName.toLowerCase().contains(partialName.toLowerCase())) { + // Partial match + matchedPlayers.add(iterPlayer); + } + } + + return matchedPlayers; + } + + @Override + public int getMaxPlayers() { + return playerList.getMaxPlayers(); + } + + // NOTE: These are dependent on the corrisponding call in MinecraftServer + // so if that changes this will need to as well + @Override + public int getPort() { + return this.getConfigInt("server-port", 25565); + } + + @Override + public int getViewDistance() { + return this.getConfigInt("view-distance", 10); + } + + @Override + public String getIp() { + return this.getConfigString("server-ip", ""); + } + + @Override + public String getServerName() { + return this.getConfigString("server-name", "Unknown Server"); + } + + @Override + public String getServerId() { + return this.getConfigString("server-id", "unnamed"); + } + + @Override + public String getWorldType() { + return this.getConfigString("level-type", "DEFAULT"); + } + + @Override + public boolean getGenerateStructures() { + return this.getConfigBoolean("generate-structures", true); + } + + @Override + public boolean getAllowEnd() { + return this.configuration.getBoolean("settings.allow-end"); + } + + @Override + public boolean getAllowNether() { + return this.getConfigBoolean("allow-nether", true); + } + + public boolean getWarnOnOverload() { + return this.configuration.getBoolean("settings.warn-on-overload"); + } + + public boolean getQueryPlugins() { + return this.configuration.getBoolean("settings.query-plugins"); + } + + @Override + public boolean hasWhitelist() { + return this.getConfigBoolean("white-list", false); + } + + // NOTE: Temporary calls through to server.properies until its replaced + private String getConfigString(String variable, String defaultValue) { + return this.console.getPropertyManager().getString(variable, defaultValue); + } + + private int getConfigInt(String variable, int defaultValue) { + return this.console.getPropertyManager().getInt(variable, defaultValue); + } + + private boolean getConfigBoolean(String variable, boolean defaultValue) { + return this.console.getPropertyManager().getBoolean(variable, defaultValue); + } + + // End Temporary calls + + @Override + public String getUpdateFolder() { + return this.configuration.getString("settings.update-folder", "update"); + } + + @Override + public File getUpdateFolderFile() { + return new File((File) console.options.valueOf("plugins"), this.configuration.getString("settings.update-folder", "update")); + } + + @Override + public long getConnectionThrottle() { + // Spigot Start - Automatically set connection throttle for bungee configurations + if (org.spigotmc.SpigotConfig.bungee) { + return -1; + } else { + return this.configuration.getInt("settings.connection-throttle"); + } + // Spigot End + } + + @Override + public int getTicksPerAnimalSpawns() { + return this.configuration.getInt("ticks-per.animal-spawns"); + } + + @Override + public int getTicksPerMonsterSpawns() { + return this.configuration.getInt("ticks-per.monster-spawns"); + } + + @Override + public PluginManager getPluginManager() { + return pluginManager; + } + + @Override + public CraftScheduler getScheduler() { + return scheduler; + } + + @Override + public ServicesManager getServicesManager() { + return servicesManager; + } + + @Override + public List getWorlds() { + return new ArrayList(worlds.values()); + } + + public DedicatedPlayerList getHandle() { + return playerList; + } + + // NOTE: Should only be called from DedicatedServer.ah() + public boolean dispatchServerCommand(CommandSender sender, ServerCommand serverCommand) { + if (sender instanceof Conversable) { + Conversable conversable = (Conversable)sender; + + if (conversable.isConversing()) { + conversable.acceptConversationInput(serverCommand.command); + return true; + } + } + try { + this.playerCommandState = true; + return dispatchCommand(sender, serverCommand.command); + } catch (Exception ex) { + getLogger().log(Level.WARNING, "Unexpected exception while parsing console command \"" + serverCommand.command + '"', ex); + return false; + } finally { + this.playerCommandState = false; + } + } + + @Override + public boolean dispatchCommand(CommandSender sender, String commandLine) { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(commandLine, "CommandLine cannot be null"); + + // PaperSpigot Start + if (!Bukkit.isPrimaryThread()) { + final CommandSender fSender = sender; + final String fCommandLine = commandLine; + Bukkit.getLogger().log(Level.SEVERE, "Command Dispatched Async: " + commandLine); + Bukkit.getLogger().log(Level.SEVERE, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable()); + org.bukkit.craftbukkit.util.Waitable wait = new org.bukkit.craftbukkit.util.Waitable() { + @Override + protected Boolean evaluate() { + return dispatchCommand(fSender, fCommandLine); + } + }; + net.minecraft.server.MinecraftServer.getServer().processQueue.add(wait); + try { + return wait.get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on! + } catch (Exception e) { + throw new RuntimeException("Exception processing dispatch command", e.getCause()); + } + } + // PaperSpigot End + + if (commandMap.dispatch(sender, commandLine)) { + return true; + } + + sender.sendMessage(org.spigotmc.SpigotConfig.unknownCommandMessage); + + 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 + } + + pluginManager.clearPlugins(); + commandMap.clearCommands(); + resetRecipes(); + org.spigotmc.SpigotConfig.registerCommands(); // Spigot + org.github.paperspigot.PaperSpigotConfig.registerCommands(); // PaperSpigot + MythicCore.getCore().load(); // Mythic + + 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 e) {} + 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 { + final File file = new File(new File("."), "server-icon.png"); + if (file.isFile()) { + icon = loadServerIcon0(file); + } + } catch (Exception ex) { + getLogger().log(Level.WARNING, "Couldn't load server icon", ex); + } + } + + @SuppressWarnings({ "unchecked", "finally" }) + private void loadCustomPermissions() { + File file = new File(configuration.getString("settings.permissions-file")); + FileInputStream stream; + + try { + stream = new FileInputStream(file); + } catch (FileNotFoundException ex) { + try { + file.createNewFile(); + } finally { + return; + } + } + + Map> perms; + + try { + perms = (Map>) yaml.load(stream); + } catch (MarkedYAMLException 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); + return; + } finally { + try { + stream.close(); + } catch (IOException ex) {} + } + + if (perms == null) { + getLogger().log(Level.INFO, "Server permissions file " + file + " is empty, ignoring it"); + return; + } + + List permsList = Permission.loadPermissions(perms, "Permission node '%s' in " + file + " is invalid", Permission.DEFAULT_PERMISSION); + + for (Permission perm : permsList) { + try { + pluginManager.addPermission(perm); + } catch (IllegalArgumentException ex) { + getLogger().log(Level.SEVERE, "Permission in " + file + " was already defined", ex); + } + } + } + + @Override + public String toString() { + return "CraftServer{" + "serverName=" + serverName + ",serverVersion=" + serverVersion + ",minecraftVersion=" + console.getVersion() + '}'; + } + + public World createWorld(String name, World.Environment environment) { + return WorldCreator.name(name).environment(environment).createWorld(); + } + + public World createWorld(String name, World.Environment environment, long seed) { + return WorldCreator.name(name).environment(environment).seed(seed).createWorld(); + } + + public World createWorld(String name, Environment environment, ChunkGenerator generator) { + return WorldCreator.name(name).environment(environment).generator(generator).createWorld(); + } + + public World createWorld(String name, Environment environment, long seed, ChunkGenerator generator) { + return WorldCreator.name(name).environment(environment).seed(seed).generator(generator).createWorld(); + } + + @Override + public World createWorld(WorldCreator creator) { + Validate.notNull(creator, "Creator may not be null"); + + String name = creator.name(); + ChunkGenerator generator = creator.generator(); + File folder = new File(getWorldContainer(), name); + World world = getWorld(name); + WorldType type = WorldType.getType(creator.type().getName()); + boolean generateStructures = creator.generateStructures(); + + if (world != null) { + return world; + } + + if ((folder.exists()) && (!folder.isDirectory())) { + throw new IllegalArgumentException("File exists with the name '" + name + "' and isn't a folder"); + } + + if (generator == null) { + generator = getGenerator(name); + } + + Convertable converter = new WorldLoaderServer(getWorldContainer()); + if (converter.isConvertable(name)) { + getLogger().info("Converting world '" + name + "'"); + converter.convert(name, new IProgressUpdate() { + private long b = System.currentTimeMillis(); + + public void a(String s) {} + + public void a(int i) { + if (System.currentTimeMillis() - this.b >= 1000L) { + this.b = System.currentTimeMillis(); + MinecraftServer.LOGGER.info("Converting... " + i + "%"); + } + + } + + public void c(String s) {} + }); + } + + int dimension = CraftWorld.CUSTOM_DIMENSION_OFFSET + console.worlds.size(); + boolean used = false; + do { + for (WorldServer server : console.worlds) { + used = server.dimension == dimension; + if (used) { + dimension++; + break; + } + } + } while(used); + boolean hardcore = false; + + IDataManager sdm = new ServerNBTManager(getWorldContainer(), name, true); + WorldData worlddata = sdm.getWorldData(); + if (worlddata == null) { + WorldSettings worldSettings = new WorldSettings(creator.seed(), WorldSettings.EnumGamemode.getById(getDefaultGameMode().getValue()), generateStructures, hardcore, type); + worldSettings.setGeneratorSettings(creator.generatorSettings()); + worlddata = new WorldData(worldSettings, name); + } + worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end) + WorldServer internal = (WorldServer) new WorldServer(console, sdm, worlddata, dimension, console.methodProfiler, creator.environment(), generator).b(); + + if (!(worlds.containsKey(name.toLowerCase()))) { + return null; + } + + internal.scoreboard = getScoreboardManager().getMainScoreboard().getHandle(); + + internal.tracker = new EntityTracker(internal); + internal.addIWorldAccess(new WorldManager(console, internal)); + internal.worldData.setDifficulty(EnumDifficulty.EASY); + internal.setSpawnFlags(true, true); + console.worlds.add(internal); + + if (generator != null) { + internal.getWorld().getPopulators().addAll(generator.getDefaultPopulators(internal.getWorld())); + } + + pluginManager.callEvent(new WorldInitEvent(internal.getWorld())); + System.out.print("Preparing start region for level " + (console.worlds.size() - 1) + " (Seed: " + internal.getSeed() + ")"); + + if (internal.getWorld().getKeepSpawnInMemory()) { + short short1 = 196; + long i = System.currentTimeMillis(); + for (int j = -short1; j <= short1; j += 16) { + for (int k = -short1; k <= short1; k += 16) { + long l = System.currentTimeMillis(); + + if (l < i) { + i = l; + } + + if (l > i + 1000L) { + int i1 = (short1 * 2 + 1) * (short1 * 2 + 1); + int j1 = (j + short1) * (short1 * 2 + 1) + k + 1; + + System.out.println("Preparing spawn area for " + name + ", " + (j1 * 100 / i1) + "%"); + i = l; + } + + BlockPosition chunkcoordinates = internal.getSpawn(); + internal.chunkProviderServer.getChunkAt(chunkcoordinates.getX() + j >> 4, chunkcoordinates.getZ() + k >> 4); + } + } + } + pluginManager.callEvent(new WorldLoadEvent(internal.getWorld())); + return internal.getWorld(); + } + + @Override + public boolean unloadWorld(String name, boolean save) { + return unloadWorld(getWorld(name), save); + } + + @Override + public boolean unloadWorld(World world, boolean save) { + if (world == null) { + return false; + } + + WorldServer handle = ((CraftWorld) world).getHandle(); + + if (!(console.worlds.contains(handle))) { + return false; + } + + if (!(handle.dimension > 1)) { + return false; + } + + if (handle.players.size() > 0) { + return false; + } + + WorldUnloadEvent e = new WorldUnloadEvent(handle.getWorld()); + pluginManager.callEvent(e); + + if (e.isCancelled()) { + return false; + } + + if (save) { + try { + handle.save(true, null); + handle.saveLevel(); + } catch (ExceptionWorldConflict ex) { + getLogger().log(Level.SEVERE, null, ex); + } + } + + worlds.remove(world.getName().toLowerCase()); + console.worlds.remove(handle); + + File parentFolder = world.getWorldFolder().getAbsoluteFile(); + + // Synchronized because access to RegionFileCache.a is guarded by this lock. + synchronized (RegionFileCache.class) { + // RegionFileCache.a should be RegionFileCache.cache + Iterator> i = RegionFileCache.a.entrySet().iterator(); + while(i.hasNext()) { + Map.Entry entry = i.next(); + File child = entry.getKey().getAbsoluteFile(); + while (child != null) { + if (child.equals(parentFolder)) { + i.remove(); + try { + entry.getValue().c(); // Should be RegionFile.close(); + } catch (IOException ex) { + getLogger().log(Level.SEVERE, null, ex); + } + break; + } + child = child.getParentFile(); + } + } + } + + return true; + } + + public MinecraftServer getServer() { + return console; + } + + @Override + public World getWorld(String name) { + Validate.notNull(name, "Name cannot be null"); + + return worlds.get(name.toLowerCase()); + } + + @Override + public World getWorld(UUID uid) { + for (World world : worlds.values()) { + if (world.getUID().equals(uid)) { + return world; + } + } + return null; + } + + public void addWorld(World world) { + // Check if a World already exists with the UID. + if (getWorld(world.getUID()) != null) { + System.out.println("World " + world.getName() + " is a duplicate of another world and has been prevented from loading. Please delete the uid.dat file from " + world.getName() + "'s world directory if you want to be able to load the duplicate world."); + return; + } + worlds.put(world.getName().toLowerCase(), world); + } + + @Override + public Logger getLogger() { + return logger; + } + + public ConsoleReader getReader() { + return console.reader; + } + + @Override + public PluginCommand getPluginCommand(String name) { + Command command = commandMap.getCommand(name); + + if (command instanceof PluginCommand) { + return (PluginCommand) command; + } else { + return null; + } + } + + @Override + public void savePlayers() { + checkSaveState(); + playerList.savePlayers(); + } + + @Override + public void configureDbConfig(ServerConfig config) { + 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"))); + + if (ds.getDriver().contains("sqlite")) { + config.setDatabasePlatform(new SQLitePlatform()); + config.getDatabasePlatform().getDbDdlSyntax().setIdentity(""); + } + + config.setDataSourceConfig(ds); + } + + @Override + public boolean addRecipe(Recipe recipe) { + CraftRecipe toAdd; + if (recipe instanceof CraftRecipe) { + toAdd = (CraftRecipe) recipe; + } else { + if (recipe instanceof ShapedRecipe) { + toAdd = CraftShapedRecipe.fromBukkitRecipe((ShapedRecipe) recipe); + } else if (recipe instanceof ShapelessRecipe) { + toAdd = CraftShapelessRecipe.fromBukkitRecipe((ShapelessRecipe) recipe); + } else if (recipe instanceof FurnaceRecipe) { + toAdd = CraftFurnaceRecipe.fromBukkitRecipe((FurnaceRecipe) recipe); + } else { + return false; + } + } + toAdd.addToCraftingManager(); + CraftingManager.getInstance().sort(); + return true; + } + + @Override + public List getRecipesFor(ItemStack result) { + Validate.notNull(result, "Result cannot be null"); + + List results = new ArrayList(); + Iterator iter = recipeIterator(); + while (iter.hasNext()) { + Recipe recipe = iter.next(); + ItemStack stack = recipe.getResult(); + if (stack.getType() != result.getType()) { + continue; + } + if (result.getDurability() == -1 || result.getDurability() == stack.getDurability()) { + results.add(recipe); + } + } + return results; + } + + @Override + public Iterator recipeIterator() { + return new RecipeIterator(); + } + + @Override + public void clearRecipes() { + CraftingManager.getInstance().recipes.clear(); + RecipesFurnace.getInstance().recipes.clear(); + RecipesFurnace.getInstance().customRecipes.clear(); + } + + @Override + public void resetRecipes() { + CraftingManager.getInstance().recipes = new CraftingManager().recipes; + RecipesFurnace.getInstance().recipes = new RecipesFurnace().recipes; + RecipesFurnace.getInstance().customRecipes.clear(); + } + + @Override + public Map getCommandAliases() { + ConfigurationSection section = commandsConfiguration.getConfigurationSection("aliases"); + Map result = new LinkedHashMap(); + + if (section != null) { + for (String key : section.getKeys(false)) { + List commands; + + if (section.isList(key)) { + commands = section.getStringList(key); + } else { + commands = ImmutableList.of(section.getString(key)); + } + + 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); + } + + @Override + public String getShutdownMessage() { + return configuration.getString("settings.shutdown-message"); + } + + @Override + public int getSpawnRadius() { + return ((DedicatedServer) console).propertyManager.getInt("spawn-protection", 16); + } + + @Override + public void setSpawnRadius(int value) { + configuration.set("settings.spawn-radius", value); + saveConfig(); + } + + @Override + public boolean getOnlineMode() { + return online.value; + } + + @Override + public boolean getAllowFlight() { + return console.getAllowFlight(); + } + + @Override + public boolean isHardcore() { + return console.isHardcore(); + } + + @Override + public boolean useExactLoginLocation() { + return configuration.getBoolean("settings.use-exact-login-location"); + } + + public ChunkGenerator getGenerator(String world) { + ConfigurationSection section = configuration.getConfigurationSection("worlds"); + ChunkGenerator result = null; + + if (section != null) { + section = section.getConfigurationSection(world); + + if (section != null) { + String name = section.getString("generator"); + + if ((name != null) && (!name.equals(""))) { + String[] split = name.split(":", 2); + String id = (split.length > 1) ? split[1] : null; + Plugin plugin = pluginManager.getPlugin(split[0]); + + if (plugin == null) { + getLogger().severe("Could not set generator for default world '" + world + "': Plugin '" + split[0] + "' does not exist"); + } else if (!plugin.isEnabled()) { + getLogger().severe("Could not set generator for default world '" + world + "': Plugin '" + plugin.getDescription().getFullName() + "' is not enabled yet (is it load:STARTUP?)"); + } else { + try { + result = plugin.getDefaultWorldGenerator(world, id); + if (result == null) { + getLogger().severe("Could not set generator for default world '" + world + "': Plugin '" + plugin.getDescription().getFullName() + "' lacks a default world generator"); + } + } catch (Throwable t) { + plugin.getLogger().log(Level.SEVERE, "Could not set generator for default world '" + world + "': Plugin '" + plugin.getDescription().getFullName(), t); + } + } + } + } + } + + return result; + } + + @Override + @Deprecated + public CraftMapView getMap(short id) { + PersistentCollection collection = console.worlds.get(0).worldMaps; + WorldMap worldmap = (WorldMap) collection.get(WorldMap.class, "map_" + id); + if (worldmap == null) { + return null; + } + return worldmap.mapView; + } + + @Override + public CraftMapView createMap(World world) { + Validate.notNull(world, "World cannot be null"); + + net.minecraft.server.ItemStack stack = new net.minecraft.server.ItemStack(Items.MAP, 1, -1); + WorldMap worldmap = Items.FILLED_MAP.getSavedMap(stack, ((CraftWorld) world).getHandle()); + return worldmap.mapView; + } + + @Override + public void shutdown() { + console.safeShutdown(); + } + + @Override + public int broadcast(String message, String permission) { + int count = 0; + Set permissibles = getPluginManager().getPermissionSubscriptions(permission); + + for (Permissible permissible : permissibles) { + if (permissible instanceof CommandSender && permissible.hasPermission(permission)) { + CommandSender user = (CommandSender) permissible; + user.sendMessage(message); + count++; + } + } + + return count; + } + + // Paper start + @Override + public void broadcast(BaseComponent component) { + for (Player player : getOnlinePlayers()) { + player.sendMessage(component); + } + } + + @Override + public void broadcast(BaseComponent... components) { + for (Player player : getOnlinePlayers()) { + player.sendMessage(components); + } + } + // Paper end + + @Override + @Deprecated + public OfflinePlayer getOfflinePlayer(String name) { + Validate.notNull(name, "Name cannot be null"); + com.google.common.base.Preconditions.checkArgument( !org.apache.commons.lang.StringUtils.isBlank( name ), "Name cannot be blank" ); // Spigot + + OfflinePlayer result = getPlayerExact(name); + if (result == null) { + // Spigot Start + GameProfile profile = null; + // Only fetch an online UUID in online mode + if ( MinecraftServer.getServer().getOnlineMode() || org.spigotmc.SpigotConfig.bungee ) + { + profile = MinecraftServer.getServer().getUserCache().getProfile( name ); + } + // Spigot end + if (profile == null) { + // Make an OfflinePlayer using an offline mode UUID since the name has no profile + result = getOfflinePlayer(new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name)); + } else { + // Use the GameProfile even when we get a UUID so we ensure we still have a name + result = getOfflinePlayer(profile); + } + } else { + offlinePlayers.remove(result.getUniqueId()); + } + + return result; + } + + @Override + public OfflinePlayer getOfflinePlayer(UUID id) { + Validate.notNull(id, "UUID cannot be null"); + + OfflinePlayer result = getPlayer(id); + if (result == null) { + result = offlinePlayers.get(id); + if (result == null) { + result = new CraftOfflinePlayer(this, new GameProfile(id, null)); + offlinePlayers.put(id, result); + } + } else { + offlinePlayers.remove(id); + } + + return result; + } + + public OfflinePlayer getOfflinePlayer(GameProfile profile) { + OfflinePlayer player = new CraftOfflinePlayer(this, profile); + offlinePlayers.put(profile.getId(), player); + return player; + } + + @Override + @SuppressWarnings("unchecked") + public Set getIPBans() { + return new HashSet(Arrays.asList(playerList.getIPBans().getEntries())); + } + + @Override + public void banIP(String address) { + Validate.notNull(address, "Address cannot be null."); + + this.getBanList(org.bukkit.BanList.Type.IP).addBan(address, null, null, null); + } + + @Override + public void unbanIP(String address) { + Validate.notNull(address, "Address cannot be null."); + + this.getBanList(org.bukkit.BanList.Type.IP).pardon(address); + } + + @Override + public Set getBannedPlayers() { + Set result = new HashSet(); + + for (JsonListEntry entry : playerList.getProfileBans().getValues()) { + result.add(getOfflinePlayer((GameProfile) entry.getKey())); + } + + return result; + } + + @Override + public BanList getBanList(BanList.Type type) { + Validate.notNull(type, "Type cannot be null"); + + switch(type){ + case IP: + return new CraftIpBanList(playerList.getIPBans()); + case NAME: + default: + return new CraftProfileBanList(playerList.getProfileBans()); + } + } + + @Override + public void setWhitelist(boolean value) { + playerList.setHasWhitelist(value); + console.getPropertyManager().setProperty("white-list", value); + } + + @Override + public Set getWhitelistedPlayers() { + Set result = new LinkedHashSet(); + + for (JsonListEntry entry : playerList.getWhitelist().getValues()) { + result.add(getOfflinePlayer((GameProfile) entry.getKey())); + } + + return result; + } + + @Override + public Set getOperators() { + Set result = new HashSet(); + + for (JsonListEntry entry : playerList.getOPs().getValues()) { + result.add(getOfflinePlayer((GameProfile) entry.getKey())); + } + + return result; + } + + @Override + public void reloadWhitelist() { + playerList.reloadWhitelist(); + } + + @Override + public GameMode getDefaultGameMode() { + return GameMode.getByValue(console.worlds.get(0).getWorldData().getGameType().getId()); + } + + @Override + public void setDefaultGameMode(GameMode mode) { + Validate.notNull(mode, "Mode cannot be null"); + + for (World world : getWorlds()) { + ((CraftWorld) world).getHandle().worldData.setGameType(WorldSettings.EnumGamemode.getById(mode.getValue())); + } + } + + @Override + public ConsoleCommandSender getConsoleSender() { + return console.console; + } + + public EntityMetadataStore getEntityMetadata() { + return entityMetadata; + } + + public PlayerMetadataStore getPlayerMetadata() { + return playerMetadata; + } + + public WorldMetadataStore getWorldMetadata() { + return worldMetadata; + } + + @Override + public File getWorldContainer() { + if (this.getServer().universe != null) { + return this.getServer().universe; + } + + if (container == null) { + container = new File(configuration.getString("settings.world-container", ".")); + } + + return container; + } + + @Override + public OfflinePlayer[] getOfflinePlayers() { + WorldNBTStorage storage = (WorldNBTStorage) console.worlds.get(0).getDataManager(); + String[] files = storage.getPlayerDir().list(new DatFileFilter()); + Set players = new HashSet(); + + for (String file : files) { + try { + players.add(getOfflinePlayer(UUID.fromString(file.substring(0, file.length() - 4)))); + } catch (IllegalArgumentException ex) { + // Who knows what is in this directory, just ignore invalid files + } + } + + players.addAll(getOnlinePlayers()); + + return players.toArray(new OfflinePlayer[players.size()]); + } + + @Override + public Messenger getMessenger() { + return messenger; + } + + @Override + public void sendPluginMessage(Plugin source, String channel, byte[] message) { + StandardMessenger.validatePluginMessage(getMessenger(), source, channel, message); + + for (Player player : getOnlinePlayers()) { + player.sendPluginMessage(source, channel, message); + } + } + + @Override + public Set getListeningPluginChannels() { + Set result = new HashSet(); + + for (Player player : getOnlinePlayers()) { + result.addAll(player.getListeningPluginChannels()); + } + + return result; + } + + @Override + public Inventory createInventory(InventoryHolder owner, InventoryType type) { + // TODO: Create the appropriate type, rather than Custom? + return new CraftInventoryCustom(owner, type); + } + + @Override + public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) { + return new CraftInventoryCustom(owner, type, title); + } + + @Override + public Inventory createInventory(InventoryHolder owner, int size) throws IllegalArgumentException { + Validate.isTrue(size % 9 == 0, "Chests must have a size that is a multiple of 9!"); + return new CraftInventoryCustom(owner, size); + } + + @Override + public Inventory createInventory(InventoryHolder owner, int size, String title) throws IllegalArgumentException { + Validate.isTrue(size % 9 == 0, "Chests must have a size that is a multiple of 9!"); + return new CraftInventoryCustom(owner, size, title); + } + + @Override + public HelpMap getHelpMap() { + return helpMap; + } + + @Override // Paper - add override + public SimpleCommandMap getCommandMap() { + return commandMap; + } + + @Override + public int getMonsterSpawnLimit() { + return monsterSpawn; + } + + @Override + public int getAnimalSpawnLimit() { + return animalSpawn; + } + + @Override + public int getWaterAnimalSpawnLimit() { + return waterAnimalSpawn; + } + + @Override + public int getAmbientSpawnLimit() { + return ambientSpawn; + } + + @Override + public boolean isPrimaryThread() { + return Thread.currentThread().equals(console.primaryThread); + } + + @Override + public String getMotd() { + return console.getMotd(); + } + + @Override + public WarningState getWarningState() { + return warningState; + } + + public List tabComplete(net.minecraft.server.ICommandListener sender, String message) { + return tabComplete(sender, message, null); // PaperSpigot - location tab-completes. Original code here moved below + } + + // PaperSpigot start - add BlockPosition support + /* + this code is copied, except for the noted change, from the original tabComplete(net.minecraft.server.ICommandListener sender, String message) method + */ + public List tabComplete(net.minecraft.server.ICommandListener sender, String message, BlockPosition blockPosition) { + if (!(sender instanceof EntityPlayer)) { + return ImmutableList.of(); + } + + Player player = ((EntityPlayer) sender).getBukkitEntity(); + if (message.startsWith("/")) { + return tabCompleteCommand(player, message, blockPosition); + } else { + return tabCompleteChat(player, message); + } + } + // PaperSpigot end + + public List tabCompleteCommand(Player player, String message) { + return tabCompleteCommand(player, message, null); // PaperSpigot - location tab-completes. Original code here moved below + } + + // PaperSpigot start - add BlockPosition support + /* + this code is copied, except for the noted change, from the original tabCompleteCommand(Player player, String message) method + */ + public List tabCompleteCommand(Player player, String message, BlockPosition blockPosition) { + // Spigot Start + if ( (org.spigotmc.SpigotConfig.tabComplete < 0 || message.length() <= org.spigotmc.SpigotConfig.tabComplete) && !message.contains( " " ) ) + { + return ImmutableList.of(); + } + // Spigot End + + List completions = null; + try { + // send location info if present + // completions = getCommandMap().tabComplete(player, message.substring(1)); + if (blockPosition == null || !((CraftWorld) player.getWorld()).getHandle().paperSpigotConfig.allowBlockLocationTabCompletion) { + completions = getCommandMap().tabComplete(player, message.substring(1)); + } else { + completions = getCommandMap().tabComplete(player, message.substring(1), new Location(player.getWorld(), blockPosition.getX(), blockPosition.getY(), blockPosition.getZ())); + } + } catch (CommandException ex) { + player.sendMessage(ChatColor.RED + "An internal error occurred while attempting to tab-complete this command"); + getLogger().log(Level.SEVERE, "Exception when " + player.getName() + " attempted to tab complete " + message, ex); + } + + return completions == null ? ImmutableList.of() : completions; + } + // PaperSpigot end + + public List tabCompleteChat(Player player, String message) { + List completions = new ArrayList(); + PlayerChatTabCompleteEvent event = new PlayerChatTabCompleteEvent(player, message, completions); + String token = event.getLastToken(); + for (Player p : getOnlinePlayers()) { + if (player.canSee(p) && StringUtil.startsWithIgnoreCase(p.getName(), token)) { + completions.add(p.getName()); + } + } + pluginManager.callEvent(event); + + Iterator it = completions.iterator(); + while (it.hasNext()) { + Object current = it.next(); + if (!(current instanceof String)) { + // Sanity + it.remove(); + } + } + Collections.sort(completions, String.CASE_INSENSITIVE_ORDER); + return completions; + } + + @Override + public CraftItemFactory getItemFactory() { + return CraftItemFactory.instance(); + } + + @Override + public CraftScoreboardManager getScoreboardManager() { + return scoreboardManager; + } + + public void checkSaveState() { + if (this.playerCommandState || this.printSaveWarning || this.console.autosavePeriod <= 0) { + return; + } + this.printSaveWarning = true; + getLogger().log(Level.WARNING, "A manual (plugin-induced) save has been detected while server is configured to auto-save. This may affect performance.", warningState == WarningState.ON ? new Throwable() : null); + } + + @Override + public CraftIconCache getServerIcon() { + return icon; + } + + @Override + public CraftIconCache loadServerIcon(File file) throws Exception { + Validate.notNull(file, "File cannot be null"); + if (!file.isFile()) { + throw new IllegalArgumentException(file + " is not a file"); + } + return loadServerIcon0(file); + } + + static CraftIconCache loadServerIcon0(File file) throws Exception { + return loadServerIcon0(ImageIO.read(file)); + } + + @Override + public CraftIconCache loadServerIcon(BufferedImage image) throws Exception { + Validate.notNull(image, "Image cannot be null"); + return loadServerIcon0(image); + } + + static CraftIconCache loadServerIcon0(BufferedImage image) throws Exception { + ByteBuf bytebuf = Unpooled.buffer(); + + Validate.isTrue(image.getWidth() == 64, "Must be 64 pixels wide"); + Validate.isTrue(image.getHeight() == 64, "Must be 64 pixels high"); + ImageIO.write(image, "PNG", new ByteBufOutputStream(bytebuf)); + ByteBuf bytebuf1 = Base64.encode(bytebuf); + + return new CraftIconCache("data:image/png;base64," + bytebuf1.toString(Charsets.UTF_8)); + } + + @Override + public void setIdleTimeout(int threshold) { + console.setIdleTimeout(threshold); + } + + @Override + public int getIdleTimeout() { + return console.getIdleTimeout(); + } + + @Override + public ChunkGenerator.ChunkData createChunkData(World world) { + return new CraftChunkData(world); + } + + @Deprecated + @Override + public UnsafeValues getUnsafe() { + return CraftMagicNumbers.INSTANCE; + } + + private final Spigot spigot = new Spigot() + { + + // PaperSpigot start - Add getTPS (Further improve tick loop) + @Override + public double[] getTPS() { + return new double[] { + MinecraftServer.getServer().tps1.getAverage(), + MinecraftServer.getServer().tps5.getAverage(), + MinecraftServer.getServer().tps15.getAverage() + }; + } + // PaperSpigot end + + @Deprecated + @Override + public YamlConfiguration getConfig() + { + return getBukkitConfig(); + } + + @Override + public YamlConfiguration getBukkitConfig() + { + return configuration; + } + + @Override + public YamlConfiguration getSpigotConfig() + { + return org.spigotmc.SpigotConfig.config; + } + + @Override + public YamlConfiguration getPaperSpigotConfig() + { + return org.github.paperspigot.PaperSpigotConfig.config; + } + + @Override + public void restart() { + org.spigotmc.RestartCommand.restart(); + } + + @Override + public void broadcast(BaseComponent component) { + for (Player player : getOnlinePlayers()) { + player.spigot().sendMessage(component); + } + } + + @Override + public void broadcast(BaseComponent... components) { + for (Player player : getOnlinePlayers()) { + player.spigot().sendMessage(components); + } + } + }; + + public Spigot spigot() + { + return spigot; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftSound.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftSound.java new file mode 100644 index 0000000..0cc8f9b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftSound.java @@ -0,0 +1,231 @@ +package org.bukkit.craftbukkit; + +import static org.bukkit.Sound.*; + +import org.apache.commons.lang.Validate; +import org.bukkit.Sound; + +public class CraftSound { + private static final String[] sounds = new String[Sound.values().length]; + + static { + // Ambient + set(AMBIENCE_CAVE, "ambient.cave.cave"); + set(AMBIENCE_RAIN, "ambient.weather.rain"); + set(AMBIENCE_THUNDER, "ambient.weather.thunder"); + // Damage + set(HURT_FLESH, "game.neutral.hurt"); + set(FALL_BIG, "game.neutral.hurt.fall.big"); + set(FALL_SMALL, "game.neutral.hurt.fall.small"); + // Dig Sounds + set(DIG_WOOL, "dig.cloth"); + set(DIG_GRASS, "dig.grass"); + set(DIG_GRAVEL, "dig.gravel"); + set(DIG_SAND, "dig.sand"); + set(DIG_SNOW, "dig.snow"); + set(DIG_STONE, "dig.stone"); + set(DIG_WOOD, "dig.wood"); + // Fire + set(FIRE, "fire.fire"); + set(FIRE_IGNITE, "fire.ignite"); + // Fireworks + set(FIREWORK_BLAST, "fireworks.blast"); + set(FIREWORK_BLAST2, "fireworks.blast_far"); + set(FIREWORK_LARGE_BLAST, "fireworks.largeBlast"); + set(FIREWORK_LARGE_BLAST2, "fireworks.largeBlast_far"); + set(FIREWORK_TWINKLE, "fireworks.twinkle"); + set(FIREWORK_TWINKLE2, "fireworks.twinkle_far"); + set(FIREWORK_LAUNCH, "fireworks.launch"); + // Liquid + set(SPLASH2, "game.neutral.swim.splash"); + set(SWIM, "game.neutral.swim"); + set(WATER, "liquid.water"); + set(LAVA, "liquid.lava"); + set(LAVA_POP, "liquid.lavapop"); + // Minecart + set(MINECART_BASE, "minecart.base"); + set(MINECART_INSIDE, "minecart.inside"); + // Mob + set(BAT_DEATH, "mob.bat.death"); + set(BAT_HURT, "mob.bat.hurt"); + set(BAT_IDLE, "mob.bat.idle"); + set(BAT_LOOP, "mob.bat.loop"); + set(BAT_TAKEOFF, "mob.bat.takeoff"); + set(BLAZE_BREATH, "mob.blaze.breathe"); + set(BLAZE_DEATH, "mob.blaze.death"); + set(BLAZE_HIT, "mob.blaze.hit"); + set(CAT_HISS, "mob.cat.hiss"); + set(CAT_HIT, "mob.cat.hitt"); + set(CAT_MEOW, "mob.cat.meow"); + set(CAT_PURR, "mob.cat.purr"); + set(CAT_PURREOW, "mob.cat.purreow"); + set(CHICKEN_IDLE, "mob.chicken.say"); + set(CHICKEN_HURT, "mob.chicken.hurt"); + set(CHICKEN_EGG_POP, "mob.chicken.plop"); + set(CHICKEN_WALK, "mob.chicken.step"); + set(COW_HURT, "mob.cow.hurt"); + set(COW_IDLE, "mob.cow.say"); + set(COW_WALK, "mob.cow.step"); + set(CREEPER_DEATH, "mob.creeper.death"); + set(CREEPER_HISS, "mob.creeper.say"); + set(ENDERDRAGON_DEATH, "mob.enderdragon.end"); + set(ENDERDRAGON_GROWL, "mob.enderdragon.growl"); + set(ENDERDRAGON_HIT, "mob.enderdragon.hit"); + set(ENDERDRAGON_WINGS, "mob.enderdragon.wings"); + set(ENDERMAN_DEATH, "mob.endermen.death"); + set(ENDERMAN_HIT, "mob.endermen.hit"); + set(ENDERMAN_IDLE, "mob.endermen.idle"); + set(ENDERMAN_TELEPORT, "mob.endermen.portal"); + set(ENDERMAN_SCREAM, "mob.endermen.scream"); + set(ENDERMAN_STARE, "mob.endermen.stare"); + set(GHAST_SCREAM2, "mob.ghast.affectionate_scream"); + set(GHAST_CHARGE, "mob.ghast.charge"); + set(GHAST_DEATH, "mob.ghast.death"); + set(GHAST_FIREBALL, "mob.ghast.fireball"); + set(GHAST_MOAN, "mob.ghast.moan"); + set(GHAST_SCREAM, "mob.ghast.scream"); + set(HORSE_ANGRY, "mob.horse.angry"); + set(HORSE_ARMOR, "mob.horse.armor"); + set(HORSE_BREATHE, "mob.horse.breathe"); + set(HORSE_DEATH, "mob.horse.death"); + set(HORSE_GALLOP, "mob.horse.gallop"); + set(HORSE_HIT, "mob.horse.hit"); + set(HORSE_IDLE, "mob.horse.idle"); + set(HORSE_JUMP, "mob.horse.jump"); + set(HORSE_LAND, "mob.horse.land"); + set(HORSE_SADDLE, "mob.horse.leather"); + set(HORSE_SOFT, "mob.horse.soft"); + set(HORSE_WOOD, "mob.horse.wood"); + set(DONKEY_ANGRY, "mob.horse.donkey.angry"); + set(DONKEY_DEATH, "mob.horse.donkey.death"); + set(DONKEY_HIT, "mob.horse.donkey.hit"); + set(DONKEY_IDLE, "mob.horse.donkey.idle"); + set(HORSE_SKELETON_DEATH, "mob.horse.skeleton.death"); + set(HORSE_SKELETON_HIT, "mob.horse.skeleton.hit"); + set(HORSE_SKELETON_IDLE, "mob.horse.skeleton.idle"); + set(HORSE_ZOMBIE_DEATH, "mob.horse.zombie.death"); + set(HORSE_ZOMBIE_HIT, "mob.horse.zombie.hit"); + set(HORSE_ZOMBIE_IDLE, "mob.horse.zombie.idle"); + set(IRONGOLEM_DEATH, "mob.irongolem.death"); + set(IRONGOLEM_HIT, "mob.irongolem.hit"); + set(IRONGOLEM_THROW, "mob.irongolem.throw"); + set(IRONGOLEM_WALK, "mob.irongolem.walk"); + set(MAGMACUBE_WALK, "mob.magmacube.small"); + set(MAGMACUBE_WALK2, "mob.magmacube.big"); + set(MAGMACUBE_JUMP, "mob.magmacube.jump"); + set(PIG_IDLE, "mob.pig.say"); + set(PIG_DEATH, "mob.pig.death"); + set(PIG_WALK, "mob.pig.step"); + set(SHEEP_IDLE, "mob.sheep.say"); + set(SHEEP_SHEAR, "mob.sheep.shear"); + set(SHEEP_WALK, "mob.sheep.step"); + set(SILVERFISH_HIT, "mob.silverfish.hit"); + set(SILVERFISH_KILL, "mob.silverfish.kill"); + set(SILVERFISH_IDLE, "mob.silverfish.say"); + set(SILVERFISH_WALK, "mob.silverfish.step"); + set(SKELETON_IDLE, "mob.skeleton.say"); + set(SKELETON_DEATH, "mob.skeleton.death"); + set(SKELETON_HURT, "mob.skeleton.hurt"); + set(SKELETON_WALK, "mob.skeleton.step"); + set(SLIME_ATTACK, "mob.slime.attack"); + set(SLIME_WALK, "mob.slime.small"); + set(SLIME_WALK2, "mob.slime.big"); + set(SPIDER_IDLE, "mob.spider.say"); + set(SPIDER_DEATH, "mob.spider.death"); + set(SPIDER_WALK, "mob.spider.step"); + set(VILLAGER_DEATH, "mob.villager.death"); + set(VILLAGER_HAGGLE, "mob.villager.haggle"); + set(VILLAGER_HIT, "mob.villager.hit"); + set(VILLAGER_IDLE, "mob.villager.idle"); + set(VILLAGER_NO, "mob.villager.no"); + set(VILLAGER_YES, "mob.villager.yes"); + set(WITHER_DEATH, "mob.wither.death"); + set(WITHER_HURT, "mob.wither.hurt"); + set(WITHER_IDLE, "mob.wither.idle"); + set(WITHER_SHOOT, "mob.wither.shoot"); + set(WITHER_SPAWN, "mob.wither.spawn"); + set(WOLF_BARK, "mob.wolf.bark"); + set(WOLF_DEATH, "mob.wolf.death"); + set(WOLF_GROWL, "mob.wolf.growl"); + set(WOLF_HOWL, "mob.wolf.howl"); + set(WOLF_HURT, "mob.wolf.hurt"); + set(WOLF_PANT, "mob.wolf.panting"); + set(WOLF_SHAKE, "mob.wolf.shake"); + set(WOLF_WALK, "mob.wolf.step"); + set(WOLF_WHINE, "mob.wolf.whine"); + set(ZOMBIE_METAL, "mob.zombie.metal"); + set(ZOMBIE_WOOD, "mob.zombie.wood"); + set(ZOMBIE_WOODBREAK, "mob.zombie.woodbreak"); + set(ZOMBIE_IDLE, "mob.zombie.say"); + set(ZOMBIE_DEATH, "mob.zombie.death"); + set(ZOMBIE_HURT, "mob.zombie.hurt"); + set(ZOMBIE_INFECT, "mob.zombie.infect"); + set(ZOMBIE_UNFECT, "mob.zombie.unfect"); + set(ZOMBIE_REMEDY, "mob.zombie.remedy"); + set(ZOMBIE_WALK, "mob.zombie.step"); + set(ZOMBIE_PIG_IDLE, "mob.zombiepig.zpig"); + set(ZOMBIE_PIG_ANGRY, "mob.zombiepig.zpigangry"); + set(ZOMBIE_PIG_DEATH, "mob.zombiepig.zpigdeath"); + set(ZOMBIE_PIG_HURT, "mob.zombiepig.zpighurt"); + // Note (blocks) + set(NOTE_BASS_GUITAR, "note.bassattack"); + set(NOTE_SNARE_DRUM, "note.snare"); + set(NOTE_PLING, "note.pling"); + set(NOTE_BASS, "note.bass"); + set(NOTE_PIANO, "note.harp"); + set(NOTE_BASS_DRUM, "note.bd"); + set(NOTE_STICKS, "note.hat"); + // Portal + set(PORTAL, "portal.portal"); + set(PORTAL_TRAVEL, "portal.travel"); + set(PORTAL_TRIGGER, "portal.trigger"); + // Random + set(ANVIL_BREAK, "random.anvil_break"); + set(ANVIL_LAND, "random.anvil_land"); + set(ANVIL_USE, "random.anvil_use"); + set(SHOOT_ARROW, "random.bow"); + set(ARROW_HIT, "random.bowhit"); + set(ITEM_BREAK, "random.break"); + set(BURP, "random.burp"); + set(CHEST_CLOSE, "random.chestclosed"); + set(CHEST_OPEN, "random.chestopen"); + set(CLICK, "random.click"); + set(DOOR_CLOSE, "random.door_close"); + set(DOOR_OPEN, "random.door_open"); + set(DRINK, "random.drink"); + set(EAT, "random.eat"); + set(EXPLODE, "random.explode"); + set(FIZZ, "random.fizz"); + set(FUSE, "creeper.primed"); + set(GLASS, "dig.glass"); + set(LEVEL_UP, "random.levelup"); + set(ORB_PICKUP, "random.orb"); + set(ITEM_PICKUP, "random.pop"); + set(SPLASH, "random.splash"); + set(SUCCESSFUL_HIT, "random.successful_hit"); + set(WOOD_CLICK, "random.wood_click"); + // Step + set(STEP_WOOL, "step.cloth"); + set(STEP_GRASS, "step.grass"); + set(STEP_GRAVEL, "step.gravel"); + set(STEP_LADDER, "step.ladder"); + set(STEP_SAND, "step.sand"); + set(STEP_SNOW, "step.snow"); + set(STEP_STONE, "step.stone"); + set(STEP_WOOD, "step.wood"); + // Tile + set(PISTON_EXTEND, "tile.piston.out"); + set(PISTON_RETRACT, "tile.piston.in"); + } + + private static void set(Sound sound, String key) { + sounds[sound.ordinal()] = key; + } + + public static String getSound(final Sound sound) { + Validate.notNull(sound, "Sound cannot be null"); + return sounds[sound.ordinal()]; + } + + private CraftSound() {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java new file mode 100644 index 0000000..3341c99 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java @@ -0,0 +1,152 @@ +package org.bukkit.craftbukkit; + +import net.minecraft.server.EntityTypes; +import net.minecraft.server.EntityTypes.MonsterEggInfo; +import net.minecraft.server.StatisticList; + +import org.bukkit.Achievement; +import org.bukkit.Statistic; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; + +import com.google.common.base.CaseFormat; +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.Block; +import net.minecraft.server.Item; +import net.minecraft.server.MinecraftKey; + +public class CraftStatistic { + private static final BiMap statistics; + private static final BiMap achievements; + + static { + ImmutableMap specialCases = ImmutableMap. builder() + .put("achievement.buildWorkBench", Achievement.BUILD_WORKBENCH) + .put("achievement.diamonds", Achievement.GET_DIAMONDS) + .put("achievement.portal", Achievement.NETHER_PORTAL) + .put("achievement.ghast", Achievement.GHAST_RETURN) + .put("achievement.theEnd", Achievement.END_PORTAL) + .put("achievement.theEnd2", Achievement.THE_END) + .put("achievement.blazeRod", Achievement.GET_BLAZE_ROD) + .put("achievement.potion", Achievement.BREW_POTION) + .build(); + ImmutableBiMap.Builder statisticBuilder = ImmutableBiMap.builder(); + ImmutableBiMap.Builder achievementBuilder = ImmutableBiMap.builder(); + for (Statistic statistic : Statistic.values()) { + if (statistic == Statistic.PLAY_ONE_TICK) { + statisticBuilder.put("stat.playOneMinute", statistic); + } else { + statisticBuilder.put("stat." + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, statistic.name()), statistic); + } + } + for (Achievement achievement : Achievement.values()) { + if (specialCases.values().contains(achievement)) { + continue; + } + achievementBuilder.put("achievement." + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, achievement.name()), achievement); + } + + achievementBuilder.putAll(specialCases); + + statistics = statisticBuilder.build(); + achievements = achievementBuilder.build(); + } + + private CraftStatistic() {} + + public static org.bukkit.Achievement getBukkitAchievement(net.minecraft.server.Achievement achievement) { + return getBukkitAchievementByName(achievement.name); + } + + public static org.bukkit.Achievement getBukkitAchievementByName(String name) { + return achievements.get(name); + } + + public static org.bukkit.Statistic getBukkitStatistic(net.minecraft.server.Statistic statistic) { + return getBukkitStatisticByName(statistic.name); + } + + public static org.bukkit.Statistic getBukkitStatisticByName(String name) { + if (name.startsWith("stat.killEntity")) { + name = "stat.killEntity"; + } + if (name.startsWith("stat.entityKilledBy")) { + name = "stat.entityKilledBy"; + } + if (name.startsWith("stat.breakItem")) { + name = "stat.breakItem"; + } + if (name.startsWith("stat.useItem")) { + name = "stat.useItem"; + } + if (name.startsWith("stat.mineBlock")) { + name = "stat.mineBlock"; + } + if (name.startsWith("stat.craftItem")) { + name = "stat.craftItem"; + } + return statistics.get(name); + } + + public static net.minecraft.server.Statistic getNMSStatistic(org.bukkit.Statistic statistic) { + return StatisticList.getStatistic(statistics.inverse().get(statistic)); + } + + public static net.minecraft.server.Achievement getNMSAchievement(org.bukkit.Achievement achievement) { + return (net.minecraft.server.Achievement) StatisticList.getStatistic(achievements.inverse().get(achievement)); + } + + public static net.minecraft.server.Statistic getMaterialStatistic(org.bukkit.Statistic stat, Material material) { + try { + if (stat == Statistic.MINE_BLOCK) { + return StatisticList.MINE_BLOCK_COUNT[material.getId()]; + } + if (stat == Statistic.CRAFT_ITEM) { + return StatisticList.CRAFT_BLOCK_COUNT[material.getId()]; + } + if (stat == Statistic.USE_ITEM) { + return StatisticList.USE_ITEM_COUNT[material.getId()]; + } + if (stat == Statistic.BREAK_ITEM) { + return StatisticList.BREAK_ITEM_COUNT[material.getId()]; + } + } catch (ArrayIndexOutOfBoundsException e) { + return null; + } + return null; + } + + public static net.minecraft.server.Statistic getEntityStatistic(org.bukkit.Statistic stat, EntityType entity) { + MonsterEggInfo monsteregginfo = (MonsterEggInfo) EntityTypes.eggInfo.get(Integer.valueOf(entity.getTypeId())); + + if (monsteregginfo != null) { + return monsteregginfo.killEntityStatistic; + } + return null; + } + + public static EntityType getEntityTypeFromStatistic(net.minecraft.server.Statistic statistic) { + String statisticString = statistic.name; + return EntityType.fromName(statisticString.substring(statisticString.lastIndexOf(".") + 1)); + } + + public static Material getMaterialFromStatistic(net.minecraft.server.Statistic statistic) { + String statisticString = statistic.name; + String val = statisticString.substring(statisticString.lastIndexOf(".") + 1); + Item item = (Item) Item.REGISTRY.get(new MinecraftKey(val)); + if (item != null) { + return Material.getMaterial(Item.getId(item)); + } + Block block = (Block) Block.REGISTRY.get(new MinecraftKey(val)); + if (block != null) { + return Material.getMaterial(Block.getId(block)); + } + try { + return Material.getMaterial(Integer.parseInt(val)); + } catch (NumberFormatException e) { + return null; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java new file mode 100644 index 0000000..cae65cf --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java @@ -0,0 +1,88 @@ +package org.bukkit.craftbukkit; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.PortalTravelAgent; +import net.minecraft.server.WorldServer; + +import org.bukkit.Location; +import org.bukkit.TravelAgent; + +public class CraftTravelAgent extends PortalTravelAgent implements TravelAgent { + + public static TravelAgent DEFAULT = null; + + private int searchRadius = 128; + private int creationRadius = 16; + private boolean canCreatePortal = true; + + public CraftTravelAgent(WorldServer worldserver) { + super(worldserver); + if (DEFAULT == null && worldserver.dimension == 0) { + DEFAULT = this; + } + } + + @Override + public Location findOrCreate(Location target) { + WorldServer worldServer = ((CraftWorld) target.getWorld()).getHandle(); + boolean before = worldServer.chunkProviderServer.forceChunkLoad; + worldServer.chunkProviderServer.forceChunkLoad = true; + + Location found = this.findPortal(target); + if (found == null) { + if (this.getCanCreatePortal() && this.createPortal(target)) { + found = this.findPortal(target); + } else { + found = target; // fallback to original if unable to find or create + } + } + + worldServer.chunkProviderServer.forceChunkLoad = before; + return found; + } + + @Override + public Location findPortal(Location location) { + PortalTravelAgent pta = ((CraftWorld) location.getWorld()).getHandle().getTravelAgent(); + BlockPosition found = pta.findPortal(location.getX(), location.getY(), location.getZ(), this.getSearchRadius()); + return found != null ? new Location(location.getWorld(), found.getX(), found.getY(), found.getZ(), location.getYaw(), location.getPitch()) : null; + } + + @Override + public boolean createPortal(Location location) { + PortalTravelAgent pta = ((CraftWorld) location.getWorld()).getHandle().getTravelAgent(); + return pta.createPortal(location.getX(), location.getY(), location.getZ(), this.getCreationRadius()); + } + + @Override + public TravelAgent setSearchRadius(int radius) { + this.searchRadius = radius; + return this; + } + + @Override + public int getSearchRadius() { + return this.searchRadius; + } + + @Override + public TravelAgent setCreationRadius(int radius) { + this.creationRadius = radius < 2 ? 0 : radius; + return this; + } + + @Override + public int getCreationRadius() { + return this.creationRadius; + } + + @Override + public boolean getCanCreatePortal() { + return this.canCreatePortal; + } + + @Override + public void setCanCreatePortal(boolean create) { + this.canCreatePortal = create; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java new file mode 100644 index 0000000..52b6a3c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -0,0 +1,1505 @@ +package org.bukkit.craftbukkit; + +import com.google.common.base.Preconditions; +import net.minecraft.server.*; +import org.apache.commons.lang.Validate; +import org.bukkit.Chunk; +import org.bukkit.ChunkSnapshot; +import org.bukkit.World; +import org.bukkit.WorldBorder; +import org.bukkit.*; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.entity.CraftItem; +import org.bukkit.craftbukkit.entity.CraftLightningStrike; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.metadata.BlockMetadataStore; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.craftbukkit.util.LongHash; +import org.bukkit.entity.Entity; +import org.bukkit.entity.*; +import org.bukkit.entity.minecart.PoweredMinecart; +import org.bukkit.entity.minecart.StorageMinecart; +import org.bukkit.entity.minecart.*; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.world.SpawnChangeEvent; +import org.bukkit.generator.BlockPopulator; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.messaging.StandardMessenger; +import org.bukkit.util.Vector; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +public class CraftWorld implements World { + public static final int CUSTOM_DIMENSION_OFFSET = 10; + + private final WorldServer world; + private WorldBorder worldBorder; + private Environment environment; + private final CraftServer server = (CraftServer) Bukkit.getServer(); + private final ChunkGenerator generator; + private final List populators = new ArrayList(); + private final BlockMetadataStore blockMetadata = new BlockMetadataStore(this); + private int monsterSpawn = -1; + private int animalSpawn = -1; + private int waterAnimalSpawn = -1; + private int ambientSpawn = -1; + private int chunkLoadCount = 0; + private int chunkGCTickCount; + + private static final Random rand = new Random(); + + public CraftWorld(WorldServer world, ChunkGenerator gen, Environment env) { + this.world = world; + this.generator = gen; + + environment = env; + + if (server.chunkGCPeriod > 0) { + chunkGCTickCount = rand.nextInt(server.chunkGCPeriod); + } + } + + public Block getBlockAt(int x, int y, int z) { + return getChunkAt(x >> 4, z >> 4).getBlock(x & 0xF, y, z & 0xF); + } + + public int getBlockTypeIdAt(int x, int y, int z) { + return CraftMagicNumbers.getId(world.getType(x, y, z).getBlock()); + } + + public int getHighestBlockYAt(int x, int z) { + if (!isChunkLoaded(x >> 4, z >> 4)) { + loadChunk(x >> 4, z >> 4); + } + + return world.getHighestBlockYAt(x, z); + } + + public Location getSpawnLocation() { + BlockPosition spawn = world.getSpawn(); + return new Location(this, spawn.getX(), spawn.getY(), spawn.getZ()); + } + + public boolean setSpawnLocation(int x, int y, int z) { + try { + Location previousLocation = getSpawnLocation(); + world.worldData.setSpawn(new BlockPosition(x, y, z)); + + // Notify anyone who's listening. + SpawnChangeEvent event = new SpawnChangeEvent(this, previousLocation); + server.getPluginManager().callEvent(event); + + return true; + } catch (Exception e) { + return false; + } + } + + // PaperSpigot start - Async chunk load API + public void getChunkAtAsync(final int x, final int z, final ChunkLoadCallback callback) { + final ChunkProviderServer cps = this.world.chunkProviderServer; + cps.getChunkAt(x, z, new Runnable() { + @Override + public void run() { + callback.onLoad(cps.getChunkAt(x, z).bukkitChunk); + } + }); + } + public void getChunkAtAsync(Block block, ChunkLoadCallback callback) { + getChunkAtAsync(block.getX() >> 4, block.getZ() >> 4, callback); + } + public void getChunkAtAsync(Location location, ChunkLoadCallback callback) { + getChunkAtAsync(location.getBlockX() >> 4, location.getBlockZ() >> 4, callback); + } + + public java.util.concurrent.CompletableFuture getChunkAtAsync(final int x, final int z, final boolean gen) { + final ChunkProviderServer cps = this.world.chunkProviderServer; + java.util.concurrent.CompletableFuture future = new java.util.concurrent.CompletableFuture<>(); + cps.getChunkAt(x, z); + return future; + } + // PaperSpigot end + + public Chunk getChunkAt(int x, int z) { + return this.world.chunkProviderServer.getChunkAt(x, z).bukkitChunk; + } + + public Chunk getChunkAt(Block block) { + return getChunkAt(block.getX() >> 4, block.getZ() >> 4); + } + + public boolean isChunkLoaded(int x, int z) { + return world.chunkProviderServer.isChunkLoaded(x, z); + } + + public Chunk[] getLoadedChunks() { + Object[] chunks = world.chunkProviderServer.chunks.values().toArray(); + org.bukkit.Chunk[] craftChunks = new CraftChunk[chunks.length]; + + for (int i = 0; i < chunks.length; i++) { + net.minecraft.server.Chunk chunk = (net.minecraft.server.Chunk) chunks[i]; + craftChunks[i] = chunk.bukkitChunk; + } + + return craftChunks; + } + + public void loadChunk(int x, int z) { + loadChunk(x, z, true); + } + + public boolean unloadChunk(Chunk chunk) { + return unloadChunk(chunk.getX(), chunk.getZ()); + } + + public boolean unloadChunk(int x, int z) { + return unloadChunk(x, z, true); + } + + public boolean unloadChunk(int x, int z, boolean save) { + return unloadChunk(x, z, save, false); + } + + public boolean unloadChunkRequest(int x, int z) { + return unloadChunkRequest(x, z, true); + } + + public boolean unloadChunkRequest(int x, int z, boolean safe) { + org.spigotmc.AsyncCatcher.catchOp( "chunk unload"); // Spigot + if (safe && isChunkInUse(x, z)) { + return false; + } + + world.chunkProviderServer.queueUnload(x, z); + + return true; + } + + public boolean unloadChunk(int x, int z, boolean save, boolean safe) { + org.spigotmc.AsyncCatcher.catchOp( "chunk unload"); // Spigot + if (safe && isChunkInUse(x, z)) { + return false; + } + + net.minecraft.server.Chunk chunk = world.chunkProviderServer.getChunkIfLoaded(x, z); + // PaperSpigot start - Don't create a chunk just to unload it + if (chunk == null) { + return false; + } + // PaperSpigot end + if (chunk.mustSave) { // If chunk had previously been queued to save, must do save to avoid loss of that data + save = true; + } + + chunk.removeEntities(); // Always remove entities - even if discarding, need to get them out of world table + + if (save && !(chunk instanceof EmptyChunk)) { + world.chunkProviderServer.saveChunk(chunk); + world.chunkProviderServer.saveChunkNOP(chunk); + } + + world.chunkProviderServer.unloadQueue.remove(LongHash.toLong(x, z)); // TacoSpigot - invoke LongHash directly + world.chunkProviderServer.chunks.remove(LongHash.toLong(x, z)); + + return true; + } + + public boolean regenerateChunk(int x, int z) { + unloadChunk(x, z, false, false); + + world.chunkProviderServer.unloadQueue.remove(LongHash.toLong(x, z)); // TacoSpigot - invoke LongHash directly + + net.minecraft.server.Chunk chunk = null; + + if (world.chunkProviderServer.chunkProvider == null) { + chunk = world.chunkProviderServer.emptyChunk; + } else { + chunk = world.chunkProviderServer.chunkProvider.getOrCreateChunk(x, z); + } + + chunkLoadPostProcess(chunk, x, z); + + refreshChunk(x, z); + + return chunk != null; + } + + public boolean refreshChunk(int x, int z) { + if (!isChunkLoaded(x, z)) { + return false; + } + + int px = x << 4; + int pz = z << 4; + + // If there are more than 64 updates to a chunk at once, it will update all 'touched' sections within the chunk + // And will include biome data if all sections have been 'touched' + // This flags 65 blocks distributed across all the sections of the chunk, so that everything is sent, including biomes + int height = getMaxHeight() / 16; + for (int idx = 0; idx < 64; idx++) { + world.notify(new BlockPosition(px + (idx / height), ((idx % height) * 16), pz)); + } + world.notify(new BlockPosition(px + 15, (height * 16) - 1, pz + 15)); + + return true; + } + + public boolean isChunkInUse(int x, int z) { + return world.getPlayerChunkMap().isChunkInUse(x, z); + } + + public boolean loadChunk(int x, int z, boolean generate) { + org.spigotmc.AsyncCatcher.catchOp( "chunk load"); // Spigot + chunkLoadCount++; + if (generate) { + // Use the default variant of loadChunk when generate == true. + return world.chunkProviderServer.getChunkAt(x, z) != null; + } + + world.chunkProviderServer.unloadQueue.remove(LongHash.toLong(x, z)); // TacoSpigot - invoke LongHash directly + net.minecraft.server.Chunk chunk = world.chunkProviderServer.chunks.get(LongHash.toLong(x, z)); + + if (chunk == null) { + world.timings.syncChunkLoadTimer.startTiming(); // Spigot + chunk = world.chunkProviderServer.loadChunk(x, z); + + chunkLoadPostProcess(chunk, x, z); + world.timings.syncChunkLoadTimer.stopTiming(); // Spigot + } + return chunk != null; + } + + private void chunkLoadPostProcess(net.minecraft.server.Chunk chunk, int cx, int cz) { + if (chunk != null) { + world.chunkProviderServer.chunks.put(LongHash.toLong(cx, cz), chunk); + + chunk.addEntities(); + + // Update neighbor counts + for (int x = -2; x < 3; x++) { + for (int z = -2; z < 3; z++) { + if (x == 0 && z == 0) { + continue; + } + + net.minecraft.server.Chunk neighbor = world.chunkProviderServer.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z); + if (neighbor != null) { + neighbor.setNeighborLoaded(-x, -z); + chunk.setNeighborLoaded(x, z); + } + } + } + // CraftBukkit end + + chunk.loadNearby(world.chunkProviderServer, world.chunkProviderServer, cx, cz); + } + } + + public boolean isChunkLoaded(Chunk chunk) { + return isChunkLoaded(chunk.getX(), chunk.getZ()); + } + + public void loadChunk(Chunk chunk) { + loadChunk(chunk.getX(), chunk.getZ()); + ((CraftChunk) getChunkAt(chunk.getX(), chunk.getZ())).getHandle().bukkitChunk = chunk; + } + + public WorldServer getHandle() { + return world; + } + + public org.bukkit.entity.Item dropItem(Location loc, ItemStack item) { + Validate.notNull(item, "Cannot drop a Null item."); + Validate.isTrue(item.getTypeId() != 0, "Cannot drop AIR."); + EntityItem entity = new EntityItem(world, loc.getX(), loc.getY(), loc.getZ(), CraftItemStack.asNMSCopy(item)); + entity.pickupDelay = 10; + world.addEntity(entity); + // TODO this is inconsistent with how Entity.getBukkitEntity() works. + // However, this entity is not at the moment backed by a server entity class so it may be left. + return new CraftItem(world.getServer(), entity); + } + + private static void randomLocationWithinBlock(Location loc, double xs, double ys, double zs) { + double prevX = loc.getX(); + double prevY = loc.getY(); + double prevZ = loc.getZ(); + loc.add(xs, ys, zs); + if (loc.getX() < Math.floor(prevX)) { + loc.setX(Math.floor(prevX)); + } + if (loc.getX() >= Math.ceil(prevX)) { + loc.setX(Math.ceil(prevX - 0.01)); + } + if (loc.getY() < Math.floor(prevY)) { + loc.setY(Math.floor(prevY)); + } + if (loc.getY() >= Math.ceil(prevY)) { + loc.setY(Math.ceil(prevY - 0.01)); + } + if (loc.getZ() < Math.floor(prevZ)) { + loc.setZ(Math.floor(prevZ)); + } + if (loc.getZ() >= Math.ceil(prevZ)) { + loc.setZ(Math.ceil(prevZ - 0.01)); + } + } + + public org.bukkit.entity.Item dropItemNaturally(Location loc, ItemStack item) { + double xs = world.random.nextFloat() * 0.7F - 0.35D; + double ys = world.random.nextFloat() * 0.7F - 0.35D; + double zs = world.random.nextFloat() * 0.7F - 0.35D; + loc = loc.clone(); + // Makes sure the new item is created within the block the location points to. + // This prevents item spill in 1-block wide farms. + randomLocationWithinBlock(loc, xs, ys, zs); + return dropItem(loc, item); + } + + public Arrow spawnArrow(Location loc, Vector velocity, float speed, float spread) { + Validate.notNull(loc, "Can not spawn arrow with a null location"); + Validate.notNull(velocity, "Can not spawn arrow with a null velocity"); + + EntityArrow arrow = new EntityArrow(world); + arrow.setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch()); + arrow.shoot(velocity.getX(), velocity.getY(), velocity.getZ(), speed, spread); + world.addEntity(arrow); + return (Arrow) arrow.getBukkitEntity(); + } + + @Deprecated + public LivingEntity spawnCreature(Location loc, CreatureType creatureType) { + return spawnCreature(loc, creatureType.toEntityType()); + } + + @Deprecated + public LivingEntity spawnCreature(Location loc, EntityType creatureType) { + Validate.isTrue(creatureType.isAlive(), "EntityType not instance of LivingEntity"); + return (LivingEntity) spawnEntity(loc, creatureType); + } + + public Entity spawnEntity(Location loc, EntityType entityType) { + return spawn(loc, entityType.getEntityClass()); + } + + public LightningStrike strikeLightning(Location loc) { + EntityLightning lightning = new EntityLightning(world, loc.getX(), loc.getY(), loc.getZ()); + world.strikeLightning(lightning); + return new CraftLightningStrike(server, lightning); + } + + public LightningStrike strikeLightningEffect(Location loc) { + EntityLightning lightning = new EntityLightning(world, loc.getX(), loc.getY(), loc.getZ(), true); + world.strikeLightning(lightning); + return new CraftLightningStrike(server, lightning); + } + + public boolean generateTree(Location loc, TreeType type) { + net.minecraft.server.WorldGenerator gen; + switch (type) { + case BIG_TREE: + gen = new WorldGenBigTree(true); + break; + case BIRCH: + gen = new WorldGenForest(true, false); + break; + case REDWOOD: + gen = new WorldGenTaiga2(true); + break; + case TALL_REDWOOD: + gen = new WorldGenTaiga1(); + break; + case JUNGLE: + IBlockData iblockdata1 = Blocks.LOG.getBlockData().set(BlockLog1.VARIANT, BlockWood.EnumLogVariant.JUNGLE); + IBlockData iblockdata2 = Blocks.LEAVES.getBlockData().set(BlockLeaves1.VARIANT, BlockWood.EnumLogVariant.JUNGLE).set(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + gen = new WorldGenJungleTree(true, 10, 20, iblockdata1, iblockdata2); // Magic values as in BlockSapling + break; + case SMALL_JUNGLE: + iblockdata1 = Blocks.LOG.getBlockData().set(BlockLog1.VARIANT, BlockWood.EnumLogVariant.JUNGLE); + iblockdata2 = Blocks.LEAVES.getBlockData().set(BlockLeaves1.VARIANT, BlockWood.EnumLogVariant.JUNGLE).set(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + gen = new WorldGenTrees(true, 4 + rand.nextInt(7), iblockdata1, iblockdata2, false); + break; + case COCOA_TREE: + iblockdata1 = Blocks.LOG.getBlockData().set(BlockLog1.VARIANT, BlockWood.EnumLogVariant.JUNGLE); + iblockdata2 = Blocks.LEAVES.getBlockData().set(BlockLeaves1.VARIANT, BlockWood.EnumLogVariant.JUNGLE).set(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + gen = new WorldGenTrees(true, 4 + rand.nextInt(7), iblockdata1, iblockdata2, true); + break; + case JUNGLE_BUSH: + iblockdata1 = Blocks.LOG.getBlockData().set(BlockLog1.VARIANT, BlockWood.EnumLogVariant.JUNGLE); + iblockdata2 = Blocks.LEAVES.getBlockData().set(BlockLeaves1.VARIANT, BlockWood.EnumLogVariant.OAK).set(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + gen = new WorldGenGroundBush(iblockdata1, iblockdata2); + break; + case RED_MUSHROOM: + gen = new WorldGenHugeMushroom(Blocks.RED_MUSHROOM_BLOCK); + break; + case BROWN_MUSHROOM: + gen = new WorldGenHugeMushroom(Blocks.BROWN_MUSHROOM_BLOCK); + break; + case SWAMP: + gen = new WorldGenSwampTree(); + break; + case ACACIA: + gen = new WorldGenAcaciaTree(true); + break; + case DARK_OAK: + gen = new WorldGenForestTree(true); + break; + case MEGA_REDWOOD: + gen = new WorldGenMegaTree(false, rand.nextBoolean()); + break; + case TALL_BIRCH: + gen = new WorldGenForest(true, true); + break; + case TREE: + default: + gen = new WorldGenTrees(true); + break; + } + + return gen.generate(world, rand, new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + } + + public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { + world.captureTreeGeneration = true; + world.captureBlockStates = true; + boolean grownTree = generateTree(loc, type); + world.captureBlockStates = false; + world.captureTreeGeneration = false; + if (grownTree) { // Copy block data to delegate + for (BlockState blockstate : world.capturedBlockStates) { + int x = blockstate.getX(); + int y = blockstate.getY(); + int z = blockstate.getZ(); + BlockPosition position = new BlockPosition(x, y, z); + net.minecraft.server.Block oldBlock = world.getType(position).getBlock(); + int typeId = blockstate.getTypeId(); + int data = blockstate.getRawData(); + int flag = ((CraftBlockState)blockstate).getFlag(); + delegate.setTypeIdAndData(x, y, z, typeId, data); + net.minecraft.server.Block newBlock = world.getType(position).getBlock(); + world.notifyAndUpdatePhysics(position, null, oldBlock, newBlock, flag); + } + world.capturedBlockStates.clear(); + return true; + } else { + world.capturedBlockStates.clear(); + return false; + } + } + + public TileEntity getTileEntityAt(final int x, final int y, final int z) { + return world.getTileEntity(new BlockPosition(x, y, z)); + } + + public String getName() { + return world.worldData.getName(); + } + + @Deprecated + public long getId() { + return world.worldData.getSeed(); + } + + public UUID getUID() { + return world.getDataManager().getUUID(); + } + + @Override + public String toString() { + return "CraftWorld{name=" + getName() + '}'; + } + + public long getTime() { + long time = getFullTime() % 24000; + if (time < 0) time += 24000; + return time; + } + + public void setTime(long time) { + long margin = (time - getFullTime()) % 24000; + if (margin < 0) margin += 24000; + setFullTime(getFullTime() + margin); + } + + public long getFullTime() { + return world.getDayTime(); + } + + public void setFullTime(long time) { + world.setDayTime(time); + + // Forces the client to update to the new time immediately + for (Player p : getPlayers()) { + CraftPlayer cp = (CraftPlayer) p; + if (cp.getHandle().playerConnection == null) continue; + + cp.getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateTime(cp.getHandle().world.getTime(), cp.getHandle().getPlayerTime(), cp.getHandle().world.getGameRules().getBoolean("doDaylightCycle"))); + } + } + + public boolean createExplosion(double x, double y, double z, float power) { + return createExplosion(x, y, z, power, false, true); + } + + public boolean createExplosion(double x, double y, double z, float power, boolean setFire) { + return createExplosion(x, y, z, power, setFire, true); + } + + public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks) { + return !world.createExplosion(null, x, y, z, power, setFire, breakBlocks).wasCanceled; + } + + public boolean createExplosion(Location loc, float power) { + return createExplosion(loc, power, false); + } + + public boolean createExplosion(Location loc, float power, boolean setFire) { + return createExplosion(loc.getX(), loc.getY(), loc.getZ(), power, setFire); + } + + public Environment getEnvironment() { + return environment; + } + + public void setEnvironment(Environment env) { + if (environment != env) { + environment = env; + world.worldProvider = WorldProvider.byDimension(environment.getId()); + } + } + + public Block getBlockAt(Location location) { + return getBlockAt(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + + public int getBlockTypeIdAt(Location location) { + return getBlockTypeIdAt(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + + public int getHighestBlockYAt(Location location) { + return getHighestBlockYAt(location.getBlockX(), location.getBlockZ()); + } + + public Chunk getChunkAt(Location location) { + return getChunkAt(location.getBlockX() >> 4, location.getBlockZ() >> 4); + } + + // Paper start + public boolean isChunkGenerated(int x, int z) throws IOException { + return this.getHandle().getChunkProviderServer().isChunkGenerated(x, z); + } + // Paper end + + public ChunkGenerator getGenerator() { + return generator; + } + + public List getPopulators() { + return populators; + } + + public Block getHighestBlockAt(int x, int z) { + return getBlockAt(x, getHighestBlockYAt(x, z), z); + } + + public Block getHighestBlockAt(Location location) { + return getHighestBlockAt(location.getBlockX(), location.getBlockZ()); + } + + public Biome getBiome(int x, int z) { + return CraftBlock.biomeBaseToBiome(this.world.getBiome(new BlockPosition(x, 0, z))); + } + + public void setBiome(int x, int z, Biome bio) { + BiomeBase bb = CraftBlock.biomeToBiomeBase(bio); + if (this.world.isLoaded(x, 0, z)) { + net.minecraft.server.Chunk chunk = this.world.getChunkAtWorldCoords(x, z); + + if (chunk != null) { + byte[] biomevals = chunk.getBiomeIndex(); + biomevals[((z & 0xF) << 4) | (x & 0xF)] = (byte)bb.id; + } + } + } + + public double getTemperature(int x, int z) { + return this.world.getBiome(new BlockPosition(x, 0, z)).temperature; + } + + public double getHumidity(int x, int z) { + return this.world.getBiome(new BlockPosition(x, 0, z)).humidity; + } + + public List getEntities() { + List list = new ArrayList(); + + for (Object o : world.entityList) { + if (o instanceof net.minecraft.server.Entity) { + net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o; + Entity bukkitEntity = mcEnt.getBukkitEntity(); + + // Assuming that bukkitEntity isn't null + if (bukkitEntity != null) { + list.add(bukkitEntity); + } + } + } + + return list; + } + + public List getLivingEntities() { + List list = new ArrayList(); + + for (Object o : world.entityList) { + if (o instanceof net.minecraft.server.Entity) { + net.minecraft.server.Entity mcEnt = (net.minecraft.server.Entity) o; + Entity bukkitEntity = mcEnt.getBukkitEntity(); + + // Assuming that bukkitEntity isn't null + if (bukkitEntity != null && bukkitEntity instanceof LivingEntity) { + list.add((LivingEntity) bukkitEntity); + } + } + } + + return list; + } + + @SuppressWarnings("unchecked") + @Deprecated + public Collection getEntitiesByClass(Class... classes) { + return (Collection)getEntitiesByClasses(classes); + } + + @SuppressWarnings("unchecked") + public Collection getEntitiesByClass(Class clazz) { + Collection list = new ArrayList(); + + for (Object entity: world.entityList) { + if (entity instanceof net.minecraft.server.Entity) { + Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity(); + + if (bukkitEntity == null) { + continue; + } + + Class bukkitClass = bukkitEntity.getClass(); + + if (clazz.isAssignableFrom(bukkitClass)) { + list.add((T) bukkitEntity); + } + } + } + + return list; + } + + public Collection getEntitiesByClasses(Class... classes) { + Collection list = new ArrayList(); + + for (Object entity: world.entityList) { + if (entity instanceof net.minecraft.server.Entity) { + Entity bukkitEntity = ((net.minecraft.server.Entity) entity).getBukkitEntity(); + + if (bukkitEntity == null) { + continue; + } + + Class bukkitClass = bukkitEntity.getClass(); + + for (Class clazz : classes) { + if (clazz.isAssignableFrom(bukkitClass)) { + list.add(bukkitEntity); + break; + } + } + } + } + + return list; + } + + @Override + public Collection getNearbyEntities(Location location, double x, double y, double z) { + if (location == null || !location.getWorld().equals(this)) { + return Collections.emptyList(); + } + + AxisAlignedBB bb = new AxisAlignedBB(location.getX() - x, location.getY() - y, location.getZ() - z, location.getX() + x, location.getY() + y, location.getZ() + z); + List entityList = getHandle().a((net.minecraft.server.Entity) null, bb, null); // PAIL : rename + List bukkitEntityList = new ArrayList(entityList.size()); + for (Object entity : entityList) { + bukkitEntityList.add(((net.minecraft.server.Entity) entity).getBukkitEntity()); + } + return bukkitEntityList; + } + + public List getPlayers() { + List list = new ArrayList(world.players.size()); + + for (EntityHuman human : world.players) { + HumanEntity bukkitEntity = human.getBukkitEntity(); + + if ((bukkitEntity != null) && (bukkitEntity instanceof Player)) { + list.add((Player) bukkitEntity); + } + } + + return list; + } + + public void save() { + // Spigot start + save(true); + } + public void save(boolean forceSave) { + // Spigot end + this.server.checkSaveState(); + try { + boolean oldSave = world.savingDisabled; + + world.savingDisabled = false; + world.save(forceSave, null); // Spigot + + world.savingDisabled = oldSave; + } catch (ExceptionWorldConflict ex) { + ex.printStackTrace(); + } + } + + public boolean isAutoSave() { + return !world.savingDisabled; + } + + public void setAutoSave(boolean value) { + world.savingDisabled = !value; + } + + public void setDifficulty(Difficulty difficulty) { + this.getHandle().worldData.setDifficulty(EnumDifficulty.getById(difficulty.getValue())); + } + + public Difficulty getDifficulty() { + return Difficulty.getByValue(this.getHandle().getDifficulty().ordinal()); + } + + public BlockMetadataStore getBlockMetadata() { + return blockMetadata; + } + + public boolean hasStorm() { + return world.worldData.hasStorm(); + } + + public void setStorm(boolean hasStorm) { + world.worldData.setStorm(hasStorm); + } + + public int getWeatherDuration() { + return world.worldData.getWeatherDuration(); + } + + public void setWeatherDuration(int duration) { + world.worldData.setWeatherDuration(duration); + } + + public boolean isThundering() { + return world.worldData.isThundering(); + } + + public void setThundering(boolean thundering) { + world.worldData.setThundering(thundering); + } + + public int getThunderDuration() { + return world.worldData.getThunderDuration(); + } + + public void setThunderDuration(int duration) { + world.worldData.setThunderDuration(duration); + } + + public long getSeed() { + return world.worldData.getSeed(); + } + + public boolean getPVP() { + return world.pvpMode; + } + + public void setPVP(boolean pvp) { + world.pvpMode = pvp; + } + + public void playEffect(Player player, Effect effect, int data) { + playEffect(player.getLocation(), effect, data, 0); + } + + public void playEffect(Location location, Effect effect, int data) { + playEffect(location, effect, data, 64); + } + + public void playEffect(Location loc, Effect effect, T data) { + playEffect(loc, effect, data, 64); + } + + public void playEffect(Location loc, Effect effect, T data, int radius) { + if (data != null) { + Validate.isTrue(data.getClass().isAssignableFrom(effect.getData()), "Wrong kind of data for this effect!"); + } else { + Validate.isTrue(effect.getData() == null, "Wrong kind of data for this effect!"); + } + + if (data != null && data.getClass().equals( org.bukkit.material.MaterialData.class )) { + org.bukkit.material.MaterialData materialData = (org.bukkit.material.MaterialData) data; + Validate.isTrue( materialData.getItemType().isBlock(), "Material must be block" ); + spigot().playEffect( loc, effect, materialData.getItemType().getId(), materialData.getData(), 0, 0, 0, 1, 1, radius ); + } else { + int dataValue = data == null ? 0 : CraftEffect.getDataValue( effect, data ); + playEffect( loc, effect, dataValue, radius ); + } + } + + public void playEffect(Location location, Effect effect, int data, int radius) { + spigot().playEffect( location, effect, data, 0, 0, 0, 0, 1, 1, radius ); + } + + public T spawn(Location location, Class clazz) throws IllegalArgumentException { + return spawn(location, clazz, SpawnReason.CUSTOM); + } + + public FallingBlock spawnFallingBlock(Location location, org.bukkit.Material material, byte data) throws IllegalArgumentException { + Validate.notNull(location, "Location cannot be null"); + Validate.notNull(material, "Material cannot be null"); + Validate.isTrue(material.isBlock(), "Material must be a block"); + + double x = location.getBlockX() + 0.5; + double y = location.getBlockY() + 0.5; + double z = location.getBlockZ() + 0.5; + + // PaperSpigot start - Add FallingBlock source location API + location = location.clone(); + EntityFallingBlock entity = new EntityFallingBlock(location, world, x, y, z, net.minecraft.server.Block.getById(material.getId()).fromLegacyData(data)); + // PaperSpigot end + entity.ticksLived = 1; + + world.addEntity(entity, SpawnReason.CUSTOM); + return (FallingBlock) entity.getBukkitEntity(); + } + + public FallingBlock spawnFallingBlock(Location location, int blockId, byte blockData) throws IllegalArgumentException { + return spawnFallingBlock(location, org.bukkit.Material.getMaterial(blockId), blockData); + } + + @SuppressWarnings("unchecked") + public net.minecraft.server.Entity createEntity(Location location, Class clazz) throws IllegalArgumentException { + if (location == null || clazz == null) { + throw new IllegalArgumentException("Location or entity class cannot be null"); + } + + net.minecraft.server.Entity entity = null; + + double x = location.getX(); + double y = location.getY(); + double z = location.getZ(); + float pitch = location.getPitch(); + float yaw = location.getYaw(); + + // order is important for some of these + if (Boat.class.isAssignableFrom(clazz)) { + entity = new EntityBoat(world, x, y, z); + } else if (FallingBlock.class.isAssignableFrom(clazz)) { + x = location.getBlockX(); + y = location.getBlockY(); + z = location.getBlockZ(); + IBlockData blockData = world.getType(new BlockPosition(x, y, z)); + int type = CraftMagicNumbers.getId(blockData.getBlock()); + int data = blockData.getBlock().toLegacyData(blockData); + // PaperSpigot start - Add FallingBlock source location API + location = location.clone(); + entity = new EntityFallingBlock(location, world, x + 0.5, y + 0.5, z + 0.5, net.minecraft.server.Block.getById(type).fromLegacyData(data)); + // PaperSpigot end + } else if (Projectile.class.isAssignableFrom(clazz)) { + if (Snowball.class.isAssignableFrom(clazz)) { + entity = new EntitySnowball(world, x, y, z); + } else if (Egg.class.isAssignableFrom(clazz)) { + entity = new EntityEgg(world, x, y, z); + } else if (Arrow.class.isAssignableFrom(clazz)) { + entity = new EntityArrow(world); + entity.setPositionRotation(x, y, z, 0, 0); + } else if (ThrownExpBottle.class.isAssignableFrom(clazz)) { + entity = new EntityThrownExpBottle(world); + entity.setPositionRotation(x, y, z, 0, 0); + } else if (EnderPearl.class.isAssignableFrom(clazz)) { + entity = new EntityEnderPearl(world, null); + entity.setPositionRotation(x, y, z, 0, 0); + } else if (ThrownPotion.class.isAssignableFrom(clazz)) { + entity = new EntityPotion(world, x, y, z, CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.POTION, 1))); + } else if (Fireball.class.isAssignableFrom(clazz)) { + if (SmallFireball.class.isAssignableFrom(clazz)) { + entity = new EntitySmallFireball(world); + } else if (WitherSkull.class.isAssignableFrom(clazz)) { + entity = new EntityWitherSkull(world); + } else { + entity = new EntityLargeFireball(world); + } + entity.setPositionRotation(x, y, z, yaw, pitch); + Vector direction = location.getDirection().multiply(10); + ((EntityFireball) entity).setDirection(direction.getX(), direction.getY(), direction.getZ()); + } + } else if (Minecart.class.isAssignableFrom(clazz)) { + if (PoweredMinecart.class.isAssignableFrom(clazz)) { + entity = new EntityMinecartFurnace(world, x, y, z); + } else if (StorageMinecart.class.isAssignableFrom(clazz)) { + entity = new EntityMinecartChest(world, x, y, z); + } else if (ExplosiveMinecart.class.isAssignableFrom(clazz)) { + entity = new EntityMinecartTNT(world, x, y, z); + } else if (HopperMinecart.class.isAssignableFrom(clazz)) { + entity = new EntityMinecartHopper(world, x, y, z); + } else if (SpawnerMinecart.class.isAssignableFrom(clazz)) { + entity = new EntityMinecartMobSpawner(world, x, y, z); + } else { // Default to rideable minecart for pre-rideable compatibility + entity = new EntityMinecartRideable(world, x, y, z); + } + } else if (EnderSignal.class.isAssignableFrom(clazz)) { + entity = new EntityEnderSignal(world, x, y, z); + } else if (EnderCrystal.class.isAssignableFrom(clazz)) { + entity = new EntityEnderCrystal(world); + entity.setPositionRotation(x, y, z, 0, 0); + } else if (LivingEntity.class.isAssignableFrom(clazz)) { + if (Chicken.class.isAssignableFrom(clazz)) { + entity = new EntityChicken(world); + } else if (Cow.class.isAssignableFrom(clazz)) { + if (MushroomCow.class.isAssignableFrom(clazz)) { + entity = new EntityMushroomCow(world); + } else { + entity = new EntityCow(world); + } + } else if (Golem.class.isAssignableFrom(clazz)) { + if (Snowman.class.isAssignableFrom(clazz)) { + entity = new EntitySnowman(world); + } else if (IronGolem.class.isAssignableFrom(clazz)) { + entity = new EntityIronGolem(world); + } + } else if (Creeper.class.isAssignableFrom(clazz)) { + entity = new EntityCreeper(world); + } else if (Ghast.class.isAssignableFrom(clazz)) { + entity = new EntityGhast(world); + } else if (Pig.class.isAssignableFrom(clazz)) { + entity = new EntityPig(world); + } else if (Player.class.isAssignableFrom(clazz)) { + // need a net server handler for this one + } else if (Sheep.class.isAssignableFrom(clazz)) { + entity = new EntitySheep(world); + } else if (Horse.class.isAssignableFrom(clazz)) { + entity = new EntityHorse(world); + } else if (Skeleton.class.isAssignableFrom(clazz)) { + entity = new EntitySkeleton(world); + } else if (Slime.class.isAssignableFrom(clazz)) { + if (MagmaCube.class.isAssignableFrom(clazz)) { + entity = new EntityMagmaCube(world); + } else { + entity = new EntitySlime(world); + } + } else if (Spider.class.isAssignableFrom(clazz)) { + if (CaveSpider.class.isAssignableFrom(clazz)) { + entity = new EntityCaveSpider(world); + } else { + entity = new EntitySpider(world); + } + } else if (Squid.class.isAssignableFrom(clazz)) { + entity = new EntitySquid(world); + } else if (Tameable.class.isAssignableFrom(clazz)) { + if (Wolf.class.isAssignableFrom(clazz)) { + entity = new EntityWolf(world); + } else if (Ocelot.class.isAssignableFrom(clazz)) { + entity = new EntityOcelot(world); + } + } else if (PigZombie.class.isAssignableFrom(clazz)) { + entity = new EntityPigZombie(world); + } else if (Zombie.class.isAssignableFrom(clazz)) { + entity = new EntityZombie(world); + } else if (Giant.class.isAssignableFrom(clazz)) { + entity = new EntityGiantZombie(world); + } else if (Silverfish.class.isAssignableFrom(clazz)) { + entity = new EntitySilverfish(world); + } else if (Enderman.class.isAssignableFrom(clazz)) { + entity = new EntityEnderman(world); + } else if (Blaze.class.isAssignableFrom(clazz)) { + entity = new EntityBlaze(world); + } else if (Villager.class.isAssignableFrom(clazz)) { + entity = new EntityVillager(world); + } else if (Witch.class.isAssignableFrom(clazz)) { + entity = new EntityWitch(world); + } else if (Wither.class.isAssignableFrom(clazz)) { + entity = new EntityWither(world); + } else if (ComplexLivingEntity.class.isAssignableFrom(clazz)) { + if (EnderDragon.class.isAssignableFrom(clazz)) { + entity = new EntityEnderDragon(world); + } + } else if (Ambient.class.isAssignableFrom(clazz)) { + if (Bat.class.isAssignableFrom(clazz)) { + entity = new EntityBat(world); + } + } else if (Rabbit.class.isAssignableFrom(clazz)) { + entity = new EntityRabbit(world); + } else if (Endermite.class.isAssignableFrom(clazz)) { + entity = new EntityEndermite(world); + } else if (Guardian.class.isAssignableFrom(clazz)){ + entity = new EntityGuardian(world); + } else if (ArmorStand.class.isAssignableFrom(clazz)) { + entity = new EntityArmorStand(world, x, y, z); + } + + if (entity != null) { + entity.setLocation(x, y, z, yaw, pitch); + } + } else if (Hanging.class.isAssignableFrom(clazz)) { + Block block = getBlockAt(location); + BlockFace face = BlockFace.SELF; + + int width = 16; // 1 full block, also painting smallest size. + int height = 16; // 1 full block, also painting smallest size. + + if (ItemFrame.class.isAssignableFrom(clazz)) { + width = 12; + height = 12; + } else if (LeashHitch.class.isAssignableFrom(clazz)) { + width = 9; + height = 9; + } + + BlockFace[] faces = new BlockFace[]{BlockFace.EAST,BlockFace.NORTH,BlockFace.WEST,BlockFace.SOUTH}; + final BlockPosition pos = new BlockPosition((int) x, (int) y, (int) z); + for (BlockFace dir : faces) { + net.minecraft.server.Block nmsBlock = CraftMagicNumbers.getBlock(block.getRelative(dir)); + if (nmsBlock.getMaterial().isBuildable() || BlockDiodeAbstract.d(nmsBlock)) { + boolean taken = false; + AxisAlignedBB bb = EntityHanging.calculateBoundingBox(pos,CraftBlock.blockFaceToNotch(dir).opposite(),width,height); + List list = world.getEntities(null, bb); + for (Iterator it = list.iterator(); !taken && it.hasNext();) { + net.minecraft.server.Entity e = it.next(); + if (e instanceof EntityHanging) { + taken = true; // Hanging entities do not like hanging entities which intersect them. + } + } + + if (!taken) { + face = dir; + break; + } + } + } + + EnumDirection dir = CraftBlock.blockFaceToNotch(face).opposite(); + + if (Painting.class.isAssignableFrom(clazz)) { + entity = new EntityPainting(world, new BlockPosition((int) x, (int) y, (int) z), dir); + } else if (ItemFrame.class.isAssignableFrom(clazz)) { + entity = new EntityItemFrame(world, new BlockPosition((int) x, (int) y, (int) z), dir); + } else if (LeashHitch.class.isAssignableFrom(clazz)) { + entity = new EntityLeash(world, new BlockPosition((int) x, (int) y, (int) z)); + entity.attachedToPlayer = true; + } + + if (entity != null && !((EntityHanging) entity).survives()) { + throw new IllegalArgumentException("Cannot spawn hanging entity for " + clazz.getName() + " at " + location); + } + } else if (TNTPrimed.class.isAssignableFrom(clazz)) { + org.bukkit.Location loc = new org.bukkit.Location(world.getWorld(), x, y, z); // PaperSpigot + entity = new EntityTNTPrimed(loc, world, x, y, z, null); + } else if (ExperienceOrb.class.isAssignableFrom(clazz)) { + entity = new EntityExperienceOrb(world, x, y, z, 0); + } else if (Weather.class.isAssignableFrom(clazz)) { + // not sure what this can do + if (LightningStrike.class.isAssignableFrom(clazz)) { + entity = new EntityLightning(world, x, y, z); + // what is this, I don't even + } + } else if (Firework.class.isAssignableFrom(clazz)) { + entity = new EntityFireworks(world, x, y, z, null); + } + + if (entity != null) { + // Spigot start + if (entity instanceof EntityOcelot) + { + ( (EntityOcelot) entity ).spawnBonus = false; + } + // Spigot end + return entity; + } + + throw new IllegalArgumentException("Cannot spawn an entity for " + clazz.getName()); + } + + @SuppressWarnings("unchecked") + public T addEntity(net.minecraft.server.Entity entity, SpawnReason reason) throws IllegalArgumentException { + Preconditions.checkArgument(entity != null, "Cannot spawn null entity"); + + if (entity instanceof EntityInsentient) { + ((EntityInsentient) entity).prepare(getHandle().E(new BlockPosition(entity)), null); + } + + world.addEntity(entity, reason); + return (T) entity.getBukkitEntity(); + } + + public T spawn(Location location, Class clazz, SpawnReason reason) throws IllegalArgumentException { + net.minecraft.server.Entity entity = createEntity(location, clazz); + + return addEntity(entity, reason); + } + + public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTempRain) { + return CraftChunk.getEmptyChunkSnapshot(x, z, this, includeBiome, includeBiomeTempRain); + } + + public void setSpawnFlags(boolean allowMonsters, boolean allowAnimals) { + world.setSpawnFlags(allowMonsters, allowAnimals); + } + + public boolean getAllowAnimals() { + return world.allowAnimals; + } + + public boolean getAllowMonsters() { + return world.allowMonsters; + } + + public int getMaxHeight() { + return world.getHeight(); + } + + public int getSeaLevel() { + return 64; + } + + public boolean getKeepSpawnInMemory() { + return world.keepSpawnInMemory; + } + + public void setKeepSpawnInMemory(boolean keepLoaded) { + world.keepSpawnInMemory = keepLoaded; + // Grab the worlds spawn chunk + BlockPosition chunkcoordinates = this.world.getSpawn(); + int chunkCoordX = chunkcoordinates.getX() >> 4; + int chunkCoordZ = chunkcoordinates.getZ() >> 4; + // Cycle through the 25x25 Chunks around it to load/unload the chunks. + for (int x = -12; x <= 12; x++) { + for (int z = -12; z <= 12; z++) { + if (keepLoaded) { + loadChunk(chunkCoordX + x, chunkCoordZ + z); + } else { + if (isChunkLoaded(chunkCoordX + x, chunkCoordZ + z)) { + if (this.getHandle().getChunkAt(chunkCoordX + x, chunkCoordZ + z) instanceof EmptyChunk) { + unloadChunk(chunkCoordX + x, chunkCoordZ + z, false); + } else { + unloadChunk(chunkCoordX + x, chunkCoordZ + z); + } + } + } + } + } + } + + @Override + public int hashCode() { + return getUID().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + + final CraftWorld other = (CraftWorld) obj; + + return this.getUID() == other.getUID(); + } + + public File getWorldFolder() { + return world.getDataManager().getDirectory(); + } + + public void sendPluginMessage(Plugin source, String channel, byte[] message) { + StandardMessenger.validatePluginMessage(server.getMessenger(), source, channel, message); + + for (Player player : getPlayers()) { + player.sendPluginMessage(source, channel, message); + } + } + + public Set getListeningPluginChannels() { + Set result = new HashSet(); + + for (Player player : getPlayers()) { + result.addAll(player.getListeningPluginChannels()); + } + + return result; + } + + public org.bukkit.WorldType getWorldType() { + return org.bukkit.WorldType.getByName(world.getWorldData().getType().name()); + } + + public boolean canGenerateStructures() { + return world.getWorldData().shouldGenerateMapFeatures(); + } + + public long getTicksPerAnimalSpawns() { + return world.ticksPerAnimalSpawns; + } + + public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns) { + world.ticksPerAnimalSpawns = ticksPerAnimalSpawns; + } + + public long getTicksPerMonsterSpawns() { + return world.ticksPerMonsterSpawns; + } + + public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns) { + world.ticksPerMonsterSpawns = ticksPerMonsterSpawns; + } + + public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { + server.getWorldMetadata().setMetadata(this, metadataKey, newMetadataValue); + } + + public List getMetadata(String metadataKey) { + return server.getWorldMetadata().getMetadata(this, metadataKey); + } + + public boolean hasMetadata(String metadataKey) { + return server.getWorldMetadata().hasMetadata(this, metadataKey); + } + + public void removeMetadata(String metadataKey, Plugin owningPlugin) { + server.getWorldMetadata().removeMetadata(this, metadataKey, owningPlugin); + } + + public int getMonsterSpawnLimit() { + if (monsterSpawn < 0) { + return server.getMonsterSpawnLimit(); + } + + return monsterSpawn; + } + + public void setMonsterSpawnLimit(int limit) { + monsterSpawn = limit; + } + + public int getAnimalSpawnLimit() { + if (animalSpawn < 0) { + return server.getAnimalSpawnLimit(); + } + + return animalSpawn; + } + + public void setAnimalSpawnLimit(int limit) { + animalSpawn = limit; + } + + public int getWaterAnimalSpawnLimit() { + if (waterAnimalSpawn < 0) { + return server.getWaterAnimalSpawnLimit(); + } + + return waterAnimalSpawn; + } + + public void setWaterAnimalSpawnLimit(int limit) { + waterAnimalSpawn = limit; + } + + public int getAmbientSpawnLimit() { + if (ambientSpawn < 0) { + return server.getAmbientSpawnLimit(); + } + + return ambientSpawn; + } + + public void setAmbientSpawnLimit(int limit) { + ambientSpawn = limit; + } + + + public void playSound(Location loc, Sound sound, float volume, float pitch) { + if (loc == null || sound == null) return; + + double x = loc.getX(); + double y = loc.getY(); + double z = loc.getZ(); + + getHandle().makeSound(x, y, z, CraftSound.getSound(sound), volume, pitch); + } + + public String getGameRuleValue(String rule) { + return getHandle().getGameRules().get(rule); + } + + public boolean setGameRuleValue(String rule, String value) { + // No null values allowed + if (rule == null || value == null) return false; + + if (!isGameRule(rule)) return false; + + getHandle().getGameRules().set(rule, value); + return true; + } + + public String[] getGameRules() { + return getHandle().getGameRules().getGameRules(); + } + + public boolean isGameRule(String rule) { + return getHandle().getGameRules().contains(rule); + } + + @Override + public WorldBorder getWorldBorder() { + if (this.worldBorder == null) { + this.worldBorder = new CraftWorldBorder(this); + } + + return this.worldBorder; + } + + public void processChunkGC() { + chunkGCTickCount++; + + if (chunkLoadCount >= server.chunkGCLoadThresh && server.chunkGCLoadThresh > 0) { + chunkLoadCount = 0; + } else if (chunkGCTickCount >= server.chunkGCPeriod && server.chunkGCPeriod > 0) { + chunkGCTickCount = 0; + } else { + return; + } + + ChunkProviderServer cps = world.chunkProviderServer; + for (net.minecraft.server.Chunk chunk : cps.chunks.values()) { + // If in use, skip it + if (isChunkInUse(chunk.locX, chunk.locZ)) { + continue; + } + + // Already unloading? + if (cps.unloadQueue.contains(LongHash.toLong(chunk.locX, chunk.locZ))) { // TacoSpigot - invoke LongHash directly + continue; + } + + // Add unload request + cps.queueUnload(chunk.locX, chunk.locZ); + } + } + // Spigot start + private final Spigot spigot = new Spigot() + { + @Override + public void playEffect( Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius ) + { + Validate.notNull( location, "Location cannot be null" ); + Validate.notNull( effect, "Effect cannot be null" ); + Validate.notNull( location.getWorld(), "World cannot be null" ); + Packet packet; + if ( effect.getType() != Effect.Type.PARTICLE ) + { + int packetData = effect.getId(); + packet = new PacketPlayOutWorldEvent( packetData, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ() ), id, false ); + } else + { + net.minecraft.server.EnumParticle particle = null; + int[] extra = null; + for ( net.minecraft.server.EnumParticle p : net.minecraft.server.EnumParticle.values() ) + { + if ( effect.getName().startsWith( p.b().replace("_", "") ) ) + { + particle = p; + if ( effect.getData() != null ) + { + if ( effect.getData().equals( org.bukkit.Material.class ) ) + { + extra = new int[]{ id }; + } else + { + extra = new int[]{ (data << 12) | (id & 0xFFF) }; + } + } + break; + } + } + if ( extra == null ) + { + extra = new int[0]; + } + packet = new PacketPlayOutWorldParticles( particle, true, (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount, extra ); + } + int distance; + radius *= radius; + for ( Player player : getPlayers() ) + { + if ( ( (CraftPlayer) player ).getHandle().playerConnection == null ) + { + continue; + } + if ( !location.getWorld().equals( player.getWorld() ) ) + { + continue; + } + distance = (int) player.getLocation().distanceSquared( location ); + if ( distance <= radius ) + { + ( (CraftPlayer) player ).getHandle().playerConnection.sendPacket( packet ); + } + } + } + + @Override + public void playEffect( Location location, Effect effect ) + { + CraftWorld.this.playEffect( location, effect, 0 ); + } + + @Override + public LightningStrike strikeLightning(Location loc, boolean isSilent) + { + EntityLightning lightning = new EntityLightning( world, loc.getX(), loc.getY(), loc.getZ(), false, isSilent ); + world.strikeLightning( lightning ); + return new CraftLightningStrike( server, lightning ); + } + + @Override + public LightningStrike strikeLightningEffect(Location loc, boolean isSilent) + { + EntityLightning lightning = new EntityLightning( world, loc.getX(), loc.getY(), loc.getZ(), true, isSilent ); + world.strikeLightning( lightning ); + return new CraftLightningStrike( server, lightning ); + } + }; + + public Spigot spigot() + { + return spigot; + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorldBorder.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorldBorder.java new file mode 100644 index 0000000..e5395a1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/CraftWorldBorder.java @@ -0,0 +1,111 @@ +package org.bukkit.craftbukkit; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.WorldBorder; + +public class CraftWorldBorder implements WorldBorder { + + private final World world; + private final net.minecraft.server.WorldBorder handle; + + public CraftWorldBorder(CraftWorld world) { + this.world = world; + this.handle = world.getHandle().getWorldBorder(); + } + + @Override + public void reset() { + this.setSize(6.0E7D); + this.setDamageAmount(0.2D); + this.setDamageBuffer(5.0D); + this.setWarningDistance(5); + this.setWarningTime(15); + this.setCenter(0, 0); + } + + @Override + public double getSize() { + return this.handle.getSize(); + } + + @Override + public void setSize(double newSize) { + this.setSize(newSize, 0L); + } + + @Override + public void setSize(double newSize, long time) { + // PAIL: TODO: Magic Values + newSize = Math.min(6.0E7D, Math.max(1.0D, newSize)); + time = Math.min(9223372036854775L, Math.max(0L, time)); + + if (time > 0L) { + this.handle.transitionSizeBetween(this.handle.getSize(), newSize, time * 1000L); + } else { + this.handle.setSize(newSize); + } + } + + @Override + public Location getCenter() { + double x = this.handle.getCenterX(); + double z = this.handle.getCenterZ(); + + return new Location(this.world, x, 0, z); + } + + @Override + public void setCenter(double x, double z) { + // PAIL: TODO: Magic Values + x = Math.min(3.0E7D, Math.max(-3.0E7D, x)); + z = Math.min(3.0E7D, Math.max(-3.0E7D, z)); + + this.handle.setCenter(x, z); + } + + @Override + public void setCenter(Location location) { + this.setCenter(location.getX(), location.getZ()); + } + + @Override + public double getDamageBuffer() { + return this.handle.getDamageBuffer(); + } + + @Override + public void setDamageBuffer(double blocks) { + this.handle.setDamageBuffer(blocks); + } + + @Override + public double getDamageAmount() { + return this.handle.getDamageAmount(); + } + + @Override + public void setDamageAmount(double damage) { + this.handle.setDamageAmount(damage); + } + + @Override + public int getWarningTime() { + return this.handle.getWarningTime(); + } + + @Override + public void setWarningTime(int time) { + this.handle.setWarningTime(time); + } + + @Override + public int getWarningDistance() { + return this.handle.getWarningDistance(); + } + + @Override + public void setWarningDistance(int distance) { + this.handle.setWarningDistance(distance); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java new file mode 100644 index 0000000..93526ab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java @@ -0,0 +1,31 @@ +package org.bukkit.craftbukkit; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.Logger; + +public class LoggerOutputStream extends ByteArrayOutputStream { + private final String separator = System.getProperty("line.separator"); + private final Logger logger; + private final Level level; + + public LoggerOutputStream(Logger logger, Level level) { + super(); + this.logger = logger; + this.level = level; + } + + @Override + public void flush() throws IOException { + synchronized (this) { + super.flush(); + String record = this.toString(); + super.reset(); + + if ((record.length() > 0) && (!record.equals(separator))) { + logger.log(level, record); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/Main.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/Main.java new file mode 100644 index 0000000..a5bbd8b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/Main.java @@ -0,0 +1,230 @@ +package org.bukkit.craftbukkit; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import net.minecraft.server.MinecraftServer; + +import org.apache.commons.lang3.JavaVersion; +import org.apache.commons.lang3.SystemUtils; +import org.fusesource.jansi.AnsiConsole; + +public class Main { + public static boolean useJline = true; + public static boolean useConsole = true; + + public static void main(String[] args) { + if (!SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_1_8)) { + System.err.println("TacoSpigot requires java 8"); + System.err.println("Oracle dropped all support for java " + SystemUtils.JAVA_VERSION); + System.err.println("Please update to use TacoSpigot and the numerous bug-fixes, performance improvements, and security fixes"); + System.err.println("Shutting down"); + System.exit(1); + } + // Todo: Installation script + OptionParser parser = new OptionParser() { + { + acceptsAll(asList("?", "help"), "Show the help"); + + acceptsAll(asList("c", "config"), "Properties file to use") + .withRequiredArg() + .ofType(File.class) + .defaultsTo(new File("server.properties")) + .describedAs("Properties file"); + + acceptsAll(asList("P", "plugins"), "Plugin directory to use") + .withRequiredArg() + .ofType(File.class) + .defaultsTo(new File("plugins")) + .describedAs("Plugin directory"); + + acceptsAll(asList("h", "host", "server-ip"), "Host to listen on") + .withRequiredArg() + .ofType(String.class) + .describedAs("Hostname or IP"); + + acceptsAll(asList("W", "world-dir", "universe", "world-container"), "World container") + .withRequiredArg() + .ofType(File.class) + .describedAs("Directory containing worlds"); + + acceptsAll(asList("w", "world", "level-name"), "World name") + .withRequiredArg() + .ofType(String.class) + .describedAs("World name"); + + acceptsAll(asList("p", "port", "server-port"), "Port to listen on") + .withRequiredArg() + .ofType(Integer.class) + .describedAs("Port"); + + acceptsAll(asList("o", "online-mode"), "Whether to use online authentication") + .withRequiredArg() + .ofType(Boolean.class) + .describedAs("Authentication"); + + acceptsAll(asList("s", "size", "max-players"), "Maximum amount of players") + .withRequiredArg() + .ofType(Integer.class) + .describedAs("Server size"); + + acceptsAll(asList("d", "date-format"), "Format of the date to display in the console (for log entries)") + .withRequiredArg() + .ofType(SimpleDateFormat.class) + .describedAs("Log date format"); + + acceptsAll(asList("log-pattern"), "Specfies the log filename pattern") + .withRequiredArg() + .ofType(String.class) + .defaultsTo("server.log") + .describedAs("Log filename"); + + acceptsAll(asList("log-limit"), "Limits the maximum size of the log file (0 = unlimited)") + .withRequiredArg() + .ofType(Integer.class) + .defaultsTo(0) + .describedAs("Max log size"); + + acceptsAll(asList("log-count"), "Specified how many log files to cycle through") + .withRequiredArg() + .ofType(Integer.class) + .defaultsTo(1) + .describedAs("Log count"); + + acceptsAll(asList("log-append"), "Whether to append to the log file") + .withRequiredArg() + .ofType(Boolean.class) + .defaultsTo(true) + .describedAs("Log append"); + + acceptsAll(asList("log-strip-color"), "Strips color codes from log file"); + + acceptsAll(asList("b", "bukkit-settings"), "File for bukkit settings") + .withRequiredArg() + .ofType(File.class) + .defaultsTo(new File("bukkit.yml")) + .describedAs("Yml file"); + + acceptsAll(asList("C", "commands-settings"), "File for command settings") + .withRequiredArg() + .ofType(File.class) + .defaultsTo(new File("commands.yml")) + .describedAs("Yml file"); + + acceptsAll(asList("nojline"), "Disables jline and emulates the vanilla console"); + + acceptsAll(asList("noconsole"), "Disables the console"); + + acceptsAll(asList("v", "version"), "Show the CraftBukkit Version"); + + acceptsAll(asList("demo"), "Demo mode"); + + // Spigot Start + acceptsAll(asList("S", "spigot-settings"), "File for spigot settings") + .withRequiredArg() + .ofType(File.class) + .defaultsTo(new File("spigot.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 + } + }; + + OptionSet options = null; + + try { + options = parser.parse(args); + } catch (joptsimple.OptionException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage()); + } + + if ((options == null) || (options.has("?"))) { + try { + parser.printHelpOn(System.out); + } catch (IOException ex) { + Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + } + } else if (options.has("v")) { + System.out.println(CraftServer.class.getPackage().getImplementationVersion()); + } else { + // Do you love Java using + and ! as string based identifiers? I sure do! + String path = new File(".").getAbsolutePath(); + if (path.contains("!") || path.contains("+")) { + System.err.println("Cannot run server in a directory with ! or + in the pathname. Please rename the affected folders and try again."); + return; + } + + try { + // This trick bypasses Maven Shade's clever rewriting of our getProperty call when using String literals + String jline_UnsupportedTerminal = new String(new char[] {'j','l','i','n','e','.','U','n','s','u','p','p','o','r','t','e','d','T','e','r','m','i','n','a','l'}); + String jline_terminal = new String(new char[] {'j','l','i','n','e','.','t','e','r','m','i','n','a','l'}); + + useJline = !(jline_UnsupportedTerminal).equals(System.getProperty(jline_terminal)); + + if (options.has("nojline")) { + System.setProperty("user.language", "en"); + useJline = false; + } + + if (useJline) { + AnsiConsole.systemInstall(); + } else { + // This ensures the terminal literal will always match the jline implementation + System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName()); + } + + + if (options.has("noconsole")) { + useConsole = false; + } + + // Spigot Start + int maxPermGen = 0; // In kb + for ( String s : java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments() ) + { + if ( s.startsWith( "-XX:MaxPermSize" ) ) + { + maxPermGen = Integer.parseInt( s.replaceAll( "[^\\d]", "" ) ); + maxPermGen <<= 10 * ("kmg".indexOf( Character.toLowerCase( s.charAt( s.length() - 1 ) ) ) ); + } + } + if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 52 && maxPermGen < ( 128 << 10 ) ) // 128mb + { + System.out.println( "Warning, your max perm gen size is not set or less than 128mb. It is recommended you restart Java with the following argument: -XX:MaxPermSize=128M" ); + System.out.println( "Please see http://www.spigotmc.org/wiki/changing-permgen-size/ for more details and more in-depth instructions." ); + } + // Spigot End + 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..."); + MinecraftServer.main(options); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + + private static List asList(String... params) { + return Arrays.asList(params); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/Overridden.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/Overridden.java new file mode 100644 index 0000000..1c19c69 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/Overridden.java @@ -0,0 +1,14 @@ +package org.bukkit.craftbukkit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates a method needs to be overridden in sub classes + */ +@Target({ElementType.CONSTRUCTOR, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Overridden { +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/TrigMath.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/TrigMath.java new file mode 100644 index 0000000..6d613c5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/TrigMath.java @@ -0,0 +1,47 @@ +package org.bukkit.craftbukkit; + +/** + * Credits for this class goes to user aioobe on stackoverflow.com + * Source: http://stackoverflow.com/questions/4454630/j2me-calculate-the-the-distance-between-2-latitude-and-longitude + */ +public class TrigMath { + + static final double sq2p1 = 2.414213562373095048802e0; + static final double sq2m1 = .414213562373095048802e0; + static final double p4 = .161536412982230228262e2; + static final double p3 = .26842548195503973794141e3; + static final double p2 = .11530293515404850115428136e4; + static final double p1 = .178040631643319697105464587e4; + static final double p0 = .89678597403663861959987488e3; + static final double q4 = .5895697050844462222791e2; + static final double q3 = .536265374031215315104235e3; + static final double q2 = .16667838148816337184521798e4; + static final double q1 = .207933497444540981287275926e4; + static final double q0 = .89678597403663861962481162e3; + static final double PIO2 = 1.5707963267948966135E0; + + private static double mxatan(double arg) { + double argsq = arg * arg, value; + + value = ((((p4 * argsq + p3) * argsq + p2) * argsq + p1) * argsq + p0); + value = value / (((((argsq + q4) * argsq + q3) * argsq + q2) * argsq + q1) * argsq + q0); + return value * arg; + } + + private static double msatan(double arg) { + return arg < sq2m1 ? mxatan(arg) + : arg > sq2p1 ? PIO2 - mxatan(1 / arg) + : PIO2 / 2 + mxatan((arg - 1) / (arg + 1)); + } + + public static double atan(double arg) { + return arg > 0 ? msatan(arg) : -msatan(-arg); + } + + public static double atan2(double arg1, double arg2) { + if (arg1 + arg2 == arg1) + return arg1 >= 0 ? PIO2 : -PIO2; + arg1 = atan(arg1 / arg2); + return arg2 < 0 ? arg1 <= 0 ? arg1 + Math.PI : arg1 - Math.PI : arg1; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java new file mode 100644 index 0000000..f233b7a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBanner.java @@ -0,0 +1,120 @@ +package org.bukkit.craftbukkit.block; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; +import net.minecraft.server.TileEntityBanner; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.block.Banner; +import org.bukkit.block.Block; +import org.bukkit.block.banner.Pattern; +import org.bukkit.block.banner.PatternType; +import org.bukkit.craftbukkit.CraftWorld; + +public class CraftBanner extends CraftBlockState implements Banner { + + private final TileEntityBanner banner; + private DyeColor base; + private List patterns = new ArrayList(); + + public CraftBanner(final Block block) { + super(block); + + CraftWorld world = (CraftWorld) block.getWorld(); + banner = (TileEntityBanner) world.getTileEntityAt(getX(), getY(), getZ()); + + base = DyeColor.getByDyeData((byte) banner.color); + + if (banner.patterns != null) { + for (int i = 0; i < banner.patterns.size(); i++) { + NBTTagCompound p = (NBTTagCompound) banner.patterns.get(i); + patterns.add(new Pattern(DyeColor.getByDyeData((byte) p.getInt("Color")), PatternType.getByIdentifier(p.getString("Pattern")))); + } + } + } + + public CraftBanner(final Material material, final TileEntityBanner te) { + super(material); + banner = te; + + base = DyeColor.getByDyeData((byte) banner.color); + + if (banner.patterns != null) { + for (int i = 0; i < banner.patterns.size(); i++) { + NBTTagCompound p = (NBTTagCompound) banner.patterns.get(i); + patterns.add(new Pattern(DyeColor.getByDyeData((byte) p.getInt("Color")), PatternType.getByIdentifier(p.getString("Pattern")))); + } + } + } + + @Override + public DyeColor getBaseColor() { + return this.base; + } + + @Override + public void setBaseColor(DyeColor color) { + this.base = color; + } + + @Override + public List getPatterns() { + return new ArrayList(patterns); + } + + @Override + public void setPatterns(List patterns) { + this.patterns = new ArrayList(patterns); + } + + @Override + public void addPattern(Pattern pattern) { + this.patterns.add(pattern); + } + + @Override + public Pattern getPattern(int i) { + return this.patterns.get(i); + } + + @Override + public Pattern removePattern(int i) { + return this.patterns.remove(i); + } + + @Override + public void setPattern(int i, Pattern pattern) { + this.patterns.set(i, pattern); + } + + @Override + public int numberOfPatterns() { + return patterns.size(); + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + banner.color = base.getDyeData(); + + NBTTagList newPatterns = new NBTTagList(); + + for (Pattern p : patterns) { + NBTTagCompound compound = new NBTTagCompound(); + compound.setInt("Color", p.getColor().getDyeData()); + compound.setString("Pattern", p.getPattern().getIdentifier()); + newPatterns.add(compound); + } + + banner.patterns = newPatterns; + + banner.update(); + } + + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java new file mode 100644 index 0000000..632b22d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java @@ -0,0 +1,49 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityBeacon; +import org.bukkit.Material; + +import org.bukkit.block.Block; +import org.bukkit.block.Beacon; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftInventoryBeacon; +import org.bukkit.inventory.Inventory; + +public class CraftBeacon extends CraftBlockState implements Beacon { + private final CraftWorld world; + private final TileEntityBeacon beacon; + + public CraftBeacon(final Block block) { + super(block); + + world = (CraftWorld) block.getWorld(); + beacon = (TileEntityBeacon) world.getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftBeacon(final Material material, final TileEntityBeacon te) { + super(material); + world = null; + beacon = te; + } + + public Inventory getInventory() { + return new CraftInventoryBeacon(beacon); + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + beacon.update(); + } + + return result; + } + + @Override + public TileEntityBeacon getTileEntity() { + return beacon; + } +} + diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java new file mode 100644 index 0000000..ea0e6ad --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -0,0 +1,559 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.*; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.*; +import org.bukkit.craftbukkit.CraftChunk; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.Plugin; +import org.bukkit.util.BlockVector; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class CraftBlock implements Block { + private final CraftChunk chunk; + private final int x; + private final int y; + private final int z; + private static final Biome[] BIOME_MAPPING; + private static final BiomeBase[] BIOMEBASE_MAPPING; + + public CraftBlock(CraftChunk chunk, int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + this.chunk = chunk; + } + + private net.minecraft.server.Block getNMSBlock() { + return CraftMagicNumbers.getBlock(this); // TODO: UPDATE THIS + } + + private static net.minecraft.server.Block getNMSBlock(int type) { + return CraftMagicNumbers.getBlock(type); + } + + public World getWorld() { + return chunk.getWorld(); + } + + public Location getLocation() { + return new Location(getWorld(), x, y, z); + } + + public Location getLocation(Location loc) { + if (loc != null) { + loc.setWorld(getWorld()); + loc.setX(x); + loc.setY(y); + loc.setZ(z); + loc.setYaw(0); + loc.setPitch(0); + } + + return loc; + } + + public BlockVector getVector() { + return new BlockVector(x, y, z); + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getZ() { + return z; + } + + public Chunk getChunk() { + return chunk; + } + + public void setData(final byte data) { + setData(data, 3); + } + + public void setData(final byte data, boolean applyPhysics) { + if (applyPhysics) { + setData(data, 3); + } else { + setData(data, 2); + } + } + + private void setData(final byte data, int flag) { + net.minecraft.server.World world = chunk.getHandle().getWorld(); + BlockPosition position = new BlockPosition(x, y, z); + IBlockData blockData = world.getType(position); + world.setTypeAndData(position, blockData.getBlock().fromLegacyData(data), flag); + } + + public byte getData() { + IBlockData blockData = chunk.getHandle().getBlockData(new BlockPosition(x, y, z)); + return (byte) blockData.getBlock().toLegacyData(blockData); + } + + public void setType(final Material type) { + setType(type, true); + } + + @Override + public void setType(Material type, boolean applyPhysics) { + setTypeId(type.getId(), applyPhysics); + } + + public boolean setTypeId(final int type) { + return setTypeId(type, true); + } + + public boolean setTypeId(final int type, final boolean applyPhysics) { + net.minecraft.server.Block block = getNMSBlock(type); + return setTypeIdAndData(type, (byte) block.toLegacyData(block.getBlockData()), applyPhysics); + } + + public boolean setTypeIdAndData(final int type, final byte data, final boolean applyPhysics) { + IBlockData blockData = getNMSBlock(type).fromLegacyData(data); + BlockPosition position = new BlockPosition(x, y, z); + if (applyPhysics) { + return chunk.getHandle().getWorld().setTypeAndData(position, blockData, 3); + } else { + boolean success = chunk.getHandle().getWorld().setTypeAndData(position, blockData, 2); + if (success) { + chunk.getHandle().getWorld().notify(position); + } + return success; + } + } + + public Material getType() { + return Material.getMaterial(getTypeId()); + } + + @Deprecated + @Override + public int getTypeId() { + return CraftMagicNumbers.getId(chunk.getHandle().getTypeNew(this.x, this.y, this.z)); + } + + public byte getLightLevel() { + return (byte) chunk.getHandle().getWorld().getLightLevel(this.x, this.y, this.z); + } + + public byte getLightFromSky() { + return (byte) chunk.getHandle().getBrightness(EnumSkyBlock.SKY, new BlockPosition(this.x, this.y, this.z)); + } + + public byte getLightFromBlocks() { + return (byte) chunk.getHandle().getBrightness(EnumSkyBlock.BLOCK, new BlockPosition(this.x, this.y, this.z)); + } + + + public Block getFace(final BlockFace face) { + return getRelative(face, 1); + } + + public Block getFace(final BlockFace face, final int distance) { + return getRelative(face, distance); + } + + public Block getRelative(final int modX, final int modY, final int modZ) { + return getWorld().getBlockAt(getX() + modX, getY() + modY, getZ() + modZ); + } + + public Block getRelative(BlockFace face) { + return getRelative(face, 1); + } + + public Block getRelative(BlockFace face, int distance) { + return getRelative(face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance); + } + + public BlockFace getFace(final Block block) { + BlockFace[] values = BlockFace.values(); + + for (BlockFace face : values) { + if ((this.getX() + face.getModX() == block.getX()) && + (this.getY() + face.getModY() == block.getY()) && + (this.getZ() + face.getModZ() == block.getZ()) + ) { + return face; + } + } + + return null; + } + + @Override + public String toString() { + return "CraftBlock{" + "chunk=" + chunk + ",x=" + x + ",y=" + y + ",z=" + z + ",type=" + getType() + ",data=" + getData() + '}'; + } + + public static BlockFace notchToBlockFace(EnumDirection notch) { + if (notch == null) return BlockFace.SELF; + switch (notch) { + case DOWN: + return BlockFace.DOWN; + case UP: + return BlockFace.UP; + case NORTH: + return BlockFace.NORTH; + case SOUTH: + return BlockFace.SOUTH; + case WEST: + return BlockFace.WEST; + case EAST: + return BlockFace.EAST; + default: + return BlockFace.SELF; + } + } + + public static EnumDirection blockFaceToNotch(BlockFace face) { + switch (face) { + case DOWN: + return EnumDirection.DOWN; + case UP: + return EnumDirection.UP; + case NORTH: + return EnumDirection.NORTH; + case SOUTH: + return EnumDirection.SOUTH; + case WEST: + return EnumDirection.WEST; + case EAST: + return EnumDirection.EAST; + default: + return null; + } + } + + public BlockState getState() { + Material material = getType(); + + switch (material) { + case SIGN: + case SIGN_POST: + case WALL_SIGN: + return new CraftSign(this); + case CHEST: + case TRAPPED_CHEST: + return new CraftChest(this); + case BURNING_FURNACE: + case FURNACE: + return new CraftFurnace(this); + case DISPENSER: + return new CraftDispenser(this); + case DROPPER: + return new CraftDropper(this); + case HOPPER: + return new CraftHopper(this); + case MOB_SPAWNER: + return new CraftCreatureSpawner(this); + case NOTE_BLOCK: + return new CraftNoteBlock(this); + case JUKEBOX: + return new CraftJukebox(this); + case BREWING_STAND: + return new CraftBrewingStand(this); + case SKULL: + return new CraftSkull(this); + case COMMAND: + return new CraftCommandBlock(this); + case BEACON: + return new CraftBeacon(this); + case BANNER: + case WALL_BANNER: + case STANDING_BANNER: + return new CraftBanner(this); + default: + return new CraftBlockState(this); + } + } + + public Biome getBiome() { + return getWorld().getBiome(x, z); + } + + public void setBiome(Biome bio) { + getWorld().setBiome(x, z, bio); + } + + public static Biome biomeBaseToBiome(BiomeBase base) { + if (base == null) { + return null; + } + + return BIOME_MAPPING[base.id]; + } + + public static BiomeBase biomeToBiomeBase(Biome bio) { + if (bio == null) { + return null; + } + return BIOMEBASE_MAPPING[bio.ordinal()]; + } + + public double getTemperature() { + return getWorld().getTemperature(x, z); + } + + public double getHumidity() { + return getWorld().getHumidity(x, z); + } + + public boolean isBlockPowered() { + return chunk.getHandle().getWorld().getBlockPower(new BlockPosition(x, y, z)) > 0; + } + + public boolean isBlockIndirectlyPowered() { + return chunk.getHandle().getWorld().isBlockIndirectlyPowered(new BlockPosition(x, y, z)); + } + + @Override + public boolean equals(Object o) { + if (o == this) return true; + if (!(o instanceof CraftBlock)) return false; + CraftBlock other = (CraftBlock) o; + + return this.x == other.x && this.y == other.y && this.z == other.z && this.getWorld().equals(other.getWorld()); + } + + @Override + public int hashCode() { + return this.y << 24 ^ this.x ^ this.z ^ this.getWorld().hashCode(); + } + + public boolean isBlockFacePowered(BlockFace face) { + return chunk.getHandle().getWorld().isBlockFacePowered(new BlockPosition(x, y, z), blockFaceToNotch(face)); + } + + public boolean isBlockFaceIndirectlyPowered(BlockFace face) { + int power = chunk.getHandle().getWorld().getBlockFacePower(new BlockPosition(x, y, z), blockFaceToNotch(face)); + + Block relative = getRelative(face); + if (relative.getType() == Material.REDSTONE_WIRE) { + return Math.max(power, relative.getData()) > 0; + } + + return power > 0; + } + + public int getBlockPower(BlockFace face) { + int power = 0; + BlockRedstoneWire wire = Blocks.REDSTONE_WIRE; + net.minecraft.server.World world = chunk.getHandle().getWorld(); + if ((face == BlockFace.DOWN || face == BlockFace.SELF) && world.isBlockFacePowered(new BlockPosition(x, y - 1, z), EnumDirection.DOWN)) power = wire.getPower(world, new BlockPosition(x, y - 1, z), power); + if ((face == BlockFace.UP || face == BlockFace.SELF) && world.isBlockFacePowered(new BlockPosition(x, y + 1, z), EnumDirection.UP)) power = wire.getPower(world, new BlockPosition(x, y + 1, z), power); + if ((face == BlockFace.EAST || face == BlockFace.SELF) && world.isBlockFacePowered(new BlockPosition(x + 1, y, z), EnumDirection.EAST)) power = wire.getPower(world, new BlockPosition(x + 1, y, z), power); + if ((face == BlockFace.WEST || face == BlockFace.SELF) && world.isBlockFacePowered(new BlockPosition(x - 1, y, z), EnumDirection.WEST)) power = wire.getPower(world, new BlockPosition(x - 1, y, z), power); + if ((face == BlockFace.NORTH || face == BlockFace.SELF) && world.isBlockFacePowered(new BlockPosition(x, y, z - 1), EnumDirection.NORTH)) power = wire.getPower(world, new BlockPosition(x, y, z - 1), power); + if ((face == BlockFace.SOUTH || face == BlockFace.SELF) && world.isBlockFacePowered(new BlockPosition(x, y, z + 1), EnumDirection.SOUTH)) power = wire.getPower(world, new BlockPosition(x, y, z - 1), power); + return power > 0 ? power : (face == BlockFace.SELF ? isBlockIndirectlyPowered() : isBlockFaceIndirectlyPowered(face)) ? 15 : 0; + } + + public int getBlockPower() { + return getBlockPower(BlockFace.SELF); + } + + public boolean isEmpty() { + return getType() == Material.AIR; + } + + public boolean isLiquid() { + return (getType() == Material.WATER) || (getType() == Material.STATIONARY_WATER) || (getType() == Material.LAVA) || (getType() == Material.STATIONARY_LAVA); + } + + public PistonMoveReaction getPistonMoveReaction() { + return PistonMoveReaction.getById(getNMSBlock().getMaterial().getPushReaction()); + } + + private boolean itemCausesDrops(ItemStack item) { + net.minecraft.server.Block block = this.getNMSBlock(); + net.minecraft.server.Item itemType = item != null ? net.minecraft.server.Item.getById(item.getTypeId()) : null; + return block != null && (block.getMaterial().isAlwaysDestroyable() || (itemType != null && itemType.canDestroySpecialBlock(block))); + } + + public boolean breakNaturally() { + // Order matters here, need to drop before setting to air so skulls can get their data + net.minecraft.server.Block block = this.getNMSBlock(); + byte data = getData(); + boolean result = false; + + if (block != null && block != Blocks.AIR) { + block.dropNaturally(chunk.getHandle().getWorld(), new BlockPosition(x, y, z), block.fromLegacyData(data), 1.0F, 0); + result = true; + } + + setTypeId(Material.AIR.getId()); + return result; + } + + public boolean breakNaturally(ItemStack item) { + if (itemCausesDrops(item)) { + return breakNaturally(); + } else { + return setTypeId(Material.AIR.getId()); + } + } + + public Collection getDrops() { + List drops = new ArrayList(); + + net.minecraft.server.Block block = this.getNMSBlock(); + if (block != Blocks.AIR) { + byte data = getData(); + // based on nms.Block.dropNaturally + int count = block.getDropCount(0, chunk.getHandle().getWorld().random); + for (int i = 0; i < count; ++i) { + Item item = block.getDropType(block.fromLegacyData(data), chunk.getHandle().getWorld().random, 0); + if (item != null) { + // Skulls are special, their data is based on the tile entity + if (Blocks.SKULL == block) { + net.minecraft.server.ItemStack nmsStack = new net.minecraft.server.ItemStack(item, 1, block.getDropData(chunk.getHandle().getWorld(), new BlockPosition(x, y, z))); + TileEntitySkull tileentityskull = (TileEntitySkull) chunk.getHandle().getWorld().getTileEntity(new BlockPosition(x, y, z)); + + if (tileentityskull.getSkullType() == 3 && tileentityskull.getGameProfile() != null) { + nmsStack.setTag(new NBTTagCompound()); + NBTTagCompound nbttagcompound = new NBTTagCompound(); + + GameProfileSerializer.serialize(nbttagcompound, tileentityskull.getGameProfile()); + nmsStack.getTag().set("SkullOwner", nbttagcompound); + } + + drops.add(CraftItemStack.asBukkitCopy(nmsStack)); + // We don't want to drop cocoa blocks, we want to drop cocoa beans. + } else if (Blocks.COCOA == block) { + int age = block.fromLegacyData(data).get(BlockCocoa.AGE); + int dropAmount = (age >= 2 ? 3 : 1); + for (int j = 0; j < dropAmount; ++j) { + drops.add(new ItemStack(Material.INK_SACK, 1, (short) 3)); + } + } else { + drops.add(new ItemStack(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(item), 1, (short) block.getDropData(block.fromLegacyData(data)))); + } + } + } + } + return drops; + } + + public Collection getDrops(ItemStack item) { + if (itemCausesDrops(item)) { + return getDrops(); + } else { + return Collections.emptyList(); + } + } + + /* Build biome index based lookup table for BiomeBase to Biome mapping */ + static { + BIOME_MAPPING = new Biome[BiomeBase.getBiomes().length]; + BIOMEBASE_MAPPING = new BiomeBase[Biome.values().length]; + BIOME_MAPPING[BiomeBase.OCEAN.id] = Biome.OCEAN; + BIOME_MAPPING[BiomeBase.PLAINS.id] = Biome.PLAINS; + BIOME_MAPPING[BiomeBase.DESERT.id] = Biome.DESERT; + BIOME_MAPPING[BiomeBase.EXTREME_HILLS.id] = Biome.EXTREME_HILLS; + BIOME_MAPPING[BiomeBase.FOREST.id] = Biome.FOREST; + BIOME_MAPPING[BiomeBase.TAIGA.id] = Biome.TAIGA; + BIOME_MAPPING[BiomeBase.SWAMPLAND.id] = Biome.SWAMPLAND; + BIOME_MAPPING[BiomeBase.RIVER.id] = Biome.RIVER; + BIOME_MAPPING[BiomeBase.HELL.id] = Biome.HELL; + BIOME_MAPPING[BiomeBase.SKY.id] = Biome.SKY; + BIOME_MAPPING[BiomeBase.FROZEN_OCEAN.id] = Biome.FROZEN_OCEAN; + BIOME_MAPPING[BiomeBase.FROZEN_RIVER.id] = Biome.FROZEN_RIVER; + BIOME_MAPPING[BiomeBase.ICE_PLAINS.id] = Biome.ICE_PLAINS; + BIOME_MAPPING[BiomeBase.ICE_MOUNTAINS.id] = Biome.ICE_MOUNTAINS; + BIOME_MAPPING[BiomeBase.MUSHROOM_ISLAND.id] = Biome.MUSHROOM_ISLAND; + BIOME_MAPPING[BiomeBase.MUSHROOM_SHORE.id] = Biome.MUSHROOM_SHORE; + BIOME_MAPPING[BiomeBase.BEACH.id] = Biome.BEACH; + BIOME_MAPPING[BiomeBase.DESERT_HILLS.id] = Biome.DESERT_HILLS; + BIOME_MAPPING[BiomeBase.FOREST_HILLS.id] = Biome.FOREST_HILLS; + BIOME_MAPPING[BiomeBase.TAIGA_HILLS.id] = Biome.TAIGA_HILLS; + BIOME_MAPPING[BiomeBase.SMALL_MOUNTAINS.id] = Biome.SMALL_MOUNTAINS; + BIOME_MAPPING[BiomeBase.JUNGLE.id] = Biome.JUNGLE; + BIOME_MAPPING[BiomeBase.JUNGLE_HILLS.id] = Biome.JUNGLE_HILLS; + BIOME_MAPPING[BiomeBase.JUNGLE_EDGE.id] = Biome.JUNGLE_EDGE; + BIOME_MAPPING[BiomeBase.DEEP_OCEAN.id] = Biome.DEEP_OCEAN; + BIOME_MAPPING[BiomeBase.STONE_BEACH.id] = Biome.STONE_BEACH; + BIOME_MAPPING[BiomeBase.COLD_BEACH.id] = Biome.COLD_BEACH; + BIOME_MAPPING[BiomeBase.BIRCH_FOREST.id] = Biome.BIRCH_FOREST; + BIOME_MAPPING[BiomeBase.BIRCH_FOREST_HILLS.id] = Biome.BIRCH_FOREST_HILLS; + BIOME_MAPPING[BiomeBase.ROOFED_FOREST.id] = Biome.ROOFED_FOREST; + BIOME_MAPPING[BiomeBase.COLD_TAIGA.id] = Biome.COLD_TAIGA; + BIOME_MAPPING[BiomeBase.COLD_TAIGA_HILLS.id] = Biome.COLD_TAIGA_HILLS; + BIOME_MAPPING[BiomeBase.MEGA_TAIGA.id] = Biome.MEGA_TAIGA; + BIOME_MAPPING[BiomeBase.MEGA_TAIGA_HILLS.id] = Biome.MEGA_TAIGA_HILLS; + BIOME_MAPPING[BiomeBase.EXTREME_HILLS_PLUS.id] = Biome.EXTREME_HILLS_PLUS; + BIOME_MAPPING[BiomeBase.SAVANNA.id] = Biome.SAVANNA; + BIOME_MAPPING[BiomeBase.SAVANNA_PLATEAU.id] = Biome.SAVANNA_PLATEAU; + BIOME_MAPPING[BiomeBase.MESA.id] = Biome.MESA; + BIOME_MAPPING[BiomeBase.MESA_PLATEAU_F.id] = Biome.MESA_PLATEAU_FOREST; + BIOME_MAPPING[BiomeBase.MESA_PLATEAU.id] = Biome.MESA_PLATEAU; + + // Extended Biomes + BIOME_MAPPING[BiomeBase.PLAINS.id + 128] = Biome.SUNFLOWER_PLAINS; + BIOME_MAPPING[BiomeBase.DESERT.id + 128] = Biome.DESERT_MOUNTAINS; + BIOME_MAPPING[BiomeBase.FOREST.id + 128] = Biome.FLOWER_FOREST; + BIOME_MAPPING[BiomeBase.TAIGA.id + 128] = Biome.TAIGA_MOUNTAINS; + BIOME_MAPPING[BiomeBase.SWAMPLAND.id + 128] = Biome.SWAMPLAND_MOUNTAINS; + BIOME_MAPPING[BiomeBase.ICE_PLAINS.id + 128] = Biome.ICE_PLAINS_SPIKES; + BIOME_MAPPING[BiomeBase.JUNGLE.id + 128] = Biome.JUNGLE_MOUNTAINS; + BIOME_MAPPING[BiomeBase.JUNGLE_EDGE.id + 128] = Biome.JUNGLE_EDGE_MOUNTAINS; + BIOME_MAPPING[BiomeBase.COLD_TAIGA.id + 128] = Biome.COLD_TAIGA_MOUNTAINS; + BIOME_MAPPING[BiomeBase.SAVANNA.id + 128] = Biome.SAVANNA_MOUNTAINS; + BIOME_MAPPING[BiomeBase.SAVANNA_PLATEAU.id + 128] = Biome.SAVANNA_PLATEAU_MOUNTAINS; + BIOME_MAPPING[BiomeBase.MESA.id + 128] = Biome.MESA_BRYCE; + BIOME_MAPPING[BiomeBase.MESA_PLATEAU_F.id + 128] = Biome.MESA_PLATEAU_FOREST_MOUNTAINS; + BIOME_MAPPING[BiomeBase.MESA_PLATEAU.id + 128] = Biome.MESA_PLATEAU_MOUNTAINS; + BIOME_MAPPING[BiomeBase.BIRCH_FOREST.id + 128] = Biome.BIRCH_FOREST_MOUNTAINS; + BIOME_MAPPING[BiomeBase.BIRCH_FOREST_HILLS.id + 128] = Biome.BIRCH_FOREST_HILLS_MOUNTAINS; + BIOME_MAPPING[BiomeBase.ROOFED_FOREST.id + 128] = Biome.ROOFED_FOREST_MOUNTAINS; + BIOME_MAPPING[BiomeBase.MEGA_TAIGA.id + 128] = Biome.MEGA_SPRUCE_TAIGA; + BIOME_MAPPING[BiomeBase.EXTREME_HILLS.id + 128] = Biome.EXTREME_HILLS_MOUNTAINS; + BIOME_MAPPING[BiomeBase.EXTREME_HILLS_PLUS.id + 128] = Biome.EXTREME_HILLS_PLUS_MOUNTAINS; + BIOME_MAPPING[BiomeBase.MEGA_TAIGA_HILLS.id + 128] = Biome.MEGA_SPRUCE_TAIGA_HILLS; + + /* Sanity check - we should have a record for each record in the BiomeBase.a table */ + /* Helps avoid missed biomes when we upgrade bukkit to new code with new biomes */ + for (int i = 0; i < BIOME_MAPPING.length; i++) { + if ((BiomeBase.getBiome(i) != null) && (BIOME_MAPPING[i] == null)) { + throw new IllegalArgumentException("Missing Biome mapping for BiomeBase[" + i + ", " + BiomeBase.getBiome(i) + "]"); + } + if (BIOME_MAPPING[i] != null) { /* Build reverse mapping for setBiome */ + BIOMEBASE_MAPPING[BIOME_MAPPING[i].ordinal()] = BiomeBase.getBiome(i); + } + } + } + + public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { + chunk.getCraftWorld().getBlockMetadata().setMetadata(this, metadataKey, newMetadataValue); + } + + public List getMetadata(String metadataKey) { + return chunk.getCraftWorld().getBlockMetadata().getMetadata(this, metadataKey); + } + + public boolean hasMetadata(String metadataKey) { + return chunk.getCraftWorld().getBlockMetadata().hasMetadata(this, metadataKey); + } + + public void removeMetadata(String metadataKey, Plugin owningPlugin) { + chunk.getCraftWorld().getBlockMetadata().removeMetadata(this, metadataKey, owningPlugin); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java new file mode 100644 index 0000000..4a8c814 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java @@ -0,0 +1,277 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.BlockPosition; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.CraftChunk; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.material.MaterialData; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.Plugin; + +import java.util.List; +import net.minecraft.server.TileEntity; + +public class CraftBlockState implements BlockState { + private final CraftWorld world; + private final CraftChunk chunk; + private final int x; + private final int y; + private final int z; + protected int type; + protected MaterialData data; + protected int flag; + protected final byte light; + + public CraftBlockState(final Block block) { + this.world = (CraftWorld) block.getWorld(); + this.x = block.getX(); + this.y = block.getY(); + this.z = block.getZ(); + this.type = block.getTypeId(); + this.light = block.getLightLevel(); + this.chunk = (CraftChunk) block.getChunk(); + this.flag = 3; + + createData(block.getData()); + } + + public CraftBlockState(final Block block, int flag) { + this(block); + this.flag = flag; + } + + public CraftBlockState(Material material) { + world = null; + type = material.getId(); + light = 0; + chunk = null; + x = y = z = 0; + } + + public static CraftBlockState getBlockState(net.minecraft.server.World world, int x, int y, int z) { + return new CraftBlockState(world.getWorld().getBlockAt(x, y, z)); + } + + public static CraftBlockState getBlockState(net.minecraft.server.World world, int x, int y, int z, int flag) { + return new CraftBlockState(world.getWorld().getBlockAt(x, y, z), flag); + } + + public World getWorld() { + requirePlaced(); + return world; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getZ() { + return z; + } + + public Chunk getChunk() { + requirePlaced(); + return chunk; + } + + public void setData(final MaterialData data) { + Material mat = getType(); + + if ((mat == null) || (mat.getData() == null)) { + this.data = data; + } else { + if ((data.getClass() == mat.getData()) || (data.getClass() == MaterialData.class)) { + this.data = data; + } else { + throw new IllegalArgumentException("Provided data is not of type " + + mat.getData().getName() + ", found " + data.getClass().getName()); + } + } + } + + public MaterialData getData() { + return data; + } + + public void setType(final Material type) { + setTypeId(type.getId()); + } + + public boolean setTypeId(final int type) { + if (this.type != type) { + this.type = type; + + createData((byte) 0); + } + return true; + } + + public Material getType() { + return Material.getMaterial(getTypeId()); + } + + public void setFlag(int flag) { + this.flag = flag; + } + + public int getFlag() { + return flag; + } + + public int getTypeId() { + return type; + } + + public byte getLightLevel() { + return light; + } + + public Block getBlock() { + requirePlaced(); + return world.getBlockAt(x, y, z); + } + + public boolean update() { + return update(false); + } + + public boolean update(boolean force) { + return update(force, true); + } + + public boolean update(boolean force, boolean applyPhysics) { + requirePlaced(); + Block block = getBlock(); + + if (block.getType() != getType()) { + if (!force) { + return false; + } + } + + block.setTypeIdAndData(getTypeId(), getRawData(), applyPhysics); + world.getHandle().notify(new BlockPosition(x, y, z)); + + return true; + } + + private void createData(final byte data) { + Material mat = getType(); + if (mat == null || mat.getData() == null) { + this.data = new MaterialData(type, data); + } else { + this.data = mat.getNewData(data); + } + } + + public byte getRawData() { + return data.getData(); + } + + public Location getLocation() { + return new Location(world, x, y, z); + } + + public Location getLocation(Location loc) { + if (loc != null) { + loc.setWorld(world); + loc.setX(x); + loc.setY(y); + loc.setZ(z); + loc.setYaw(0); + loc.setPitch(0); + } + + return loc; + } + + public void setRawData(byte data) { + this.data.setData(data); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final CraftBlockState other = (CraftBlockState) obj; + if (this.world != other.world && (this.world == null || !this.world.equals(other.world))) { + return false; + } + if (this.x != other.x) { + return false; + } + if (this.y != other.y) { + return false; + } + if (this.z != other.z) { + return false; + } + if (this.type != other.type) { + return false; + } + if (this.data != other.data && (this.data == null || !this.data.equals(other.data))) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 73 * hash + (this.world != null ? this.world.hashCode() : 0); + hash = 73 * hash + this.x; + hash = 73 * hash + this.y; + hash = 73 * hash + this.z; + hash = 73 * hash + this.type; + hash = 73 * hash + (this.data != null ? this.data.hashCode() : 0); + return hash; + } + + public TileEntity getTileEntity() { + return null; + } + + public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { + requirePlaced(); + chunk.getCraftWorld().getBlockMetadata().setMetadata(getBlock(), metadataKey, newMetadataValue); + } + + public List getMetadata(String metadataKey) { + requirePlaced(); + return chunk.getCraftWorld().getBlockMetadata().getMetadata(getBlock(), metadataKey); + } + + public boolean hasMetadata(String metadataKey) { + requirePlaced(); + return chunk.getCraftWorld().getBlockMetadata().hasMetadata(getBlock(), metadataKey); + } + + public void removeMetadata(String metadataKey, Plugin owningPlugin) { + requirePlaced(); + chunk.getCraftWorld().getBlockMetadata().removeMetadata(getBlock(), metadataKey, owningPlugin); + } + + @Override + public boolean isPlaced() { + return world != null; + } + + protected void requirePlaced() { + if (!isPlaced()) { + throw new IllegalStateException("The blockState must be placed to call this method"); + } + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java new file mode 100644 index 0000000..a910da2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java @@ -0,0 +1,52 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityBrewingStand; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BrewingStand; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer; +import org.bukkit.inventory.BrewerInventory; + +public class CraftBrewingStand extends CraftBlockState implements BrewingStand { + private final TileEntityBrewingStand brewingStand; + + public CraftBrewingStand(Block block) { + super(block); + + brewingStand = (TileEntityBrewingStand) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftBrewingStand(final Material material, final TileEntityBrewingStand te) { + super(material); + brewingStand = te; + } + + public BrewerInventory getInventory() { + return new CraftInventoryBrewer(brewingStand); + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + brewingStand.update(); + } + + return result; + } + + public int getBrewingTime() { + return brewingStand.brewTime; + } + + public void setBrewingTime(int brewTime) { + brewingStand.brewTime = brewTime; + } + + @Override + public TileEntityBrewingStand getTileEntity() { + return brewingStand; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java new file mode 100644 index 0000000..ce36ee4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java @@ -0,0 +1,87 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.TileEntityChest; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest; +import org.bukkit.inventory.Inventory; + +public class CraftChest extends CraftBlockState implements Chest { + private final CraftWorld world; + private final TileEntityChest chest; + + public CraftChest(final Block block) { + super(block); + + world = (CraftWorld) block.getWorld(); + chest = (TileEntityChest) world.getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftChest(final Material material, final TileEntityChest te) { + super(material); + chest = te; + world = null; + } + + public Inventory getBlockInventory() { + return new CraftInventory(chest); + } + + public Inventory getInventory() { + int x = getX(); + int y = getY(); + int z = getZ(); + // The logic here is basically identical to the logic in BlockChest.interact + CraftInventory inventory = new CraftInventory(chest); + if (!isPlaced()) { + return inventory; + } + int id; + if (world.getBlockTypeIdAt(x, y, z) == Material.CHEST.getId()) { + id = Material.CHEST.getId(); + } else if (world.getBlockTypeIdAt(x, y, z) == Material.TRAPPED_CHEST.getId()) { + id = Material.TRAPPED_CHEST.getId(); + } else { + throw new IllegalStateException("CraftChest is not a chest but is instead " + world.getBlockAt(x, y, z)); + } + + if (world.getBlockTypeIdAt(x - 1, y, z) == id) { + CraftInventory left = new CraftInventory((TileEntityChest)world.getHandle().getTileEntity(new BlockPosition(x - 1, y, z))); + inventory = new CraftInventoryDoubleChest(left, inventory); + } + if (world.getBlockTypeIdAt(x + 1, y, z) == id) { + CraftInventory right = new CraftInventory((TileEntityChest) world.getHandle().getTileEntity(new BlockPosition(x + 1, y, z))); + inventory = new CraftInventoryDoubleChest(inventory, right); + } + if (world.getBlockTypeIdAt(x, y, z - 1) == id) { + CraftInventory left = new CraftInventory((TileEntityChest) world.getHandle().getTileEntity(new BlockPosition(x, y, z - 1))); + inventory = new CraftInventoryDoubleChest(left, inventory); + } + if (world.getBlockTypeIdAt(x, y, z + 1) == id) { + CraftInventory right = new CraftInventory((TileEntityChest) world.getHandle().getTileEntity(new BlockPosition(x, y, z + 1))); + inventory = new CraftInventoryDoubleChest(inventory, right); + } + return inventory; + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + chest.update(); + } + + return result; + } + + @Override + public TileEntityChest getTileEntity() { + return chest; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java new file mode 100644 index 0000000..9bbc790 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java @@ -0,0 +1,61 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityCommand; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.CommandBlock; +import org.bukkit.craftbukkit.CraftWorld; + +public class CraftCommandBlock extends CraftBlockState implements CommandBlock { + private final TileEntityCommand commandBlock; + private String command; + private String name; + + public CraftCommandBlock(Block block) { + super(block); + + CraftWorld world = (CraftWorld) block.getWorld(); + commandBlock = (TileEntityCommand) world.getTileEntityAt(getX(), getY(), getZ()); + command = commandBlock.getCommandBlock().getCommand(); + name = commandBlock.getCommandBlock().getName(); + } + + public CraftCommandBlock(final Material material, final TileEntityCommand te) { + super(material); + commandBlock = te; + command = commandBlock.getCommandBlock().getCommand(); + name = commandBlock.getCommandBlock().getName(); + } + + public String getCommand() { + return command; + } + + public void setCommand(String command) { + this.command = command != null ? command : ""; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name != null ? name : "@"; + } + + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + commandBlock.getCommandBlock().setCommand(command); + commandBlock.getCommandBlock().setName(name); + } + + return result; + } + + @Override + public TileEntityCommand getTileEntity() { + return commandBlock; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java new file mode 100644 index 0000000..697cd91 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java @@ -0,0 +1,83 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityMobSpawner; +import org.bukkit.Material; + +import org.bukkit.block.Block; +import org.bukkit.block.CreatureSpawner; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.entity.CreatureType; +import org.bukkit.entity.EntityType; + +public class CraftCreatureSpawner extends CraftBlockState implements CreatureSpawner { + private final TileEntityMobSpawner spawner; + + public CraftCreatureSpawner(final Block block) { + super(block); + + spawner = (TileEntityMobSpawner) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftCreatureSpawner(final Material material, TileEntityMobSpawner te) { + super(material); + spawner = te; + } + + @Deprecated + public CreatureType getCreatureType() { + return CreatureType.fromName(spawner.getSpawner().getMobName()); + } + + public EntityType getSpawnedType() { + return EntityType.fromName(spawner.getSpawner().getMobName()); + } + + @Deprecated + public void setCreatureType(CreatureType creatureType) { + spawner.getSpawner().setMobName(creatureType.getName()); + } + + public void setSpawnedType(EntityType entityType) { + if (entityType == null || entityType.getName() == null) { + throw new IllegalArgumentException("Can't spawn EntityType " + entityType + " from mobspawners!"); + } + + spawner.getSpawner().setMobName(entityType.getName()); + } + + @Deprecated + public String getCreatureTypeId() { + return spawner.getSpawner().getMobName(); + } + + @Deprecated + public void setCreatureTypeId(String creatureName) { + setCreatureTypeByName(creatureName); + } + + public String getCreatureTypeName() { + return spawner.getSpawner().getMobName(); + } + + public void setCreatureTypeByName(String creatureType) { + // Verify input + EntityType type = EntityType.fromName(creatureType); + if (type == null) { + return; + } + setSpawnedType(type); + } + + public int getDelay() { + return spawner.getSpawner().spawnDelay; + } + + public void setDelay(int delay) { + spawner.getSpawner().spawnDelay = delay; + } + + @Override + public TileEntityMobSpawner getTileEntity() { + return spawner; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java new file mode 100644 index 0000000..a3ca3a5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java @@ -0,0 +1,76 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.BlockDispenser; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.Blocks; +import net.minecraft.server.TileEntityDispenser; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Dispenser; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource; +import org.bukkit.inventory.Inventory; +import org.bukkit.projectiles.BlockProjectileSource; + +public class CraftDispenser extends CraftBlockState implements Dispenser { + private final CraftWorld world; + private final TileEntityDispenser dispenser; + + public CraftDispenser(final Block block) { + super(block); + + world = (CraftWorld) block.getWorld(); + dispenser = (TileEntityDispenser) world.getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftDispenser(final Material material, final TileEntityDispenser te) { + super(material); + world = null; + dispenser = te; + } + + public Inventory getInventory() { + return new CraftInventory(dispenser); + } + + public BlockProjectileSource getBlockProjectileSource() { + Block block = getBlock(); + + if (block.getType() != Material.DISPENSER) { + return null; + } + + return new CraftBlockProjectileSource(dispenser); + } + + public boolean dispense() { + Block block = getBlock(); + + if (block.getType() == Material.DISPENSER) { + BlockDispenser dispense = (BlockDispenser) Blocks.DISPENSER; + + dispense.dispense(world.getHandle(), new BlockPosition(getX(), getY(), getZ())); + return true; + } else { + return false; + } + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + dispenser.update(); + } + + return result; + } + + @Override + public TileEntityDispenser getTileEntity() { + return dispenser; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java new file mode 100644 index 0000000..3f7f536 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java @@ -0,0 +1,61 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.BlockDropper; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.Blocks; +import net.minecraft.server.TileEntityDropper; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Dropper; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.inventory.Inventory; + +public class CraftDropper extends CraftBlockState implements Dropper { + private final CraftWorld world; + private final TileEntityDropper dropper; + + public CraftDropper(final Block block) { + super(block); + + world = (CraftWorld) block.getWorld(); + dropper = (TileEntityDropper) world.getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftDropper(final Material material, TileEntityDropper te) { + super(material); + world = null; + dropper = te; + } + + public Inventory getInventory() { + return new CraftInventory(dropper); + } + + public void drop() { + Block block = getBlock(); + + if (block.getType() == Material.DROPPER) { + BlockDropper drop = (BlockDropper) Blocks.DROPPER; + + drop.dispense(world.getHandle(), new BlockPosition(getX(), getY(), getZ())); + } + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + dropper.update(); + } + + return result; + } + + @Override + public TileEntityDropper getTileEntity() { + return dropper; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java new file mode 100644 index 0000000..e58aabc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java @@ -0,0 +1,60 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityFurnace; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Furnace; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace; +import org.bukkit.inventory.FurnaceInventory; + +public class CraftFurnace extends CraftBlockState implements Furnace { + private final TileEntityFurnace furnace; + + public CraftFurnace(final Block block) { + super(block); + + furnace = (TileEntityFurnace) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftFurnace(final Material material, final TileEntityFurnace te) { + super(material); + furnace = te; + } + + public FurnaceInventory getInventory() { + return new CraftInventoryFurnace(furnace); + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + furnace.update(); + } + + return result; + } + + public short getBurnTime() { + return (short) furnace.burnTime; + } + + public void setBurnTime(short burnTime) { + furnace.burnTime = burnTime; + } + + public short getCookTime() { + return (short) furnace.cookTime; + } + + public void setCookTime(short cookTime) { + furnace.cookTime = cookTime; + } + + @Override + public TileEntityFurnace getTileEntity() { + return furnace; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java new file mode 100644 index 0000000..db844a3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java @@ -0,0 +1,45 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.TileEntityHopper; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Hopper; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.inventory.Inventory; + +public class CraftHopper extends CraftBlockState implements Hopper { + private final TileEntityHopper hopper; + + public CraftHopper(final Block block) { + super(block); + + hopper = (TileEntityHopper) ((CraftWorld) block.getWorld()).getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftHopper(final Material material, final TileEntityHopper te) { + super(material); + + hopper = te; + } + + public Inventory getInventory() { + return new CraftInventory(hopper); + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + hopper.update(); + } + + return result; + } + + @Override + public TileEntityHopper getTileEntity() { + return hopper; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java new file mode 100644 index 0000000..ebe7a6d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java @@ -0,0 +1,77 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.*; +import net.minecraft.server.BlockJukeBox.TileEntityRecordPlayer; +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Jukebox; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; + +public class CraftJukebox extends CraftBlockState implements Jukebox { + private final CraftWorld world; + private final TileEntityRecordPlayer jukebox; + + public CraftJukebox(final Block block) { + super(block); + + world = (CraftWorld) block.getWorld(); + jukebox = (TileEntityRecordPlayer) world.getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftJukebox(final Material material, TileEntityRecordPlayer te) { + super(material); + world = null; + jukebox = te; + } + + @Override + public Material getPlaying() { + ItemStack record = jukebox.getRecord(); + if (record == null) { + return Material.AIR; + } + return CraftMagicNumbers.getMaterial(record.getItem()); + } + + @Override + public void setPlaying(Material record) { + if (record == null || CraftMagicNumbers.getItem(record) == null) { + record = Material.AIR; + jukebox.setRecord(null); + } else { + jukebox.setRecord(new ItemStack(CraftMagicNumbers.getItem(record), 1)); + } + if (!isPlaced()) { + return; + } + jukebox.update(); + if (record == Material.AIR) { + world.getHandle().setTypeAndData(new BlockPosition(getX(), getY(), getZ()), + Blocks.JUKEBOX.getBlockData() + .set(BlockJukeBox.HAS_RECORD, false), 3); + } else { + world.getHandle().setTypeAndData(new BlockPosition(getX(), getY(), getZ()), + Blocks.JUKEBOX.getBlockData() + .set(BlockJukeBox.HAS_RECORD, true), 3); + } + world.playEffect(getLocation(), Effect.RECORD_PLAY, record.getId()); + } + + public boolean isPlaying() { + return getRawData() == 1; + } + + public boolean eject() { + requirePlaced(); + boolean result = isPlaying(); + ((BlockJukeBox) Blocks.JUKEBOX).dropRecord(world.getHandle(), new BlockPosition(getX(), getY(), getZ()), null); + return result; + } + + @Override + public TileEntityRecordPlayer getTileEntity() { + return jukebox; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java new file mode 100644 index 0000000..0507f3b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java @@ -0,0 +1,86 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.TileEntityNote; + +import org.bukkit.Instrument; +import org.bukkit.Material; +import org.bukkit.Note; +import org.bukkit.block.Block; +import org.bukkit.block.NoteBlock; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; + +public class CraftNoteBlock extends CraftBlockState implements NoteBlock { + private final CraftWorld world; + private final TileEntityNote note; + + public CraftNoteBlock(final Block block) { + super(block); + + world = (CraftWorld) block.getWorld(); + note = (TileEntityNote) world.getTileEntityAt(getX(), getY(), getZ()); + } + + public CraftNoteBlock(final Material material, final TileEntityNote te) { + super(material); + world = null; + note = te; + } + + public Note getNote() { + return new Note(note.note); + } + + public byte getRawNote() { + return note.note; + } + + public void setNote(Note n) { + note.note = n.getId(); + } + + public void setRawNote(byte n) { + note.note = n; + } + + public boolean play() { + Block block = getBlock(); + + if (block.getType() == Material.NOTE_BLOCK) { + note.play(world.getHandle(), new BlockPosition(getX(), getY(), getZ())); + return true; + } else { + return false; + } + } + + @Override + public boolean play(byte instrument, byte note) { + Block block = getBlock(); + + if (block.getType() == Material.NOTE_BLOCK) { + world.getHandle().playBlockAction(new BlockPosition(getX(), getY(), getZ()), CraftMagicNumbers.getBlock(block), instrument, note); + return true; + } else { + return false; + } + } + + @Override + public boolean play(Instrument instrument, Note note) { + Block block = getBlock(); + + if (block.getType() == Material.NOTE_BLOCK) { + world.getHandle().playBlockAction(new BlockPosition(getX(), getY(), getZ()), CraftMagicNumbers.getBlock(block), instrument.getType(), note.getId()); + return true; + } else { + return false; + } + } + + @Override + public TileEntityNote getTileEntity() { + return note; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java new file mode 100644 index 0000000..43adfcc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java @@ -0,0 +1,93 @@ +package org.bukkit.craftbukkit.block; + +import net.minecraft.server.ChatComponentText; +import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.TileEntitySign; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.util.CraftChatMessage; + +public class CraftSign extends CraftBlockState implements Sign { + private final TileEntitySign sign; + private final String[] lines; + + public CraftSign(final Block block) { + super(block); + + CraftWorld world = (CraftWorld) block.getWorld(); + sign = (TileEntitySign) world.getTileEntityAt(getX(), getY(), getZ()); + // Spigot start + if (sign == null) { + lines = new String[]{"", "", "", ""}; + return; + } + // Spigot end + lines = new String[sign.lines.length]; + System.arraycopy(revertComponents(sign.lines), 0, lines, 0, lines.length); + } + + public CraftSign(final Material material, final TileEntitySign te) { + super(material); + sign = te; + lines = new String[sign.lines.length]; + System.arraycopy(revertComponents(sign.lines), 0, lines, 0, lines.length); + } + + public String[] getLines() { + return lines; + } + + public String getLine(int index) throws IndexOutOfBoundsException { + return lines[index]; + } + + public void setLine(int index, String line) throws IndexOutOfBoundsException { + lines[index] = line; + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + IChatBaseComponent[] newLines = sanitizeLines(lines); + System.arraycopy(newLines, 0, sign.lines, 0, 4); + sign.update(); + } + + return result; + } + + public static IChatBaseComponent[] sanitizeLines(String[] lines) { + IChatBaseComponent[] components = new IChatBaseComponent[4]; + + for (int i = 0; i < 4; i++) { + if (i < lines.length && lines[i] != null) { + components[i] = CraftChatMessage.fromString(lines[i])[0]; + } else { + components[i] = new ChatComponentText(""); + } + } + + return components; + } + + public static String[] revertComponents(IChatBaseComponent[] components) { + String[] lines = new String[components.length]; + for (int i = 0; i < lines.length; i++) { + lines[i] = revertComponent(components[i]); + } + return lines; + } + + private static String revertComponent(IChatBaseComponent component) { + return CraftChatMessage.fromComponent(component); + } + + @Override + public TileEntitySign getTileEntity() { + return sign; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java new file mode 100644 index 0000000..77f5dcc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java @@ -0,0 +1,217 @@ +package org.bukkit.craftbukkit.block; + +import com.mojang.authlib.GameProfile; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.TileEntitySkull; +import org.bukkit.Material; + +import org.bukkit.SkullType; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.Skull; +import org.bukkit.craftbukkit.CraftWorld; + +public class CraftSkull extends CraftBlockState implements Skull { + private static final int MAX_OWNER_LENGTH = 16; + private final TileEntitySkull skull; + private GameProfile profile; + private SkullType skullType; + private byte rotation; + + public CraftSkull(final Block block) { + super(block); + + CraftWorld world = (CraftWorld) block.getWorld(); + skull = (TileEntitySkull) world.getTileEntityAt(getX(), getY(), getZ()); + profile = skull.getGameProfile(); + skullType = getSkullType(skull.getSkullType()); + rotation = (byte) skull.getRotation(); + } + + public CraftSkull(final Material material, final TileEntitySkull te) { + super(material); + skull = te; + profile = skull.getGameProfile(); + skullType = getSkullType(skull.getSkullType()); + rotation = (byte) skull.getRotation(); + } + + static SkullType getSkullType(int id) { + switch (id) { + default: + case 0: + return SkullType.SKELETON; + case 1: + return SkullType.WITHER; + case 2: + return SkullType.ZOMBIE; + case 3: + return SkullType.PLAYER; + case 4: + return SkullType.CREEPER; + } + } + + static int getSkullType(SkullType type) { + switch(type) { + default: + case SKELETON: + return 0; + case WITHER: + return 1; + case ZOMBIE: + return 2; + case PLAYER: + return 3; + case CREEPER: + return 4; + } + } + + static byte getBlockFace(BlockFace rotation) { + switch (rotation) { + case NORTH: + return 0; + case NORTH_NORTH_EAST: + return 1; + case NORTH_EAST: + return 2; + case EAST_NORTH_EAST: + return 3; + case EAST: + return 4; + case EAST_SOUTH_EAST: + return 5; + case SOUTH_EAST: + return 6; + case SOUTH_SOUTH_EAST: + return 7; + case SOUTH: + return 8; + case SOUTH_SOUTH_WEST: + return 9; + case SOUTH_WEST: + return 10; + case WEST_SOUTH_WEST: + return 11; + case WEST: + return 12; + case WEST_NORTH_WEST: + return 13; + case NORTH_WEST: + return 14; + case NORTH_NORTH_WEST: + return 15; + default: + throw new IllegalArgumentException("Invalid BlockFace rotation: " + rotation); + } + } + + static BlockFace getBlockFace(byte rotation) { + switch (rotation) { + case 0: + return BlockFace.NORTH; + case 1: + return BlockFace.NORTH_NORTH_EAST; + case 2: + return BlockFace.NORTH_EAST; + case 3: + return BlockFace.EAST_NORTH_EAST; + case 4: + return BlockFace.EAST; + case 5: + return BlockFace.EAST_SOUTH_EAST; + case 6: + return BlockFace.SOUTH_EAST; + case 7: + return BlockFace.SOUTH_SOUTH_EAST; + case 8: + return BlockFace.SOUTH; + case 9: + return BlockFace.SOUTH_SOUTH_WEST; + case 10: + return BlockFace.SOUTH_WEST; + case 11: + return BlockFace.WEST_SOUTH_WEST; + case 12: + return BlockFace.WEST; + case 13: + return BlockFace.WEST_NORTH_WEST; + case 14: + return BlockFace.NORTH_WEST; + case 15: + return BlockFace.NORTH_NORTH_WEST; + default: + throw new AssertionError(rotation); + } + } + + public boolean hasOwner() { + return profile != null; + } + + public String getOwner() { + return hasOwner() ? profile.getName() : null; + } + + public boolean setOwner(String name) { + if (name == null || name.length() > MAX_OWNER_LENGTH) { + return false; + } + + GameProfile profile = MinecraftServer.getServer().getUserCache().getProfile(name); + if (profile == null) { + return false; + } + + if (skullType != SkullType.PLAYER) { + skullType = SkullType.PLAYER; + } + + this.profile = profile; + return true; + } + + public BlockFace getRotation() { + return getBlockFace(rotation); + } + + public void setRotation(BlockFace rotation) { + this.rotation = getBlockFace(rotation); + } + + public SkullType getSkullType() { + return skullType; + } + + public void setSkullType(SkullType skullType) { + this.skullType = skullType; + + if (skullType != SkullType.PLAYER) { + profile = null; + } + } + + @Override + public boolean update(boolean force, boolean applyPhysics) { + boolean result = super.update(force, applyPhysics); + + if (result) { + if (skullType == SkullType.PLAYER) { + skull.setGameProfile(profile); + } else { + skull.setSkullType(getSkullType(skullType)); + } + + skull.setRotation(rotation); + skull.update(); + } + + return result; + } + + @Override + public TileEntitySkull getTileEntity() { + return skull; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java new file mode 100644 index 0000000..69e5da4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOExecutor.java @@ -0,0 +1,36 @@ +package org.bukkit.craftbukkit.chunkio; + +import net.minecraft.server.Chunk; +import net.minecraft.server.ChunkProviderServer; +import net.minecraft.server.ChunkRegionLoader; +import net.minecraft.server.World; +import org.bukkit.craftbukkit.util.AsynchronousExecutor; + +public class ChunkIOExecutor { + static final int BASE_THREADS = 2; // PaperSpigot - Bumped value + static final int PLAYERS_PER_THREAD = 50; + + private static final AsynchronousExecutor instance = new AsynchronousExecutor(new ChunkIOProvider(), BASE_THREADS); + + public static Chunk syncChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z) { + return instance.getSkipQueue(new QueuedChunk(x, z, loader, world, provider)); + } + + public static void queueChunkLoad(World world, ChunkRegionLoader loader, ChunkProviderServer provider, int x, int z, Runnable runnable) { + instance.add(new QueuedChunk(x, z, loader, world, provider), runnable); + } + + // Abuses the fact that hashCode and equals for QueuedChunk only use world and coords + public static void dropQueuedChunkLoad(World world, int x, int z, Runnable runnable) { + instance.drop(new QueuedChunk(x, z, null, world, null), runnable); + } + + public static void adjustPoolSize(int players) { + int size = Math.max(BASE_THREADS, (int) Math.ceil(players / PLAYERS_PER_THREAD)); + instance.setActiveThreads(size); + } + + public static void tick() { + instance.finishActive(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java new file mode 100644 index 0000000..1178ad7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java @@ -0,0 +1,89 @@ +package org.bukkit.craftbukkit.chunkio; + +import java.io.IOException; +import net.minecraft.server.Chunk; +import net.minecraft.server.ChunkRegionLoader; +import net.minecraft.server.NBTTagCompound; + +import org.bukkit.Server; +import org.bukkit.craftbukkit.util.AsynchronousExecutor; +import org.bukkit.craftbukkit.util.LongHash; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.minecraft.server.Entity; +import net.minecraft.server.EntitySlice; + +class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider { + private final AtomicInteger threadNumber = new AtomicInteger(1); + + // async stuff + public Chunk callStage1(QueuedChunk queuedChunk) throws RuntimeException { + try { + ChunkRegionLoader loader = queuedChunk.loader; + Object[] data = loader.loadChunk(queuedChunk.world, queuedChunk.x, queuedChunk.z); + + if (data != null) { + queuedChunk.compound = (NBTTagCompound) data[1]; + return (Chunk) data[0]; + } + + return null; + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + // sync stuff + public void callStage2(QueuedChunk queuedChunk, Chunk chunk) throws RuntimeException { + if (chunk == null) { + // If the chunk loading failed just do it synchronously (may generate) + queuedChunk.provider.originalGetChunkAt(queuedChunk.x, queuedChunk.z); + return; + } + + queuedChunk.loader.loadEntities(chunk, queuedChunk.compound.getCompound("Level"), queuedChunk.world); + chunk.setLastSaved(queuedChunk.provider.world.getTime()); + queuedChunk.provider.chunks.put(LongHash.toLong(queuedChunk.x, queuedChunk.z), chunk); + chunk.addEntities(); + + if (queuedChunk.provider.chunkProvider != null) { + queuedChunk.provider.world.timings.syncChunkLoadStructuresTimer.startTiming(); // Spigot + queuedChunk.provider.chunkProvider.recreateStructures(chunk, queuedChunk.x, queuedChunk.z); + queuedChunk.provider.world.timings.syncChunkLoadStructuresTimer.stopTiming(); // Spigot + } + + Server server = queuedChunk.provider.world.getServer(); + if (server != null) { + server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, false)); + } + + // Update neighbor counts + for (int x = -2; x < 3; x++) { + for (int z = -2; z < 3; z++) { + if (x == 0 && z == 0) { + continue; + } + + Chunk neighbor = queuedChunk.provider.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z); + if (neighbor != null) { + neighbor.setNeighborLoaded(-x, -z); + chunk.setNeighborLoaded(x, z); + } + } + } + + chunk.loadNearby(queuedChunk.provider, queuedChunk.provider, queuedChunk.x, queuedChunk.z); + } + + public void callStage3(QueuedChunk queuedChunk, Chunk chunk, Runnable runnable) throws RuntimeException { + runnable.run(); + } + + public Thread newThread(Runnable runnable) { + Thread thread = new Thread(runnable, "Chunk I/O Executor Thread-" + threadNumber.getAndIncrement()); + thread.setDaemon(true); + return thread; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java new file mode 100644 index 0000000..842d424 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/chunkio/QueuedChunk.java @@ -0,0 +1,38 @@ +package org.bukkit.craftbukkit.chunkio; + +import net.minecraft.server.ChunkProviderServer; +import net.minecraft.server.ChunkRegionLoader; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.World; + +class QueuedChunk { + final int x; + final int z; + final ChunkRegionLoader loader; + final World world; + final ChunkProviderServer provider; + NBTTagCompound compound; + + public QueuedChunk(int x, int z, ChunkRegionLoader loader, World world, ChunkProviderServer provider) { + this.x = x; + this.z = z; + this.loader = loader; + this.world = world; + this.provider = provider; + } + + @Override + public int hashCode() { + return (x * 31 + z * 29) ^ world.hashCode(); + } + + @Override + public boolean equals(Object object) { + if (object instanceof QueuedChunk) { + QueuedChunk other = (QueuedChunk) object; + return x == other.x && z == other.z && world == other.world; + } + + return false; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java new file mode 100644 index 0000000..26a2fb8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java @@ -0,0 +1,74 @@ +package org.bukkit.craftbukkit.command; + +import java.util.EnumMap; +import java.util.Map; + +import org.fusesource.jansi.Ansi; +import org.fusesource.jansi.Ansi.Attribute; +import jline.Terminal; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.craftbukkit.CraftServer; + +public class ColouredConsoleSender extends CraftConsoleCommandSender { + private final Terminal terminal; + private final Map replacements = new EnumMap(ChatColor.class); + private final ChatColor[] colors = ChatColor.values(); + + protected ColouredConsoleSender() { + super(); + this.terminal = ((CraftServer) getServer()).getReader().getTerminal(); + + replacements.put(ChatColor.BLACK, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).boldOff().toString()); + replacements.put(ChatColor.DARK_BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).boldOff().toString()); + replacements.put(ChatColor.DARK_GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).boldOff().toString()); + replacements.put(ChatColor.DARK_AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).boldOff().toString()); + replacements.put(ChatColor.DARK_RED, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.RED).boldOff().toString()); + replacements.put(ChatColor.DARK_PURPLE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.MAGENTA).boldOff().toString()); + replacements.put(ChatColor.GOLD, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.YELLOW).boldOff().toString()); + replacements.put(ChatColor.GRAY, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.WHITE).boldOff().toString()); + replacements.put(ChatColor.DARK_GRAY, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLACK).bold().toString()); + replacements.put(ChatColor.BLUE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.BLUE).bold().toString()); + replacements.put(ChatColor.GREEN, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.GREEN).bold().toString()); + replacements.put(ChatColor.AQUA, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.CYAN).bold().toString()); + replacements.put(ChatColor.RED, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.RED).bold().toString()); + replacements.put(ChatColor.LIGHT_PURPLE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.MAGENTA).bold().toString()); + replacements.put(ChatColor.YELLOW, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.YELLOW).bold().toString()); + replacements.put(ChatColor.WHITE, Ansi.ansi().a(Attribute.RESET).fg(Ansi.Color.WHITE).bold().toString()); + replacements.put(ChatColor.MAGIC, Ansi.ansi().a(Attribute.BLINK_SLOW).toString()); + replacements.put(ChatColor.BOLD, Ansi.ansi().a(Attribute.UNDERLINE_DOUBLE).toString()); + replacements.put(ChatColor.STRIKETHROUGH, Ansi.ansi().a(Attribute.STRIKETHROUGH_ON).toString()); + replacements.put(ChatColor.UNDERLINE, Ansi.ansi().a(Attribute.UNDERLINE).toString()); + replacements.put(ChatColor.ITALIC, Ansi.ansi().a(Attribute.ITALIC).toString()); + replacements.put(ChatColor.RESET, Ansi.ansi().a(Attribute.RESET).toString()); + } + + @Override + public void sendMessage(String message) { + if (terminal.isAnsiSupported()) { + if (!conversationTracker.isConversingModaly()) { + String result = message; + for (ChatColor color : colors) { + if (replacements.containsKey(color)) { + result = result.replaceAll("(?i)" + color.toString(), replacements.get(color)); + } else { + result = result.replaceAll("(?i)" + color.toString(), ""); + } + } + System.out.println(result + Ansi.ansi().reset().toString()); + } + } else { + super.sendMessage(message); + } + } + + public static ConsoleCommandSender getInstance() { + if (Bukkit.getConsoleSender() != null) { + return Bukkit.getConsoleSender(); + } else { + return new ColouredConsoleSender(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java new file mode 100644 index 0000000..7ef5772 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java @@ -0,0 +1,47 @@ +package org.bukkit.craftbukkit.command; + +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.util.Waitable; + +import jline.console.completer.Completer; + +public class ConsoleCommandCompleter implements Completer { + private final CraftServer server; + + public ConsoleCommandCompleter(CraftServer server) { + this.server = server; + } + + public int complete(final String buffer, final int cursor, final List candidates) { + Waitable> waitable = new Waitable>() { + @Override + protected List evaluate() { + return server.getCommandMap().tabComplete(server.getConsoleSender(), buffer); + } + }; + this.server.getServer().processQueue.add(waitable); + try { + List offers = waitable.get(); + if (offers == null) { + return cursor; + } + candidates.addAll(offers); + + final int lastSpace = buffer.lastIndexOf(' '); + if (lastSpace == -1) { + return cursor - buffer.length(); + } else { + return cursor - (buffer.length() - lastSpace - 1); + } + } catch (ExecutionException e) { + this.server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return cursor; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java new file mode 100644 index 0000000..01f616b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java @@ -0,0 +1,53 @@ +package org.bukkit.craftbukkit.command; + +import net.minecraft.server.ICommandListener; +import net.minecraft.server.CommandBlockListenerAbstract; +import net.minecraft.server.IChatBaseComponent; + +import org.bukkit.block.Block; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.craftbukkit.util.CraftChatMessage; + +/** + * Represents input from a command block + */ +public class CraftBlockCommandSender extends ServerCommandSender implements BlockCommandSender { + private final CommandBlockListenerAbstract commandBlock; + + public CraftBlockCommandSender(CommandBlockListenerAbstract commandBlockListenerAbstract) { + super(); + this.commandBlock = commandBlockListenerAbstract; + } + + public Block getBlock() { + return commandBlock.getWorld().getWorld().getBlockAt(commandBlock.getChunkCoordinates().getX(), commandBlock.getChunkCoordinates().getY(), commandBlock.getChunkCoordinates().getZ()); + } + + public void sendMessage(String message) { + for (IChatBaseComponent component : CraftChatMessage.fromString(message)) { + commandBlock.sendMessage(component); + } + } + + public void sendMessage(String[] messages) { + for (String message : messages) { + sendMessage(message); + } + } + + public String getName() { + return commandBlock.getName(); + } + + public boolean isOp() { + return true; + } + + public void setOp(boolean value) { + throw new UnsupportedOperationException("Cannot change operator status of a block"); + } + + public ICommandListener getTileEntity() { + return commandBlock; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java new file mode 100644 index 0000000..9abcf92 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java @@ -0,0 +1,66 @@ +package org.bukkit.craftbukkit.command; + +import org.bukkit.ChatColor; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.conversations.Conversation; +import org.bukkit.conversations.ConversationAbandonedEvent; +import org.bukkit.conversations.ManuallyAbandonedConversationCanceller; +import org.bukkit.craftbukkit.conversations.ConversationTracker; + +/** + * Represents CLI input from a console + */ +public class CraftConsoleCommandSender extends ServerCommandSender implements ConsoleCommandSender { + + protected final ConversationTracker conversationTracker = new ConversationTracker(); + + protected CraftConsoleCommandSender() { + super(); + } + + public void sendMessage(String message) { + sendRawMessage(message); + } + + public void sendRawMessage(String message) { + System.out.println(ChatColor.stripColor(message)); + } + + public void sendMessage(String[] messages) { + for (String message : messages) { + sendMessage(message); + } + } + + public String getName() { + return "CONSOLE"; + } + + public boolean isOp() { + return true; + } + + public void setOp(boolean value) { + throw new UnsupportedOperationException("Cannot change operator status of server console"); + } + + public boolean beginConversation(Conversation conversation) { + return conversationTracker.beginConversation(conversation); + } + + public void abandonConversation(Conversation conversation) { + conversationTracker.abandonConversation(conversation, new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller())); + } + + public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) { + conversationTracker.abandonConversation(conversation, details); + } + + public void acceptConversationInput(String input) { + conversationTracker.acceptConversationInput(input); + } + + public boolean isConversing() { + return conversationTracker.isConversing(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftRemoteConsoleCommandSender.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftRemoteConsoleCommandSender.java new file mode 100644 index 0000000..7c5523b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/CraftRemoteConsoleCommandSender.java @@ -0,0 +1,38 @@ +package org.bukkit.craftbukkit.command; + +import net.minecraft.server.ChatComponentText; +import net.minecraft.server.RemoteControlCommandListener; +import org.bukkit.command.RemoteConsoleCommandSender; + +public class CraftRemoteConsoleCommandSender extends ServerCommandSender implements RemoteConsoleCommandSender { + public CraftRemoteConsoleCommandSender() { + super(); + } + + @Override + public void sendMessage(String message) { + RemoteControlCommandListener.getInstance().sendMessage(new ChatComponentText(message + "\n")); // Send a newline after each message, to preserve formatting. + } + + @Override + public void sendMessage(String[] messages) { + for (String message : messages) { + sendMessage(message); + } + } + + @Override + public String getName() { + return "Rcon"; + } + + @Override + public boolean isOp() { + return true; + } + + @Override + public void setOp(boolean value) { + throw new UnsupportedOperationException("Cannot change operator status of remote controller."); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ProxiedNativeCommandSender.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ProxiedNativeCommandSender.java new file mode 100644 index 0000000..9acd92c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ProxiedNativeCommandSender.java @@ -0,0 +1,126 @@ + +package org.bukkit.craftbukkit.command; + +import java.util.Set; +import net.minecraft.server.ICommandListener; + +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ProxiedCommandSender; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + +public class ProxiedNativeCommandSender implements ProxiedCommandSender { + + private final ICommandListener orig; + private final CommandSender caller; + private final CommandSender callee; + + public ProxiedNativeCommandSender(ICommandListener orig, CommandSender caller, CommandSender callee) { + this.orig = orig; + this.caller = caller; + this.callee = callee; + } + + public ICommandListener getHandle() { + return orig; + } + + @Override + public CommandSender getCaller() { + return caller; + } + + @Override + public CommandSender getCallee() { + return callee; + } + + @Override + public void sendMessage(String message) { + getCaller().sendMessage(message); + } + + @Override + public void sendMessage(String[] messages) { + getCaller().sendMessage(messages); + } + + @Override + public Server getServer() { + return getCallee().getServer(); + } + + @Override + public String getName() { + return getCallee().getName(); + } + + @Override + public boolean isPermissionSet(String name) { + return getCaller().isPermissionSet(name); + } + + @Override + public boolean isPermissionSet(Permission perm) { + return getCaller().isPermissionSet(perm); + } + + @Override + public boolean hasPermission(String name) { + return getCaller().hasPermission(name); + } + + @Override + public boolean hasPermission(Permission perm) { + return getCaller().hasPermission(perm); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + return getCaller().addAttachment(plugin, name, value); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin) { + return getCaller().addAttachment(plugin); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + return getCaller().addAttachment(plugin, name, value, ticks); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + return getCaller().addAttachment(plugin, ticks); + } + + @Override + public void removeAttachment(PermissionAttachment attachment) { + getCaller().removeAttachment(attachment); + } + + @Override + public void recalculatePermissions() { + getCaller().recalculatePermissions(); + } + + @Override + public Set getEffectivePermissions() { + return getCaller().getEffectivePermissions(); + } + + @Override + public boolean isOp() { + return getCaller().isOp(); + } + + @Override + public void setOp(boolean value) { + getCaller().setOp(value); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java new file mode 100644 index 0000000..b339cf3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java @@ -0,0 +1,80 @@ +package org.bukkit.craftbukkit.command; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.permissions.PermissibleBase; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + +import java.util.Set; + +public abstract class ServerCommandSender implements CommandSender { + private static PermissibleBase blockPermInst; + private final PermissibleBase perm; + + public ServerCommandSender() { + if (this instanceof CraftBlockCommandSender) { + if (blockPermInst == null) { + blockPermInst = new PermissibleBase(this); + } + this.perm = blockPermInst; + } else { + this.perm = new PermissibleBase(this); + } + } + + public boolean isPermissionSet(String name) { + return perm.isPermissionSet(name); + } + + public boolean isPermissionSet(Permission perm) { + return this.perm.isPermissionSet(perm); + } + + public boolean hasPermission(String name) { + return perm.hasPermission(name); + } + + public boolean hasPermission(Permission perm) { + return this.perm.hasPermission(perm); + } + + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + return perm.addAttachment(plugin, name, value); + } + + public PermissionAttachment addAttachment(Plugin plugin) { + return perm.addAttachment(plugin); + } + + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + return perm.addAttachment(plugin, name, value, ticks); + } + + public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + return perm.addAttachment(plugin, ticks); + } + + public void removeAttachment(PermissionAttachment attachment) { + perm.removeAttachment(attachment); + } + + public void recalculatePermissions() { + perm.recalculatePermissions(); + } + + public Set getEffectivePermissions() { + return perm.getEffectivePermissions(); + } + + public boolean isPlayer() { + return false; + } + + public Server getServer() { + return Bukkit.getServer(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java new file mode 100644 index 0000000..db46eb0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java @@ -0,0 +1,195 @@ +package org.bukkit.craftbukkit.command; + +import java.util.Iterator; +import java.util.List; + +import net.minecraft.server.*; + +import org.apache.commons.lang.Validate; +import org.apache.logging.log4j.Level; +import org.bukkit.Location; +import org.bukkit.command.BlockCommandSender; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.ProxiedCommandSender; +import org.bukkit.command.RemoteConsoleCommandSender; +import org.bukkit.command.defaults.*; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.entity.CraftMinecartCommand; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.entity.minecart.CommandMinecart; + +public final class VanillaCommandWrapper extends VanillaCommand { + protected final CommandAbstract vanillaCommand; + + public VanillaCommandWrapper(CommandAbstract vanillaCommand) { + super(vanillaCommand.getCommand()); + this.vanillaCommand = vanillaCommand; + } + + public VanillaCommandWrapper(CommandAbstract vanillaCommand, String usage) { + super(vanillaCommand.getCommand()); + this.vanillaCommand = vanillaCommand; + this.description = "A Mojang provided command."; + this.usageMessage = usage; + this.setPermission("minecraft.command." + vanillaCommand.getCommand()); + } + + @Override + public boolean execute(CommandSender sender, String commandLabel, String[] args) { + if (!testPermission(sender)) return true; + + ICommandListener icommandlistener = getListener(sender); + dispatchVanillaCommand(sender, icommandlistener, args); + return true; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + return tabComplete(sender, alias, args, null); // PaperSpigot - location tab-completes. Original code moved below + } + + // PaperSpigot start - location tab-completes + /* + this code is copied, except for the noted change, from the original tabComplete(CommandSender sender, String alias, String[] args) method + */ + @Override + public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException { + Validate.notNull(sender, "Sender cannot be null"); + Validate.notNull(args, "Arguments cannot be null"); + Validate.notNull(alias, "Alias cannot be null"); + if (location == null) { // PaperSpigot use location information if available + return (List) vanillaCommand.tabComplete(getListener(sender), args, new BlockPosition(0, 0, 0)); + } else { + return (List) vanillaCommand.tabComplete(getListener(sender), args, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + } + } + // PaperSpigot end + + public static CommandSender lastSender = null; // Nasty :( + + public final int dispatchVanillaCommand(CommandSender bSender, ICommandListener icommandlistener, String[] as) { + // Copied from net.minecraft.server.CommandHandler + int i = getPlayerListSize(as); + int j = 0; + // Some commands use the worldserver variable but we leave it full of null values, + // so we must temporarily populate it with the world of the commandsender + WorldServer[] prev = MinecraftServer.getServer().worldServer; + MinecraftServer server = MinecraftServer.getServer(); + server.worldServer = new WorldServer[server.worlds.size()]; + server.worldServer[0] = (WorldServer) icommandlistener.getWorld(); + int bpos = 0; + for (int pos = 1; pos < server.worldServer.length; pos++) { + WorldServer world = server.worlds.get(bpos++); + if (server.worldServer[0] == world) { + pos--; + continue; + } + server.worldServer[pos] = world; + } + + try { + if (vanillaCommand.canUse(icommandlistener)) { + if (i > -1) { + List list = ((List)PlayerSelector.getPlayers(icommandlistener, as[i], Entity.class)); + String s2 = as[i]; + + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.AFFECTED_ENTITIES, list.size()); + Iterator iterator = list.iterator(); + + while (iterator.hasNext()) { + Entity entity = iterator.next(); + + CommandSender oldSender = lastSender; + lastSender = bSender; + try { + as[i] = entity.getUniqueID().toString(); + vanillaCommand.execute(icommandlistener, as); + j++; + } catch (ExceptionUsage exceptionusage) { + ChatMessage chatmessage = new ChatMessage("commands.generic.usage", new Object[] { new ChatMessage(exceptionusage.getMessage(), exceptionusage.getArgs())}); + chatmessage.getChatModifier().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage); + } catch (CommandException commandexception) { + CommandAbstract.a(icommandlistener, vanillaCommand, 1, commandexception.getMessage(), commandexception.getArgs()); + } finally { + lastSender = oldSender; + } + } + as[i] = s2; + } else { + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.AFFECTED_ENTITIES, 1); + vanillaCommand.execute(icommandlistener, as); + j++; + } + } else { + ChatMessage chatmessage = new ChatMessage("commands.generic.permission", new Object[0]); + chatmessage.getChatModifier().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage); + } + } catch (ExceptionUsage exceptionusage) { + ChatMessage chatmessage1 = new ChatMessage("commands.generic.usage", new Object[] { new ChatMessage(exceptionusage.getMessage(), exceptionusage.getArgs()) }); + chatmessage1.getChatModifier().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage1); + } catch (CommandException commandexception) { + CommandAbstract.a(icommandlistener, vanillaCommand, 1, commandexception.getMessage(), commandexception.getArgs()); + } catch (Throwable throwable) { + ChatMessage chatmessage3 = new ChatMessage("commands.generic.exception", new Object[0]); + chatmessage3.getChatModifier().setColor(EnumChatFormat.RED); + icommandlistener.sendMessage(chatmessage3); + if (icommandlistener.f() instanceof EntityMinecartCommandBlock) { + MinecraftServer.LOGGER.log(Level.WARN, String.format("MinecartCommandBlock at (%d,%d,%d) failed to handle command", icommandlistener.getChunkCoordinates().getX(), icommandlistener.getChunkCoordinates().getY(), icommandlistener.getChunkCoordinates().getZ()), throwable); + } else if(icommandlistener instanceof CommandBlockListenerAbstract) { + CommandBlockListenerAbstract listener = (CommandBlockListenerAbstract) icommandlistener; + MinecraftServer.LOGGER.log(Level.WARN, String.format("CommandBlock at (%d,%d,%d) failed to handle command", listener.getChunkCoordinates().getX(), listener.getChunkCoordinates().getY(), listener.getChunkCoordinates().getZ()), throwable); + } else { + MinecraftServer.LOGGER.log(Level.WARN, String.format("Unknown CommandBlock failed to handle command"), throwable); + } + } finally { + MinecraftServer.getServer().worldServer = prev; + } + icommandlistener.a(CommandObjectiveExecutor.EnumCommandResult.SUCCESS_COUNT, j); + return j; + } + + private ICommandListener getListener(CommandSender sender) { + if (sender instanceof Player) { + return ((CraftPlayer) sender).getHandle(); + } + if (sender instanceof BlockCommandSender) { + return ((CraftBlockCommandSender) sender).getTileEntity(); + } + if (sender instanceof CommandMinecart) { + return ((EntityMinecartCommandBlock) ((CraftMinecartCommand) sender).getHandle()).getCommandBlock(); + } + if (sender instanceof RemoteConsoleCommandSender) { + return RemoteControlCommandListener.getInstance(); + } + if (sender instanceof ConsoleCommandSender) { + return ((CraftServer) sender.getServer()).getServer(); + } + if (sender instanceof ProxiedCommandSender) { + return ((ProxiedNativeCommandSender) sender).getHandle(); + } + throw new IllegalArgumentException("Cannot make " + sender + " a vanilla command listener"); + } + + private int getPlayerListSize(String as[]) { + for (int i = 0; i < as.length; i++) { + if (vanillaCommand.isListStart(as, i) && PlayerSelector.isList(as[i])) { + return i; + } + } + return -1; + } + + public static String[] dropFirstArgument(String as[]) { + String as1[] = new String[as.length - 1]; + for (int i = 1; i < as.length; i++) { + as1[i - 1] = as[i]; + } + + return as1; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/conversations/ConversationTracker.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/conversations/ConversationTracker.java new file mode 100644 index 0000000..30ef7d9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/conversations/ConversationTracker.java @@ -0,0 +1,69 @@ +package org.bukkit.craftbukkit.conversations; + +import java.util.LinkedList; +import java.util.logging.Level; + +import org.bukkit.Bukkit; +import org.bukkit.conversations.Conversation; +import org.bukkit.conversations.ConversationAbandonedEvent; +import org.bukkit.conversations.ManuallyAbandonedConversationCanceller; + +/** + */ +public class ConversationTracker { + + private LinkedList conversationQueue = new LinkedList(); + + public synchronized boolean beginConversation(Conversation conversation) { + if (!conversationQueue.contains(conversation)) { + conversationQueue.addLast(conversation); + if (conversationQueue.getFirst() == conversation) { + conversation.begin(); + conversation.outputNextPrompt(); + return true; + } + } + return true; + } + + public synchronized void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) { + if (!conversationQueue.isEmpty()) { + if (conversationQueue.getFirst() == conversation) { + conversation.abandon(details); + } + if (conversationQueue.contains(conversation)) { + conversationQueue.remove(conversation); + } + if (!conversationQueue.isEmpty()) { + conversationQueue.getFirst().outputNextPrompt(); + } + } + } + + public synchronized void abandonAllConversations() { + + LinkedList oldQueue = conversationQueue; + conversationQueue = new LinkedList(); + for (Conversation conversation : oldQueue) { + try { + conversation.abandon(new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller())); + } catch (Throwable t) { + Bukkit.getLogger().log(Level.SEVERE, "Unexpected exception while abandoning a conversation", t); + } + } + } + + public synchronized void acceptConversationInput(String input) { + if (isConversing()) { + conversationQueue.getFirst().acceptInput(input); + } + } + + public synchronized boolean isConversing() { + return !conversationQueue.isEmpty(); + } + + public synchronized boolean isConversingModaly() { + return isConversing() && conversationQueue.getFirst().isModal(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java new file mode 100644 index 0000000..8a55949 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java @@ -0,0 +1,141 @@ +package org.bukkit.craftbukkit.enchantments; + +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentTarget; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.inventory.ItemStack; + +public class CraftEnchantment extends Enchantment { + private final net.minecraft.server.Enchantment target; + + public CraftEnchantment(net.minecraft.server.Enchantment target) { + super(target.id); + this.target = target; + } + + @Override + public int getMaxLevel() { + return target.getMaxLevel(); + } + + @Override + public int getStartLevel() { + return target.getStartLevel(); + } + + @Override + public EnchantmentTarget getItemTarget() { + switch (target.slot) { + case ALL: + return EnchantmentTarget.ALL; + case ARMOR: + return EnchantmentTarget.ARMOR; + case ARMOR_FEET: + return EnchantmentTarget.ARMOR_FEET; + case ARMOR_HEAD: + return EnchantmentTarget.ARMOR_HEAD; + case ARMOR_LEGS: + return EnchantmentTarget.ARMOR_LEGS; + case ARMOR_TORSO: + return EnchantmentTarget.ARMOR_TORSO; + case DIGGER: + return EnchantmentTarget.TOOL; + case WEAPON: + return EnchantmentTarget.WEAPON; + case BOW: + return EnchantmentTarget.BOW; + case FISHING_ROD: + return EnchantmentTarget.FISHING_ROD; + default: + return null; + } + } + + @Override + public boolean canEnchantItem(ItemStack item) { + return target.canEnchant(CraftItemStack.asNMSCopy(item)); + } + + @Override + public String getName() { + switch (target.id) { + case 0: + return "PROTECTION_ENVIRONMENTAL"; + case 1: + return "PROTECTION_FIRE"; + case 2: + return "PROTECTION_FALL"; + case 3: + return "PROTECTION_EXPLOSIONS"; + case 4: + return "PROTECTION_PROJECTILE"; + case 5: + return "OXYGEN"; + case 6: + return "WATER_WORKER"; + case 7: + return "THORNS"; + case 8: + return "DEPTH_STRIDER"; + case 16: + return "DAMAGE_ALL"; + case 17: + return "DAMAGE_UNDEAD"; + case 18: + return "DAMAGE_ARTHROPODS"; + case 19: + return "KNOCKBACK"; + case 20: + return "FIRE_ASPECT"; + case 21: + return "LOOT_BONUS_MOBS"; + case 32: + return "DIG_SPEED"; + case 33: + return "SILK_TOUCH"; + case 34: + return "DURABILITY"; + case 35: + return "LOOT_BONUS_BLOCKS"; + case 48: + return "ARROW_DAMAGE"; + case 49: + return "ARROW_KNOCKBACK"; + case 50: + return "ARROW_FIRE"; + case 51: + return "ARROW_INFINITE"; + case 61: + return "LUCK"; + case 62: + return "LURE"; + default: + return "UNKNOWN_ENCHANT_" + target.id; + } + } + + public static net.minecraft.server.Enchantment getRaw(Enchantment enchantment) { + if (enchantment instanceof EnchantmentWrapper) { + enchantment = ((EnchantmentWrapper) enchantment).getEnchantment(); + } + + if (enchantment instanceof CraftEnchantment) { + return ((CraftEnchantment) enchantment).target; + } + + return null; + } + + @Override + public boolean conflictsWith(Enchantment other) { + if (other instanceof EnchantmentWrapper) { + other = ((EnchantmentWrapper) other).getEnchantment(); + } + if (!(other instanceof CraftEnchantment)) { + return false; + } + CraftEnchantment ench = (CraftEnchantment) other; + return !target.a(ench.target); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java new file mode 100644 index 0000000..7c16255 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java @@ -0,0 +1,23 @@ +package org.bukkit.craftbukkit.entity; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Projectile; + +public abstract class AbstractProjectile extends CraftEntity implements Projectile { + + private boolean doesBounce; + + public AbstractProjectile(CraftServer server, net.minecraft.server.Entity entity) { + super(server, entity); + doesBounce = false; + } + + public boolean doesBounce() { + return doesBounce; + } + + public void setBounce(boolean doesBounce) { + this.doesBounce = doesBounce; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java new file mode 100644 index 0000000..edb0796 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java @@ -0,0 +1,67 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityAgeable; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Ageable; + +public class CraftAgeable extends CraftCreature implements Ageable { + public CraftAgeable(CraftServer server, EntityAgeable entity) { + super(server, entity); + } + + public int getAge() { + return getHandle().getAge(); + } + + public void setAge(int age) { + getHandle().setAgeRaw(age); + } + + public void setAgeLock(boolean lock) { + getHandle().ageLocked = lock; + } + + public boolean getAgeLock() { + return getHandle().ageLocked; + } + + public void setBaby() { + if (isAdult()) { + setAge(-24000); + } + } + + public void setAdult() { + if (!isAdult()) { + setAge(0); + } + } + + public boolean isAdult() { + return getAge() >= 0; + } + + + public boolean canBreed() { + return getAge() == 0; + } + + public void setBreed(boolean breed) { + if (breed) { + setAge(0); + } else if (isAdult()) { + setAge(6000); + } + } + + @Override + public EntityAgeable getHandle() { + return (EntityAgeable) entity; + } + + @Override + public String toString() { + return "CraftAgeable"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java new file mode 100644 index 0000000..086980e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityAmbient; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Ambient; +import org.bukkit.entity.EntityType; + +public class CraftAmbient extends CraftLivingEntity implements Ambient { + public CraftAmbient(CraftServer server, EntityAmbient entity) { + super(server, entity); + } + + @Override + public EntityAmbient getHandle() { + return (EntityAmbient) entity; + } + + @Override + public String toString() { + return "CraftAmbient"; + } + + public EntityType getType() { + return EntityType.UNKNOWN; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java new file mode 100644 index 0000000..4b9b078 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java @@ -0,0 +1,22 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityAnimal; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Animals; + +public class CraftAnimals extends CraftAgeable implements Animals { + + public CraftAnimals(CraftServer server, EntityAnimal entity) { + super(server, entity); + } + + @Override + public EntityAnimal getHandle() { + return (EntityAnimal) entity; + } + + @Override + public String toString() { + return "CraftAnimals"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java new file mode 100644 index 0000000..09443fe --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -0,0 +1,219 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityArmorStand; +import net.minecraft.server.Vector3f; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.EulerAngle; + +public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { + + public CraftArmorStand(CraftServer server, EntityArmorStand entity) { + super(server, entity); + } + + @Override + public String toString() { + return "CraftArmorStand"; + } + + @Override + public EntityType getType() { + return EntityType.ARMOR_STAND; + } + + @Override + public EntityArmorStand getHandle() { + return (EntityArmorStand) super.getHandle(); + } + + @Override + public ItemStack getItemInHand() { + return getEquipment().getItemInHand(); + } + + @Override + public void setItemInHand(ItemStack item) { + getEquipment().setItemInHand(item); + } + + @Override + public ItemStack getBoots() { + return getEquipment().getBoots(); + } + + @Override + public void setBoots(ItemStack item) { + getEquipment().setBoots(item); + } + + @Override + public ItemStack getLeggings() { + return getEquipment().getLeggings(); + } + + @Override + public void setLeggings(ItemStack item) { + getEquipment().setLeggings(item); + } + + @Override + public ItemStack getChestplate() { + return getEquipment().getChestplate(); + } + + @Override + public void setChestplate(ItemStack item) { + getEquipment().setChestplate(item); + } + + @Override + public ItemStack getHelmet() { + return getEquipment().getHelmet(); + } + + @Override + public void setHelmet(ItemStack item) { + getEquipment().setHelmet(item); + } + + @Override + public EulerAngle getBodyPose() { + return fromNMS(getHandle().bodyPose); + } + + @Override + public void setBodyPose(EulerAngle pose) { + getHandle().setBodyPose(toNMS(pose)); + } + + @Override + public EulerAngle getLeftArmPose() { + return fromNMS(getHandle().leftArmPose); + } + + @Override + public void setLeftArmPose(EulerAngle pose) { + getHandle().setLeftArmPose(toNMS(pose)); + } + + @Override + public EulerAngle getRightArmPose() { + return fromNMS(getHandle().rightArmPose); + } + + @Override + public void setRightArmPose(EulerAngle pose) { + getHandle().setRightArmPose(toNMS(pose)); + } + + @Override + public EulerAngle getLeftLegPose() { + return fromNMS(getHandle().leftLegPose); + } + + @Override + public void setLeftLegPose(EulerAngle pose) { + getHandle().setLeftLegPose(toNMS(pose)); + } + + @Override + public EulerAngle getRightLegPose() { + return fromNMS(getHandle().rightLegPose); + } + + @Override + public void setRightLegPose(EulerAngle pose) { + getHandle().setRightLegPose(toNMS(pose)); + } + + @Override + public EulerAngle getHeadPose() { + return fromNMS(getHandle().headPose); + } + + @Override + public void setHeadPose(EulerAngle pose) { + getHandle().setHeadPose(toNMS(pose)); + } + + @Override + public boolean hasBasePlate() { + return !getHandle().hasBasePlate(); + } + + @Override + public void setBasePlate(boolean basePlate) { + getHandle().setBasePlate(!basePlate); + } + + @Override + public boolean hasGravity() { + return !getHandle().hasGravity(); + } + + @Override + public void setGravity(boolean gravity) { + getHandle().setGravity(!gravity); + } + + @Override + public boolean isVisible() { + return !getHandle().isInvisible(); + } + + @Override + public void setVisible(boolean visible) { + getHandle().setInvisible(!visible); + } + + @Override + public boolean hasArms() { + return getHandle().hasArms(); + } + + @Override + public void setArms(boolean arms) { + getHandle().setArms(arms); + } + + @Override + public boolean isSmall() { + return getHandle().isSmall(); + } + + @Override + public void setSmall(boolean small) { + getHandle().setSmall(small); + } + + private static EulerAngle fromNMS(Vector3f old) { + return new EulerAngle( + Math.toRadians(old.getX()), + Math.toRadians(old.getY()), + Math.toRadians(old.getZ()) + ); + } + + private static Vector3f toNMS(EulerAngle old) { + return new Vector3f( + (float) Math.toDegrees(old.getX()), + (float) Math.toDegrees(old.getY()), + (float) Math.toDegrees(old.getZ()) + ); + } + + @Override + public boolean isMarker() { + // PAIL + return getHandle().s(); + } + + @Override + public void setMarker(boolean marker) { + // PAIL + getHandle().n(marker); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java new file mode 100644 index 0000000..ad489cc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java @@ -0,0 +1,96 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityArrow; + +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.projectiles.ProjectileSource; + +public class CraftArrow extends AbstractProjectile implements Arrow { + + public CraftArrow(CraftServer server, EntityArrow entity) { + super(server, entity); + } + + public void setKnockbackStrength(int knockbackStrength) { + Validate.isTrue(knockbackStrength >= 0, "Knockback cannot be negative"); + getHandle().setKnockbackStrength(knockbackStrength); + } + + public int getKnockbackStrength() { + return getHandle().knockbackStrength; + } + + public boolean isCritical() { + return getHandle().isCritical(); + } + + public void setCritical(boolean critical) { + getHandle().setCritical(critical); + } + + public ProjectileSource getShooter() { + return getHandle().projectileSource; + } + + public void setShooter(ProjectileSource shooter) { + if (shooter instanceof LivingEntity) { + getHandle().shooter = ((CraftLivingEntity) shooter).getHandle(); + } else { + getHandle().shooter = null; + } + getHandle().projectileSource = shooter; + } + + @Override + public EntityArrow getHandle() { + return (EntityArrow) entity; + } + + @Override + public String toString() { + return "CraftArrow"; + } + + public EntityType getType() { + return EntityType.ARROW; + } + + @Deprecated + public LivingEntity _INVALID_getShooter() { + if (getHandle().shooter == null) { + return null; + } + return (LivingEntity) getHandle().shooter.getBukkitEntity(); + } + + @Deprecated + public void _INVALID_setShooter(LivingEntity shooter) { + getHandle().shooter = ((CraftLivingEntity) shooter).getHandle(); + } + + // Spigot start + private final Arrow.Spigot spigot = new Arrow.Spigot() + { + @Override + public double getDamage() + { + return getHandle().j(); + } + + @Override + public void setDamage(double damage) + { + getHandle().b( damage ); + } + }; + + public Arrow.Spigot spigot() + { + return spigot; + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java new file mode 100644 index 0000000..76ada1c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java @@ -0,0 +1,36 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityBat; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Bat; +import org.bukkit.entity.EntityType; + +public class CraftBat extends CraftAmbient implements Bat { + public CraftBat(CraftServer server, EntityBat entity) { + super(server, entity); + } + + @Override + public EntityBat getHandle() { + return (EntityBat) entity; + } + + @Override + public String toString() { + return "CraftBat"; + } + + public EntityType getType() { + return EntityType.BAT; + } + + @Override + public boolean isAwake() { + return !getHandle().isAsleep(); + } + + @Override + public void setAwake(boolean state) { + getHandle().setAsleep(!state); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java new file mode 100644 index 0000000..830d7a8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityBlaze; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Blaze; +import org.bukkit.entity.EntityType; + +public class CraftBlaze extends CraftMonster implements Blaze { + public CraftBlaze(CraftServer server, EntityBlaze entity) { + super(server, entity); + } + + @Override + public EntityBlaze getHandle() { + return (EntityBlaze) entity; + } + + @Override + public String toString() { + return "CraftBlaze"; + } + + public EntityType getType() { + return EntityType.BLAZE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java new file mode 100644 index 0000000..103b9d4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java @@ -0,0 +1,63 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityBoat; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Boat; +import org.bukkit.entity.EntityType; + +public class CraftBoat extends CraftVehicle implements Boat { + + public CraftBoat(CraftServer server, EntityBoat entity) { + super(server, entity); + } + + public double getMaxSpeed() { + return getHandle().maxSpeed; + } + + public void setMaxSpeed(double speed) { + if (speed >= 0D) { + getHandle().maxSpeed = speed; + } + } + + public double getOccupiedDeceleration() { + return getHandle().occupiedDeceleration; + } + + public void setOccupiedDeceleration(double speed) { + if (speed >= 0D) { + getHandle().occupiedDeceleration = speed; + } + } + + public double getUnoccupiedDeceleration() { + return getHandle().unoccupiedDeceleration; + } + + public void setUnoccupiedDeceleration(double speed) { + getHandle().unoccupiedDeceleration = speed; + } + + public boolean getWorkOnLand() { + return getHandle().landBoats; + } + + public void setWorkOnLand(boolean workOnLand) { + getHandle().landBoats = workOnLand; + } + + @Override + public EntityBoat getHandle() { + return (EntityBoat) entity; + } + + @Override + public String toString() { + return "CraftBoat"; + } + + public EntityType getType() { + return EntityType.BOAT; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java new file mode 100644 index 0000000..0648a85 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityCaveSpider; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.CaveSpider; +import org.bukkit.entity.EntityType; + +public class CraftCaveSpider extends CraftSpider implements CaveSpider { + public CraftCaveSpider(CraftServer server, EntityCaveSpider entity) { + super(server, entity); + } + + @Override + public EntityCaveSpider getHandle() { + return (EntityCaveSpider) entity; + } + + @Override + public String toString() { + return "CraftCaveSpider"; + } + + public EntityType getType() { + return EntityType.CAVE_SPIDER; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java new file mode 100644 index 0000000..d20c219 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityChicken; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.EntityType; + +public class CraftChicken extends CraftAnimals implements Chicken { + + public CraftChicken(CraftServer server, EntityChicken entity) { + super(server, entity); + } + + @Override + public EntityChicken getHandle() { + return (EntityChicken) entity; + } + + @Override + public String toString() { + return "CraftChicken"; + } + + public EntityType getType() { + return EntityType.CHICKEN; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java new file mode 100644 index 0000000..cc115cc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java @@ -0,0 +1,21 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityLiving; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.ComplexLivingEntity; + +public abstract class CraftComplexLivingEntity extends CraftLivingEntity implements ComplexLivingEntity { + public CraftComplexLivingEntity(CraftServer server, EntityLiving entity) { + super(server, entity); + } + + @Override + public EntityLiving getHandle() { + return (EntityLiving) entity; + } + + @Override + public String toString() { + return "CraftComplexLivingEntity"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java new file mode 100644 index 0000000..eb1ce79 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java @@ -0,0 +1,43 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityComplexPart; +import net.minecraft.server.EntityEnderDragon; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.ComplexEntityPart; +import org.bukkit.entity.ComplexLivingEntity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.entity.EntityDamageEvent; + +public class CraftComplexPart extends CraftEntity implements ComplexEntityPart { + public CraftComplexPart(CraftServer server, EntityComplexPart entity) { + super(server, entity); + } + + public ComplexLivingEntity getParent() { + return (ComplexLivingEntity) ((EntityEnderDragon) getHandle().owner).getBukkitEntity(); + } + + @Override + public void setLastDamageCause(EntityDamageEvent cause) { + getParent().setLastDamageCause(cause); + } + + @Override + public EntityDamageEvent getLastDamageCause() { + return getParent().getLastDamageCause(); + } + + @Override + public EntityComplexPart getHandle() { + return (EntityComplexPart) entity; + } + + @Override + public String toString() { + return "CraftComplexPart"; + } + + public EntityType getType() { + return EntityType.COMPLEX_PART; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java new file mode 100644 index 0000000..fc48ebd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityCow; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Cow; +import org.bukkit.entity.EntityType; + +public class CraftCow extends CraftAnimals implements Cow { + + public CraftCow(CraftServer server, EntityCow entity) { + super(server, entity); + } + + @Override + public EntityCow getHandle() { + return (EntityCow) entity; + } + + @Override + public String toString() { + return "CraftCow"; + } + + public EntityType getType() { + return EntityType.COW; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java new file mode 100644 index 0000000..09d4214 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java @@ -0,0 +1,37 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityCreature; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Creature; +import org.bukkit.entity.LivingEntity; + +public class CraftCreature extends CraftLivingEntity implements Creature { + public CraftCreature(CraftServer server, EntityCreature entity) { + super(server, entity); + } + + public void setTarget(LivingEntity target) { + EntityCreature entity = getHandle(); + if (target == null) { + entity.setGoalTarget(null, null, false); + } else if (target instanceof CraftLivingEntity) { + entity.setGoalTarget(((CraftLivingEntity) target).getHandle(), null, false); + } + } + + public CraftLivingEntity getTarget() { + if (getHandle().getGoalTarget() == null) return null; + + return (CraftLivingEntity) getHandle().getGoalTarget().getBukkitEntity(); + } + + @Override + public EntityCreature getHandle() { + return (EntityCreature) entity; + } + + @Override + public String toString() { + return "CraftCreature"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java new file mode 100644 index 0000000..ed771a5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java @@ -0,0 +1,54 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityCreeper; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.EntityType; +import org.bukkit.event.entity.CreeperPowerEvent; + +public class CraftCreeper extends CraftMonster implements Creeper { + + public CraftCreeper(CraftServer server, EntityCreeper entity) { + super(server, entity); + } + + public boolean isPowered() { + return getHandle().isPowered(); + } + + public void setPowered(boolean powered) { + CraftServer server = this.server; + Creeper entity = (Creeper) this.getHandle().getBukkitEntity(); + + if (powered) { + CreeperPowerEvent event = new CreeperPowerEvent(entity, CreeperPowerEvent.PowerCause.SET_ON); + server.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + getHandle().setPowered(true); + } + } else { + CreeperPowerEvent event = new CreeperPowerEvent(entity, CreeperPowerEvent.PowerCause.SET_OFF); + server.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + getHandle().setPowered(false); + } + } + } + + @Override + public EntityCreeper getHandle() { + return (EntityCreeper) entity; + } + + @Override + public String toString() { + return "CraftCreeper"; + } + + public EntityType getType() { + return EntityType.CREEPER; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java new file mode 100644 index 0000000..60c5188 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityEgg; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Egg; +import org.bukkit.entity.EntityType; + +public class CraftEgg extends CraftProjectile implements Egg { + public CraftEgg(CraftServer server, EntityEgg entity) { + super(server, entity); + } + + @Override + public EntityEgg getHandle() { + return (EntityEgg) entity; + } + + @Override + public String toString() { + return "CraftEgg"; + } + + public EntityType getType() { + return EntityType.EGG; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java new file mode 100644 index 0000000..2bcf3a1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityEnderCrystal; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EnderCrystal; +import org.bukkit.entity.EntityType; + +public class CraftEnderCrystal extends CraftEntity implements EnderCrystal { + public CraftEnderCrystal(CraftServer server, EntityEnderCrystal entity) { + super(server, entity); + } + + @Override + public EntityEnderCrystal getHandle() { + return (EntityEnderCrystal) entity; + } + + @Override + public String toString() { + return "CraftEnderCrystal"; + } + + public EntityType getType() { + return EntityType.ENDER_CRYSTAL; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java new file mode 100644 index 0000000..fa0d63a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java @@ -0,0 +1,44 @@ +package org.bukkit.craftbukkit.entity; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; + +import java.util.Set; + +import net.minecraft.server.EntityComplexPart; +import net.minecraft.server.EntityEnderDragon; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.ComplexEntityPart; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.EntityType; + +public class CraftEnderDragon extends CraftComplexLivingEntity implements EnderDragon { + public CraftEnderDragon(CraftServer server, EntityEnderDragon entity) { + super(server, entity); + } + + public Set getParts() { + Builder builder = ImmutableSet.builder(); + + for (EntityComplexPart part : getHandle().children) { + builder.add((ComplexEntityPart) part.getBukkitEntity()); + } + + return builder.build(); + } + + @Override + public EntityEnderDragon getHandle() { + return (EntityEnderDragon) entity; + } + + @Override + public String toString() { + return "CraftEnderDragon"; + } + + public EntityType getType() { + return EntityType.ENDER_DRAGON; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java new file mode 100644 index 0000000..736a460 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java @@ -0,0 +1,87 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityComplexPart; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.EnderDragonPart; +import org.bukkit.entity.Entity; +import org.bukkit.util.NumberConversions; + +public class CraftEnderDragonPart extends CraftComplexPart implements EnderDragonPart { + public CraftEnderDragonPart(CraftServer server, EntityComplexPart entity) { + super(server, entity); + } + + @Override + public EnderDragon getParent() { + return (EnderDragon) super.getParent(); + } + + @Override + public EntityComplexPart getHandle() { + return (EntityComplexPart) entity; + } + + @Override + public String toString() { + return "CraftEnderDragonPart"; + } + + public void damage(double amount) { + getParent().damage(amount); + } + + public void damage(double amount, Entity source) { + getParent().damage(amount, source); + } + + public double getHealth() { + return getParent().getHealth(); + } + + public void setHealth(double health) { + getParent().setHealth(health); + } + + public double getMaxHealth() { + return getParent().getMaxHealth(); + } + + public void setMaxHealth(double health) { + getParent().setMaxHealth(health); + } + + public void resetMaxHealth() { + getParent().resetMaxHealth(); + } + + @Deprecated + public void _INVALID_damage(int amount) { + damage(amount); + } + + @Deprecated + public void _INVALID_damage(int amount, Entity source) { + damage(amount, source); + } + + @Deprecated + public int _INVALID_getHealth() { + return NumberConversions.ceil(getHealth()); + } + + @Deprecated + public void _INVALID_setHealth(int health) { + setHealth(health); + } + + @Deprecated + public int _INVALID_getMaxHealth() { + return NumberConversions.ceil(getMaxHealth()); + } + + @Deprecated + public void _INVALID_setMaxHealth(int health) { + setMaxHealth(health); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java new file mode 100644 index 0000000..f42f9ab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityEnderPearl; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EnderPearl; +import org.bukkit.entity.EntityType; + +public class CraftEnderPearl extends CraftProjectile implements EnderPearl { + public CraftEnderPearl(CraftServer server, EntityEnderPearl entity) { + super(server, entity); + } + + @Override + public EntityEnderPearl getHandle() { + return (EntityEnderPearl) entity; + } + + @Override + public String toString() { + return "CraftEnderPearl"; + } + + public EntityType getType() { + return EntityType.ENDER_PEARL; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java new file mode 100644 index 0000000..e3a5081 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityEnderSignal; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EnderSignal; +import org.bukkit.entity.EntityType; + +public class CraftEnderSignal extends CraftEntity implements EnderSignal { + public CraftEnderSignal(CraftServer server, EntityEnderSignal entity) { + super(server, entity); + } + + @Override + public EntityEnderSignal getHandle() { + return (EntityEnderSignal) entity; + } + + @Override + public String toString() { + return "CraftEnderSignal"; + } + + public EntityType getType() { + return EntityType.ENDER_SIGNAL; + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java new file mode 100644 index 0000000..b1bf7a4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java @@ -0,0 +1,39 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityEnderman; + +import net.minecraft.server.IBlockData; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.EntityType; +import org.bukkit.material.MaterialData; + +public class CraftEnderman extends CraftMonster implements Enderman { + public CraftEnderman(CraftServer server, EntityEnderman entity) { + super(server, entity); + } + + public MaterialData getCarriedMaterial() { + IBlockData blockData = getHandle().getCarried(); + return CraftMagicNumbers.getMaterial(blockData.getBlock()).getNewData((byte) blockData.getBlock().toLegacyData(blockData)); + } + + public void setCarriedMaterial(MaterialData data) { + getHandle().setCarried(CraftMagicNumbers.getBlock(data.getItemTypeId()).fromLegacyData(data.getData())); + } + + @Override + public EntityEnderman getHandle() { + return (EntityEnderman) entity; + } + + @Override + public String toString() { + return "CraftEnderman"; + } + + public EntityType getType() { + return EntityType.ENDERMAN; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java new file mode 100644 index 0000000..4fd49ea --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java @@ -0,0 +1,23 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityEndermite; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Endermite; +import org.bukkit.entity.EntityType; + +public class CraftEndermite extends CraftMonster implements Endermite { + + public CraftEndermite(CraftServer server, EntityEndermite entity) { + super(server, entity); + } + + @Override + public String toString() { + return "CraftEndermite"; + } + + @Override + public EntityType getType() { + return EntityType.ENDERMITE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java new file mode 100644 index 0000000..4f91799 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -0,0 +1,575 @@ +package org.bukkit.craftbukkit.entity; + +import com.google.common.base.Preconditions; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import net.minecraft.server.*; + +import org.bukkit.EntityEffect; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.permissions.PermissibleBase; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.permissions.ServerOperator; +import org.bukkit.plugin.Plugin; +import org.bukkit.util.Vector; +import org.github.paperspigot.PaperSpigotConfig; + +public abstract class CraftEntity implements org.bukkit.entity.Entity { + private static final PermissibleBase perm = new PermissibleBase(new ServerOperator() { + + @Override + public boolean isOp() { + return false; + } + + @Override + public void setOp(boolean value) { + + } + }); + + protected final CraftServer server; + protected Entity entity; + private EntityDamageEvent lastDamageEvent; + + public CraftEntity(final CraftServer server, final Entity entity) { + this.server = server; + this.entity = entity; + } + + public static CraftEntity getEntity(CraftServer server, Entity entity) { + /** + * Order is *EXTREMELY* important -- keep it right! =D + */ + if (entity instanceof EntityLiving) { + // Players + if (entity instanceof EntityHuman) { + if (entity instanceof EntityPlayer) { return new CraftPlayer(server, (EntityPlayer) entity); } + else { return new CraftHumanEntity(server, (EntityHuman) entity); } + } + // Water Animals + else if (entity instanceof EntityWaterAnimal) { + if (entity instanceof EntitySquid) { return new CraftSquid(server, (EntitySquid) entity); } + else { return new CraftWaterMob(server, (EntityWaterAnimal) entity); } + } + else if (entity instanceof EntityCreature) { + // Animals + if (entity instanceof EntityAnimal) { + if (entity instanceof EntityChicken) { return new CraftChicken(server, (EntityChicken) entity); } + else if (entity instanceof EntityCow) { + if (entity instanceof EntityMushroomCow) { return new CraftMushroomCow(server, (EntityMushroomCow) entity); } + else { return new CraftCow(server, (EntityCow) entity); } + } + else if (entity instanceof EntityPig) { return new CraftPig(server, (EntityPig) entity); } + else if (entity instanceof EntityTameableAnimal) { + if (entity instanceof EntityWolf) { return new CraftWolf(server, (EntityWolf) entity); } + else if (entity instanceof EntityOcelot) { return new CraftOcelot(server, (EntityOcelot) entity); } + } + else if (entity instanceof EntitySheep) { return new CraftSheep(server, (EntitySheep) entity); } + else if (entity instanceof EntityHorse) { return new CraftHorse(server, (EntityHorse) entity); } + else if (entity instanceof EntityRabbit) { return new CraftRabbit(server, (EntityRabbit) entity); } + else { return new CraftAnimals(server, (EntityAnimal) entity); } + } + // Monsters + else if (entity instanceof EntityMonster) { + if (entity instanceof EntityZombie) { + if (entity instanceof EntityPigZombie) { return new CraftPigZombie(server, (EntityPigZombie) entity); } + else { return new CraftZombie(server, (EntityZombie) entity); } + } + else if (entity instanceof EntityCreeper) { return new CraftCreeper(server, (EntityCreeper) entity); } + else if (entity instanceof EntityEnderman) { return new CraftEnderman(server, (EntityEnderman) entity); } + else if (entity instanceof EntitySilverfish) { return new CraftSilverfish(server, (EntitySilverfish) entity); } + else if (entity instanceof EntityGiantZombie) { return new CraftGiant(server, (EntityGiantZombie) entity); } + else if (entity instanceof EntitySkeleton) { return new CraftSkeleton(server, (EntitySkeleton) entity); } + else if (entity instanceof EntityBlaze) { return new CraftBlaze(server, (EntityBlaze) entity); } + else if (entity instanceof EntityWitch) { return new CraftWitch(server, (EntityWitch) entity); } + else if (entity instanceof EntityWither) { return new CraftWither(server, (EntityWither) entity); } + else if (entity instanceof EntitySpider) { + if (entity instanceof EntityCaveSpider) { return new CraftCaveSpider(server, (EntityCaveSpider) entity); } + else { return new CraftSpider(server, (EntitySpider) entity); } + } + else if (entity instanceof EntityEndermite) { return new CraftEndermite(server, (EntityEndermite) entity); } + else if (entity instanceof EntityGuardian) { return new CraftGuardian(server, (EntityGuardian) entity); } + + else { return new CraftMonster(server, (EntityMonster) entity); } + } + else if (entity instanceof EntityGolem) { + if (entity instanceof EntitySnowman) { return new CraftSnowman(server, (EntitySnowman) entity); } + else if (entity instanceof EntityIronGolem) { return new CraftIronGolem(server, (EntityIronGolem) entity); } + } + else if (entity instanceof EntityVillager) { return new CraftVillager(server, (EntityVillager) entity); } + else { return new CraftCreature(server, (EntityCreature) entity); } + } + // Slimes are a special (and broken) case + else if (entity instanceof EntitySlime) { + if (entity instanceof EntityMagmaCube) { return new CraftMagmaCube(server, (EntityMagmaCube) entity); } + else { return new CraftSlime(server, (EntitySlime) entity); } + } + // Flying + else if (entity instanceof EntityFlying) { + if (entity instanceof EntityGhast) { return new CraftGhast(server, (EntityGhast) entity); } + else { return new CraftFlying(server, (EntityFlying) entity); } + } + else if (entity instanceof EntityEnderDragon) { + return new CraftEnderDragon(server, (EntityEnderDragon) entity); + } + // Ambient + else if (entity instanceof EntityAmbient) { + if (entity instanceof EntityBat) { return new CraftBat(server, (EntityBat) entity); } + else { return new CraftAmbient(server, (EntityAmbient) entity); } + } + else if (entity instanceof EntityArmorStand) { return new CraftArmorStand(server, (EntityArmorStand) entity); } + else { return new CraftLivingEntity(server, (EntityLiving) entity); } + } + else if (entity instanceof EntityComplexPart) { + EntityComplexPart part = (EntityComplexPart) entity; + if (part.owner instanceof EntityEnderDragon) { return new CraftEnderDragonPart(server, (EntityComplexPart) entity); } + else { return new CraftComplexPart(server, (EntityComplexPart) entity); } + } + else if (entity instanceof EntityExperienceOrb) { return new CraftExperienceOrb(server, (EntityExperienceOrb) entity); } + else if (entity instanceof EntityArrow) { return new CraftArrow(server, (EntityArrow) entity); } + else if (entity instanceof EntityBoat) { return new CraftBoat(server, (EntityBoat) entity); } + else if (entity instanceof EntityProjectile) { + if (entity instanceof EntityEgg) { return new CraftEgg(server, (EntityEgg) entity); } + else if (entity instanceof EntitySnowball) { return new CraftSnowball(server, (EntitySnowball) entity); } + else if (entity instanceof EntityPotion) { return new CraftThrownPotion(server, (EntityPotion) entity); } + else if (entity instanceof EntityEnderPearl) { return new CraftEnderPearl(server, (EntityEnderPearl) entity); } + else if (entity instanceof EntityThrownExpBottle) { return new CraftThrownExpBottle(server, (EntityThrownExpBottle) entity); } + } + else if (entity instanceof EntityFallingBlock) { return new CraftFallingSand(server, (EntityFallingBlock) entity); } + else if (entity instanceof EntityFireball) { + if (entity instanceof EntitySmallFireball) { return new CraftSmallFireball(server, (EntitySmallFireball) entity); } + else if (entity instanceof EntityLargeFireball) { return new CraftLargeFireball(server, (EntityLargeFireball) entity); } + else if (entity instanceof EntityWitherSkull) { return new CraftWitherSkull(server, (EntityWitherSkull) entity); } + else { return new CraftFireball(server, (EntityFireball) entity); } + } + else if (entity instanceof EntityEnderSignal) { return new CraftEnderSignal(server, (EntityEnderSignal) entity); } + else if (entity instanceof EntityEnderCrystal) { return new CraftEnderCrystal(server, (EntityEnderCrystal) entity); } + else if (entity instanceof EntityFishingHook) { return new CraftFish(server, (EntityFishingHook) entity); } + else if (entity instanceof EntityItem) { return new CraftItem(server, (EntityItem) entity); } + else if (entity instanceof EntityWeather) { + if (entity instanceof EntityLightning) { return new CraftLightningStrike(server, (EntityLightning) entity); } + else { return new CraftWeather(server, (EntityWeather) entity); } + } + else if (entity instanceof EntityMinecartAbstract) { + if (entity instanceof EntityMinecartFurnace) { return new CraftMinecartFurnace(server, (EntityMinecartFurnace) entity); } + else if (entity instanceof EntityMinecartChest) { return new CraftMinecartChest(server, (EntityMinecartChest) entity); } + else if (entity instanceof EntityMinecartTNT) { return new CraftMinecartTNT(server, (EntityMinecartTNT) entity); } + else if (entity instanceof EntityMinecartHopper) { return new CraftMinecartHopper(server, (EntityMinecartHopper) entity); } + else if (entity instanceof EntityMinecartMobSpawner) { return new CraftMinecartMobSpawner(server, (EntityMinecartMobSpawner) entity); } + else if (entity instanceof EntityMinecartRideable) { return new CraftMinecartRideable(server, (EntityMinecartRideable) entity); } + else if (entity instanceof EntityMinecartCommandBlock) { return new CraftMinecartCommand(server, (EntityMinecartCommandBlock) entity); } + } else if (entity instanceof EntityHanging) { + if (entity instanceof EntityPainting) { return new CraftPainting(server, (EntityPainting) entity); } + else if (entity instanceof EntityItemFrame) { return new CraftItemFrame(server, (EntityItemFrame) entity); } + else if (entity instanceof EntityLeash) { return new CraftLeash(server, (EntityLeash) entity); } + else { return new CraftHanging(server, (EntityHanging) entity); } + } + else if (entity instanceof EntityTNTPrimed) { return new CraftTNTPrimed(server, (EntityTNTPrimed) entity); } + else if (entity instanceof EntityFireworks) { return new CraftFirework(server, (EntityFireworks) entity); } + + throw new AssertionError("Unknown entity " + (entity == null ? null : entity.getClass())); + } + + public Location getLocation() { + return new Location(getWorld(), entity.locX, entity.locY, entity.locZ, entity.yaw, entity.pitch); + } + + public Location getLocation(Location loc) { + if (loc != null) { + loc.setWorld(getWorld()); + loc.setX(entity.locX); + loc.setY(entity.locY); + loc.setZ(entity.locZ); + loc.setYaw(entity.yaw); + loc.setPitch(entity.pitch); + } + + return loc; + } + + public Vector getVelocity() { + return new Vector(entity.motX, entity.motY, entity.motZ); + } + + public void setVelocity(Vector vel) { + // Paper start - warn server owners when plugins try to set super high velocities + if (PaperSpigotConfig.warnForExcessiveVelocity) { + if(vel.getX() > 4 || vel.getX() < -4 || vel.getY() > 4 || vel.getY() < -4 || vel.getZ() > 4 || vel.getZ() < -4) { + getServer().getLogger().warning("Excessive velocity set detected: tried to set velocity of entity #"+getEntityId()+" to ("+vel.getX()+","+vel.getY()+","+vel.getZ()+")."); + Thread.dumpStack(); + } + } + // Paper end + + entity.motX = vel.getX(); + entity.motY = vel.getY(); + entity.motZ = vel.getZ(); + entity.velocityChanged = true; + } + + public boolean isOnGround() { + if (entity instanceof EntityArrow) { + return ((EntityArrow) entity).isInGround(); + } + return entity.onGround; + } + + public World getWorld() { + return entity.world.getWorld(); + } + + public boolean teleport(Location location) { + return teleport(location, TeleportCause.PLUGIN); + } + + public boolean teleport(Location location, TeleportCause cause) { + if (entity.passenger != null || entity.dead) { + return false; + } + + // If this entity is riding another entity, we must dismount before teleporting. + entity.mount(null); + + // Spigot start + if (!location.getWorld().equals(getWorld())) { + entity.teleportTo(location, cause.equals(TeleportCause.NETHER_PORTAL)); + return true; + } + + // entity.world = ((CraftWorld) location.getWorld()).getHandle(); + // Spigot end + entity.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + entity.world.entityJoinedWorld(entity, false); // PaperSpigot - Fix issues with entities not being switched to their new chunk + // entity.setLocation() throws no event, and so cannot be cancelled + return true; + } + + public boolean teleport(org.bukkit.entity.Entity destination) { + return teleport(destination.getLocation()); + } + + public boolean teleport(org.bukkit.entity.Entity destination, TeleportCause cause) { + return teleport(destination.getLocation(), cause); + } + + public List getNearbyEntities(double x, double y, double z) { + List notchEntityList = entity.world.a(entity, entity.getBoundingBox().grow(x, y, z), null); + List bukkitEntityList = new java.util.ArrayList(notchEntityList.size()); + + for (Entity e : notchEntityList) { + bukkitEntityList.add(e.getBukkitEntity()); + } + return bukkitEntityList; + } + + public int getEntityId() { + return entity.getId(); + } + + public int getFireTicks() { + return entity.fireTicks; + } + + public int getMaxFireTicks() { + return entity.maxFireTicks; + } + + public void setFireTicks(int ticks) { + entity.fireTicks = ticks; + } + + public void remove() { + entity.dead = true; + } + + public boolean isDead() { + return !entity.isAlive(); + } + + public boolean isValid() { + return entity.isAlive() && entity.valid; + } + + public Server getServer() { + return server; + } + + public Vector getMomentum() { + return getVelocity(); + } + + public void setMomentum(Vector value) { + setVelocity(value); + } + + public org.bukkit.entity.Entity getPassenger() { + return isEmpty() ? null : getHandle().passenger.getBukkitEntity(); + } + + public boolean setPassenger(org.bukkit.entity.Entity passenger) { + Preconditions.checkArgument(!this.equals(passenger), "Entity cannot ride itself."); + if (passenger instanceof CraftEntity) { + ((CraftEntity) passenger).getHandle().mount(getHandle()); + return true; + } else { + return false; + } + } + + public boolean isEmpty() { + return getHandle().passenger == null; + } + + public boolean eject() { + if (getHandle().passenger == null) { + return false; + } + + getHandle().passenger.mount(null); + return true; + } + + public float getFallDistance() { + return getHandle().fallDistance; + } + + public void setFallDistance(float distance) { + getHandle().fallDistance = distance; + } + + public void setLastDamageCause(EntityDamageEvent event) { + lastDamageEvent = event; + } + + public EntityDamageEvent getLastDamageCause() { + return lastDamageEvent; + } + + public UUID getUniqueId() { + return getHandle().getUniqueID(); + } + + public int getTicksLived() { + return getHandle().ticksLived; + } + + public void setTicksLived(int value) { + if (value <= 0) { + throw new IllegalArgumentException("Age must be at least 1 tick"); + } + getHandle().ticksLived = value; + } + + public Entity getHandle() { + return entity; + } + + public void playEffect(EntityEffect type) { + this.getHandle().world.broadcastEntityEffect(getHandle(), type.getData()); + } + + public void setHandle(final Entity entity) { + this.entity = entity; + } + + @Override + public String toString() { + return "CraftEntity{" + "id=" + getEntityId() + '}'; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final CraftEntity other = (CraftEntity) obj; + return (this.getEntityId() == other.getEntityId()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 29 * hash + this.getEntityId(); + return hash; + } + + public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { + server.getEntityMetadata().setMetadata(this, metadataKey, newMetadataValue); + } + + public List getMetadata(String metadataKey) { + return server.getEntityMetadata().getMetadata(this, metadataKey); + } + + public boolean hasMetadata(String metadataKey) { + return server.getEntityMetadata().hasMetadata(this, metadataKey); + } + + public void removeMetadata(String metadataKey, Plugin owningPlugin) { + server.getEntityMetadata().removeMetadata(this, metadataKey, owningPlugin); + } + + public boolean isInsideVehicle() { + return getHandle().vehicle != null; + } + + public boolean leaveVehicle() { + if (getHandle().vehicle == null) { + return false; + } + + getHandle().mount(null); + return true; + } + + public org.bukkit.entity.Entity getVehicle() { + if (getHandle().vehicle == null) { + return null; + } + + return getHandle().vehicle.getBukkitEntity(); + } + + @Override + public void setCustomName(String name) { + if (name == null) { + name = ""; + } + + getHandle().setCustomName(name); + } + + @Override + public String getCustomName() { + String name = getHandle().getCustomName(); + + if (name == null || name.length() == 0) { + return null; + } + + return name; + } + + @Override + public void setCustomNameVisible(boolean flag) { + getHandle().setCustomNameVisible(flag); + } + + @Override + public boolean isCustomNameVisible() { + return getHandle().getCustomNameVisible(); + } + + @Override + public void sendMessage(String message) { + + } + + @Override + public void sendMessage(String[] messages) { + + } + + @Override + public String getName() { + return getHandle().getName(); + } + + @Override + public boolean isPermissionSet(String name) { + return perm.isPermissionSet(name); + } + + @Override + public boolean isPermissionSet(Permission perm) { + return CraftEntity.perm.isPermissionSet(perm); + } + + @Override + public boolean hasPermission(String name) { + return perm.hasPermission(name); + } + + @Override + public boolean hasPermission(Permission perm) { + return this.perm.hasPermission(perm); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + return perm.addAttachment(plugin, name, value); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin) { + return perm.addAttachment(plugin); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + return perm.addAttachment(plugin, name, value, ticks); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + return perm.addAttachment(plugin, ticks); + } + + @Override + public void removeAttachment(PermissionAttachment attachment) { + perm.removeAttachment(attachment); + } + + @Override + public void recalculatePermissions() { + perm.recalculatePermissions(); + } + + @Override + public Set getEffectivePermissions() { + return perm.getEffectivePermissions(); + } + + @Override + public boolean isOp() { + return perm.isOp(); + } + + @Override + public void setOp(boolean value) { + perm.setOp(value); + } + + // Spigot start + private final Spigot spigot = new Spigot() + { + @Override + public boolean isInvulnerable() + { + return getHandle().isInvulnerable(net.minecraft.server.DamageSource.GENERIC); + } + }; + + public Spigot spigot() + { + return spigot; + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java new file mode 100644 index 0000000..3a09cab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java @@ -0,0 +1,34 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityExperienceOrb; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ExperienceOrb; + +public class CraftExperienceOrb extends CraftEntity implements ExperienceOrb { + public CraftExperienceOrb(CraftServer server, EntityExperienceOrb entity) { + super(server, entity); + } + + public int getExperience() { + return getHandle().value; + } + + public void setExperience(int value) { + getHandle().value = value; + } + + @Override + public EntityExperienceOrb getHandle() { + return (EntityExperienceOrb) entity; + } + + @Override + public String toString() { + return "CraftExperienceOrb"; + } + + public EntityType getType() { + return EntityType.EXPERIENCE_ORB; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingSand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingSand.java new file mode 100644 index 0000000..eedb66f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFallingSand.java @@ -0,0 +1,67 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityFallingBlock; + +import org.bukkit.Material; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingSand; + +public class CraftFallingSand extends CraftEntity implements FallingSand { + + public CraftFallingSand(CraftServer server, EntityFallingBlock entity) { + super(server, entity); + } + + @Override + public EntityFallingBlock getHandle() { + return (EntityFallingBlock) entity; + } + + @Override + public String toString() { + return "CraftFallingSand"; + } + + public EntityType getType() { + return EntityType.FALLING_BLOCK; + } + + public Material getMaterial() { + return Material.getMaterial(getBlockId()); + } + + public int getBlockId() { + return CraftMagicNumbers.getId(getHandle().getBlock().getBlock()); + } + + public byte getBlockData() { + return (byte) getHandle().getBlock().getBlock().toLegacyData(getHandle().getBlock()); + } + + public boolean getDropItem() { + return getHandle().dropItem; + } + + public void setDropItem(boolean drop) { + getHandle().dropItem = drop; + } + + @Override + public boolean canHurtEntities() { + return getHandle().hurtEntities; + } + + @Override + public void setHurtEntities(boolean hurtEntities) { + getHandle().hurtEntities = hurtEntities; + } + + // PaperSpigot start - Add FallingBlock source location API + @Override + public org.bukkit.Location getSourceLoc() { + return getHandle().sourceLoc; + } + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java new file mode 100644 index 0000000..6f0b942 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java @@ -0,0 +1,89 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityFireball; +import net.minecraft.server.MathHelper; + +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Fireball; +import org.bukkit.entity.LivingEntity; +import org.bukkit.projectiles.ProjectileSource; +import org.bukkit.util.Vector; + +public class CraftFireball extends AbstractProjectile implements Fireball { + public CraftFireball(CraftServer server, EntityFireball entity) { + super(server, entity); + } + + public float getYield() { + return getHandle().bukkitYield; + } + + public boolean isIncendiary() { + return getHandle().isIncendiary; + } + + public void setIsIncendiary(boolean isIncendiary) { + getHandle().isIncendiary = isIncendiary; + } + + public void setYield(float yield) { + getHandle().bukkitYield = yield; + } + + public ProjectileSource getShooter() { + return getHandle().projectileSource; + } + + public void setShooter(ProjectileSource shooter) { + if (shooter instanceof CraftLivingEntity) { + getHandle().shooter = ((CraftLivingEntity) shooter).getHandle(); + } else { + getHandle().shooter = null; + } + getHandle().projectileSource = shooter; + } + + public Vector getDirection() { + return new Vector(getHandle().dirX, getHandle().dirY, getHandle().dirZ); + } + + public void setDirection(Vector direction) { + Validate.notNull(direction, "Direction can not be null"); + double x = direction.getX(); + double y = direction.getY(); + double z = direction.getZ(); + double magnitude = (double) MathHelper.sqrt(x * x + y * y + z * z); + getHandle().dirX = x / magnitude; + getHandle().dirY = y / magnitude; + getHandle().dirZ = z / magnitude; + } + + @Override + public EntityFireball getHandle() { + return (EntityFireball) entity; + } + + @Override + public String toString() { + return "CraftFireball"; + } + + public EntityType getType() { + return EntityType.UNKNOWN; + } + + @Deprecated + public void _INVALID_setShooter(LivingEntity shooter) { + setShooter(shooter); + } + + @Deprecated + public LivingEntity _INVALID_getShooter() { + if (getHandle().shooter != null) { + return (LivingEntity) getHandle().shooter.getBukkitEntity(); + } + return null; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java new file mode 100644 index 0000000..76a9bdb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java @@ -0,0 +1,74 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityFireworks; +import net.minecraft.server.ItemStack; +import net.minecraft.server.Items; + +import org.bukkit.Material; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Firework; +import org.bukkit.inventory.meta.FireworkMeta; + +import java.util.Random; + +public class CraftFirework extends CraftEntity implements Firework { + private static final int FIREWORK_ITEM_INDEX = 8; + + private final Random random = new Random(); + private final CraftItemStack item; + + public CraftFirework(CraftServer server, EntityFireworks entity) { + super(server, entity); + + ItemStack item = getHandle().getDataWatcher().getItemStack(FIREWORK_ITEM_INDEX); + + if (item == null) { + item = new ItemStack(Items.FIREWORKS); + getHandle().getDataWatcher().watch(FIREWORK_ITEM_INDEX, item); + } + + this.item = CraftItemStack.asCraftMirror(item); + + // Ensure the item is a firework... + if (this.item.getType() != Material.FIREWORK) { + this.item.setType(Material.FIREWORK); + } + } + + @Override + public EntityFireworks getHandle() { + return (EntityFireworks) entity; + } + + @Override + public String toString() { + return "CraftFirework"; + } + + @Override + public EntityType getType() { + return EntityType.FIREWORK; + } + + @Override + public FireworkMeta getFireworkMeta() { + return (FireworkMeta) item.getItemMeta(); + } + + @Override + public void setFireworkMeta(FireworkMeta meta) { + item.setItemMeta(meta); + + // Copied from EntityFireworks constructor, update firework lifetime/power + getHandle().expectedLifespan = 10 * (1 + meta.getPower()) + random.nextInt(6) + random.nextInt(7); + + getHandle().getDataWatcher().update(FIREWORK_ITEM_INDEX); + } + + @Override + public void detonate() { + getHandle().expectedLifespan = 0; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java new file mode 100644 index 0000000..ecfc316 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java @@ -0,0 +1,76 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.EntityFishingHook; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.MathHelper; + +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Fish; +import org.bukkit.entity.LivingEntity; +import org.bukkit.projectiles.ProjectileSource; + +public class CraftFish extends AbstractProjectile implements Fish { + private double biteChance = -1; + + public CraftFish(CraftServer server, EntityFishingHook entity) { + super(server, entity); + } + + public ProjectileSource getShooter() { + if (getHandle().owner != null) { + return getHandle().owner.getBukkitEntity(); + } + + return null; + } + + public void setShooter(ProjectileSource shooter) { + if (shooter instanceof CraftHumanEntity) { + getHandle().owner = (EntityHuman) ((CraftHumanEntity) shooter).entity; + } + } + + @Override + public EntityFishingHook getHandle() { + return (EntityFishingHook) entity; + } + + @Override + public String toString() { + return "CraftFish"; + } + + public EntityType getType() { + return EntityType.FISHING_HOOK; + } + + public double getBiteChance() { + EntityFishingHook hook = getHandle(); + + if (this.biteChance == -1) { + if (hook.world.isRainingAt(new BlockPosition(MathHelper.floor(hook.locX), MathHelper.floor(hook.locY) + 1, MathHelper.floor(hook.locZ)))) { + return 1/300.0; + } + return 1/500.0; + } + return this.biteChance; + } + + public void setBiteChance(double chance) { + Validate.isTrue(chance >= 0 && chance <= 1, "The bite chance must be between 0 and 1."); + this.biteChance = chance; + } + + @Deprecated + public LivingEntity _INVALID_getShooter() { + return (LivingEntity) getShooter(); + } + + @Deprecated + public void _INVALID_setShooter(LivingEntity shooter) { + setShooter(shooter); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java new file mode 100644 index 0000000..f374c7b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java @@ -0,0 +1,22 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityFlying; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Flying; + +public class CraftFlying extends CraftLivingEntity implements Flying { + + public CraftFlying(CraftServer server, EntityFlying entity) { + super(server, entity); + } + + @Override + public EntityFlying getHandle() { + return (EntityFlying) entity; + } + + @Override + public String toString() { + return "CraftFlying"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java new file mode 100644 index 0000000..ee9516f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityGhast; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Ghast; + +public class CraftGhast extends CraftFlying implements Ghast { + + public CraftGhast(CraftServer server, EntityGhast entity) { + super(server, entity); + } + + @Override + public EntityGhast getHandle() { + return (EntityGhast) entity; + } + + @Override + public String toString() { + return "CraftGhast"; + } + + public EntityType getType() { + return EntityType.GHAST; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java new file mode 100644 index 0000000..e560913 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityGiantZombie; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Giant; + +public class CraftGiant extends CraftMonster implements Giant { + + public CraftGiant(CraftServer server, EntityGiantZombie entity) { + super(server, entity); + } + + @Override + public EntityGiantZombie getHandle() { + return (EntityGiantZombie) entity; + } + + @Override + public String toString() { + return "CraftGiant"; + } + + public EntityType getType() { + return EntityType.GIANT; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGolem.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGolem.java new file mode 100644 index 0000000..1fef5e0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGolem.java @@ -0,0 +1,21 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityGolem; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Golem; + +public class CraftGolem extends CraftCreature implements Golem { + public CraftGolem(CraftServer server, EntityGolem entity) { + super(server, entity); + } + + @Override + public EntityGolem getHandle() { + return (EntityGolem) entity; + } + + @Override + public String toString() { + return "CraftGolem"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGuardian.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGuardian.java new file mode 100644 index 0000000..3a0ce67 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftGuardian.java @@ -0,0 +1,56 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityGuardian; +import net.minecraft.server.GenericAttributes; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Guardian; + +public class CraftGuardian extends CraftMonster implements Guardian { + + public CraftGuardian(CraftServer server, EntityGuardian entity) { + super(server, entity); + } + + @Override + public String toString() { + return "CraftGuardian"; + } + + @Override + public EntityType getType() { + return EntityType.GUARDIAN; + } + + @Override + public boolean isElder() { + return ((EntityGuardian)entity).isElder(); + } + + @Override + public void setElder( boolean shouldBeElder ) { + EntityGuardian entityGuardian = (EntityGuardian) entity; + + if (!isElder() && shouldBeElder) { + entityGuardian.setElder(true); + } else if (isElder() && !shouldBeElder) { + entityGuardian.setElder(false); + + // Since minecraft does not reset the elder Guardian to a guardian we have to do that + entity.setSize(0.85F, 0.85F); + + // Since aW() calls its supers it will try to re register attributes which is invalid + // check these on update + entityGuardian.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(6.0D); + entityGuardian.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.5D); + entityGuardian.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(16.0D); + entityGuardian.getAttributeInstance(GenericAttributes.maxHealth).setValue(30.0D); + + // Update pathfinding (random stroll back to 80) + entityGuardian.goalRandomStroll.setTimeBetweenMovement(80); + + // Tell minecraft that we need persistence since the guardian changed + entityGuardian.initAttributes(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java new file mode 100644 index 0000000..411c023 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java @@ -0,0 +1,80 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.EntityHanging; +import net.minecraft.server.EnumDirection; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Hanging; + +public class CraftHanging extends CraftEntity implements Hanging { + public CraftHanging(CraftServer server, EntityHanging entity) { + super(server, entity); + } + + public BlockFace getAttachedFace() { + return getFacing().getOppositeFace(); + } + + public void setFacingDirection(BlockFace face) { + setFacingDirection(face, false); + } + + public boolean setFacingDirection(BlockFace face, boolean force) { + EntityHanging hanging = getHandle(); + EnumDirection dir = hanging.direction; + switch (face) { + case SOUTH: + default: + getHandle().setDirection(EnumDirection.SOUTH); + break; + case WEST: + getHandle().setDirection(EnumDirection.WEST); + break; + case NORTH: + getHandle().setDirection(EnumDirection.NORTH); + break; + case EAST: + getHandle().setDirection(EnumDirection.EAST); + break; + } + if (!force && !hanging.survives()) { + // Revert since it doesn't fit + hanging.setDirection(dir); + return false; + } + return true; + } + + public BlockFace getFacing() { + EnumDirection direction = this.getHandle().direction; + if (direction == null) return BlockFace.SELF; + switch (direction) { + case SOUTH: + default: + return BlockFace.SOUTH; + case WEST: + return BlockFace.WEST; + case NORTH: + return BlockFace.NORTH; + case EAST: + return BlockFace.EAST; + } + } + + @Override + public EntityHanging getHandle() { + return (EntityHanging) entity; + } + + @Override + public String toString() { + return "CraftHanging"; + } + + public EntityType getType() { + return EntityType.UNKNOWN; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java new file mode 100644 index 0000000..230ae9e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java @@ -0,0 +1,146 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityHorse; +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftInventoryHorse; +import org.bukkit.entity.AnimalTamer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse; +import org.bukkit.inventory.HorseInventory; + +import java.util.UUID; + +public class CraftHorse extends CraftAnimals implements Horse { + + public CraftHorse(CraftServer server, EntityHorse entity) { + super(server, entity); + } + + @Override + public EntityHorse getHandle() { + return (EntityHorse) entity; + } + + public Variant getVariant() { + return Variant.values()[getHandle().getType()]; + } + + public void setVariant(Variant variant) { + Validate.notNull(variant, "Variant cannot be null"); + getHandle().setType(variant.ordinal()); + } + + public Color getColor() { + return Color.values()[getHandle().getVariant() & 0xFF]; + } + + public void setColor(Color color) { + Validate.notNull(color, "Color cannot be null"); + getHandle().setVariant(color.ordinal() & 0xFF | getStyle().ordinal() << 8); + } + + public Style getStyle() { + return Style.values()[getHandle().getVariant() >>> 8]; + } + + public void setStyle(Style style) { + Validate.notNull(style, "Style cannot be null"); + getHandle().setVariant(getColor().ordinal() & 0xFF | style.ordinal() << 8); + } + + public boolean isCarryingChest() { + return getHandle().hasChest(); + } + + public void setCarryingChest(boolean chest) { + if (chest == isCarryingChest()) return; + getHandle().setHasChest(chest); + getHandle().loadChest(); + } + + public int getDomestication() { + return getHandle().getTemper(); + } + + public void setDomestication(int value) { + Validate.isTrue(value >= 0, "Domestication cannot be less than zero"); + Validate.isTrue(value <= getMaxDomestication(), "Domestication cannot be greater than the max domestication"); + getHandle().setTemper(value); + } + + public int getMaxDomestication() { + return getHandle().getMaxDomestication(); + } + + public void setMaxDomestication(int value) { + Validate.isTrue(value > 0, "Max domestication cannot be zero or less"); + getHandle().maxDomestication = value; + } + + public double getJumpStrength() { + return getHandle().getJumpStrength(); + } + + public void setJumpStrength(double strength) { + Validate.isTrue(strength >= 0, "Jump strength cannot be less than zero"); + getHandle().getAttributeInstance(EntityHorse.attributeJumpStrength).setValue(strength); + } + + @Override + public boolean isTamed() { + return getHandle().isTame(); + } + + @Override + public void setTamed(boolean tamed) { + getHandle().setTame(tamed); + } + + @Override + public AnimalTamer getOwner() { + if (getOwnerUUID() == null) return null; + return getServer().getOfflinePlayer(getOwnerUUID()); + } + + @Override + public void setOwner(AnimalTamer owner) { + if (owner != null) { + setTamed(true); + getHandle().setGoalTarget(null, null, false); + setOwnerUUID(owner.getUniqueId()); + } else { + setTamed(false); + setOwnerUUID(null); + } + } + + public UUID getOwnerUUID() { + try { + return UUID.fromString(getHandle().getOwnerUUID()); + } catch (IllegalArgumentException ex) { + return null; + } + } + + public void setOwnerUUID(UUID uuid) { + if (uuid == null) { + getHandle().setOwnerUUID(""); + } else { + getHandle().setOwnerUUID(uuid.toString()); + } + } + + public HorseInventory getInventory() { + return new CraftInventoryHorse(getHandle().inventoryChest); + } + + @Override + public String toString() { + return "CraftHorse{variant=" + getVariant() + ", owner=" + getOwner() + '}'; + } + + public EntityType getType() { + return EntityType.HORSE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java new file mode 100644 index 0000000..8a08bab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -0,0 +1,365 @@ +package org.bukkit.craftbukkit.entity; + +import java.util.Set; + +import net.minecraft.server.*; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.craftbukkit.inventory.CraftContainer; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.craftbukkit.inventory.CraftInventoryPlayer; +import org.bukkit.craftbukkit.inventory.CraftInventoryView; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.permissions.PermissibleBase; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + +public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + private CraftInventoryPlayer inventory; + private final CraftInventory enderChest; + protected final PermissibleBase perm = new PermissibleBase(this); + private boolean op; + private GameMode mode; + + public CraftHumanEntity(final CraftServer server, final EntityHuman entity) { + super(server, entity); + mode = server.getDefaultGameMode(); + this.inventory = new CraftInventoryPlayer(entity.inventory); + enderChest = new CraftInventory(entity.getEnderChest()); + } + + public String getName() { + return getHandle().getName(); + } + + public PlayerInventory getInventory() { + return inventory; + } + + public EntityEquipment getEquipment() { + return inventory; + } + + public Inventory getEnderChest() { + return enderChest; + } + + public ItemStack getItemInHand() { + return getInventory().getItemInHand(); + } + + public void setItemInHand(ItemStack item) { + getInventory().setItemInHand(item); + } + + public ItemStack getItemOnCursor() { + return CraftItemStack.asCraftMirror(getHandle().inventory.getCarried()); + } + + public void setItemOnCursor(ItemStack item) { + net.minecraft.server.ItemStack stack = CraftItemStack.asNMSCopy(item); + getHandle().inventory.setCarried(stack); + if (this instanceof CraftPlayer) { + ((EntityPlayer) getHandle()).broadcastCarriedItem(); // Send set slot for cursor + } + } + + public boolean isSleeping() { + return getHandle().sleeping; + } + + public int getSleepTicks() { + return getHandle().sleepTicks; + } + + public boolean isOp() { + return op; + } + + public boolean isPermissionSet(String name) { + return perm.isPermissionSet(name); + } + + public boolean isPermissionSet(Permission perm) { + return this.perm.isPermissionSet(perm); + } + + public boolean hasPermission(String name) { + return perm.hasPermission(name); + } + + public boolean hasPermission(Permission perm) { + return this.perm.hasPermission(perm); + } + + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + return perm.addAttachment(plugin, name, value); + } + + public PermissionAttachment addAttachment(Plugin plugin) { + return perm.addAttachment(plugin); + } + + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + return perm.addAttachment(plugin, name, value, ticks); + } + + public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + return perm.addAttachment(plugin, ticks); + } + + public void removeAttachment(PermissionAttachment attachment) { + perm.removeAttachment(attachment); + } + + public void recalculatePermissions() { + perm.recalculatePermissions(); + } + + public void setOp(boolean value) { + this.op = value; + perm.recalculatePermissions(); + } + + public Set getEffectivePermissions() { + return perm.getEffectivePermissions(); + } + + public GameMode getGameMode() { + return mode; + } + + public void setGameMode(GameMode mode) { + if (mode == null) { + throw new IllegalArgumentException("Mode cannot be null"); + } + + this.mode = mode; + } + + @Override + public EntityHuman getHandle() { + return (EntityHuman) entity; + } + + public void setHandle(final EntityHuman entity) { + super.setHandle(entity); + this.inventory = new CraftInventoryPlayer(entity.inventory); + } + + @Override + public String toString() { + return "CraftHumanEntity{" + "id=" + getEntityId() + "name=" + getName() + '}'; + } + + public InventoryView getOpenInventory() { + return getHandle().activeContainer.getBukkitView(); + } + + public InventoryView openInventory(Inventory inventory) { + if(!(getHandle() instanceof EntityPlayer)) return null; + EntityPlayer player = (EntityPlayer) getHandle(); + InventoryType type = inventory.getType(); + Container formerContainer = getHandle().activeContainer; + + IInventory iinventory = (inventory instanceof CraftInventory) ? ((CraftInventory) inventory).getInventory() : new org.bukkit.craftbukkit.inventory.InventoryWrapper(inventory); + + switch (type) { + case PLAYER: + case CHEST: + case ENDER_CHEST: + getHandle().openContainer(iinventory); + break; + case DISPENSER: + if (iinventory instanceof TileEntityDispenser) { + getHandle().openContainer((TileEntityDispenser) iinventory); + } else { + openCustomInventory(inventory, player, "minecraft:dispenser"); + } + break; + case DROPPER: + if (iinventory instanceof TileEntityDropper) { + getHandle().openContainer((TileEntityDropper) iinventory); + } else { + openCustomInventory(inventory, player, "minecraft:dropper"); + } + break; + case FURNACE: + if (iinventory instanceof TileEntityFurnace) { + getHandle().openContainer((TileEntityFurnace) iinventory); + } else { + openCustomInventory(inventory, player, "minecraft:furnace"); + } + break; + case WORKBENCH: + openCustomInventory(inventory, player, "minecraft:crafting_table"); + break; + case BREWING: + if (iinventory instanceof TileEntityBrewingStand) { + getHandle().openContainer((TileEntityBrewingStand) iinventory); + } else { + openCustomInventory(inventory, player, "minecraft:brewing_stand"); + } + break; + case ENCHANTING: + openCustomInventory(inventory, player, "minecraft:enchanting_table"); + break; + case HOPPER: + if (iinventory instanceof TileEntityHopper) { + getHandle().openContainer((TileEntityHopper) iinventory); + } else if (iinventory instanceof EntityMinecartHopper) { + getHandle().openContainer((EntityMinecartHopper) iinventory); + } else { + openCustomInventory(inventory, player, "minecraft:hopper"); + } + break; + case BEACON: + if (iinventory instanceof TileEntityBeacon) { + getHandle().openContainer((TileEntityBeacon) iinventory); + } else { + openCustomInventory(inventory, player, "minecraft:beacon"); + } + break; + case ANVIL: + if (iinventory instanceof BlockAnvil.TileEntityContainerAnvil) { + getHandle().openTileEntity((BlockAnvil.TileEntityContainerAnvil) iinventory); + } else { + openCustomInventory(inventory, player, "minecraft:anvil"); + } + break; + case CREATIVE: + case CRAFTING: + throw new IllegalArgumentException("Can't open a " + type + " inventory!"); + } + if (getHandle().activeContainer == formerContainer) { + return null; + } + getHandle().activeContainer.checkReachable = false; + return getHandle().activeContainer.getBukkitView(); + } + + private void openCustomInventory(Inventory inventory, EntityPlayer player, String windowType) { + if (player.playerConnection == null) return; + Container container = new CraftContainer(inventory, this, player.nextContainerCounter()); + + container = CraftEventFactory.callInventoryOpenEvent(player, container); + if(container == null) return; + + String title = container.getBukkitView().getTitle(); + int size = container.getBukkitView().getTopInventory().getSize(); + + // Special cases + if (windowType.equals("minecraft:crafting_table") + || windowType.equals("minecraft:anvil") + || windowType.equals("minecraft:enchanting_table") + ) { + size = 0; + } + + player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title), size)); + getHandle().activeContainer = container; + getHandle().activeContainer.addSlotListener(player); + } + + public InventoryView openWorkbench(Location location, boolean force) { + if (!force) { + Block block = location.getBlock(); + if (block.getType() != Material.WORKBENCH) { + return null; + } + } + if (location == null) { + location = getLocation(); + } + getHandle().openTileEntity(new BlockWorkbench.TileEntityContainerWorkbench(getHandle().world, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()))); + if (force) { + getHandle().activeContainer.checkReachable = false; + } + return getHandle().activeContainer.getBukkitView(); + } + + public InventoryView openEnchanting(Location location, boolean force) { + if (!force) { + Block block = location.getBlock(); + if (block.getType() != Material.ENCHANTMENT_TABLE) { + return null; + } + } + if (location == null) { + location = getLocation(); + } + + // If there isn't an enchant table we can force create one, won't be very useful though. + TileEntity container = getHandle().world.getTileEntity(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + if (container == null && force) { + container = new TileEntityEnchantTable(); + } + getHandle().openTileEntity((ITileEntityContainer) container); + + if (force) { + getHandle().activeContainer.checkReachable = false; + } + return getHandle().activeContainer.getBukkitView(); + } + + public void openInventory(InventoryView inventory) { + if (!(getHandle() instanceof EntityPlayer)) return; // TODO: NPC support? + if (((EntityPlayer) getHandle()).playerConnection == null) return; + if (getHandle().activeContainer != getHandle().defaultContainer) { + // fire INVENTORY_CLOSE if one already open + ((EntityPlayer)getHandle()).playerConnection.a(new PacketPlayInCloseWindow(getHandle().activeContainer.windowId)); + } + EntityPlayer player = (EntityPlayer) getHandle(); + Container container; + if (inventory instanceof CraftInventoryView) { + container = ((CraftInventoryView) inventory).getHandle(); + } else { + container = new CraftContainer(inventory, player.nextContainerCounter()); + } + + // Trigger an INVENTORY_OPEN event + container = CraftEventFactory.callInventoryOpenEvent(player, container); + if (container == null) { + return; + } + + // Now open the window + InventoryType type = inventory.getType(); + String windowType = CraftContainer.getNotchInventoryType(type); + String title = inventory.getTitle(); + int size = inventory.getTopInventory().getSize(); + player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(container.windowId, windowType, new ChatComponentText(title), size)); + player.activeContainer = container; + player.activeContainer.addSlotListener(player); + } + + public void closeInventory() { + getHandle().closeInventory(); + } + + public boolean isBlocking() { + return getHandle().isBlocking(); + } + + public boolean setWindowProperty(InventoryView.Property prop, int value) { + return false; + } + + public int getExpToLevel() { + return getHandle().getExpToLevel(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java new file mode 100644 index 0000000..ddee207 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java @@ -0,0 +1,35 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityIronGolem; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.IronGolem; + +public class CraftIronGolem extends CraftGolem implements IronGolem { + public CraftIronGolem(CraftServer server, EntityIronGolem entity) { + super(server, entity); + } + + @Override + public EntityIronGolem getHandle() { + return (EntityIronGolem) entity; + } + + @Override + public String toString() { + return "CraftIronGolem"; + } + + public boolean isPlayerCreated() { + return getHandle().isPlayerCreated(); + } + + public void setPlayerCreated(boolean playerCreated) { + getHandle().setPlayerCreated(playerCreated); + } + + @Override + public EntityType getType() { + return EntityType.IRON_GOLEM; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java new file mode 100644 index 0000000..a17a537 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java @@ -0,0 +1,48 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.Entity; +import net.minecraft.server.EntityItem; + +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.inventory.ItemStack; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.CraftServer; + +public class CraftItem extends CraftEntity implements Item { + private final EntityItem item; + + public CraftItem(CraftServer server, Entity entity, EntityItem item) { + super(server, entity); + this.item = item; + } + + public CraftItem(CraftServer server, EntityItem entity) { + this(server, entity, entity); + } + + public ItemStack getItemStack() { + return CraftItemStack.asCraftMirror(item.getItemStack()); + } + + public void setItemStack(ItemStack stack) { + item.setItemStack(CraftItemStack.asNMSCopy(stack)); + } + + public int getPickupDelay() { + return item.pickupDelay; + } + + public void setPickupDelay(int delay) { + item.pickupDelay = Math.min(delay, Short.MAX_VALUE); + } + + @Override + public String toString() { + return "CraftItem"; + } + + public EntityType getType() { + return EntityType.DROPPED_ITEM; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java new file mode 100644 index 0000000..d27f24f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java @@ -0,0 +1,133 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.BlockPosition; +import net.minecraft.server.EntityItemFrame; +import net.minecraft.server.EnumDirection; +import net.minecraft.server.ItemStack; +import net.minecraft.server.WorldServer; + +import org.apache.commons.lang.Validate; + +import org.bukkit.Rotation; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ItemFrame; + +public class CraftItemFrame extends CraftHanging implements ItemFrame { + public CraftItemFrame(CraftServer server, EntityItemFrame entity) { + super(server, entity); + } + + public boolean setFacingDirection(BlockFace face, boolean force) { + if (!super.setFacingDirection(face, force)) { + return false; + } + + update(); + + return true; + } + + private void update() { + EntityItemFrame old = this.getHandle(); + + WorldServer world = ((CraftWorld) getWorld()).getHandle(); + BlockPosition position = old.getBlockPosition(); + EnumDirection direction = old.getDirection(); + ItemStack item = old.getItem() != null ? old.getItem().cloneItemStack() : null; + + old.die(); + + EntityItemFrame frame = new EntityItemFrame(world,position,direction); + frame.setItem(item); + world.addEntity(frame); + this.entity = frame; + } + + + public void setItem(org.bukkit.inventory.ItemStack item) { + if (item == null || item.getTypeId() == 0) { + getHandle().setItem(null); + } else { + getHandle().setItem(CraftItemStack.asNMSCopy(item)); + } + } + + public org.bukkit.inventory.ItemStack getItem() { + return CraftItemStack.asBukkitCopy(getHandle().getItem()); + } + + public Rotation getRotation() { + return toBukkitRotation(getHandle().getRotation()); + } + + Rotation toBukkitRotation(int value) { + // Translate NMS rotation integer to Bukkit API + switch (value) { + case 0: + return Rotation.NONE; + case 1: + return Rotation.CLOCKWISE_45; + case 2: + return Rotation.CLOCKWISE; + case 3: + return Rotation.CLOCKWISE_135; + case 4: + return Rotation.FLIPPED; + case 5: + return Rotation.FLIPPED_45; + case 6: + return Rotation.COUNTER_CLOCKWISE; + case 7: + return Rotation.COUNTER_CLOCKWISE_45; + default: + throw new AssertionError("Unknown rotation " + value + " for " + getHandle()); + } + } + + public void setRotation(Rotation rotation) { + Validate.notNull(rotation, "Rotation cannot be null"); + getHandle().setRotation(toInteger(rotation)); + } + + static int toInteger(Rotation rotation) { + // Translate Bukkit API rotation to NMS integer + switch (rotation) { + case NONE: + return 0; + case CLOCKWISE_45: + return 1; + case CLOCKWISE: + return 2; + case CLOCKWISE_135: + return 3; + case FLIPPED: + return 4; + case FLIPPED_45: + return 5; + case COUNTER_CLOCKWISE: + return 6; + case COUNTER_CLOCKWISE_45: + return 7; + default: + throw new IllegalArgumentException(rotation + " is not applicable to an ItemFrame"); + } + } + + @Override + public EntityItemFrame getHandle() { + return (EntityItemFrame) entity; + } + + @Override + public String toString() { + return "CraftItemFrame{item=" + getItem() + ", rotation=" + getRotation() + "}"; + } + + public EntityType getType() { + return EntityType.ITEM_FRAME; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java new file mode 100644 index 0000000..ca03794 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java @@ -0,0 +1,32 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityLargeFireball; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LargeFireball; + +public class CraftLargeFireball extends CraftFireball implements LargeFireball { + public CraftLargeFireball(CraftServer server, EntityLargeFireball entity) { + super(server, entity); + } + + @Override + public void setYield(float yield) { + super.setYield(yield); + getHandle().yield = (int) yield; + } + + @Override + public EntityLargeFireball getHandle() { + return (EntityLargeFireball) entity; + } + + @Override + public String toString() { + return "CraftLargeFireball"; + } + + public EntityType getType() { + return EntityType.FIREBALL; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java new file mode 100644 index 0000000..710ed7a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityLeash; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LeashHitch; + +public class CraftLeash extends CraftHanging implements LeashHitch { + public CraftLeash(CraftServer server, EntityLeash entity) { + super(server, entity); + } + + @Override + public EntityLeash getHandle() { + return (EntityLeash) entity; + } + + @Override + public String toString() { + return "CraftLeash"; + } + + public EntityType getType() { + return EntityType.LEASH_HITCH; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java new file mode 100644 index 0000000..0bacc83 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java @@ -0,0 +1,46 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityLightning; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LightningStrike; + +public class CraftLightningStrike extends CraftEntity implements LightningStrike { + public CraftLightningStrike(final CraftServer server, final EntityLightning entity) { + super(server, entity); + } + + public boolean isEffect() { + return ((EntityLightning) super.getHandle()).isEffect; + } + + @Override + public EntityLightning getHandle() { + return (EntityLightning) entity; + } + + @Override + public String toString() { + return "CraftLightningStrike"; + } + + public EntityType getType() { + return EntityType.LIGHTNING; + } + + // Spigot start + private final LightningStrike.Spigot spigot = new LightningStrike.Spigot() { + + @Override + public boolean isSilent() + { + return getHandle().isSilent; + } + }; + + @Override + public LightningStrike.Spigot spigot() { + return spigot; + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java new file mode 100644 index 0000000..5d164c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java @@ -0,0 +1,498 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.*; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.inventory.CraftEntityEquipment; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Entity; +import org.bukkit.entity.*; +import org.bukkit.event.entity.PotionEffectAddEvent; +import org.bukkit.event.entity.PotionEffectExtendEvent; +import org.bukkit.event.entity.PotionEffectRemoveEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.BlockIterator; +import org.bukkit.util.NumberConversions; +import org.bukkit.util.Vector; + +import java.util.*; + +public class CraftLivingEntity extends CraftEntity implements LivingEntity { + private CraftEntityEquipment equipment; + + public CraftLivingEntity(final CraftServer server, final EntityLiving entity) { + super(server, entity); + + if (entity instanceof EntityInsentient || entity instanceof EntityArmorStand) { + equipment = new CraftEntityEquipment(this); + } + } + + public double getHealth() { + return Math.min(Math.max(0, getHandle().getHealth()), getMaxHealth()); + } + + public void setHealth(double health) { + if ((health < 0) || (health > getMaxHealth())) { + throw new IllegalArgumentException("Health must be between 0 and " + getMaxHealth() + ", but was " + health + + ". (attribute base value: " + this.getHandle().getAttributeInstance(GenericAttributes.maxHealth).b() + + (this instanceof CraftPlayer ? ", player: " + this.getName() + ')' : ')')); + } + + if (entity instanceof EntityPlayer && health == 0) { + ((EntityPlayer) entity).die(DamageSource.GENERIC); + } + + getHandle().setHealth((float) health); + } + + public double getMaxHealth() { + return getHandle().getMaxHealth(); + } + + public void setMaxHealth(double amount) { + Validate.isTrue(amount > 0, "Max health must be greater than 0"); + + getHandle().getAttributeInstance(GenericAttributes.maxHealth).setValue(amount); + + if (getHealth() > amount) { + setHealth(amount); + } + } + + public void resetMaxHealth() { + setMaxHealth(getHandle().getMaxHealth()); + } + + @Deprecated + public Egg throwEgg() { + return launchProjectile(Egg.class); + } + + @Deprecated + public Snowball throwSnowball() { + return launchProjectile(Snowball.class); + } + + public double getEyeHeight() { + return getHandle().getHeadHeight(); + } + + public double getEyeHeight(boolean ignoreSneaking) { + return getEyeHeight(); + } + + private List getLineOfSight(HashSet transparent, int maxDistance, int maxLength) { + if (maxDistance > 120) { + maxDistance = 120; + } + ArrayList blocks = new ArrayList(); + Iterator itr = new BlockIterator(this, maxDistance); + while (itr.hasNext()) { + Block block = itr.next(); + blocks.add(block); + if (maxLength != 0 && blocks.size() > maxLength) { + blocks.remove(0); + } + int id = block.getTypeId(); + if (transparent == null) { + if (id != 0) { + break; + } + } else { + if (!transparent.contains((byte) id)) { + break; + } + } + } + return blocks; + } + + private List getLineOfSight(Set transparent, int maxDistance, int maxLength) { + if (maxDistance > 120) { + maxDistance = 120; + } + ArrayList blocks = new ArrayList(); + Iterator itr = new BlockIterator(this, maxDistance); + while (itr.hasNext()) { + Block block = itr.next(); + blocks.add(block); + if (maxLength != 0 && blocks.size() > maxLength) { + blocks.remove(0); + } + Material material = block.getType(); + if (transparent == null) { + if (!material.equals(Material.AIR)) { + break; + } + } else { + if (!transparent.contains(material)) { + break; + } + } + } + return blocks; + } + + public List getLineOfSight(HashSet transparent, int maxDistance) { + return getLineOfSight(transparent, maxDistance, 0); + } + + public List getLineOfSight(Set transparent, int maxDistance) { + return getLineOfSight(transparent, maxDistance, 0); + } + + public Block getTargetBlock(HashSet transparent, int maxDistance) { + List blocks = getLineOfSight(transparent, maxDistance, 1); + return blocks.get(0); + } + + public Block getTargetBlock(Set transparent, int maxDistance) { + List blocks = getLineOfSight(transparent, maxDistance, 1); + return blocks.get(0); + } + + public List getLastTwoTargetBlocks(HashSet transparent, int maxDistance) { + return getLineOfSight(transparent, maxDistance, 2); + } + + public List getLastTwoTargetBlocks(Set transparent, int maxDistance) { + return getLineOfSight(transparent, maxDistance, 2); + } + + @Deprecated + public Arrow shootArrow() { + return launchProjectile(Arrow.class); + } + + public int getRemainingAir() { + return getHandle().getAirTicks(); + } + + public void setRemainingAir(int ticks) { + getHandle().setAirTicks(ticks); + } + + public int getMaximumAir() { + return getHandle().maxAirTicks; + } + + public void setMaximumAir(int ticks) { + getHandle().maxAirTicks = ticks; + } + + public void damage(double amount) { + damage(amount, null); + } + + public void damage(double amount, org.bukkit.entity.Entity source) { + DamageSource reason = DamageSource.GENERIC; + + if (source instanceof HumanEntity) { + reason = DamageSource.playerAttack(((CraftHumanEntity) source).getHandle()); + } else if (source instanceof LivingEntity) { + reason = DamageSource.mobAttack(((CraftLivingEntity) source).getHandle()); + } + + entity.damageEntity(reason, (float) amount); + } + + public Location getEyeLocation() { + Location loc = getLocation(); + loc.setY(loc.getY() + getEyeHeight()); + return loc; + } + + public int getMaximumNoDamageTicks() { + return getHandle().maxNoDamageTicks; + } + + public void setMaximumNoDamageTicks(int ticks) { + getHandle().maxNoDamageTicks = ticks; + } + + public double getLastDamage() { + return getHandle().lastDamage; + } + + public void setLastDamage(double damage) { + getHandle().lastDamage = (float) damage; + } + + public int getNoDamageTicks() { + return getHandle().noDamageTicks; + } + + public void setNoDamageTicks(int ticks) { + getHandle().noDamageTicks = ticks; + } + + @Override + public EntityLiving getHandle() { + return (EntityLiving) entity; + } + + public void setHandle(final EntityLiving entity) { + super.setHandle(entity); + } + + @Override + public String toString() { + return "CraftLivingEntity{" + "id=" + getEntityId() + '}'; + } + + public Player getKiller() { + return getHandle().killer == null ? null : (Player) getHandle().killer.getBukkitEntity(); + } + + public boolean addPotionEffect(PotionEffect effect) { + return addPotionEffect(effect, false); + } + + public boolean addPotionEffect(PotionEffect effect, boolean force) { + if (hasPotionEffect(effect.getType())) { + if (!force) { + return false; + } + MobEffect mobEffect = getHandle().getEffect(MobEffectList.byId[effect.getType().getId()]); + if(mobEffect != null) { + PotionEffectExtendEvent event = new PotionEffectExtendEvent(this, effect, mobEffect.toBukkit()); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return false; + } + + removePotionEffect(effect.getType()); + } else { + PotionEffectAddEvent event = new PotionEffectAddEvent(this, effect); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return false; + } + getHandle().addEffect(new MobEffect(effect.getType().getId(), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(), effect.hasParticles())); + return true; + } + + public boolean addPotionEffects(Collection effects) { + boolean success = true; + for (PotionEffect effect : effects) { + success &= addPotionEffect(effect); + } + return success; + } + + public boolean hasPotionEffect(PotionEffectType type) { + return getHandle().hasEffect(MobEffectList.byId[type.getId()]); + } + + public void removePotionEffect(PotionEffectType type) { + MobEffect mobEffect = getHandle().getEffect(MobEffectList.byId[type.getId()]); + if(mobEffect != null) { + PotionEffectRemoveEvent event = new PotionEffectRemoveEvent(this, mobEffect.toBukkit()); + Bukkit.getPluginManager().callEvent(event); + if(event.isCancelled()) return; + } + + getHandle().removeEffect(type.getId()); + } + + public Collection getActivePotionEffects() { + List effects = new ArrayList(); + for (Object raw : getHandle().effects.values()) { + if (!(raw instanceof MobEffect)) + continue; + MobEffect handle = (MobEffect) raw; + effects.add(new PotionEffect(PotionEffectType.getById(handle.getEffectId()), handle.getDuration(), handle.getAmplifier(), handle.isAmbient(), handle.isShowParticles())); + } + return effects; + } + + public T launchProjectile(Class projectile) { + return launchProjectile(projectile, null); + } + + @SuppressWarnings("unchecked") + public T launchProjectile(Class projectile, Vector velocity) { + net.minecraft.server.World world = ((CraftWorld) getWorld()).getHandle(); + net.minecraft.server.Entity launch = null; + + if (Snowball.class.isAssignableFrom(projectile)) { + launch = new EntitySnowball(world, getHandle()); + } else if (Egg.class.isAssignableFrom(projectile)) { + launch = new EntityEgg(world, getHandle()); + } else if (EnderPearl.class.isAssignableFrom(projectile)) { + launch = new EntityEnderPearl(world, getHandle()); + } else if (Arrow.class.isAssignableFrom(projectile)) { + launch = new EntityArrow(world, getHandle(), 1); + } else if (ThrownPotion.class.isAssignableFrom(projectile)) { + launch = new EntityPotion(world, getHandle(), CraftItemStack.asNMSCopy(new ItemStack(Material.POTION, 1))); + } else if (ThrownExpBottle.class.isAssignableFrom(projectile)) { + launch = new EntityThrownExpBottle(world, getHandle()); + } else if (Fish.class.isAssignableFrom(projectile) && getHandle() instanceof EntityHuman) { + launch = new EntityFishingHook(world, (EntityHuman) getHandle()); + } else if (Fireball.class.isAssignableFrom(projectile)) { + Location location = getEyeLocation(); + Vector direction = location.getDirection().multiply(10); + + if (SmallFireball.class.isAssignableFrom(projectile)) { + launch = new EntitySmallFireball(world, getHandle(), direction.getX(), direction.getY(), direction.getZ()); + } else if (WitherSkull.class.isAssignableFrom(projectile)) { + launch = new EntityWitherSkull(world, getHandle(), direction.getX(), direction.getY(), direction.getZ()); + } else { + launch = new EntityLargeFireball(world, getHandle(), direction.getX(), direction.getY(), direction.getZ()); + } + + ((EntityFireball) launch).projectileSource = this; + launch.setPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } + + Validate.notNull(launch, "Projectile not supported"); + + if (velocity != null) { + ((T) launch.getBukkitEntity()).setVelocity(velocity); + } + + world.addEntity(launch); + return (T) launch.getBukkitEntity(); + } + + public EntityType getType() { + return EntityType.UNKNOWN; + } + + public boolean hasLineOfSight(Entity other) { + return getHandle().hasLineOfSight(((CraftEntity) other).getHandle()); + } + + public boolean getRemoveWhenFarAway() { + return getHandle() instanceof EntityInsentient && !((EntityInsentient) getHandle()).persistent; + } + + public void setRemoveWhenFarAway(boolean remove) { + if (getHandle() instanceof EntityInsentient) { + ((EntityInsentient) getHandle()).persistent = !remove; + } + } + + public EntityEquipment getEquipment() { + return equipment; + } + + public void setCanPickupItems(boolean pickup) { + if (getHandle() instanceof EntityInsentient) { + ((EntityInsentient) getHandle()).canPickUpLoot = pickup; + } + } + + public boolean getCanPickupItems() { + return getHandle() instanceof EntityInsentient && ((EntityInsentient) getHandle()).canPickUpLoot; + } + + @Override + public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause) { + if (getHealth() == 0) { + return false; + } + + return super.teleport(location, cause); + } + + public boolean isLeashed() { + if (!(getHandle() instanceof EntityInsentient)) { + return false; + } + return ((EntityInsentient) getHandle()).getLeashHolder() != null; + } + + public Entity getLeashHolder() throws IllegalStateException { + if (!isLeashed()) { + throw new IllegalStateException("Entity not leashed"); + } + return ((EntityInsentient) getHandle()).getLeashHolder().getBukkitEntity(); + } + + private boolean unleash() { + if (!isLeashed()) { + return false; + } + ((EntityInsentient) getHandle()).unleash(true, false); + return true; + } + + public boolean setLeashHolder(Entity holder) { + if ((getHandle() instanceof EntityWither) || !(getHandle() instanceof EntityInsentient)) { + return false; + } + + if (holder == null) { + return unleash(); + } + + if (holder.isDead()) { + return false; + } + + unleash(); + ((EntityInsentient) getHandle()).setLeashHolder(((CraftEntity) holder).getHandle(), true); + return true; + } + + @Deprecated + public int _INVALID_getLastDamage() { + return NumberConversions.ceil(getLastDamage()); + } + + @Deprecated + public void _INVALID_setLastDamage(int damage) { + setLastDamage(damage); + } + + @Deprecated + public void _INVALID_damage(int amount) { + damage(amount); + } + + @Deprecated + public void _INVALID_damage(int amount, Entity source) { + damage(amount, source); + } + + @Deprecated + public int _INVALID_getHealth() { + return NumberConversions.ceil(getHealth()); + } + + @Deprecated + public void _INVALID_setHealth(int health) { + setHealth(health); + } + + @Deprecated + public int _INVALID_getMaxHealth() { + return NumberConversions.ceil(getMaxHealth()); + } + + @Deprecated + public void _INVALID_setMaxHealth(int health) { + setMaxHealth(health); + } + + // TacoSpigot start + @Override + public int getArrowsStuck() { + return getHandle().getArrowsStuck(); + } + + @Override + public void setArrowsStuck(int arrows) { + getHandle().setArrowsStuck(arrows); + } + // TacoSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java new file mode 100644 index 0000000..dace70b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMagmaCube; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.MagmaCube; + +public class CraftMagmaCube extends CraftSlime implements MagmaCube { + + public CraftMagmaCube(CraftServer server, EntityMagmaCube entity) { + super(server, entity); + } + + public EntityMagmaCube getHandle() { + return (EntityMagmaCube) entity; + } + + @Override + public String toString() { + return "CraftMagmaCube"; + } + + public EntityType getType() { + return EntityType.MAGMA_CUBE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java new file mode 100644 index 0000000..03e0730 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java @@ -0,0 +1,100 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.Blocks; +import net.minecraft.server.EntityMinecartAbstract; + +import net.minecraft.server.IBlockData; +import org.bukkit.Material; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Minecart; +import org.bukkit.material.MaterialData; +import org.bukkit.util.NumberConversions; +import org.bukkit.util.Vector; + +public abstract class CraftMinecart extends CraftVehicle implements Minecart { + public CraftMinecart(CraftServer server, EntityMinecartAbstract entity) { + super(server, entity); + } + + public void setDamage(double damage) { + getHandle().setDamage((float) damage); + } + + public double getDamage() { + return getHandle().getDamage(); + } + + public double getMaxSpeed() { + return getHandle().maxSpeed; + } + + public void setMaxSpeed(double speed) { + if (speed >= 0D) { + getHandle().maxSpeed = speed; + } + } + + public boolean isSlowWhenEmpty() { + return getHandle().slowWhenEmpty; + } + + public void setSlowWhenEmpty(boolean slow) { + getHandle().slowWhenEmpty = slow; + } + + public Vector getFlyingVelocityMod() { + return getHandle().getFlyingVelocityMod(); + } + + public void setFlyingVelocityMod(Vector flying) { + getHandle().setFlyingVelocityMod(flying); + } + + public Vector getDerailedVelocityMod() { + return getHandle().getDerailedVelocityMod(); + } + + public void setDerailedVelocityMod(Vector derailed) { + getHandle().setDerailedVelocityMod(derailed); + } + + @Override + public EntityMinecartAbstract getHandle() { + return (EntityMinecartAbstract) entity; + } + + @Deprecated + public void _INVALID_setDamage(int damage) { + setDamage(damage); + } + + @Deprecated + public int _INVALID_getDamage() { + return NumberConversions.ceil(getDamage()); + } + + public void setDisplayBlock(MaterialData material) { + if(material != null) { + IBlockData block = CraftMagicNumbers.getBlock(material.getItemTypeId()).fromLegacyData(material.getData()); + this.getHandle().setDisplayBlock(block); + } else { + // Set block to air (default) and set the flag to not have a display block. + this.getHandle().setDisplayBlock(Blocks.AIR.getBlockData()); + this.getHandle().a(false); + } + } + + public MaterialData getDisplayBlock() { + IBlockData blockData = getHandle().getDisplayBlock(); + return CraftMagicNumbers.getMaterial(blockData.getBlock()).getNewData((byte) blockData.getBlock().toLegacyData(blockData)); + } + + public void setDisplayBlockOffset(int offset) { + getHandle().SetDisplayBlockOffset(offset); + } + + public int getDisplayBlockOffset() { + return getHandle().getDisplayBlockOffset(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java new file mode 100644 index 0000000..f5a1875 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java @@ -0,0 +1,32 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMinecartChest; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.StorageMinecart; +import org.bukkit.inventory.Inventory; + +@SuppressWarnings("deprecation") +public class CraftMinecartChest extends CraftMinecart implements StorageMinecart { + private final CraftInventory inventory; + + public CraftMinecartChest(CraftServer server, EntityMinecartChest entity) { + super(server, entity); + inventory = new CraftInventory(entity); + } + + public Inventory getInventory() { + return inventory; + } + + @Override + public String toString() { + return "CraftMinecartChest{" + "inventory=" + inventory + '}'; + } + + public EntityType getType() { + return EntityType.MINECART_CHEST; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java new file mode 100644 index 0000000..813b080 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java @@ -0,0 +1,127 @@ +package org.bukkit.craftbukkit.entity; + +import java.util.Set; + +import net.minecraft.server.EntityMinecartCommandBlock; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.minecart.CommandMinecart; +import org.bukkit.permissions.PermissibleBase; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + +public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart { + private final PermissibleBase perm = new PermissibleBase(this); + + public CraftMinecartCommand(CraftServer server, EntityMinecartCommandBlock entity) { + super(server, entity); + } + + @Override + public String getCommand() { + return ((EntityMinecartCommandBlock) getHandle()).getCommandBlock().getCommand(); + } + + @Override + public void setCommand(String command) { + ((EntityMinecartCommandBlock) getHandle()).getCommandBlock().setCommand(command != null ? command : ""); + } + + @Override + public void setName(String name) { + ((EntityMinecartCommandBlock) getHandle()).getCommandBlock().setName(name != null ? name : "@"); + } + + @Override + public EntityType getType() { + return EntityType.MINECART_COMMAND; + } + + @Override + public void sendMessage(String message) { + } + + @Override + public void sendMessage(String[] messages) { + } + + @Override + public String getName() { + return ((EntityMinecartCommandBlock) getHandle()).getCommandBlock().getName(); + } + + @Override + public boolean isOp() { + return true; + } + + @Override + public void setOp(boolean value) { + throw new UnsupportedOperationException("Cannot change operator status of a minecart"); + } + + @Override + public boolean isPermissionSet(String name) { + return perm.isPermissionSet(name); + } + + @Override + public boolean isPermissionSet(Permission perm) { + return this.perm.isPermissionSet(perm); + } + + @Override + public boolean hasPermission(String name) { + return perm.hasPermission(name); + } + + @Override + public boolean hasPermission(Permission perm) { + return this.perm.hasPermission(perm); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value) { + return perm.addAttachment(plugin, name, value); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin) { + return perm.addAttachment(plugin); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, String name, boolean value, int ticks) { + return perm.addAttachment(plugin, name, value, ticks); + } + + @Override + public PermissionAttachment addAttachment(Plugin plugin, int ticks) { + return perm.addAttachment(plugin, ticks); + } + + @Override + public void removeAttachment(PermissionAttachment attachment) { + perm.removeAttachment(attachment); + } + + @Override + public void recalculatePermissions() { + perm.recalculatePermissions(); + } + + @Override + public Set getEffectivePermissions() { + return perm.getEffectivePermissions(); + } + + @Override + public Server getServer() { + return Bukkit.getServer(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java new file mode 100644 index 0000000..463b4ce --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java @@ -0,0 +1,23 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMinecartFurnace; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.PoweredMinecart; + +@SuppressWarnings("deprecation") +public class CraftMinecartFurnace extends CraftMinecart implements PoweredMinecart { + public CraftMinecartFurnace(CraftServer server, EntityMinecartFurnace entity) { + super(server, entity); + } + + @Override + public String toString() { + return "CraftMinecartFurnace"; + } + + public EntityType getType() { + return EntityType.MINECART_FURNACE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java new file mode 100644 index 0000000..9bd358d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java @@ -0,0 +1,31 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMinecartHopper; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.minecart.HopperMinecart; +import org.bukkit.inventory.Inventory; + +final class CraftMinecartHopper extends CraftMinecart implements HopperMinecart { + private final CraftInventory inventory; + + CraftMinecartHopper(CraftServer server, EntityMinecartHopper entity) { + super(server, entity); + inventory = new CraftInventory(entity); + } + + @Override + public String toString() { + return "CraftMinecartHopper{" + "inventory=" + inventory + '}'; + } + + public EntityType getType() { + return EntityType.MINECART_HOPPER; + } + + public Inventory getInventory() { + return inventory; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java new file mode 100644 index 0000000..a78d816 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java @@ -0,0 +1,22 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMinecartMobSpawner; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.minecart.SpawnerMinecart; + +final class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMinecart { + CraftMinecartMobSpawner(CraftServer server, EntityMinecartMobSpawner entity) { + super(server, entity); + } + + @Override + public String toString() { + return "CraftMinecartMobSpawner"; + } + + public EntityType getType() { + return EntityType.MINECART_MOB_SPAWNER; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java new file mode 100644 index 0000000..9305d88 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java @@ -0,0 +1,22 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMinecartAbstract; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.minecart.RideableMinecart; + +public class CraftMinecartRideable extends CraftMinecart implements RideableMinecart { + public CraftMinecartRideable(CraftServer server, EntityMinecartAbstract entity) { + super(server, entity); + } + + @Override + public String toString() { + return "CraftMinecartRideable"; + } + + public EntityType getType() { + return EntityType.MINECART; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java new file mode 100644 index 0000000..0c8109b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java @@ -0,0 +1,22 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMinecartTNT; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.minecart.ExplosiveMinecart; + +final class CraftMinecartTNT extends CraftMinecart implements ExplosiveMinecart { + CraftMinecartTNT(CraftServer server, EntityMinecartTNT entity) { + super(server, entity); + } + + @Override + public String toString() { + return "CraftMinecartTNT"; + } + + public EntityType getType() { + return EntityType.MINECART_TNT; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java new file mode 100644 index 0000000..72dedbc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java @@ -0,0 +1,23 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMonster; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Monster; + +public class CraftMonster extends CraftCreature implements Monster { + + public CraftMonster(CraftServer server, EntityMonster entity) { + super(server, entity); + } + + @Override + public EntityMonster getHandle() { + return (EntityMonster) entity; + } + + @Override + public String toString() { + return "CraftMonster"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java new file mode 100644 index 0000000..3dd7ea3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityMushroomCow; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.MushroomCow; + +public class CraftMushroomCow extends CraftCow implements MushroomCow { + public CraftMushroomCow(CraftServer server, EntityMushroomCow entity) { + super(server, entity); + } + + @Override + public EntityMushroomCow getHandle() { + return (EntityMushroomCow) entity; + } + + @Override + public String toString() { + return "CraftMushroomCow"; + } + + public EntityType getType() { + return EntityType.MUSHROOM_COW; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java new file mode 100644 index 0000000..37cc315 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java @@ -0,0 +1,32 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityOcelot; +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Ocelot; + +public class CraftOcelot extends CraftTameableAnimal implements Ocelot { + public CraftOcelot(CraftServer server, EntityOcelot wolf) { + super(server, wolf); + } + + @Override + public EntityOcelot getHandle() { + return (EntityOcelot) entity; + } + + public Type getCatType() { + return Type.getType(getHandle().getCatType()); + } + + public void setCatType(Type type) { + Validate.notNull(type, "Cat type cannot be null"); + getHandle().setCatType(type.getId()); + } + + @Override + public EntityType getType() { + return EntityType.OCELOT; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java new file mode 100644 index 0000000..3e9448a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java @@ -0,0 +1,79 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityPainting; +import net.minecraft.server.EntityPainting.EnumArt; +import net.minecraft.server.WorldServer; + +import org.bukkit.Art; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.CraftArt; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Painting; + +public class CraftPainting extends CraftHanging implements Painting { + + public CraftPainting(CraftServer server, EntityPainting entity) { + super(server, entity); + } + + public Art getArt() { + EnumArt art = getHandle().art; + return CraftArt.NotchToBukkit(art); + } + + public boolean setArt(Art art) { + return setArt(art, false); + } + + public boolean setArt(Art art, boolean force) { + EntityPainting painting = this.getHandle(); + EnumArt oldArt = painting.art; + painting.art = CraftArt.BukkitToNotch(art); + painting.setDirection(painting.direction); + if (!force && !painting.survives()) { + // Revert painting since it doesn't fit + painting.art = oldArt; + painting.setDirection(painting.direction); + return false; + } + this.update(); + return true; + } + + public boolean setFacingDirection(BlockFace face, boolean force) { + if (super.setFacingDirection(face, force)) { + update(); + return true; + } + + return false; + } + + private void update() { + WorldServer world = ((CraftWorld) getWorld()).getHandle(); + EntityPainting painting = new EntityPainting(world); + painting.blockPosition = getHandle().blockPosition; + painting.art = getHandle().art; + painting.setDirection(getHandle().direction); + getHandle().die(); + getHandle().velocityChanged = true; // because this occurs when the painting is broken, so it might be important + world.addEntity(painting); + this.entity = painting; + } + + @Override + public EntityPainting getHandle() { + return (EntityPainting) entity; + } + + @Override + public String toString() { + return "CraftPainting{art=" + getArt() + "}"; + } + + public EntityType getType() { + return EntityType.PAINTING; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java new file mode 100644 index 0000000..82bc7a6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java @@ -0,0 +1,34 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityPig; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Pig; + +public class CraftPig extends CraftAnimals implements Pig { + public CraftPig(CraftServer server, EntityPig entity) { + super(server, entity); + } + + public boolean hasSaddle() { + return getHandle().hasSaddle(); + } + + public void setSaddle(boolean saddled) { + getHandle().setSaddle(saddled); + } + + public EntityPig getHandle() { + return (EntityPig) entity; + } + + @Override + public String toString() { + return "CraftPig"; + } + + public EntityType getType() { + return EntityType.PIG; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java new file mode 100644 index 0000000..0e6ccea --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java @@ -0,0 +1,44 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityPigZombie; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.PigZombie; + +public class CraftPigZombie extends CraftZombie implements PigZombie { + + public CraftPigZombie(CraftServer server, EntityPigZombie entity) { + super(server, entity); + } + + public int getAnger() { + return getHandle().angerLevel; + } + + public void setAnger(int level) { + getHandle().angerLevel = level; + } + + public void setAngry(boolean angry) { + setAnger(angry ? 400 : 0); + } + + public boolean isAngry() { + return getAnger() > 0; + } + + @Override + public EntityPigZombie getHandle() { + return (EntityPigZombie) entity; + } + + @Override + public String toString() { + return "CraftPigZombie"; + } + + public EntityType getType() { + return EntityType.PIG_ZOMBIE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java new file mode 100644 index 0000000..5eafeff --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -0,0 +1,1677 @@ +package org.bukkit.craftbukkit.entity; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import com.mojang.authlib.GameProfile; +import io.netty.buffer.Unpooled; +import me.levansj01.mythicspigot.kb.KBProfile; +import net.md_5.bungee.api.chat.BaseComponent; +import net.minecraft.server.*; +import net.minecraft.server.PacketPlayOutTitle.EnumTitleAction; +import org.apache.commons.lang.NotImplementedException; +import org.apache.commons.lang.Validate; +import org.bukkit.Achievement; +import org.bukkit.Material; +import org.bukkit.Statistic; +import org.bukkit.*; +import org.bukkit.World; +import org.bukkit.Statistic.Type; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.conversations.Conversation; +import org.bukkit.conversations.ConversationAbandonedEvent; +import org.bukkit.conversations.ManuallyAbandonedConversationCanceller; +import org.bukkit.craftbukkit.*; +import org.bukkit.craftbukkit.block.CraftSign; +import org.bukkit.craftbukkit.conversations.ConversationTracker; +import org.bukkit.craftbukkit.map.CraftMapView; +import org.bukkit.craftbukkit.map.RenderData; +import org.bukkit.craftbukkit.scoreboard.CraftScoreboard; +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerGameModeChangeEvent; +import org.bukkit.event.player.PlayerRegisterChannelEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerUnregisterChannelEvent; +import org.bukkit.inventory.InventoryView.Property; +import org.bukkit.map.MapCursor; +import org.bukkit.map.MapView; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.messaging.StandardMessenger; +import org.bukkit.scoreboard.Scoreboard; +import org.github.paperspigot.Title; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +// PaperSpigot start +// PaperSpigot end + +@DelegateDeserialization(CraftOfflinePlayer.class) +public class CraftPlayer extends CraftHumanEntity implements Player { + private long firstPlayed = 0; + private long lastPlayed = 0; + private boolean hasPlayedBefore = false; + private final ConversationTracker conversationTracker = new ConversationTracker(); + private final Set channels = new HashSet(); + private final Set hiddenPlayers = new HashSet(); + private int hash = 0; + private double health = 20; + private boolean scaledHealth = false; + private double healthScale = 20; + + public CraftPlayer(CraftServer server, EntityPlayer entity) { + super(server, entity); + + firstPlayed = System.currentTimeMillis(); + } + + public boolean canSeeEntity(org.bukkit.entity.Entity entity) { + Entity nmsEntity = ((CraftEntity) entity).getHandle(); + + if (nmsEntity instanceof EntityProjectile) { + EntityProjectile entityProjectile = (EntityProjectile) nmsEntity; + + if (entityProjectile.getShooter() instanceof EntityPlayer) { + return this.canSee(((EntityPlayer) entityProjectile.getShooter()).getBukkitEntity()); + } + } + + if (nmsEntity instanceof EntityItem) { + EntityItem entityItem = (EntityItem) nmsEntity; + + if (entityItem.dropper instanceof EntityPlayer) { + return this.canSee(((EntityPlayer) entityItem.dropper).getBukkitEntity()); + } + } + + if (nmsEntity instanceof EntityArrow) { + EntityArrow entityProjectile = (EntityArrow) nmsEntity; + + if (entityProjectile.shooter instanceof EntityPlayer) { + return this.canSee(((EntityPlayer) entityProjectile.shooter).getBukkitEntity()); + } + } + + return !(entity instanceof Player) || this.canSee((Player) entity); + } + + public GameProfile getProfile() { + return getHandle().getProfile(); + } + + @Override + public boolean isOp() { + return server.getHandle().isOp(getProfile()); + } + + @Override + public void setOp(boolean value) { + if (value == isOp()) return; + + if (value) { + server.getHandle().addOp(getProfile()); + } else { + server.getHandle().removeOp(getProfile()); + } + + perm.recalculatePermissions(); + } + + public boolean isOnline() { + return server.getPlayer(getUniqueId()) != null; + } + + public InetSocketAddress getAddress() { + if (getHandle().playerConnection == null) return null; + + SocketAddress addr = getHandle().playerConnection.networkManager.getSocketAddress(); + if (addr instanceof InetSocketAddress) { + return (InetSocketAddress) addr; + } else { + return null; + } + } + + @Override + public double getEyeHeight() { + return getEyeHeight(false); + } + + @Override + public double getEyeHeight(boolean ignoreSneaking) { + if (ignoreSneaking) { + return 1.62D; + } else { + if (isSneaking()) { + return 1.54D; + } else { + return 1.62D; + } + } + } + + @Override + public void sendRawMessage(String message) { + if (getHandle().playerConnection == null) return; + + for (IChatBaseComponent component : CraftChatMessage.fromString(message)) { + getHandle().playerConnection.sendPacket(new PacketPlayOutChat(component)); + } + } + + @Override + public void sendMessage(String message) { + if (!conversationTracker.isConversingModaly()) { + this.sendRawMessage(message); + } + } + + @Override + public void sendMessage(String[] messages) { + for (String message : messages) { + sendMessage(message); + } + } + + // Paper start + @Override + public void sendMessage(BaseComponent component) { + sendMessage(new BaseComponent[]{component}); + } + + @Override + public void sendMessage(BaseComponent... components) { + if (getHandle().playerConnection == null) return; + + PacketPlayOutChat packet = new PacketPlayOutChat(); + packet.components = components; + getHandle().playerConnection.sendPacket(packet); + } + + @Override + public void setPlayerListHeaderFooter(BaseComponent[] header, BaseComponent[] footer) { + PacketPlayOutPlayerListHeaderFooter packet = new PacketPlayOutPlayerListHeaderFooter(); + packet.header = header; + packet.footer = footer; + getHandle().playerConnection.sendPacket(packet); + } + + @Override + public void setPlayerListHeaderFooter(BaseComponent header, BaseComponent footer) { + this.setPlayerListHeaderFooter(header == null ? null : new BaseComponent[]{header}, + footer == null ? null : new BaseComponent[]{footer}); + } + + + @Override + public void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks) { + getHandle().playerConnection.sendPacket(new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TIMES, (BaseComponent[]) null, fadeInTicks, stayTicks, fadeOutTicks)); + } + + @Override + public void setSubtitle(BaseComponent[] subtitle) { + getHandle().playerConnection.sendPacket(new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.SUBTITLE, subtitle, 0, 0, 0)); + } + + @Override + public void setSubtitle(BaseComponent subtitle) { + setSubtitle(new BaseComponent[]{subtitle}); + } + + @Override + public void showTitle(BaseComponent[] title) { + getHandle().playerConnection.sendPacket(new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE, title, 0, 0, 0)); + } + + @Override + public void showTitle(BaseComponent title) { + showTitle(new BaseComponent[]{title}); + } + + @Override + public void showTitle(BaseComponent[] title, BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks) { + setTitleTimes(fadeInTicks, stayTicks, fadeOutTicks); + setSubtitle(subtitle); + showTitle(title); + } + + @Override + public void showTitle(BaseComponent title, BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks) { + setTitleTimes(fadeInTicks, stayTicks, fadeOutTicks); + setSubtitle(subtitle); + showTitle(title); + } + + @Override + public void sendTitle(Title title) { + Preconditions.checkNotNull(title, "Title is null"); + setTitleTimes(title.getFadeIn(), title.getStay(), title.getFadeOut()); + setSubtitle(title.getSubtitle() == null ? new BaseComponent[0] : title.getSubtitle()); + showTitle(title.getTitle()); + } + + @Override + public void updateTitle(Title title) { + Preconditions.checkNotNull(title, "Title is null"); + setTitleTimes(title.getFadeIn(), title.getStay(), title.getFadeOut()); + if (title.getSubtitle() != null) { + setSubtitle(title.getSubtitle()); + } + showTitle(title.getTitle()); + } + + @Override + public void hideTitle() { + getHandle().playerConnection.sendPacket(new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.CLEAR, (BaseComponent[]) null, 0, 0, 0)); + } + // Paper end + + @Override + public String getDisplayName() { + return getHandle().displayName; + } + + @Override + public void setDisplayName(final String name) { + getHandle().displayName = name == null ? getName() : name; + } + + @Override + public boolean canRecieveCosmetics() { return getHandle().cosmetics; } + + @Override + public boolean setRecieveCosmetics(boolean bool) { return getHandle().cosmetics = bool; } + + @Override + public String getPlayerListName() { + return getHandle().listName == null ? getName() : CraftChatMessage.fromComponent(getHandle().listName); + } + + @Override + public void setPlayerListName(String name) { + if (name == null) { + name = getName(); + } + getHandle().listName = name.equals(getName()) ? null : CraftChatMessage.fromString(name)[0]; + for (EntityPlayer player : server.getHandle().players) { + if (player.getBukkitEntity().canSee(this)) { + player.playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.UPDATE_DISPLAY_NAME, getHandle())); + } + } + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof OfflinePlayer)) { + return false; + } + OfflinePlayer other = (OfflinePlayer) obj; + if ((this.getUniqueId() == null) || (other.getUniqueId() == null)) { + return false; + } + + boolean uuidEquals = this.getUniqueId().equals(other.getUniqueId()); + boolean idEquals = true; + + if (other instanceof CraftPlayer) { + idEquals = this.getEntityId() == ((CraftPlayer) other).getEntityId(); + } + + return uuidEquals && idEquals; + } + + @Override + public void kickPlayer(String message) { + org.spigotmc.AsyncCatcher.catchOp( "player kick"); // Spigot + if (getHandle().playerConnection == null) return; + + getHandle().playerConnection.disconnect(message == null ? "" : message); + } + + @Override + public void setCompassTarget(Location loc) { + if (getHandle().playerConnection == null) return; + + // Do not directly assign here, from the packethandler we'll assign it. + getHandle().playerConnection.sendPacket(new PacketPlayOutSpawnPosition(new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()))); + } + + @Override + public Location getCompassTarget() { + return getHandle().compassTarget; + } + + @Override + public void chat(String msg) { + if (getHandle().playerConnection == null) return; + + getHandle().playerConnection.chat(msg, false); + } + + @Override + public boolean performCommand(String command) { + return server.dispatchCommand(this, command); + } + + @Override + public void playNote(Location loc, byte instrument, byte note) { + if (getHandle().playerConnection == null) return; + + String instrumentName = null; + switch (instrument) { + case 0: + instrumentName = "harp"; + break; + case 1: + instrumentName = "bd"; + break; + case 2: + instrumentName = "snare"; + break; + case 3: + instrumentName = "hat"; + break; + case 4: + instrumentName = "bassattack"; + break; + } + + float f = (float) Math.pow(2.0D, (note - 12.0D) / 12.0D); + getHandle().playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("note."+instrumentName, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, f)); + } + + @Override + public void playNote(Location loc, Instrument instrument, Note note) { + if (getHandle().playerConnection == null) return; + + String instrumentName = null; + switch (instrument.ordinal()) { + case 0: + instrumentName = "harp"; + break; + case 1: + instrumentName = "bd"; + break; + case 2: + instrumentName = "snare"; + break; + case 3: + instrumentName = "hat"; + break; + case 4: + instrumentName = "bassattack"; + break; + } + float f = (float) Math.pow(2.0D, (note.getId() - 12.0D) / 12.0D); + getHandle().playerConnection.sendPacket(new PacketPlayOutNamedSoundEffect("note."+instrumentName, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), 3.0f, f)); + } + + @Override + public void playSound(Location loc, Sound sound, float volume, float pitch) { + if (sound == null) { + return; + } + playSound(loc, CraftSound.getSound(sound), volume, pitch); + } + + @Override + public void playSound(Location loc, String sound, float volume, float pitch) { + if (loc == null || sound == null || getHandle().playerConnection == null) return; + + double x = loc.getBlockX() + 0.5; + double y = loc.getBlockY() + 0.5; + double z = loc.getBlockZ() + 0.5; + + PacketPlayOutNamedSoundEffect packet = new PacketPlayOutNamedSoundEffect(sound, x, y, z, volume, pitch); + getHandle().playerConnection.sendPacket(packet); + } + + @Override + public void playEffect(Location loc, Effect effect, int data) { + if (getHandle().playerConnection == null) return; + + spigot().playEffect(loc, effect, data, 0, 0, 0, 0, 1, 1, 64); // Spigot + } + + @Override + public void playEffect(Location loc, Effect effect, T data) { + if (data != null) { + Validate.isTrue(data.getClass().isAssignableFrom(effect.getData()), "Wrong kind of data for this effect!"); + } else { + Validate.isTrue(effect.getData() == null, "Wrong kind of data for this effect!"); + } + + int datavalue = data == null ? 0 : CraftEffect.getDataValue(effect, data); + playEffect(loc, effect, datavalue); + } + + @Override + public void sendBlockChange(Location loc, Material material, byte data) { + sendBlockChange(loc, material.getId(), data); + } + + @Override + public void sendBlockChange(Location loc, int material, byte data) { + if (getHandle().playerConnection == null) return; + + PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(((CraftWorld) loc.getWorld()).getHandle(), new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ())); + + packet.block = CraftMagicNumbers.getBlock(material).fromLegacyData(data); + getHandle().playerConnection.sendPacket(packet); + } + + @Override + public void sendSignChange(Location loc, String[] lines) { + if (getHandle().playerConnection == null) { + return; + } + + if (lines == null) { + lines = new String[4]; + } + + Validate.notNull(loc, "Location can not be null"); + if (lines.length < 4) { + throw new IllegalArgumentException("Must have at least 4 lines"); + } + + IChatBaseComponent[] components = CraftSign.sanitizeLines(lines); + + getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateSign(getHandle().world, new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()), components)); + } + + @Override + public boolean sendChunkChange(Location loc, int sx, int sy, int sz, byte[] data) { + if (getHandle().playerConnection == null) return false; + + /* + int x = loc.getBlockX(); + int y = loc.getBlockY(); + int z = loc.getBlockZ(); + + int cx = x >> 4; + int cz = z >> 4; + + if (sx <= 0 || sy <= 0 || sz <= 0) { + return false; + } + + if ((x + sx - 1) >> 4 != cx || (z + sz - 1) >> 4 != cz || y < 0 || y + sy > 128) { + return false; + } + + if (data.length != (sx * sy * sz * 5) / 2) { + return false; + } + + Packet51MapChunk packet = new Packet51MapChunk(x, y, z, sx, sy, sz, data); + + getHandle().playerConnection.sendPacket(packet); + + return true; + */ + + throw new NotImplementedException("Chunk changes do not yet work"); // TODO: Chunk changes. + } + + @Override + public void sendMap(MapView map) { + if (getHandle().playerConnection == null) return; + + RenderData data = ((CraftMapView) map).render(this); + Collection icons = new ArrayList(); + for (MapCursor cursor : data.cursors) { + if (cursor.isVisible()) { + icons.add(new MapIcon(cursor.getRawType(), cursor.getX(), cursor.getY(), cursor.getDirection())); + } + } + + PacketPlayOutMap packet = new PacketPlayOutMap(map.getId(), map.getScale().getValue(), icons, data.buffer, 0, 0, 0, 0); + getHandle().playerConnection.sendPacket(packet); + } + + @Override + public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause) { + EntityPlayer entity = getHandle(); + + if (getHealth() == 0 || entity.dead) { + return false; + } + + if (entity.playerConnection == null || entity.playerConnection.isDisconnected()) { + return false; + } + + if (entity.passenger != null) { + return false; + } + + // From = Players current Location + Location from = this.getLocation(); + // To = Players new Location if Teleport is Successful + Location to = location; + // Create & Call the Teleport Event. + PlayerTeleportEvent event = new PlayerTeleportEvent(this, from, to, cause); + server.getPluginManager().callEvent(event); + + // Return False to inform the Plugin that the Teleport was unsuccessful/cancelled. + if (event.isCancelled()) { + return false; + } + + // If this player is riding another entity, we must dismount before teleporting. + entity.mount(null); + + // Update the From Location + from = event.getFrom(); + // Grab the new To Location dependent on whether the event was cancelled. + to = event.getTo(); + // Grab the To and From World Handles. + WorldServer fromWorld = ((CraftWorld) from.getWorld()).getHandle(); + WorldServer toWorld = ((CraftWorld) to.getWorld()).getHandle(); + + // Close any foreign inventory + if (getHandle().activeContainer != getHandle().defaultContainer) { + getHandle().closeInventory(); + } + + // Check if the fromWorld and toWorld are the same. + if (fromWorld == toWorld) { + entity.playerConnection.teleport(to); + } else { + server.getHandle().moveToWorld(entity, toWorld.dimension, true, to, true); + } + return true; + } + + @Override + public void setSneaking(boolean sneak) { + getHandle().setSneaking(sneak); + } + + @Override + public boolean isSneaking() { + return getHandle().isSneaking(); + } + + @Override + public boolean isSprinting() { + return getHandle().isSprinting(); + } + + @Override + public void setSprinting(boolean sprinting) { + getHandle().setSprinting(sprinting); + } + + @Override + public void loadData() { + server.getHandle().playerFileData.load(getHandle()); + } + + @Override + public void saveData() { + server.getHandle().playerFileData.save(getHandle()); + } + + @Deprecated + @Override + public void updateInventory() { + getHandle().updateInventory(getHandle().activeContainer); + } + + @Override + public void setSleepingIgnored(boolean isSleeping) { + getHandle().fauxSleeping = isSleeping; + ((CraftWorld) getWorld()).getHandle().checkSleepStatus(); + } + + @Override + public boolean isSleepingIgnored() { + return getHandle().fauxSleeping; + } + + @Override + public void awardAchievement(Achievement achievement) { + Validate.notNull(achievement, "Achievement cannot be null"); + if (achievement.hasParent() && !hasAchievement(achievement.getParent())) { + awardAchievement(achievement.getParent()); + } + getHandle().getStatisticManager().setStatistic(getHandle(), CraftStatistic.getNMSAchievement(achievement), 1); + getHandle().getStatisticManager().updateStatistics(getHandle()); + } + + @Override + public void removeAchievement(Achievement achievement) { + Validate.notNull(achievement, "Achievement cannot be null"); + for (Achievement achieve : Achievement.values()) { + if (achieve.getParent() == achievement && hasAchievement(achieve)) { + removeAchievement(achieve); + } + } + getHandle().getStatisticManager().setStatistic(getHandle(), CraftStatistic.getNMSAchievement(achievement), 0); + } + + @Override + public boolean hasAchievement(Achievement achievement) { + Validate.notNull(achievement, "Achievement cannot be null"); + return getHandle().getStatisticManager().hasAchievement(CraftStatistic.getNMSAchievement(achievement)); + } + + @Override + public void incrementStatistic(Statistic statistic) { + incrementStatistic(statistic, 1); + } + + @Override + public void decrementStatistic(Statistic statistic) { + decrementStatistic(statistic, 1); + } + + @Override + public int getStatistic(Statistic statistic) { + Validate.notNull(statistic, "Statistic cannot be null"); + Validate.isTrue(statistic.getType() == Type.UNTYPED, "Must supply additional paramater for this statistic"); + return getHandle().getStatisticManager().getStatisticValue(CraftStatistic.getNMSStatistic(statistic)); + } + + @Override + public void incrementStatistic(Statistic statistic, int amount) { + Validate.isTrue(amount > 0, "Amount must be greater than 0"); + setStatistic(statistic, getStatistic(statistic) + amount); + } + + @Override + public void decrementStatistic(Statistic statistic, int amount) { + Validate.isTrue(amount > 0, "Amount must be greater than 0"); + setStatistic(statistic, getStatistic(statistic) - amount); + } + + @Override + public void setStatistic(Statistic statistic, int newValue) { + Validate.notNull(statistic, "Statistic cannot be null"); + Validate.isTrue(statistic.getType() == Type.UNTYPED, "Must supply additional paramater for this statistic"); + Validate.isTrue(newValue >= 0, "Value must be greater than or equal to 0"); + net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getNMSStatistic(statistic); + getHandle().getStatisticManager().setStatistic(getHandle(), nmsStatistic, newValue); + } + + @Override + public void incrementStatistic(Statistic statistic, Material material) { + incrementStatistic(statistic, material, 1); + } + + @Override + public void decrementStatistic(Statistic statistic, Material material) { + decrementStatistic(statistic, material, 1); + } + + @Override + public int getStatistic(Statistic statistic, Material material) { + Validate.notNull(statistic, "Statistic cannot be null"); + Validate.notNull(material, "Material cannot be null"); + Validate.isTrue(statistic.getType() == Type.BLOCK || statistic.getType() == Type.ITEM, "This statistic does not take a Material parameter"); + net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getMaterialStatistic(statistic, material); + Validate.notNull(nmsStatistic, "The supplied Material does not have a corresponding statistic"); + return getHandle().getStatisticManager().getStatisticValue(nmsStatistic); + } + + @Override + public void incrementStatistic(Statistic statistic, Material material, int amount) { + Validate.isTrue(amount > 0, "Amount must be greater than 0"); + setStatistic(statistic, material, getStatistic(statistic, material) + amount); + } + + @Override + public void decrementStatistic(Statistic statistic, Material material, int amount) { + Validate.isTrue(amount > 0, "Amount must be greater than 0"); + setStatistic(statistic, material, getStatistic(statistic, material) - amount); + } + + @Override + public void setStatistic(Statistic statistic, Material material, int newValue) { + Validate.notNull(statistic, "Statistic cannot be null"); + Validate.notNull(material, "Material cannot be null"); + Validate.isTrue(newValue >= 0, "Value must be greater than or equal to 0"); + Validate.isTrue(statistic.getType() == Type.BLOCK || statistic.getType() == Type.ITEM, "This statistic does not take a Material parameter"); + net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getMaterialStatistic(statistic, material); + Validate.notNull(nmsStatistic, "The supplied Material does not have a corresponding statistic"); + getHandle().getStatisticManager().setStatistic(getHandle(), nmsStatistic, newValue); + } + + @Override + public void incrementStatistic(Statistic statistic, EntityType entityType) { + incrementStatistic(statistic, entityType, 1); + } + + @Override + public void decrementStatistic(Statistic statistic, EntityType entityType) { + decrementStatistic(statistic, entityType, 1); + } + + @Override + public int getStatistic(Statistic statistic, EntityType entityType) { + Validate.notNull(statistic, "Statistic cannot be null"); + Validate.notNull(entityType, "EntityType cannot be null"); + Validate.isTrue(statistic.getType() == Type.ENTITY, "This statistic does not take an EntityType parameter"); + net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getEntityStatistic(statistic, entityType); + Validate.notNull(nmsStatistic, "The supplied EntityType does not have a corresponding statistic"); + return getHandle().getStatisticManager().getStatisticValue(nmsStatistic); + } + + @Override + public void incrementStatistic(Statistic statistic, EntityType entityType, int amount) { + Validate.isTrue(amount > 0, "Amount must be greater than 0"); + setStatistic(statistic, entityType, getStatistic(statistic, entityType) + amount); + } + + @Override + public void decrementStatistic(Statistic statistic, EntityType entityType, int amount) { + Validate.isTrue(amount > 0, "Amount must be greater than 0"); + setStatistic(statistic, entityType, getStatistic(statistic, entityType) - amount); + } + + @Override + public void setStatistic(Statistic statistic, EntityType entityType, int newValue) { + Validate.notNull(statistic, "Statistic cannot be null"); + Validate.notNull(entityType, "EntityType cannot be null"); + Validate.isTrue(newValue >= 0, "Value must be greater than or equal to 0"); + Validate.isTrue(statistic.getType() == Type.ENTITY, "This statistic does not take an EntityType parameter"); + net.minecraft.server.Statistic nmsStatistic = CraftStatistic.getEntityStatistic(statistic, entityType); + Validate.notNull(nmsStatistic, "The supplied EntityType does not have a corresponding statistic"); + getHandle().getStatisticManager().setStatistic(getHandle(), nmsStatistic, newValue); + } + + @Override + public void setPlayerTime(long time, boolean relative) { + getHandle().timeOffset = time; + getHandle().relativeTime = relative; + } + + @Override + public long getPlayerTimeOffset() { + return getHandle().timeOffset; + } + + @Override + public long getPlayerTime() { + return getHandle().getPlayerTime(); + } + + @Override + public boolean isPlayerTimeRelative() { + return getHandle().relativeTime; + } + + @Override + public void resetPlayerTime() { + setPlayerTime(0, true); + } + + @Override + public void setPlayerWeather(WeatherType type) { + getHandle().setPlayerWeather(type, true); + } + + @Override + public WeatherType getPlayerWeather() { + return getHandle().getPlayerWeather(); + } + + @Override + public void resetPlayerWeather() { + getHandle().resetPlayerWeather(); + } + + @Override + public boolean isBanned() { + return server.getBanList(BanList.Type.NAME).isBanned(getName()); + } + + @Override + public void setBanned(boolean value) { + if (value) { + server.getBanList(BanList.Type.NAME).addBan(getName(), null, null, null); + } else { + server.getBanList(BanList.Type.NAME).pardon(getName()); + } + } + + @Override + public boolean isWhitelisted() { + return server.getHandle().getWhitelist().isWhitelisted(getProfile()); + } + + @Override + public void setWhitelisted(boolean value) { + if (value) { + server.getHandle().addWhitelist(getProfile()); + } else { + server.getHandle().removeWhitelist(getProfile()); + } + } + + @Override + public void setGameMode(GameMode mode) { + if (getHandle().playerConnection == null) return; + + if (mode == null) { + throw new IllegalArgumentException("Mode cannot be null"); + } + + if (mode != getGameMode()) { + PlayerGameModeChangeEvent event = new PlayerGameModeChangeEvent(this, mode); + server.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + + getHandle().setSpectatorTarget(getHandle()); + getHandle().playerInteractManager.setGameMode(WorldSettings.EnumGamemode.getById(mode.getValue())); + getHandle().fallDistance = 0; + getHandle().playerConnection.sendPacket(new PacketPlayOutGameStateChange(3, mode.getValue())); + } + } + + @Override + public GameMode getGameMode() { + return GameMode.getByValue(getHandle().playerInteractManager.getGameMode().getId()); + } + + @Override + public void giveExp(int exp) { + getHandle().giveExp(exp); + } + + @Override + public void giveExpLevels(int levels) { + getHandle().levelDown(levels); + } + + @Override + public float getExp() { + return getHandle().exp; + } + + @Override + public void setExp(float exp) { + getHandle().exp = exp; + getHandle().lastSentExp = -1; + } + + @Override + public int getLevel() { + return getHandle().expLevel; + } + + @Override + public void setLevel(int level) { + getHandle().expLevel = level; + getHandle().lastSentExp = -1; + } + + @Override + public int getTotalExperience() { + return getHandle().expTotal; + } + + @Override + public void setTotalExperience(int exp) { + getHandle().expTotal = exp; + } + + @Override + public float getExhaustion() { + return getHandle().getFoodData().exhaustionLevel; + } + + @Override + public void setExhaustion(float value) { + getHandle().getFoodData().exhaustionLevel = value; + } + + @Override + public float getSaturation() { + return getHandle().getFoodData().saturationLevel; + } + + @Override + public void setSaturation(float value) { + getHandle().getFoodData().saturationLevel = value; + } + + @Override + public int getFoodLevel() { + return getHandle().getFoodData().foodLevel; + } + + @Override + public void setFoodLevel(int value) { + getHandle().getFoodData().foodLevel = value; + } + + @Override + public Location getBedSpawnLocation() { + World world = getServer().getWorld(getHandle().spawnWorld); + BlockPosition bed = getHandle().getBed(); + + if (world != null && bed != null) { + bed = EntityHuman.getBed(((CraftWorld) world).getHandle(), bed, getHandle().isRespawnForced()); + if (bed != null) { + return new Location(world, bed.getX(), bed.getY(), bed.getZ()); + } + } + return null; + } + + @Override + public void setBedSpawnLocation(Location location) { + setBedSpawnLocation(location, false); + } + + @Override + public void setBedSpawnLocation(Location location, boolean override) { + if (location == null) { + getHandle().setRespawnPosition(null, override); + } else { + getHandle().setRespawnPosition(new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), override); + getHandle().spawnWorld = location.getWorld().getName(); + } + } + + @Override + public void hidePlayer(Player player) { + Validate.notNull(player, "hidden player cannot be null"); + if (getHandle().playerConnection == null) return; + if (equals(player)) return; + if (hiddenPlayers.contains(player.getUniqueId())) return; + hiddenPlayers.add(player.getUniqueId()); + + //remove this player from the hidden player's EntityTrackerEntry + EntityTracker tracker = ((WorldServer) entity.world).tracker; + EntityPlayer other = ((CraftPlayer) player).getHandle(); + EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId()); + if (entry != null) { + entry.clear(getHandle()); + } + + //remove the hidden player from this player user list + getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, other)); + } + + @Override + public void showPlayer(Player player) { + Validate.notNull(player, "shown player cannot be null"); + if (getHandle().playerConnection == null) return; + if (equals(player)) return; + if (!hiddenPlayers.contains(player.getUniqueId())) return; + hiddenPlayers.remove(player.getUniqueId()); + + EntityTracker tracker = ((WorldServer) entity.world).tracker; + EntityPlayer other = ((CraftPlayer) player).getHandle(); + + getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, other)); + + EntityTrackerEntry entry = tracker.trackedEntities.get(other.getId()); + if (entry != null && !entry.trackedPlayers.contains(getHandle())) { + entry.updatePlayer(getHandle()); + } + } + + public void removeDisconnectingPlayer(Player player) { + hiddenPlayers.remove(player.getUniqueId()); + } + + @Override + public boolean canSee(Player player) { + return !hiddenPlayers.contains(player.getUniqueId()); + } + + @Override + public Map serialize() { + Map result = new LinkedHashMap(); + + result.put("name", getName()); + + return result; + } + + @Override + public Player getPlayer() { + return this; + } + + @Override + public EntityPlayer getHandle() { + return (EntityPlayer) entity; + } + + public void setHandle(final EntityPlayer entity) { + super.setHandle(entity); + } + + @Override + public String toString() { + return "CraftPlayer{" + "name=" + getName() + '}'; + } + + @Override + public int hashCode() { + if (hash == 0 || hash == 485) { + hash = 97 * 5 + (this.getUniqueId() != null ? this.getUniqueId().hashCode() : 0); + } + return hash; + } + + @Override + public long getFirstPlayed() { + return firstPlayed; + } + + @Override + public long getLastPlayed() { + return lastPlayed; + } + + @Override + public boolean hasPlayedBefore() { + return hasPlayedBefore; + } + + public void setFirstPlayed(long firstPlayed) { + this.firstPlayed = firstPlayed; + } + + public void readExtraData(NBTTagCompound nbttagcompound) { + hasPlayedBefore = true; + if (nbttagcompound.hasKey("bukkit")) { + NBTTagCompound data = nbttagcompound.getCompound("bukkit"); + + if (data.hasKey("firstPlayed")) { + firstPlayed = data.getLong("firstPlayed"); + lastPlayed = data.getLong("lastPlayed"); + } + + if (data.hasKey("newExp")) { + EntityPlayer handle = getHandle(); + handle.newExp = data.getInt("newExp"); + handle.newTotalExp = data.getInt("newTotalExp"); + handle.newLevel = data.getInt("newLevel"); + handle.expToDrop = data.getInt("expToDrop"); + handle.keepLevel = data.getBoolean("keepLevel"); + } + } + } + + public void setExtraData(NBTTagCompound nbttagcompound) { + if (!nbttagcompound.hasKey("bukkit")) { + nbttagcompound.set("bukkit", new NBTTagCompound()); + } + + NBTTagCompound data = nbttagcompound.getCompound("bukkit"); + EntityPlayer handle = getHandle(); + data.setInt("newExp", handle.newExp); + data.setInt("newTotalExp", handle.newTotalExp); + data.setInt("newLevel", handle.newLevel); + data.setInt("expToDrop", handle.expToDrop); + data.setBoolean("keepLevel", handle.keepLevel); + data.setLong("firstPlayed", getFirstPlayed()); + data.setLong("lastPlayed", System.currentTimeMillis()); + data.setString("lastKnownName", handle.getName()); + } + + @Override + public boolean beginConversation(Conversation conversation) { + return conversationTracker.beginConversation(conversation); + } + + @Override + public void abandonConversation(Conversation conversation) { + conversationTracker.abandonConversation(conversation, new ConversationAbandonedEvent(conversation, new ManuallyAbandonedConversationCanceller())); + } + + @Override + public void abandonConversation(Conversation conversation, ConversationAbandonedEvent details) { + conversationTracker.abandonConversation(conversation, details); + } + + @Override + public void acceptConversationInput(String input) { + conversationTracker.acceptConversationInput(input); + } + + @Override + public boolean isConversing() { + return conversationTracker.isConversing(); + } + + @Override + public void sendPluginMessage(Plugin source, String channel, byte[] message) { + StandardMessenger.validatePluginMessage(server.getMessenger(), source, channel, message); + if (getHandle().playerConnection == null) return; + + if (channels.contains(channel)) { + PacketPlayOutCustomPayload packet = new PacketPlayOutCustomPayload(channel, new PacketDataSerializer(Unpooled.wrappedBuffer(message))); + getHandle().playerConnection.sendPacket(packet); + } + } + + @Override + public void setTexturePack(String url) { + setResourcePack(url); + } + + @Override + public void setResourcePack(String url) { + Validate.notNull(url, "Resource pack URL cannot be null"); + + getHandle().setResourcePack(url, "null"); + } + + public void addChannel(String channel) { + com.google.common.base.Preconditions.checkState( channels.size() < 128, "Too many channels registered" ); // Spigot + if (channels.add(channel)) { + server.getPluginManager().callEvent(new PlayerRegisterChannelEvent(this, channel)); + } + } + + public void removeChannel(String channel) { + if (channels.remove(channel)) { + server.getPluginManager().callEvent(new PlayerUnregisterChannelEvent(this, channel)); + } + } + + @Override + public Set getListeningPluginChannels() { + return ImmutableSet.copyOf(channels); + } + + public void sendSupportedChannels() { + if (getHandle().playerConnection == null) return; + Set listening = server.getMessenger().getIncomingChannels(); + + if (!listening.isEmpty()) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + for (String channel : listening) { + try { + stream.write(channel.getBytes(StandardCharsets.UTF_8)); + stream.write((byte) 0); + } catch (IOException ex) { + Logger.getLogger(CraftPlayer.class.getName()).log(Level.SEVERE, "Could not send Plugin Channel REGISTER to " + getName(), ex); + } + } + + getHandle().playerConnection.sendPacket(new PacketPlayOutCustomPayload("REGISTER", new PacketDataSerializer(Unpooled.wrappedBuffer(stream.toByteArray())))); + } + } + + @Override + public EntityType getType() { + return EntityType.PLAYER; + } + + @Override + public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { + server.getPlayerMetadata().setMetadata(this, metadataKey, newMetadataValue); + } + + @Override + public List getMetadata(String metadataKey) { + return server.getPlayerMetadata().getMetadata(this, metadataKey); + } + + @Override + public boolean hasMetadata(String metadataKey) { + return server.getPlayerMetadata().hasMetadata(this, metadataKey); + } + + @Override + public void removeMetadata(String metadataKey, Plugin owningPlugin) { + server.getPlayerMetadata().removeMetadata(this, metadataKey, owningPlugin); + } + + @Override + public boolean setWindowProperty(Property prop, int value) { + Container container = getHandle().activeContainer; + if (container.getBukkitView().getType() != prop.getType()) { + return false; + } + getHandle().setContainerData(container, prop.getId(), value); + return true; + } + + public void disconnect(String reason) { + conversationTracker.abandonAllConversations(); + perm.clearPermissions(); + } + + @Override + public boolean isFlying() { + return getHandle().abilities.isFlying; + } + + @Override + public void setFlying(boolean value) { + boolean needsUpdate = getHandle().abilities.canFly != value; // PaperSpigot - Only refresh abilities if needed + if (!getAllowFlight() && value) { + throw new IllegalArgumentException("Cannot make player fly if getAllowFlight() is false"); + } + + getHandle().abilities.isFlying = value; + if (needsUpdate) getHandle().updateAbilities(); // PaperSpigot - Only refresh abilities if needed + } + + @Override + public boolean getAllowFlight() { + return getHandle().abilities.canFly; + } + + @Override + public void setAllowFlight(boolean value) { + if (isFlying() && !value) { + getHandle().abilities.isFlying = false; + } + + getHandle().abilities.canFly = value; + getHandle().updateAbilities(); + } + + @Override + public int getNoDamageTicks() { + if (getHandle().invulnerableTicks > 0) { + return Math.max(getHandle().invulnerableTicks, getHandle().noDamageTicks); + } else { + return getHandle().noDamageTicks; + } + } + + @Override + public void setFlySpeed(float value) { + validateSpeed(value); + EntityPlayer player = getHandle(); + player.abilities.flySpeed = Math.max( value, 0.0001f ) / 2f; // Spigot + player.updateAbilities(); + + } + + @Override + public void setWalkSpeed(float value) { + validateSpeed(value); + EntityPlayer player = getHandle(); + player.abilities.walkSpeed = Math.max( value, 0.0001f ) / 2f; // Spigot + player.updateAbilities(); + } + + @Override + public float getFlySpeed() { + return getHandle().abilities.flySpeed * 2f; + } + + @Override + public float getWalkSpeed() { + return getHandle().abilities.walkSpeed * 2f; + } + + private void validateSpeed(float value) { + if (value < 0) { + if (value < -1f) { + throw new IllegalArgumentException(value + " is too low"); + } + } else { + if (value > 1f) { + throw new IllegalArgumentException(value + " is too high"); + } + } + } + + @Override + public void setMaxHealth(double amount) { + super.setMaxHealth(amount); + this.health = Math.min(this.health, health); + getHandle().triggerHealthUpdate(); + } + + @Override + public void resetMaxHealth() { + super.resetMaxHealth(); + getHandle().triggerHealthUpdate(); + } + + @Override + public CraftScoreboard getScoreboard() { + return this.server.getScoreboardManager().getPlayerBoard(this); + } + + @Override + public void setScoreboard(Scoreboard scoreboard) { + Validate.notNull(scoreboard, "Scoreboard cannot be null"); + PlayerConnection playerConnection = getHandle().playerConnection; + if (playerConnection == null) { + throw new IllegalStateException("Cannot set scoreboard yet"); + } + if (playerConnection.isDisconnected()) { + // throw new IllegalStateException("Cannot set scoreboard for invalid CraftPlayer"); // Spigot - remove this as Mojang's semi asynchronous Netty implementation can lead to races + } + + this.server.getScoreboardManager().setPlayerBoard(this, scoreboard); + } + + @Override + public void setHealthScale(double value) { + Validate.isTrue((float) value > 0F, "Must be greater than 0"); + healthScale = value; + scaledHealth = true; + updateScaledHealth(); + } + + @Override + public double getHealthScale() { + return healthScale; + } + + @Override + public void setHealthScaled(boolean scale) { + if (scaledHealth != (scaledHealth = scale)) { + updateScaledHealth(); + } + } + + @Override + public boolean isHealthScaled() { + return scaledHealth; + } + + public float getScaledHealth() { + return (float) (isHealthScaled() ? getHealth() * getHealthScale() / getMaxHealth() : getHealth()); + } + + @Override + public double getHealth() { + return health; + } + + public void setRealHealth(double health) { + this.health = health; + } + + public void updateScaledHealth() { + AttributeMapServer attributemapserver = (AttributeMapServer) getHandle().getAttributeMap(); + Set set = attributemapserver.getAttributes(); + + injectScaledMaxHealth(set, true); + + getHandle().getDataWatcher().watch(6, getScaledHealth()); + getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateHealth(getScaledHealth(), getHandle().getFoodData().getFoodLevel(), getHandle().getFoodData().getSaturationLevel())); + getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(getHandle().getId(), set)); + + set.clear(); + getHandle().maxHealthCache = getMaxHealth(); + } + + public void injectScaledMaxHealth(Collection collection, boolean force) { + if (!scaledHealth && !force) { + return; + } + for (Object genericInstance : collection) { + IAttribute attribute = ((AttributeInstance) genericInstance).getAttribute(); + if (attribute.getName().equals("generic.maxHealth")) { + collection.remove(genericInstance); + break; + } + } + // Spigot start + double healthMod = scaledHealth ? healthScale : getMaxHealth(); + if ( healthMod >= Float.MAX_VALUE || healthMod <= 0 ) + { + healthMod = 20; // Reset health + getServer().getLogger().warning( getName() + " tried to crash the server with a large health attribute" ); + } + collection.add(new AttributeModifiable(getHandle().getAttributeMap(), (new AttributeRanged(null, "generic.maxHealth", healthMod, 0.0D, Float.MAX_VALUE)).a("Max Health").a(true))); + // Spigot end + } + + @Override + public org.bukkit.entity.Entity getSpectatorTarget() { + Entity followed = getHandle().C(); // PAIL + return followed == getHandle() ? null : followed.getBukkitEntity(); + } + + @Override + public void setSpectatorTarget(org.bukkit.entity.Entity entity) { + Preconditions.checkArgument(getGameMode() == GameMode.SPECTATOR, "Player must be in spectator mode"); + getHandle().setSpectatorTarget((entity == null) ? null : ((CraftEntity) entity).getHandle()); + } + + @Override + public void sendTitle(String title, String subtitle) { + if (title != null) { + PacketPlayOutTitle packetTitle = new PacketPlayOutTitle(EnumTitleAction.TITLE, CraftChatMessage.fromString(title)[0]); + getHandle().playerConnection.sendPacket(packetTitle); + } + + if (subtitle != null) { + PacketPlayOutTitle packetSubtitle = new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, CraftChatMessage.fromString(subtitle)[0]); + getHandle().playerConnection.sendPacket(packetSubtitle); + } + } + + @Override + public void resetTitle() { + PacketPlayOutTitle packetReset = new PacketPlayOutTitle(EnumTitleAction.RESET, null); + getHandle().playerConnection.sendPacket(packetReset); + } + + private final Player.Mythic mythic = new Player.Mythic(){ + public KBProfile getKBProfile() { + return getHandle().getKBProfile(); + } + + public void setKBProfile(KBProfile profile) { + getHandle().setKBProfile(profile); + } + }; + + public Player.Mythic mythic() { + return mythic; + } + + // Spigot start + private final Player.Spigot spigot = new Player.Spigot() + { + + @Override + public InetSocketAddress getRawAddress() + { + return (InetSocketAddress) getHandle().playerConnection.networkManager.getRawAddress(); + } + + @Override + public boolean getCollidesWithEntities() + { + return getHandle().collidesWithEntities; + } + + @Override + public void setCollidesWithEntities(boolean collides) + { + getHandle().collidesWithEntities = collides; + getHandle().k = collides; // First boolean of Entity + } + + @Override + public void respawn() + { + if ( getHealth() <= 0 && isOnline() ) + { + server.getServer().getPlayerList().moveToWorld( getHandle(), 0, false ); + } + } + + @Override + public void playEffect( Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius ) + { + Validate.notNull( location, "Location cannot be null" ); + Validate.notNull( effect, "Effect cannot be null" ); + Validate.notNull( location.getWorld(), "World cannot be null" ); + Packet packet; + if ( effect.getType() != Effect.Type.PARTICLE ) + { + int packetData = effect.getId(); + packet = new PacketPlayOutWorldEvent( packetData, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ() ), id, false ); + } else + { + net.minecraft.server.EnumParticle particle = null; + int[] extra = null; + for ( net.minecraft.server.EnumParticle p : net.minecraft.server.EnumParticle.values() ) + { + if ( effect.getName().startsWith( p.b().replace("_", "") ) ) + { + particle = p; + if ( effect.getData() != null ) + { + if ( effect.getData().equals( org.bukkit.Material.class ) ) + { + extra = new int[]{ id }; + } else + { + extra = new int[]{ (data << 12) | (id & 0xFFF) }; + } + } + break; + } + } + if ( extra == null ) + { + extra = new int[0]; + } + packet = new PacketPlayOutWorldParticles( particle, true, (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount, extra ); + } + int distance; + radius *= radius; + if ( getHandle().playerConnection == null ) + { + return; + } + if ( !location.getWorld().equals( getWorld() ) ) + { + return; + } + + distance = (int) getLocation().distanceSquared( location ); + if ( distance <= radius ) + { + getHandle().playerConnection.sendPacket( packet ); + } + } + + @Override + public String getLocale() + { + return getHandle().locale; + } + + @Override + public Set getHiddenPlayers() + { + Set ret = new HashSet(); + for ( UUID u : hiddenPlayers ) + { + ret.add( getServer().getPlayer( u ) ); + } + + return java.util.Collections.unmodifiableSet( ret ); + } + + @Override + public void sendMessage(BaseComponent component) { + sendMessage( new BaseComponent[] { component } ); + } + + @Override + public void sendMessage(BaseComponent... components) { + if ( getHandle().playerConnection == null ) return; + + PacketPlayOutChat packet = new PacketPlayOutChat(); + packet.components = components; + getHandle().playerConnection.sendPacket(packet); + } + + // PaperSpigot start - Implement affects spawning API + @Override + public boolean getAffectsSpawning() { + return getHandle().affectsSpawning; + } + + @Override + public void setAffectsSpawning(boolean affects) { + getHandle().affectsSpawning = affects; + } + // PaperSpigot end + + // PaperSpigot start - Player view distance API + @Override + public int getViewDistance() { + return getHandle().viewDistance; + } + + @Override + public void setViewDistance(int viewDistance) { + ((WorldServer) getHandle().world).getPlayerChunkMap().updateViewDistance(getHandle(), viewDistance); + } + // PaperSpigot end + + @Override + public int getPing() + { + return getHandle().ping; + } + }; + + // TacoSpigot start + private org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; + private String resourcePackHash; + + @Override + public void setResourcePack(String url, String hash) { + Validate.notNull(url, "Resource pack URL cannot be null"); + Validate.notNull(hash, "Hash cannot be null"); + this.getHandle().setResourcePack(url, hash); + } + + @Override + public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status getResourcePackStatus() { + return this.resourcePackStatus; + } + + @Override + public String getResourcePackHash() { + return this.resourcePackHash; + } + + @Override + public boolean hasResourcePack() { + return this.resourcePackStatus == org.bukkit.event.player.PlayerResourcePackStatusEvent.Status.SUCCESSFULLY_LOADED; + } + + public void setResourcePackStatus(org.bukkit.event.player.PlayerResourcePackStatusEvent.Status status, String hash) { + this.resourcePackStatus = status; + this.resourcePackHash = hash; + } + // TacoSpigot end + + public Player.Spigot spigot() + { + return spigot; + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java new file mode 100644 index 0000000..2f29f2f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java @@ -0,0 +1,62 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityLiving; +import net.minecraft.server.EntityProjectile; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Projectile; +import org.bukkit.projectiles.ProjectileSource; + +public abstract class CraftProjectile extends AbstractProjectile implements Projectile { + public CraftProjectile(CraftServer server, net.minecraft.server.Entity entity) { + super(server, entity); + } + + public ProjectileSource getShooter() { + return getHandle().projectileSource; + } + + public void setShooter(ProjectileSource shooter) { + if (shooter instanceof CraftLivingEntity) { + getHandle().shooter = (EntityLiving) ((CraftLivingEntity) shooter).entity; + if (shooter instanceof CraftHumanEntity) { + getHandle().shooterName = ((CraftHumanEntity) shooter).getName(); + } + } else { + getHandle().shooter = null; + getHandle().shooterName = null; + } + getHandle().projectileSource = shooter; + } + + @Override + public EntityProjectile getHandle() { + return (EntityProjectile) entity; + } + + @Override + public String toString() { + return "CraftProjectile"; + } + + + @Deprecated + public LivingEntity _INVALID_getShooter() { + if (getHandle().shooter == null) { + return null; + } + return (LivingEntity) getHandle().shooter.getBukkitEntity(); + } + + @Deprecated + public void _INVALID_setShooter(LivingEntity shooter) { + if (shooter == null) { + return; + } + getHandle().shooter = ((CraftLivingEntity) shooter).getHandle(); + if (shooter instanceof CraftHumanEntity) { + getHandle().shooterName = ((CraftHumanEntity) shooter).getName(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java new file mode 100644 index 0000000..61330d2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftRabbit.java @@ -0,0 +1,88 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.World; +import net.minecraft.server.EntityRabbit; +import net.minecraft.server.PathfinderGoalSelector; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Rabbit; +import org.bukkit.craftbukkit.CraftWorld; + +public class CraftRabbit extends CraftAnimals implements Rabbit { + + public CraftRabbit(CraftServer server, EntityRabbit entity) { + super(server, entity); + } + + @Override + public EntityRabbit getHandle() { + return (EntityRabbit) entity; + } + + @Override + public String toString() { + return "CraftRabbit{RabbitType=" + getRabbitType() + "}"; + } + + @Override + public EntityType getType() { + return EntityType.RABBIT; + } + + @Override + public Type getRabbitType() { + int type = getHandle().getRabbitType(); + return CraftMagicMapping.fromMagic(type); + } + + @Override + public void setRabbitType(Type type) { + EntityRabbit entity = getHandle(); + if (getRabbitType() == Type.THE_KILLER_BUNNY) { + // Reset goals and target finders. + World world = ((CraftWorld) this.getWorld()).getHandle(); + entity.goalSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); + entity.targetSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); + entity.initializePathFinderGoals(); + } + + entity.setRabbitType(CraftMagicMapping.toMagic(type)); + } + + private static class CraftMagicMapping { + + private static final int[] types = new int[Type.values().length]; + private static final Type[] reverse = new Type[Type.values().length]; + + static { + set(Type.BROWN, 0); + set(Type.WHITE, 1); + set(Type.BLACK, 2); + set(Type.BLACK_AND_WHITE, 3); + set(Type.GOLD, 4); + set(Type.SALT_AND_PEPPER, 5); + set(Type.THE_KILLER_BUNNY, 99); + } + + private static void set(Type type, int value) { + types[type.ordinal()] = value; + if (value < reverse.length) { + reverse[value] = type; + } + } + + public static Type fromMagic(int magic) { + if (magic >= 0 && magic < reverse.length) { + return reverse[magic]; + } else if (magic == 99) { + return Type.THE_KILLER_BUNNY; + } else { + return null; + } + } + + public static int toMagic(Type type) { + return types[type.ordinal()]; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java new file mode 100644 index 0000000..f725355 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java @@ -0,0 +1,45 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySheep; + +import net.minecraft.server.EnumColor; +import org.bukkit.DyeColor; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Sheep; + +public class CraftSheep extends CraftAnimals implements Sheep { + public CraftSheep(CraftServer server, EntitySheep entity) { + super(server, entity); + } + + public DyeColor getColor() { + return DyeColor.getByWoolData((byte) getHandle().getColor().getColorIndex()); + } + + public void setColor(DyeColor color) { + getHandle().setColor(EnumColor.fromColorIndex(color.getWoolData())); + } + + public boolean isSheared() { + return getHandle().isSheared(); + } + + public void setSheared(boolean flag) { + getHandle().setSheared(flag); + } + + @Override + public EntitySheep getHandle() { + return (EntitySheep) entity; + } + + @Override + public String toString() { + return "CraftSheep"; + } + + public EntityType getType() { + return EntityType.SHEEP; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java new file mode 100644 index 0000000..ef94775 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySilverfish; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Silverfish; + +public class CraftSilverfish extends CraftMonster implements Silverfish { + public CraftSilverfish(CraftServer server, EntitySilverfish entity) { + super(server, entity); + } + + @Override + public EntitySilverfish getHandle() { + return (EntitySilverfish) entity; + } + + @Override + public String toString() { + return "CraftSilverfish"; + } + + public EntityType getType() { + return EntityType.SILVERFISH; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java new file mode 100644 index 0000000..58da899 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java @@ -0,0 +1,38 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySkeleton; + +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Skeleton; + +public class CraftSkeleton extends CraftMonster implements Skeleton { + + public CraftSkeleton(CraftServer server, EntitySkeleton entity) { + super(server, entity); + } + + @Override + public EntitySkeleton getHandle() { + return (EntitySkeleton) entity; + } + + @Override + public String toString() { + return "CraftSkeleton"; + } + + public EntityType getType() { + return EntityType.SKELETON; + } + + public SkeletonType getSkeletonType() { + return SkeletonType.getType(getHandle().getSkeletonType()); + } + + public void setSkeletonType(SkeletonType type) { + Validate.notNull(type); + getHandle().setSkeletonType(type.getId()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java new file mode 100644 index 0000000..da3df00 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java @@ -0,0 +1,36 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySlime; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Slime; + +public class CraftSlime extends CraftLivingEntity implements Slime { + + public CraftSlime(CraftServer server, EntitySlime entity) { + super(server, entity); + } + + public int getSize() { + return getHandle().getSize(); + } + + public void setSize(int size) { + getHandle().setSize(size); + } + + @Override + public EntitySlime getHandle() { + return (EntitySlime) entity; + } + + @Override + public String toString() { + return "CraftSlime"; + } + + public EntityType getType() { + return EntityType.SLIME; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java new file mode 100644 index 0000000..7200970 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySmallFireball; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.SmallFireball; + +public class CraftSmallFireball extends CraftFireball implements SmallFireball { + public CraftSmallFireball(CraftServer server, EntitySmallFireball entity) { + super(server, entity); + } + + @Override + public EntitySmallFireball getHandle() { + return (EntitySmallFireball) entity; + } + + @Override + public String toString() { + return "CraftSmallFireball"; + } + + public EntityType getType() { + return EntityType.SMALL_FIREBALL; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java new file mode 100644 index 0000000..44de749 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySnowball; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Snowball; + +public class CraftSnowball extends CraftProjectile implements Snowball { + public CraftSnowball(CraftServer server, EntitySnowball entity) { + super(server, entity); + } + + @Override + public EntitySnowball getHandle() { + return (EntitySnowball) entity; + } + + @Override + public String toString() { + return "CraftSnowball"; + } + + public EntityType getType() { + return EntityType.SNOWBALL; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java new file mode 100644 index 0000000..319a3f3 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySnowman; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Snowman; + +public class CraftSnowman extends CraftGolem implements Snowman { + public CraftSnowman(CraftServer server, EntitySnowman entity) { + super(server, entity); + } + + @Override + public EntitySnowman getHandle() { + return (EntitySnowman) entity; + } + + @Override + public String toString() { + return "CraftSnowman"; + } + + public EntityType getType() { + return EntityType.SNOWMAN; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java new file mode 100644 index 0000000..2a07fe1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySpider; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Spider; + +public class CraftSpider extends CraftMonster implements Spider { + + public CraftSpider(CraftServer server, EntitySpider entity) { + super(server, entity); + } + + @Override + public EntitySpider getHandle() { + return (EntitySpider) entity; + } + + @Override + public String toString() { + return "CraftSpider"; + } + + public EntityType getType() { + return EntityType.SPIDER; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java new file mode 100644 index 0000000..433a7c6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntitySquid; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Squid; + +public class CraftSquid extends CraftWaterMob implements Squid { + + public CraftSquid(CraftServer server, EntitySquid entity) { + super(server, entity); + } + + @Override + public EntitySquid getHandle() { + return (EntitySquid) entity; + } + + @Override + public String toString() { + return "CraftSquid"; + } + + public EntityType getType() { + return EntityType.SQUID; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java new file mode 100644 index 0000000..b7e8b4d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java @@ -0,0 +1,75 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityLiving; +import net.minecraft.server.EntityTNTPrimed; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.TNTPrimed; + +public class CraftTNTPrimed extends CraftEntity implements TNTPrimed { + + public CraftTNTPrimed(CraftServer server, EntityTNTPrimed entity) { + super(server, entity); + } + + public float getYield() { + return getHandle().yield; + } + + public boolean isIncendiary() { + return getHandle().isIncendiary; + } + + public void setIsIncendiary(boolean isIncendiary) { + getHandle().isIncendiary = isIncendiary; + } + + public void setYield(float yield) { + getHandle().yield = yield; + } + + public int getFuseTicks() { + return getHandle().fuseTicks; + } + + public void setFuseTicks(int fuseTicks) { + getHandle().fuseTicks = fuseTicks; + } + + @Override + public EntityTNTPrimed getHandle() { + return (EntityTNTPrimed) entity; + } + + @Override + public String toString() { + return "CraftTNTPrimed"; + } + + public EntityType getType() { + return EntityType.PRIMED_TNT; + } + + public Entity getSource() { + EntityLiving source = getHandle().getSource(); + + if (source != null) { + Entity bukkitEntity = source.getBukkitEntity(); + + if (bukkitEntity.isValid()) { + return bukkitEntity; + } + } + + return null; + } + + // PaperSpigot start + @Override + public org.bukkit.Location getSourceLoc() { + return getHandle().sourceLoc; + } + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java new file mode 100644 index 0000000..ea1d10b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java @@ -0,0 +1,84 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityTameableAnimal; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.AnimalTamer; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Tameable; + +import java.util.UUID; + +public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creature { + public CraftTameableAnimal(CraftServer server, EntityTameableAnimal entity) { + super(server, entity); + } + + @Override + public EntityTameableAnimal getHandle() { + return (EntityTameableAnimal)super.getHandle(); + } + + public UUID getOwnerUUID() { + try { + return UUID.fromString(getHandle().getOwnerUUID()); + } catch (IllegalArgumentException ex) { + return null; + } + } + + public void setOwnerUUID(UUID uuid) { + if (uuid == null) { + getHandle().setOwnerUUID(""); + } else { + getHandle().setOwnerUUID(uuid.toString()); + } + } + + public AnimalTamer getOwner() { + if (getOwnerUUID() == null) { + return null; + } + + AnimalTamer owner = getServer().getPlayer(getOwnerUUID()); + if (owner == null) { + owner = getServer().getOfflinePlayer(getOwnerUUID()); + } + + return owner; + } + + public boolean isTamed() { + return getHandle().isTamed(); + } + + public void setOwner(AnimalTamer tamer) { + if (tamer != null) { + setTamed(true); + getHandle().setGoalTarget(null, null, false); + setOwnerUUID(tamer.getUniqueId()); + } else { + setTamed(false); + setOwnerUUID(null); + } + } + + public void setTamed(boolean tame) { + getHandle().setTamed(tame); + if (!tame) { + setOwnerUUID(null); + } + } + + public boolean isSitting() { + return getHandle().isSitting(); + } + + public void setSitting(boolean sitting) { + getHandle().getGoalSit().setSitting(sitting); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "{owner=" + getOwner() + ",tamed=" + isTamed() + "}"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java new file mode 100644 index 0000000..fb3416e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityThrownExpBottle; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ThrownExpBottle; + +public class CraftThrownExpBottle extends CraftProjectile implements ThrownExpBottle { + public CraftThrownExpBottle(CraftServer server, EntityThrownExpBottle entity) { + super(server, entity); + } + + @Override + public EntityThrownExpBottle getHandle() { + return (EntityThrownExpBottle) entity; + } + + @Override + public String toString() { + return "EntityThrownExpBottle"; + } + + public EntityType getType() { + return EntityType.THROWN_EXP_BOTTLE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java new file mode 100644 index 0000000..18da426 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java @@ -0,0 +1,58 @@ +package org.bukkit.craftbukkit.entity; + +import java.util.Collection; + +import net.minecraft.server.EntityPotion; + +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ThrownPotion; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.Potion; +import org.bukkit.potion.PotionEffect; + +public class CraftThrownPotion extends CraftProjectile implements ThrownPotion { + public CraftThrownPotion(CraftServer server, EntityPotion entity) { + super(server, entity); + } + + // TODO: This one does not handle custom NBT potion effects does it? + // In that case this method could be said to be misleading or incorrect + public Collection getEffects() { + return Potion.getBrewer().getEffectsFromDamage(getHandle().getPotionValue()); + } + + public ItemStack getItem() { + // We run this method once since it will set the item stack if there is none. + getHandle().getPotionValue(); + + return CraftItemStack.asBukkitCopy(getHandle().item); + } + + public void setItem(ItemStack item) { + // The ItemStack must not be null. + Validate.notNull(item, "ItemStack cannot be null."); + + // The ItemStack must be a potion. + Validate.isTrue(item.getType() == Material.POTION, "ItemStack must be a potion. This item stack was " + item.getType() + "."); + + getHandle().item = CraftItemStack.asNMSCopy(item); + } + + @Override + public EntityPotion getHandle() { + return (EntityPotion) entity; + } + + @Override + public String toString() { + return "CraftThrownPotion"; + } + + public EntityType getType() { + return EntityType.SPLASH_POTION; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftVehicle.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftVehicle.java new file mode 100644 index 0000000..8e4af46 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftVehicle.java @@ -0,0 +1,15 @@ +package org.bukkit.craftbukkit.entity; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Vehicle; + +public abstract class CraftVehicle extends CraftEntity implements Vehicle { + public CraftVehicle(CraftServer server, net.minecraft.server.Entity entity) { + super(server, entity); + } + + @Override + public String toString() { + return "CraftVehicle{passenger=" + getPassenger() + '}'; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java new file mode 100644 index 0000000..6fe21cc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java @@ -0,0 +1,44 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityVillager; +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Villager; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +public class CraftVillager extends CraftAgeable implements Villager, InventoryHolder { + public CraftVillager(CraftServer server, EntityVillager entity) { + super(server, entity); + } + + @Override + public EntityVillager getHandle() { + return (EntityVillager) entity; + } + + @Override + public String toString() { + return "CraftVillager"; + } + + public EntityType getType() { + return EntityType.VILLAGER; + } + + public Profession getProfession() { + return Profession.getProfession(getHandle().getProfession()); + } + + public void setProfession(Profession profession) { + Validate.notNull(profession); + getHandle().setProfession(profession.getId()); + } + + @Override + public Inventory getInventory() { + return new CraftInventory(getHandle().inventory); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java new file mode 100644 index 0000000..ee21d7b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java @@ -0,0 +1,24 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityWaterAnimal; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.WaterMob; + +public class CraftWaterMob extends CraftLivingEntity implements WaterMob { + + public CraftWaterMob(CraftServer server, EntityWaterAnimal entity) { + super(server, entity); + } + + @Override + public EntityWaterAnimal getHandle() { + return (EntityWaterAnimal) entity; + } + + @Override + public String toString() { + return "CraftWaterMob"; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWeather.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWeather.java new file mode 100644 index 0000000..91a7493 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWeather.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityWeather; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Weather; + +public class CraftWeather extends CraftEntity implements Weather { + public CraftWeather(final CraftServer server, final EntityWeather entity) { + super(server, entity); + } + + @Override + public EntityWeather getHandle() { + return (EntityWeather) entity; + } + + @Override + public String toString() { + return "CraftWeather"; + } + + public EntityType getType() { + return EntityType.WEATHER; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java new file mode 100644 index 0000000..c08833c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityWitch; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Witch; +import org.bukkit.entity.EntityType; + +public class CraftWitch extends CraftMonster implements Witch { + public CraftWitch(CraftServer server, EntityWitch entity) { + super(server, entity); + } + + @Override + public EntityWitch getHandle() { + return (EntityWitch) entity; + } + + @Override + public String toString() { + return "CraftWitch"; + } + + public EntityType getType() { + return EntityType.WITCH; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java new file mode 100644 index 0000000..fad3db8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityWither; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.Wither; +import org.bukkit.entity.EntityType; + +public class CraftWither extends CraftMonster implements Wither { + public CraftWither(CraftServer server, EntityWither entity) { + super(server, entity); + } + + @Override + public EntityWither getHandle() { + return (EntityWither) entity; + } + + @Override + public String toString() { + return "CraftWither"; + } + + public EntityType getType() { + return EntityType.WITHER; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java new file mode 100644 index 0000000..563177e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java @@ -0,0 +1,36 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityWitherSkull; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.WitherSkull; + +public class CraftWitherSkull extends CraftFireball implements WitherSkull { + public CraftWitherSkull(CraftServer server, EntityWitherSkull entity) { + super(server, entity); + } + + @Override + public void setCharged(boolean charged) { + getHandle().setCharged(charged); + } + + @Override + public boolean isCharged() { + return getHandle().isCharged(); + } + + @Override + public EntityWitherSkull getHandle() { + return (EntityWitherSkull) entity; + } + + @Override + public String toString() { + return "CraftWitherSkull"; + } + + public EntityType getType() { + return EntityType.WITHER_SKULL; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java new file mode 100644 index 0000000..55ce37c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java @@ -0,0 +1,40 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityWolf; +import net.minecraft.server.EnumColor; +import org.bukkit.DyeColor; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Wolf; + +public class CraftWolf extends CraftTameableAnimal implements Wolf { + public CraftWolf(CraftServer server, EntityWolf wolf) { + super(server, wolf); + } + + public boolean isAngry() { + return getHandle().isAngry(); + } + + public void setAngry(boolean angry) { + getHandle().setAngry(angry); + } + + @Override + public EntityWolf getHandle() { + return (EntityWolf) entity; + } + + @Override + public EntityType getType() { + return EntityType.WOLF; + } + + public DyeColor getCollarColor() { + return DyeColor.getByWoolData((byte) getHandle().getCollarColor().getColorIndex()); + } + + public void setCollarColor(DyeColor color) { + getHandle().setCollarColor(EnumColor.fromColorIndex(color.getWoolData())); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java new file mode 100644 index 0000000..619579d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java @@ -0,0 +1,44 @@ +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityZombie; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Zombie; + +public class CraftZombie extends CraftMonster implements Zombie { + + public CraftZombie(CraftServer server, EntityZombie entity) { + super(server, entity); + } + + @Override + public EntityZombie getHandle() { + return (EntityZombie) entity; + } + + @Override + public String toString() { + return "CraftZombie"; + } + + public EntityType getType() { + return EntityType.ZOMBIE; + } + + public boolean isBaby() { + return getHandle().isBaby(); + } + + public void setBaby(boolean flag) { + getHandle().setBaby(flag); + } + + public boolean isVillager() { + return getHandle().isVillager(); + } + + public void setVillager(boolean flag) { + getHandle().setVillager(flag); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java new file mode 100644 index 0000000..db91503 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -0,0 +1,982 @@ +package org.bukkit.craftbukkit.event; + +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +import com.google.common.base.Function; +import com.google.common.base.Functions; + +import net.minecraft.server.*; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Server; +import org.bukkit.Statistic.Type; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.CreatureSpawner; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftStatistic; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.inventory.CraftMetaBook; +import org.bukkit.craftbukkit.util.CraftDamageSource; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Firework; +import org.bukkit.entity.Horse; +import org.bukkit.entity.LightningStrike; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Pig; +import org.bukkit.entity.PigZombie; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.ThrownExpBottle; +import org.bukkit.entity.ThrownPotion; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.block.*; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.entity.*; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.event.inventory.PrepareItemCraftEvent; +import org.bukkit.event.player.*; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.meta.BookMeta; + +public class CraftEventFactory { + public static final DamageSource MELTING = CraftDamageSource.copyOf(DamageSource.BURN); + public static final DamageSource POISON = CraftDamageSource.copyOf(DamageSource.MAGIC); + public static org.bukkit.block.Block blockDamage; // For use in EntityDamageByBlockEvent + public static Entity entityDamage; // For use in EntityDamageByEntityEvent + + // helper methods + private static boolean canBuild(CraftWorld world, Player player, int x, int z) { + WorldServer worldServer = world.getHandle(); + int spawnSize = Bukkit.getServer().getSpawnRadius(); + + if (world.getHandle().dimension != 0) return true; + if (spawnSize <= 0) return true; + if (((CraftServer) Bukkit.getServer()).getHandle().getOPs().isEmpty()) return true; + if (player.isOp()) return true; + + BlockPosition chunkcoordinates = worldServer.getSpawn(); + + int distanceFromSpawn = Math.max(Math.abs(x - chunkcoordinates.getX()), Math.abs(z - chunkcoordinates.getY())); + return distanceFromSpawn > spawnSize; + } + + public static T callEvent(T event) { + Bukkit.getServer().getPluginManager().callEvent(event); + return event; + } + + /** + * Block place methods + */ + public static BlockMultiPlaceEvent callBlockMultiPlaceEvent(World world, EntityHuman who, List blockStates, int clickedX, int clickedY, int clickedZ) { + CraftWorld craftWorld = world.getWorld(); + CraftServer craftServer = world.getServer(); + Player player = (who == null) ? null : (Player) who.getBukkitEntity(); + + Block blockClicked = craftWorld.getBlockAt(clickedX, clickedY, clickedZ); + + boolean canBuild = true; + for (int i = 0; i < blockStates.size(); i++) { + if (!canBuild(craftWorld, player, blockStates.get(i).getX(), blockStates.get(i).getZ())) { + canBuild = false; + break; + } + } + + BlockMultiPlaceEvent event = new BlockMultiPlaceEvent(blockStates, blockClicked, player.getItemInHand(), player, canBuild); + craftServer.getPluginManager().callEvent(event); + + return event; + } + + public static BlockPlaceEvent callBlockPlaceEvent(World world, EntityHuman who, BlockState replacedBlockState, int clickedX, int clickedY, int clickedZ) { + CraftWorld craftWorld = world.getWorld(); + CraftServer craftServer = world.getServer(); + + Player player = (who == null) ? null : (Player) who.getBukkitEntity(); + + Block blockClicked = craftWorld.getBlockAt(clickedX, clickedY, clickedZ); + Block placedBlock = replacedBlockState.getBlock(); + + boolean canBuild = canBuild(craftWorld, player, placedBlock.getX(), placedBlock.getZ()); + + BlockPlaceEvent event = new BlockPlaceEvent(placedBlock, replacedBlockState, blockClicked, player.getItemInHand(), player, canBuild); + craftServer.getPluginManager().callEvent(event); + + return event; + } + + /** + * Mob spawner event + */ + public static SpawnerSpawnEvent callSpawnerSpawnEvent(Entity spawnee, int spawnerX, int spawnerY, int spawnerZ) { + org.bukkit.craftbukkit.entity.CraftEntity entity = spawnee.getBukkitEntity(); + BlockState state = entity.getWorld().getBlockAt(spawnerX, spawnerY, spawnerZ).getState(); + + if (!(state instanceof CreatureSpawner)) { + state = null; + } + + SpawnerSpawnEvent event = new SpawnerSpawnEvent(entity, (CreatureSpawner) state); + entity.getServer().getPluginManager().callEvent(event); + return event; + } + + /** + * Bucket methods + */ + public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemInHand) { + return (PlayerBucketEmptyEvent) getPlayerBucketEvent(false, who, clickedX, clickedY, clickedZ, clickedFace, itemInHand, Items.BUCKET); + } + + public static PlayerBucketFillEvent callPlayerBucketFillEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemInHand, net.minecraft.server.Item bucket) { + return (PlayerBucketFillEvent) getPlayerBucketEvent(true, who, clickedX, clickedY, clickedZ, clickedFace, itemInHand, bucket); + } + + private static PlayerEvent getPlayerBucketEvent(boolean isFilling, EntityHuman who, int clickedX, int clickedY, int clickedZ, EnumDirection clickedFace, ItemStack itemstack, net.minecraft.server.Item item) { + Player player = (who == null) ? null : (Player) who.getBukkitEntity(); + CraftItemStack itemInHand = CraftItemStack.asNewCraftStack(item); + Material bucket = CraftMagicNumbers.getMaterial(itemstack.getItem()); + + CraftWorld craftWorld = (CraftWorld) player.getWorld(); + CraftServer craftServer = (CraftServer) player.getServer(); + + Block blockClicked = craftWorld.getBlockAt(clickedX, clickedY, clickedZ); + BlockFace blockFace = CraftBlock.notchToBlockFace(clickedFace); + + PlayerEvent event = null; + if (isFilling) { + event = new PlayerBucketFillEvent(player, blockClicked, blockFace, bucket, itemInHand); + ((PlayerBucketFillEvent) event).setCancelled(!canBuild(craftWorld, player, clickedX, clickedZ)); + } else { + event = new PlayerBucketEmptyEvent(player, blockClicked, blockFace, bucket, itemInHand); + ((PlayerBucketEmptyEvent) event).setCancelled(!canBuild(craftWorld, player, clickedX, clickedZ)); + } + + craftServer.getPluginManager().callEvent(event); + + return event; + } + + /** + * Player Interact event + */ + public static PlayerInteractEvent callPlayerInteractEvent(EntityHuman who, Action action, ItemStack itemstack) { + if (action != Action.LEFT_CLICK_AIR && action != Action.RIGHT_CLICK_AIR) { + throw new IllegalArgumentException(String.format("%s performing %s with %s", who, action, itemstack)); // Spigot + } + return callPlayerInteractEvent(who, action, new BlockPosition(0, 256, 0), EnumDirection.SOUTH, itemstack); + } + + public static PlayerInteractEvent callPlayerInteractEvent(EntityHuman who, Action action, BlockPosition position, EnumDirection direction, ItemStack itemstack) { + return callPlayerInteractEvent(who, action, position, direction, itemstack, false); + } + + public static PlayerInteractEvent callPlayerInteractEvent(EntityHuman who, Action action, BlockPosition position, EnumDirection direction, ItemStack itemstack, boolean cancelledBlock) { + Player player = (who == null) ? null : (Player) who.getBukkitEntity(); + CraftItemStack itemInHand = CraftItemStack.asCraftMirror(itemstack); + + CraftWorld craftWorld = (CraftWorld) player.getWorld(); + CraftServer craftServer = (CraftServer) player.getServer(); + + Block blockClicked = craftWorld.getBlockAt(position.getX(), position.getY(), position.getZ()); + BlockFace blockFace = CraftBlock.notchToBlockFace(direction); + + if (position.getY() > 255) { + blockClicked = null; + switch (action) { + case LEFT_CLICK_BLOCK: + action = Action.LEFT_CLICK_AIR; + break; + case RIGHT_CLICK_BLOCK: + action = Action.RIGHT_CLICK_AIR; + break; + } + } + + if (itemInHand.getType() == Material.AIR || itemInHand.getAmount() == 0) { + itemInHand = null; + } + + PlayerInteractEvent event = new PlayerInteractEvent(player, action, itemInHand, blockClicked, blockFace); + if (cancelledBlock) { + event.setUseInteractedBlock(Event.Result.DENY); + } + craftServer.getPluginManager().callEvent(event); + + return event; + } + + /** + * EntityShootBowEvent + */ + public static EntityShootBowEvent callEntityShootBowEvent(EntityLiving who, ItemStack itemstack, EntityArrow entityArrow, float force) { + LivingEntity shooter = (LivingEntity) who.getBukkitEntity(); + CraftItemStack itemInHand = CraftItemStack.asCraftMirror(itemstack); + Arrow arrow = (Arrow) entityArrow.getBukkitEntity(); + + if (itemInHand != null && (itemInHand.getType() == Material.AIR || itemInHand.getAmount() == 0)) { + itemInHand = null; + } + + EntityShootBowEvent event = new EntityShootBowEvent(shooter, itemInHand, arrow, force); + Bukkit.getPluginManager().callEvent(event); + + return event; + } + + /** + * BlockDamageEvent + */ + public static BlockDamageEvent callBlockDamageEvent(EntityHuman who, int x, int y, int z, ItemStack itemstack, boolean instaBreak) { + Player player = (who == null) ? null : (Player) who.getBukkitEntity(); + CraftItemStack itemInHand = CraftItemStack.asCraftMirror(itemstack); + + CraftWorld craftWorld = (CraftWorld) player.getWorld(); + CraftServer craftServer = (CraftServer) player.getServer(); + + Block blockClicked = craftWorld.getBlockAt(x, y, z); + + BlockDamageEvent event = new BlockDamageEvent(player, blockClicked, itemInHand, instaBreak); + craftServer.getPluginManager().callEvent(event); + + return event; + } + + /** + * CreatureSpawnEvent + */ + public static CreatureSpawnEvent callCreatureSpawnEvent(EntityLiving entityliving, SpawnReason spawnReason) { + LivingEntity entity = (LivingEntity) entityliving.getBukkitEntity(); + CraftServer craftServer = (CraftServer) entity.getServer(); + + CreatureSpawnEvent event = new CreatureSpawnEvent(entity, spawnReason); + craftServer.getPluginManager().callEvent(event); + return event; + } + + /** + * EntityTameEvent + */ + public static EntityTameEvent callEntityTameEvent(EntityInsentient entity, EntityHuman tamer) { + org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); + org.bukkit.entity.AnimalTamer bukkitTamer = (tamer != null ? tamer.getBukkitEntity() : null); + CraftServer craftServer = (CraftServer) bukkitEntity.getServer(); + + entity.persistent = true; + + EntityTameEvent event = new EntityTameEvent((LivingEntity) bukkitEntity, bukkitTamer); + craftServer.getPluginManager().callEvent(event); + return event; + } + + /** + * ItemSpawnEvent + */ + public static ItemSpawnEvent callItemSpawnEvent(EntityItem entityitem) { + org.bukkit.entity.Item entity = (org.bukkit.entity.Item) entityitem.getBukkitEntity(); + CraftServer craftServer = (CraftServer) entity.getServer(); + + ItemSpawnEvent event = new ItemSpawnEvent(entity, entity.getLocation()); + + craftServer.getPluginManager().callEvent(event); + return event; + } + + /** + * ItemDespawnEvent + */ + public static ItemDespawnEvent callItemDespawnEvent(EntityItem entityitem) { + org.bukkit.entity.Item entity = (org.bukkit.entity.Item) entityitem.getBukkitEntity(); + + ItemDespawnEvent event = new ItemDespawnEvent(entity, entity.getLocation()); + + entity.getServer().getPluginManager().callEvent(event); + return event; + } + + /** + * ItemMergeEvent + */ + public static ItemMergeEvent callItemMergeEvent(EntityItem merging, EntityItem mergingWith) { + org.bukkit.entity.Item entityMerging = (org.bukkit.entity.Item) merging.getBukkitEntity(); + org.bukkit.entity.Item entityMergingWith = (org.bukkit.entity.Item) mergingWith.getBukkitEntity(); + + ItemMergeEvent event = new ItemMergeEvent(entityMerging, entityMergingWith); + + Bukkit.getPluginManager().callEvent(event); + return event; + } + + /** + * PotionSplashEvent + */ + public static PotionSplashEvent callPotionSplashEvent(EntityPotion potion, Map affectedEntities) { + ThrownPotion thrownPotion = (ThrownPotion) potion.getBukkitEntity(); + + PotionSplashEvent event = new PotionSplashEvent(thrownPotion, affectedEntities); + Bukkit.getPluginManager().callEvent(event); + return event; + } + + /** + * BlockFadeEvent + */ + public static BlockFadeEvent callBlockFadeEvent(Block block, net.minecraft.server.Block type) { + BlockState state = block.getState(); + state.setTypeId(net.minecraft.server.Block.getId(type)); + + BlockFadeEvent event = new BlockFadeEvent(block, state); + Bukkit.getPluginManager().callEvent(event); + return event; + } + + public static void handleBlockSpreadEvent(Block block, Block source, net.minecraft.server.Block type, int data) { + BlockState state = block.getState(); + state.setTypeId(net.minecraft.server.Block.getId(type)); + state.setRawData((byte) data); + + BlockSpreadEvent event = new BlockSpreadEvent(block, source, state); + Bukkit.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + state.update(true); + } + } + + public static EntityDeathEvent callEntityDeathEvent(EntityLiving victim) { + return callEntityDeathEvent(victim, new ArrayList(0)); + } + + public static EntityDeathEvent callEntityDeathEvent(EntityLiving victim, List drops) { + CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity(); + EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward()); + CraftWorld world = (CraftWorld) entity.getWorld(); + Bukkit.getServer().getPluginManager().callEvent(event); + + victim.expToDrop = event.getDroppedExp(); + + for (org.bukkit.inventory.ItemStack stack : event.getDrops()) { + if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue; + + world.dropItemNaturally(entity.getLocation(), stack); + } + + return event; + } + + public static PlayerDeathEvent callPlayerDeathEvent(EntityPlayer victim, List drops, String deathMessage, boolean keepInventory) { + CraftPlayer entity = victim.getBukkitEntity(); + PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage); + event.setKeepInventory(keepInventory); + org.bukkit.World world = entity.getWorld(); + Bukkit.getServer().getPluginManager().callEvent(event); + + victim.keepLevel = event.getKeepLevel(); + victim.newLevel = event.getNewLevel(); + victim.newTotalExp = event.getNewTotalExp(); + victim.expToDrop = event.getDroppedExp(); + victim.newExp = event.getNewExp(); + + if (event.getKeepInventory()) { + return event; + } + + for (org.bukkit.inventory.ItemStack stack : event.getDrops()) { + if (stack == null || stack.getType() == Material.AIR) continue; + + world.dropItemNaturally(entity.getLocation(), stack); + } + + return event; + } + + /** + * Server methods + */ + public static ServerListPingEvent callServerListPingEvent(Server craftServer, InetAddress address, String motd, int numPlayers, int maxPlayers) { + ServerListPingEvent event = new ServerListPingEvent(address, motd, numPlayers, maxPlayers); + craftServer.getPluginManager().callEvent(event); + return event; + } + + private static EntityDamageEvent handleEntityDamageEvent(Entity entity, DamageSource source, Map modifiers, Map> modifierFunctions) { + if (source.isExplosion()) { + DamageCause damageCause; + Entity damager = entityDamage; + entityDamage = null; + EntityDamageEvent event; + if (damager == null) { + event = new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.BLOCK_EXPLOSION, modifiers, modifierFunctions); + } else if (entity instanceof EntityEnderDragon && ((EntityEnderDragon) entity).target == damager) { + event = new EntityDamageEvent(entity.getBukkitEntity(), DamageCause.ENTITY_EXPLOSION, modifiers, modifierFunctions); + } else { + if (damager instanceof org.bukkit.entity.TNTPrimed) { + damageCause = DamageCause.BLOCK_EXPLOSION; + } else { + damageCause = DamageCause.ENTITY_EXPLOSION; + } + event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions); + } + + callEvent(event); + + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; + } else if (source instanceof EntityDamageSource) { + Entity damager = source.getEntity(); + DamageCause cause = DamageCause.ENTITY_ATTACK; + + if (source instanceof EntityDamageSourceIndirect) { + damager = ((EntityDamageSourceIndirect) source).getProximateDamageSource(); + if (damager.getBukkitEntity() instanceof ThrownPotion) { + cause = DamageCause.MAGIC; + } else if (damager.getBukkitEntity() instanceof Projectile) { + cause = DamageCause.PROJECTILE; + } + } else if ("thorns".equals(source.translationIndex)) { + cause = DamageCause.THORNS; + } + + return callEntityDamageEvent(damager, entity, cause, modifiers, modifierFunctions); + } else if (source == DamageSource.OUT_OF_WORLD) { + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.VOID, modifiers, modifierFunctions)); + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; + } else if (source == DamageSource.LAVA) { + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(null, entity.getBukkitEntity(), DamageCause.LAVA, modifiers, modifierFunctions)); + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; + } else if (blockDamage != null) { + DamageCause cause = null; + Block damager = blockDamage; + blockDamage = null; + if (source == DamageSource.CACTUS) { + cause = DamageCause.CONTACT; + } else { + throw new RuntimeException(String.format("Unhandled damage of %s by %s from %s", entity, damager, source.translationIndex)); // Spigot + } + EntityDamageEvent event = callEvent(new EntityDamageByBlockEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions)); + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; + } else if (entityDamage != null) { + DamageCause cause = null; + CraftEntity damager = entityDamage.getBukkitEntity(); + entityDamage = null; + if (source == DamageSource.ANVIL || source == DamageSource.FALLING_BLOCK) { + cause = DamageCause.FALLING_BLOCK; + } else if (damager instanceof LightningStrike) { + cause = DamageCause.LIGHTNING; + } else if (source == DamageSource.FALL) { + cause = DamageCause.FALL; + } else { + throw new RuntimeException(String.format("Unhandled damage of %s by %s from %s", entity, damager.getHandle(), source.translationIndex)); // Spigot + } + EntityDamageEvent event = callEvent(new EntityDamageByEntityEvent(damager, entity.getBukkitEntity(), cause, modifiers, modifierFunctions)); + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + return event; + } + + DamageCause cause = null; + if (source == DamageSource.FIRE) { + cause = DamageCause.FIRE; + } else if (source == DamageSource.STARVE) { + cause = DamageCause.STARVATION; + } else if (source == DamageSource.WITHER) { + cause = DamageCause.WITHER; + } else if (source == DamageSource.STUCK) { + cause = DamageCause.SUFFOCATION; + } else if (source == DamageSource.DROWN) { + cause = DamageCause.DROWNING; + } else if (source == DamageSource.BURN) { + cause = DamageCause.FIRE_TICK; + } else if (source == MELTING) { + cause = DamageCause.MELTING; + } else if (source == POISON) { + cause = DamageCause.POISON; + } else if (source == DamageSource.MAGIC) { + cause = DamageCause.MAGIC; + } else if (source == DamageSource.FALL) { + cause = DamageCause.FALL; + } else if (source == DamageSource.GENERIC) { + return new EntityDamageEvent(entity.getBukkitEntity(), null, modifiers, modifierFunctions); + } + + if (cause != null) { + return callEntityDamageEvent(null, entity, cause, modifiers, modifierFunctions); + } + + throw new RuntimeException(String.format("Unhandled damage of %s from %s", entity, source.translationIndex)); // Spigot + } + + private static EntityDamageEvent callEntityDamageEvent(Entity damager, Entity damagee, DamageCause cause, Map modifiers, Map> modifierFunctions) { + EntityDamageEvent event; + if (damager != null) { + event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); + } else { + event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); + } + + callEvent(event); + + if (!event.isCancelled()) { + event.getEntity().setLastDamageCause(event); + } + + return event; + } + + private static final Function ZERO = Functions.constant(-0.0); + + public static EntityDamageEvent handleLivingEntityDamageEvent(Entity damagee, DamageSource source, double rawDamage, double hardHatModifier, double blockingModifier, double armorModifier, double resistanceModifier, double magicModifier, double absorptionModifier, Function hardHat, Function blocking, Function armor, Function resistance, Function magic, Function absorption) { + Map modifiers = new EnumMap(DamageModifier.class); + Map> modifierFunctions = new EnumMap>(DamageModifier.class); + modifiers.put(DamageModifier.BASE, rawDamage); + modifierFunctions.put(DamageModifier.BASE, ZERO); + if (source == DamageSource.FALLING_BLOCK || source == DamageSource.ANVIL) { + modifiers.put(DamageModifier.HARD_HAT, hardHatModifier); + modifierFunctions.put(DamageModifier.HARD_HAT, hardHat); + } + if (damagee instanceof EntityHuman) { + modifiers.put(DamageModifier.BLOCKING, blockingModifier); + modifierFunctions.put(DamageModifier.BLOCKING, blocking); + } + modifiers.put(DamageModifier.ARMOR, armorModifier); + modifierFunctions.put(DamageModifier.ARMOR, armor); + modifiers.put(DamageModifier.RESISTANCE, resistanceModifier); + modifierFunctions.put(DamageModifier.RESISTANCE, resistance); + modifiers.put(DamageModifier.MAGIC, magicModifier); + modifierFunctions.put(DamageModifier.MAGIC, magic); + modifiers.put(DamageModifier.ABSORPTION, absorptionModifier); + modifierFunctions.put(DamageModifier.ABSORPTION, absorption); + return handleEntityDamageEvent(damagee, source, modifiers, modifierFunctions); + } + + // Non-Living Entities such as EntityEnderCrystal and EntityFireball need to call this + public static boolean handleNonLivingEntityDamageEvent(Entity entity, DamageSource source, double damage) { + return handleNonLivingEntityDamageEvent(entity, source, damage, true); + } + + public static boolean handleNonLivingEntityDamageEvent(Entity entity, DamageSource source, double damage, boolean cancelOnZeroDamage) { + if (entity instanceof EntityEnderCrystal && !(source instanceof EntityDamageSource)) { + return false; + } + + final EnumMap modifiers = new EnumMap(DamageModifier.class); + final EnumMap> functions = new EnumMap(DamageModifier.class); + + modifiers.put(DamageModifier.BASE, damage); + functions.put(DamageModifier.BASE, ZERO); + + final EntityDamageEvent event = handleEntityDamageEvent(entity, source, modifiers, functions); + if (event == null) { + return false; + } + return event.isCancelled() || (cancelOnZeroDamage && event.getDamage() == 0); + } + + public static PlayerLevelChangeEvent callPlayerLevelChangeEvent(Player player, int oldLevel, int newLevel) { + PlayerLevelChangeEvent event = new PlayerLevelChangeEvent(player, oldLevel, newLevel); + Bukkit.getPluginManager().callEvent(event); + return event; + } + + public static PlayerExpChangeEvent callPlayerExpChangeEvent(EntityHuman entity, int expAmount) { + Player player = (Player) entity.getBukkitEntity(); + PlayerExpChangeEvent event = new PlayerExpChangeEvent(player, expAmount); + Bukkit.getPluginManager().callEvent(event); + return event; + } + + public static void handleBlockGrowEvent(World world, int x, int y, int z, net.minecraft.server.Block type, int data) { + Block block = world.getWorld().getBlockAt(x, y, z); + CraftBlockState state = (CraftBlockState) block.getState(); + state.setTypeId(net.minecraft.server.Block.getId(type)); + state.setRawData((byte) data); + + BlockGrowEvent event = new BlockGrowEvent(block, state); + Bukkit.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + state.update(true); + } + } + + public static FoodLevelChangeEvent callFoodLevelChangeEvent(EntityHuman entity, int level) { + FoodLevelChangeEvent event = new FoodLevelChangeEvent(entity.getBukkitEntity(), level); + entity.getBukkitEntity().getServer().getPluginManager().callEvent(event); + return event; + } + + public static PigZapEvent callPigZapEvent(Entity pig, Entity lightning, Entity pigzombie) { + PigZapEvent event = new PigZapEvent((Pig) pig.getBukkitEntity(), (LightningStrike) lightning.getBukkitEntity(), (PigZombie) pigzombie.getBukkitEntity()); + pig.getBukkitEntity().getServer().getPluginManager().callEvent(event); + return event; + } + + public static HorseJumpEvent callHorseJumpEvent(Entity horse, float power) { + HorseJumpEvent event = new HorseJumpEvent((Horse) horse.getBukkitEntity(), power); + horse.getBukkitEntity().getServer().getPluginManager().callEvent(event); + return event; + } + + public static EntityChangeBlockEvent callEntityChangeBlockEvent(org.bukkit.entity.Entity entity, Block block, Material material) { + return callEntityChangeBlockEvent(entity, block, material, 0); + } + + public static EntityChangeBlockEvent callEntityChangeBlockEvent(Entity entity, Block block, Material material) { + return callEntityChangeBlockEvent(entity.getBukkitEntity(), block, material, 0); + } + + public static EntityChangeBlockEvent callEntityChangeBlockEvent(Entity entity, Block block, Material material, boolean cancelled) { + return callEntityChangeBlockEvent(entity.getBukkitEntity(), block, material, 0, cancelled); + } + + public static EntityChangeBlockEvent callEntityChangeBlockEvent(Entity entity, int x, int y, int z, net.minecraft.server.Block type, int data) { + Block block = entity.world.getWorld().getBlockAt(x, y, z); + Material material = CraftMagicNumbers.getMaterial(type); + + return callEntityChangeBlockEvent(entity.getBukkitEntity(), block, material, data); + } + + public static EntityChangeBlockEvent callEntityChangeBlockEvent(org.bukkit.entity.Entity entity, Block block, Material material, int data) { + return callEntityChangeBlockEvent(entity, block, material, data, false); + } + + public static EntityChangeBlockEvent callEntityChangeBlockEvent(org.bukkit.entity.Entity entity, Block block, Material material, int data, boolean cancelled) { + EntityChangeBlockEvent event = new EntityChangeBlockEvent(entity, block, material, (byte) data); + event.setCancelled(cancelled); + entity.getServer().getPluginManager().callEvent(event); + return event; + } + + public static CreeperPowerEvent callCreeperPowerEvent(Entity creeper, Entity lightning, CreeperPowerEvent.PowerCause cause) { + CreeperPowerEvent event = new CreeperPowerEvent((Creeper) creeper.getBukkitEntity(), (LightningStrike) lightning.getBukkitEntity(), cause); + creeper.getBukkitEntity().getServer().getPluginManager().callEvent(event); + return event; + } + + public static EntityTargetEvent callEntityTargetEvent(Entity entity, Entity target, EntityTargetEvent.TargetReason reason) { + EntityTargetEvent event = new EntityTargetEvent(entity.getBukkitEntity(), target == null ? null : target.getBukkitEntity(), reason); + entity.getBukkitEntity().getServer().getPluginManager().callEvent(event); + return event; + } + + public static EntityTargetLivingEntityEvent callEntityTargetLivingEvent(Entity entity, EntityLiving target, EntityTargetEvent.TargetReason reason) { + EntityTargetLivingEntityEvent event = new EntityTargetLivingEntityEvent(entity.getBukkitEntity(), (LivingEntity) target.getBukkitEntity(), reason); + entity.getBukkitEntity().getServer().getPluginManager().callEvent(event); + return event; + } + + public static EntityBreakDoorEvent callEntityBreakDoorEvent(Entity entity, int x, int y, int z) { + org.bukkit.entity.Entity entity1 = entity.getBukkitEntity(); + Block block = entity1.getWorld().getBlockAt(x, y, z); + + EntityBreakDoorEvent event = new EntityBreakDoorEvent((LivingEntity) entity1, block); + entity1.getServer().getPluginManager().callEvent(event); + + return event; + } + + public static Container callInventoryOpenEvent(EntityPlayer player, Container container) { + return callInventoryOpenEvent(player, container, false); + } + + public static Container callInventoryOpenEvent(EntityPlayer player, Container container, boolean cancelled) { + if (player.activeContainer != player.defaultContainer) { // fire INVENTORY_CLOSE if one already open + player.playerConnection.a(new PacketPlayInCloseWindow(player.activeContainer.windowId)); + } + + CraftServer server = player.world.getServer(); + CraftPlayer craftPlayer = player.getBukkitEntity(); + player.activeContainer.transferTo(container, craftPlayer); + + InventoryOpenEvent event = new InventoryOpenEvent(container.getBukkitView()); + event.setCancelled(cancelled); + server.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + container.transferTo(player.activeContainer, craftPlayer); + return null; + } + + return container; + } + + public static ItemStack callPreCraftEvent(InventoryCrafting matrix, ItemStack result, InventoryView lastCraftView, boolean isRepair) { + CraftInventoryCrafting inventory = new CraftInventoryCrafting(matrix, matrix.resultInventory); + inventory.setResult(CraftItemStack.asCraftMirror(result)); + + PrepareItemCraftEvent event = new PrepareItemCraftEvent(inventory, lastCraftView, isRepair); + Bukkit.getPluginManager().callEvent(event); + + org.bukkit.inventory.ItemStack bitem = event.getInventory().getResult(); + + return CraftItemStack.asNMSCopy(bitem); + } + + public static ProjectileLaunchEvent callProjectileLaunchEvent(Entity entity) { + Projectile bukkitEntity = (Projectile) entity.getBukkitEntity(); + ProjectileLaunchEvent event = new ProjectileLaunchEvent(bukkitEntity); + Bukkit.getPluginManager().callEvent(event); + return event; + } + + public static ProjectileHitEvent callProjectileHitEvent(Entity entity) { + ProjectileHitEvent event = new ProjectileHitEvent((Projectile) entity.getBukkitEntity()); + entity.world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static ExpBottleEvent callExpBottleEvent(Entity entity, int exp) { + ThrownExpBottle bottle = (ThrownExpBottle) entity.getBukkitEntity(); + ExpBottleEvent event = new ExpBottleEvent(bottle, exp); + Bukkit.getPluginManager().callEvent(event); + return event; + } + + public static BlockRedstoneEvent callRedstoneChange(World world, int x, int y, int z, int oldCurrent, int newCurrent) { + BlockRedstoneEvent event = new BlockRedstoneEvent(world.getWorld().getBlockAt(x, y, z), oldCurrent, newCurrent); + world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static NotePlayEvent callNotePlayEvent(World world, int x, int y, int z, byte instrument, byte note) { + NotePlayEvent event = new NotePlayEvent(world.getWorld().getBlockAt(x, y, z), org.bukkit.Instrument.getByType(instrument), new org.bukkit.Note(note)); + world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static void callPlayerItemBreakEvent(EntityHuman human, ItemStack brokenItem) { + CraftItemStack item = CraftItemStack.asCraftMirror(brokenItem); + PlayerItemBreakEvent event = new PlayerItemBreakEvent((Player) human.getBukkitEntity(), item); + Bukkit.getPluginManager().callEvent(event); + } + + public static BlockIgniteEvent callBlockIgniteEvent(World world, int x, int y, int z, int igniterX, int igniterY, int igniterZ) { + org.bukkit.World bukkitWorld = world.getWorld(); + Block igniter = bukkitWorld.getBlockAt(igniterX, igniterY, igniterZ); + IgniteCause cause; + switch (igniter.getType()) { + case LAVA: + case STATIONARY_LAVA: + cause = IgniteCause.LAVA; + break; + case DISPENSER: + cause = IgniteCause.FLINT_AND_STEEL; + break; + case FIRE: // Fire or any other unknown block counts as SPREAD. + default: + cause = IgniteCause.SPREAD; + } + + BlockIgniteEvent event = new BlockIgniteEvent(bukkitWorld.getBlockAt(x, y, z), cause, igniter); + world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static BlockIgniteEvent callBlockIgniteEvent(World world, int x, int y, int z, Entity igniter) { + org.bukkit.World bukkitWorld = world.getWorld(); + org.bukkit.entity.Entity bukkitIgniter = igniter.getBukkitEntity(); + IgniteCause cause; + switch (bukkitIgniter.getType()) { + case ENDER_CRYSTAL: + cause = IgniteCause.ENDER_CRYSTAL; + break; + case LIGHTNING: + cause = IgniteCause.LIGHTNING; + break; + case SMALL_FIREBALL: + case FIREBALL: + cause = IgniteCause.FIREBALL; + break; + default: + cause = IgniteCause.FLINT_AND_STEEL; + } + + BlockIgniteEvent event = new BlockIgniteEvent(bukkitWorld.getBlockAt(x, y, z), cause, bukkitIgniter); + world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static BlockIgniteEvent callBlockIgniteEvent(World world, int x, int y, int z, Explosion explosion) { + org.bukkit.World bukkitWorld = world.getWorld(); + org.bukkit.entity.Entity igniter = explosion.source == null ? null : explosion.source.getBukkitEntity(); + + BlockIgniteEvent event = new BlockIgniteEvent(bukkitWorld.getBlockAt(x, y, z), IgniteCause.EXPLOSION, igniter); + world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static BlockIgniteEvent callBlockIgniteEvent(World world, int x, int y, int z, IgniteCause cause, Entity igniter) { + BlockIgniteEvent event = new BlockIgniteEvent(world.getWorld().getBlockAt(x, y, z), cause, igniter.getBukkitEntity()); + world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static void handleInventoryCloseEvent(EntityHuman human) { + InventoryCloseEvent event = new InventoryCloseEvent(human.activeContainer.getBukkitView()); + human.world.getServer().getPluginManager().callEvent(event); + human.activeContainer.transferTo(human.defaultContainer, human.getBukkitEntity()); + } + + public static void handleEditBookEvent(EntityPlayer player, ItemStack newBookItem) { + int itemInHandIndex = player.inventory.itemInHandIndex; + + PlayerEditBookEvent editBookEvent = new PlayerEditBookEvent(player.getBukkitEntity(), player.inventory.itemInHandIndex, (BookMeta) CraftItemStack.getItemMeta(player.inventory.getItemInHand()), (BookMeta) CraftItemStack.getItemMeta(newBookItem), newBookItem.getItem() == Items.WRITTEN_BOOK); + player.world.getServer().getPluginManager().callEvent(editBookEvent); + ItemStack itemInHand = player.inventory.getItem(itemInHandIndex); + + // If they've got the same item in their hand, it'll need to be updated. + if (itemInHand != null && itemInHand.getItem() == Items.WRITABLE_BOOK) { + if (!editBookEvent.isCancelled()) { + if (editBookEvent.isSigning()) { + itemInHand.setItem(Items.WRITTEN_BOOK); + } + CraftMetaBook meta = (CraftMetaBook) editBookEvent.getNewBookMeta(); + List pages = meta.pages; + for (int i = 0; i < pages.size(); i++) { + pages.set(i, stripEvents(pages.get(i))); + } + CraftItemStack.setItemMeta(itemInHand, meta); + } + + // Client will have updated its idea of the book item; we need to overwrite that + Slot slot = player.activeContainer.getSlot(player.inventory, itemInHandIndex); + player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.activeContainer.windowId, slot.rawSlotIndex, itemInHand)); + } + } + + private static IChatBaseComponent stripEvents(IChatBaseComponent c) { + ChatModifier modi = c.getChatModifier(); + if (modi != null) { + modi.setChatClickable(null); + modi.setChatHoverable(null); + } + c.setChatModifier(modi); + if (c instanceof ChatMessage) { + ChatMessage cm = (ChatMessage) c; + Object[] oo = cm.j(); + for (int i = 0; i < oo.length; i++) { + Object o = oo[i]; + if (o instanceof IChatBaseComponent) { + oo[i] = stripEvents((IChatBaseComponent) o); + } + } + } + List ls = c.a(); + if (ls != null) { + for (int i = 0; i < ls.size(); i++) { + ls.set(i, stripEvents(ls.get(i))); + } + } + return c; + } + + public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(EntityInsentient entity, EntityHuman player) { + PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity()); + entity.world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static PlayerLeashEntityEvent callPlayerLeashEntityEvent(EntityInsentient entity, Entity leashHolder, EntityHuman player) { + PlayerLeashEntityEvent event = new PlayerLeashEntityEvent(entity.getBukkitEntity(), leashHolder.getBukkitEntity(), (Player) player.getBukkitEntity()); + entity.world.getServer().getPluginManager().callEvent(event); + return event; + } + + public static Cancellable handleStatisticsIncrease(EntityHuman entityHuman, net.minecraft.server.Statistic statistic, int current, int incrementation) { + Player player = ((EntityPlayer) entityHuman).getBukkitEntity(); + Event event; + if (statistic instanceof net.minecraft.server.Achievement) { + if (current != 0) { + return null; + } + event = new PlayerAchievementAwardedEvent(player, CraftStatistic.getBukkitAchievement((net.minecraft.server.Achievement) statistic)); + } else { + org.bukkit.Statistic stat = CraftStatistic.getBukkitStatistic(statistic); + if (stat == null) { + System.err.println("Unhandled statistic: " + statistic); + return null; + } + switch (stat) { + case FALL_ONE_CM: + case BOAT_ONE_CM: + case CLIMB_ONE_CM: + case DIVE_ONE_CM: + case FLY_ONE_CM: + case HORSE_ONE_CM: + case MINECART_ONE_CM: + case PIG_ONE_CM: + case PLAY_ONE_TICK: + case SWIM_ONE_CM: + case WALK_ONE_CM: + case SPRINT_ONE_CM: + case CROUCH_ONE_CM: + case TIME_SINCE_DEATH: + // Do not process event for these - too spammy + return null; + default: + } + if (stat.getType() == Type.UNTYPED) { + event = new PlayerStatisticIncrementEvent(player, stat, current, current + incrementation); + } else if (stat.getType() == Type.ENTITY) { + EntityType entityType = CraftStatistic.getEntityTypeFromStatistic(statistic); + event = new PlayerStatisticIncrementEvent(player, stat, current, current + incrementation, entityType); + } else { + Material material = CraftStatistic.getMaterialFromStatistic(statistic); + event = new PlayerStatisticIncrementEvent(player, stat, current, current + incrementation, material); + } + } + entityHuman.world.getServer().getPluginManager().callEvent(event); + return (Cancellable) event; + } + + public static FireworkExplodeEvent callFireworkExplodeEvent(EntityFireworks firework) { + FireworkExplodeEvent event = new FireworkExplodeEvent((Firework) firework.getBukkitEntity()); + firework.world.getServer().getPluginManager().callEvent(event); + return event; + } + + // PaperSpigot start - Add PlayerLocaleChangeEvent + public static PlayerLocaleChangeEvent callPlayerLocaleChangeEvent(EntityHuman who, String oldLocale, String newLocale) { + Player player = (Player) who.getBukkitEntity(); + PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(player, oldLocale, newLocale); + Bukkit.getPluginManager().callEvent(event); + return event; + } + // PaperSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java new file mode 100644 index 0000000..01264a7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/CraftChunkData.java @@ -0,0 +1,199 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.bukkit.craftbukkit.generator; + +import java.util.Arrays; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.material.MaterialData; + +/** + * Data to be used for the block types and data in a newly generated chunk. + */ +public final class CraftChunkData implements ChunkGenerator.ChunkData { + private final int maxHeight; + private final char[][] sections; + + public CraftChunkData(World world) { + this(world.getMaxHeight()); + } + + /* pp for tests */ CraftChunkData(int maxHeight) { + if (maxHeight > 256) { + throw new IllegalArgumentException("World height exceeded max chunk height"); + } + this.maxHeight = maxHeight; + // Minecraft hardcodes this to 16 chunk sections. + sections = new char[16][]; + } + + @Override + public int getMaxHeight() { + return maxHeight; + } + + @Override + public void setBlock(int x, int y, int z, Material material) { + setBlock(x, y, z, material.getId()); + } + + @Override + public void setBlock(int x, int y, int z, MaterialData material) { + setBlock(x, y, z, material.getItemTypeId(), material.getData()); + } + + @Override + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, Material material) { + setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.getId()); + } + + @Override + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, MaterialData material) { + setRegion(xMin, yMin, zMin, xMax, yMax, zMax, material.getItemTypeId(), material.getData()); + } + + @Override + public Material getType(int x, int y, int z) { + return Material.getMaterial(getTypeId(x, y, z)); + } + + @Override + public MaterialData getTypeAndData(int x, int y, int z) { + return getType(x, y, z).getNewData(getData(x, y, z)); + } + + @Override + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId) { + setRegion(xMin, yMin, zMin, xMax, yMax, zMax, blockId, (byte) 0); + } + + @Override + public void setRegion(int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, int blockId, int data) { + // Clamp to sane values. + if (xMin > 0xf || yMin >= maxHeight || zMin > 0xf) { + return; + } + if (xMin < 0) { + xMin = 0; + } + if (yMin < 0) { + yMin = 0; + } + if (zMin < 0) { + zMin = 0; + } + if (xMax > 0x10) { + xMax = 0x10; + } + if (yMax > maxHeight) { + yMax = maxHeight; + } + if (zMax > 0x10) { + zMax = 0x10; + } + if (xMin >= xMax || yMin >= yMax || zMin >= zMax) { + return; + } + char typeChar = (char) ((blockId << 4) | data); + if (xMin == 0 && xMax == 0x10) { + if (zMin == 0 && zMax == 0x10) { + for (int y = yMin & 0xf0; y < yMax; y += 0x10) { + char[] section = getChunkSection(y, true); + if (y <= yMin) { + if (y + 0x10 > yMax) { + // First and last chunk section + Arrays.fill(section, (yMin & 0xf) << 8, (yMax & 0xf) << 8, typeChar); + } else { + // First chunk section + Arrays.fill(section, (yMin & 0xf) << 8, 0x1000, typeChar); + } + } else if (y + 0x10 > yMax) { + // Last chunk section + Arrays.fill(section, 0, (yMax & 0xf) << 8, typeChar); + } else { + // Full chunk section + Arrays.fill(section, 0, 0x1000, typeChar); + } + } + } else { + for (int y = yMin; y < yMax; y++) { + char[] section = getChunkSection(y, true); + int offsetBase = (y & 0xf) << 8; + int min = offsetBase | (zMin << 4); + // Need to add zMax as it can be 16, which overlaps the y coordinate bits + int max = offsetBase + (zMax << 4); + Arrays.fill(section, min, max, typeChar); + } + } + } else { + for (int y = yMin; y < yMax; y++) { + char[] section = getChunkSection(y, true); + int offsetBase = (y & 0xf) << 8; + for (int z = zMin; z < zMax; z++) { + int offset = offsetBase | (z << 4); + // Need to add xMax as it can be 16, which overlaps the z coordinate bits + Arrays.fill(section, offset | xMin, offset + xMax, typeChar); + } + } + } + } + + @Override + public void setBlock(int x, int y, int z, int blockId) { + setBlock(x, y, z, blockId, (byte) 0); + } + + @Override + public void setBlock(int x, int y, int z, int blockId, byte data) { + setBlock(x, y, z, (char) (blockId << 4 | data)); + } + + @Override + public int getTypeId(int x, int y, int z) { + if (x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf)) { + return 0; + } + char[] section = getChunkSection(y, false); + if (section == null) { + return 0; + } else { + return section[(y & 0xf) << 8 | z << 4 | x] >> 4; + } + } + + @Override + public byte getData(int x, int y, int z) { + if (x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf)) { + return (byte) 0; + } + char[] section = getChunkSection(y, false); + if (section == null) { + return (byte) 0; + } else { + return (byte) (section[(y & 0xf) << 8 | z << 4 | x] & 0xf); + } + } + + private void setBlock(int x, int y, int z, char type) { + if (x != (x & 0xf) || y < 0 || y >= maxHeight || z != (z & 0xf)) { + return; + } + char[] section = getChunkSection(y, true); + section[(y & 0xf) << 8 | z << 4 | x] = type; + } + + private char[] getChunkSection(int y, boolean create) { + char[] section = sections[y >> 4]; + if (create && section == null) { + sections[y >> 4] = section = new char[0x1000]; + } + return section; + } + + char[][] getRawChunkData() { + return sections; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java new file mode 100644 index 0000000..04dd15d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java @@ -0,0 +1,264 @@ +package org.bukkit.craftbukkit.generator; + +import java.util.List; +import java.util.Random; + +import net.minecraft.server.*; + +import org.bukkit.block.Biome; +import org.bukkit.generator.BlockPopulator; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.craftbukkit.block.CraftBlock; + +public class CustomChunkGenerator extends InternalChunkGenerator { + private final ChunkGenerator generator; + private final WorldServer world; + private final Random random; + private final WorldGenStronghold strongholdGen = new WorldGenStronghold(); + + private static class CustomBiomeGrid implements BiomeGrid { + BiomeBase[] biome; + + public Biome getBiome(int x, int z) { + return CraftBlock.biomeBaseToBiome(biome[(z << 4) | x]); + } + + public void setBiome(int x, int z, Biome bio) { + biome[(z << 4) | x] = CraftBlock.biomeToBiomeBase(bio); + } + } + + public CustomChunkGenerator(World world, long seed, ChunkGenerator generator) { + this.world = (WorldServer) world; + this.generator = generator; + + this.random = new Random(seed); + } + + public boolean isChunkLoaded(int x, int z) { + return true; + } + + public Chunk getOrCreateChunk(int x, int z) { + random.setSeed((long) x * 341873128712L + (long) z * 132897987541L); + + Chunk chunk; + + // Get default biome data for chunk + CustomBiomeGrid biomegrid = new CustomBiomeGrid(); + biomegrid.biome = new BiomeBase[256]; + world.getWorldChunkManager().getBiomeBlock(biomegrid.biome, x << 4, z << 4, 16, 16); + + // Try ChunkData method (1.8+) + CraftChunkData data = (CraftChunkData) generator.generateChunkData(this.world.getWorld(), random, x, z, biomegrid); + if (data != null) { + char[][] sections = data.getRawChunkData(); + chunk = new Chunk(this.world, x, z); + + ChunkSection[] csect = chunk.getSections(); + int scnt = Math.min(csect.length, sections.length); + + // Loop through returned sections + for (int sec = 0; sec < scnt; sec++) { + if(sections[sec] == null) { + continue; + } + char[] section = sections[sec]; + char emptyTest = 0; + for (int i = 0; i < 4096; i++) { + // Filter invalid block id & data values. + if (Block.d.a(section[i]) == null) { + section[i] = 0; + } + emptyTest |= section[i]; + } + // Build chunk section + if (emptyTest != 0) { + csect[sec] = new ChunkSection(sec << 4, true, section); + } + } + } + else { + // Try extended block method (1.2+) + short[][] xbtypes = generator.generateExtBlockSections(this.world.getWorld(), this.random, x, z, biomegrid); + if (xbtypes != null) { + chunk = new Chunk(this.world, x, z); + + ChunkSection[] csect = chunk.getSections(); + int scnt = Math.min(csect.length, xbtypes.length); + + // Loop through returned sections + for (int sec = 0; sec < scnt; sec++) { + if (xbtypes[sec] == null) { + continue; + } + char[] secBlkID = new char[4096]; // Allocate blk ID bytes + short[] bdata = xbtypes[sec]; + for (int i = 0; i < bdata.length; i++) { + Block b = Block.getById(bdata[i]); + secBlkID[i] = (char) Block.d.b(b.getBlockData()); + } + // Build chunk section + csect[sec] = new ChunkSection(sec << 4, true, secBlkID); + } + } + else { // Else check for byte-per-block section data + byte[][] btypes = generator.generateBlockSections(this.world.getWorld(), this.random, x, z, biomegrid); + + if (btypes != null) { + chunk = new Chunk(this.world, x, z); + + ChunkSection[] csect = chunk.getSections(); + int scnt = Math.min(csect.length, btypes.length); + + for (int sec = 0; sec < scnt; sec++) { + if (btypes[sec] == null) { + continue; + } + + char[] secBlkID = new char[4096]; // Allocate block ID bytes + for (int i = 0; i < secBlkID.length; i++) { + Block b = Block.getById(btypes[sec][i] & 0xFF); + secBlkID[i] = (char) Block.d.b(b.getBlockData()); + } + csect[sec] = new ChunkSection(sec << 4, true, secBlkID); + } + } + else { // Else, fall back to pre 1.2 method + @SuppressWarnings("deprecation") + byte[] types = generator.generate(this.world.getWorld(), this.random, x, z); + int ydim = types.length / 256; + int scnt = ydim / 16; + + chunk = new Chunk(this.world, x, z); // Create empty chunk + + ChunkSection[] csect = chunk.getSections(); + + scnt = Math.min(scnt, csect.length); + // Loop through sections + for (int sec = 0; sec < scnt; sec++) { + ChunkSection cs = null; // Add sections when needed + char[] csbytes = null; + + for (int cy = 0; cy < 16; cy++) { + int cyoff = cy | (sec << 4); + + for (int cx = 0; cx < 16; cx++) { + int cxyoff = (cx * ydim * 16) + cyoff; + + for (int cz = 0; cz < 16; cz++) { + byte blk = types[cxyoff + (cz * ydim)]; + + if (blk != 0) { // If non-empty + if (cs == null) { // If no section yet, get one + cs = csect[sec] = new ChunkSection(sec << 4, true); + csbytes = cs.getIdArray(); + } + + Block b = Block.getById(blk & 0xFF); + csbytes[(cy << 8) | (cz << 4) | cx] = (char) Block.d.b(b.getBlockData()); + } + } + } + } + // If section built, finish prepping its state + if (cs != null) { + cs.recalcBlockCounts(); + } + } + } + } + } + // Set biome grid + byte[] biomeIndex = chunk.getBiomeIndex(); + for (int i = 0; i < biomeIndex.length; i++) { + biomeIndex[i] = (byte) (biomegrid.biome[i].id & 0xFF); + } + // Initialize lighting + chunk.initLighting(); + + return chunk; + } + + @Override + public Chunk getChunkAt(BlockPosition blockPosition) { + return getChunkAt(blockPosition.getX() >> 4, blockPosition.getZ() >> 4); + } + + public void getChunkAt(IChunkProvider icp, int i, int i1) { + // Nothing! + } + + @Override + public boolean a(IChunkProvider iChunkProvider, Chunk chunk, int i, int i1) { + return false; + } + + public boolean saveChunks(boolean bln, IProgressUpdate ipu) { + return true; + } + + public boolean unloadChunks() { + return false; + } + + public boolean canSave() { + return true; + } + + @SuppressWarnings("deprecation") + public byte[] generate(org.bukkit.World world, Random random, int x, int z) { + return generator.generate(world, random, x, z); + } + + public byte[][] generateBlockSections(org.bukkit.World world, Random random, int x, int z, BiomeGrid biomes) { + return generator.generateBlockSections(world, random, x, z, biomes); + } + + public short[][] generateExtBlockSections(org.bukkit.World world, Random random, int x, int z, BiomeGrid biomes) { + return generator.generateExtBlockSections(world, random, x, z, biomes); + } + + public Chunk getChunkAt(int x, int z) { + return getOrCreateChunk(x, z); + } + + @Override + public boolean canSpawn(org.bukkit.World world, int x, int z) { + return generator.canSpawn(world, x, z); + } + + @Override + public List getDefaultPopulators(org.bukkit.World world) { + return generator.getDefaultPopulators(world); + } + + @Override + public List getMobsFor(EnumCreatureType type, BlockPosition position) { + BiomeBase biomebase = world.getBiome(position); + + return biomebase == null ? null : biomebase.getMobs(type); + } + + @Override + public BlockPosition findNearestMapFeature(World world, String type, BlockPosition position) { + return "Stronghold".equals(type) && this.strongholdGen != null ? this.strongholdGen.getNearestGeneratedFeature(world, position) : null; + } + + public void recreateStructures(int i, int j) {} + + public int getLoadedChunks() { + return 0; + } + + @Override + public void recreateStructures(Chunk chunk, int i, int i1) { + + } + + public String getName() { + return "CustomChunkGenerator"; + } + + public void c() {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/InternalChunkGenerator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/InternalChunkGenerator.java new file mode 100644 index 0000000..19565e5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/InternalChunkGenerator.java @@ -0,0 +1,8 @@ +package org.bukkit.craftbukkit.generator; + +import net.minecraft.server.IChunkProvider; +import org.bukkit.generator.ChunkGenerator; + +// Do not implement functions to this class, add to NormalChunkGenerator +public abstract class InternalChunkGenerator extends ChunkGenerator implements IChunkProvider { +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/NetherChunkGenerator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/NetherChunkGenerator.java new file mode 100644 index 0000000..59d7bbe --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/NetherChunkGenerator.java @@ -0,0 +1,12 @@ +package org.bukkit.craftbukkit.generator; + +import net.minecraft.server.World; + +/** + * This class is useless. Just fyi. + */ +public class NetherChunkGenerator extends NormalChunkGenerator { + public NetherChunkGenerator(World world, long seed) { + super(world, seed); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/NormalChunkGenerator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/NormalChunkGenerator.java new file mode 100644 index 0000000..fc4bc81 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/NormalChunkGenerator.java @@ -0,0 +1,102 @@ +package org.bukkit.craftbukkit.generator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import net.minecraft.server.*; + +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.generator.BlockPopulator; + +public class NormalChunkGenerator extends InternalChunkGenerator { + private final IChunkProvider provider; + + public NormalChunkGenerator(World world, long seed) { + provider = world.worldProvider.getChunkProvider(); + } + + @Override + public byte[] generate(org.bukkit.World world, Random random, int x, int z) { + throw new UnsupportedOperationException("Not supported."); + } + + @Override + public boolean canSpawn(org.bukkit.World world, int x, int z) { + return ((CraftWorld) world).getHandle().worldProvider.canSpawn(x, z); + } + + @Override + public List getDefaultPopulators(org.bukkit.World world) { + return new ArrayList(); + } + + @Override + public boolean isChunkLoaded(int i, int i1) { + return provider.isChunkLoaded(i, i1); + } + + @Override + public Chunk getOrCreateChunk(int i, int i1) { + return provider.getOrCreateChunk(i, i1); + } + + @Override + public Chunk getChunkAt(BlockPosition blockPosition) { + return provider.getChunkAt(blockPosition); + } + + @Override + public void getChunkAt(IChunkProvider icp, int i, int i1) { + provider.getChunkAt(icp, i, i1); + } + + @Override + public boolean a(IChunkProvider iChunkProvider, Chunk chunk, int i, int i1) { + return provider.a(provider, chunk, i, i1); + } + + @Override + public boolean saveChunks(boolean bln, IProgressUpdate ipu) { + return provider.saveChunks(bln, ipu); + } + + @Override + public boolean unloadChunks() { + return provider.unloadChunks(); + } + + @Override + public boolean canSave() { + return provider.canSave(); + } + + @Override + public List getMobsFor(EnumCreatureType ect, BlockPosition position) { + return provider.getMobsFor(ect, position); + } + + @Override + public BlockPosition findNearestMapFeature(World world, String string, BlockPosition position) { + return provider.findNearestMapFeature(world, string, position); + } + + // n.m.s implementations always return 0. (The true implementation is in ChunkProviderServer) + @Override + public int getLoadedChunks() { + return 0; + } + + @Override + public void recreateStructures(Chunk chunk, int i, int i1) { + provider.recreateStructures(chunk, i, i1); + } + + @Override + public String getName() { + return "NormalWorldGenerator"; + } + + @Override + public void c() {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/SkyLandsChunkGenerator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/SkyLandsChunkGenerator.java new file mode 100644 index 0000000..e327996 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/generator/SkyLandsChunkGenerator.java @@ -0,0 +1,12 @@ +package org.bukkit.craftbukkit.generator; + +import net.minecraft.server.World; + +/** + * This class is useless. Just fyi. + */ +public class SkyLandsChunkGenerator extends NormalChunkGenerator { + public SkyLandsChunkGenerator(World world, long seed) { + super(world, seed); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CommandAliasHelpTopic.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CommandAliasHelpTopic.java new file mode 100644 index 0000000..9f2238c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CommandAliasHelpTopic.java @@ -0,0 +1,46 @@ +package org.bukkit.craftbukkit.help; + +import org.apache.commons.lang.Validate; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.help.HelpMap; +import org.bukkit.help.HelpTopic; + +public class CommandAliasHelpTopic extends HelpTopic { + + private final String aliasFor; + private final HelpMap helpMap; + + public CommandAliasHelpTopic(String alias, String aliasFor, HelpMap helpMap) { + this.aliasFor = aliasFor.startsWith("/") ? aliasFor : "/" + aliasFor; + this.helpMap = helpMap; + this.name = alias.startsWith("/") ? alias : "/" + alias; + Validate.isTrue(!this.name.equals(this.aliasFor), "Command " + this.name + " cannot be alias for itself"); + this.shortText = ChatColor.YELLOW + "Alias for " + ChatColor.WHITE + this.aliasFor; + } + + @Override + public String getFullText(CommandSender forWho) { + StringBuilder sb = new StringBuilder(shortText); + HelpTopic aliasForTopic = helpMap.getHelpTopic(aliasFor); + if (aliasForTopic != null) { + sb.append("\n"); + sb.append(aliasForTopic.getFullText(forWho)); + } + return sb.toString(); + } + + @Override + public boolean canSee(CommandSender commandSender) { + if (amendedPermission == null) { + HelpTopic aliasForTopic = helpMap.getHelpTopic(aliasFor); + if (aliasForTopic != null) { + return aliasForTopic.canSee(commandSender); + } else { + return false; + } + } else { + return commandSender.hasPermission(amendedPermission); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CustomHelpTopic.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CustomHelpTopic.java new file mode 100644 index 0000000..6dee229 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CustomHelpTopic.java @@ -0,0 +1,31 @@ +package org.bukkit.craftbukkit.help; + +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.help.HelpTopic; + +/** + * This is a help topic implementation for general topics registered in the help.yml file. + */ +public class CustomHelpTopic extends HelpTopic { + private final String permissionNode; + + public CustomHelpTopic(String name, String shortText, String fullText, String permissionNode) { + this.permissionNode = permissionNode; + this.name = name; + this.shortText = shortText; + this.fullText = shortText + "\n" + fullText; + } + + public boolean canSee(CommandSender sender) { + if (sender instanceof ConsoleCommandSender) { + return true; + } + + if (!permissionNode.equals("")) { + return sender.hasPermission(permissionNode); + } else { + return true; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CustomIndexHelpTopic.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CustomIndexHelpTopic.java new file mode 100644 index 0000000..2089a5f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/CustomIndexHelpTopic.java @@ -0,0 +1,40 @@ +package org.bukkit.craftbukkit.help; + +import org.bukkit.command.CommandSender; +import org.bukkit.help.HelpMap; +import org.bukkit.help.HelpTopic; +import org.bukkit.help.IndexHelpTopic; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + +/** + */ +public class CustomIndexHelpTopic extends IndexHelpTopic { + private List futureTopics; + private final HelpMap helpMap; + + public CustomIndexHelpTopic(HelpMap helpMap, String name, String shortText, String permission, List futureTopics, String preamble) { + super(name, shortText, permission, new HashSet(), preamble); + this.helpMap = helpMap; + this.futureTopics = futureTopics; + } + + @Override + public String getFullText(CommandSender sender) { + if (futureTopics != null) { + List topics = new LinkedList(); + for (String futureTopic : futureTopics) { + HelpTopic topic = helpMap.getHelpTopic(futureTopic); + if (topic != null) { + topics.add(topic); + } + } + setTopicsCollection(topics); + futureTopics = null; + } + + return super.getFullText(sender); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/HelpTopicAmendment.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/HelpTopicAmendment.java new file mode 100644 index 0000000..4f0e00e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/HelpTopicAmendment.java @@ -0,0 +1,50 @@ +package org.bukkit.craftbukkit.help; + +/** + * A HelpTopicAmendment represents the contents of a topic amendment from the help.yml + */ +public class HelpTopicAmendment { + private final String topicName; + private final String shortText; + private final String fullText; + private final String permission; + + public HelpTopicAmendment(String topicName, String shortText, String fullText, String permission) { + this.fullText = fullText; + this.shortText = shortText; + this.topicName = topicName; + this.permission = permission; + } + + /** + * Gets the amended full text + * @return the full text + */ + public String getFullText() { + return fullText; + } + + /** + * Gets the amended short text + * @return the short text + */ + public String getShortText() { + return shortText; + } + + /** + * Gets the name of the topic being amended + * @return the topic name + */ + public String getTopicName() { + return topicName; + } + + /** + * Gets the amended permission + * @return the permission + */ + public String getPermission() { + return permission; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/HelpYamlReader.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/HelpYamlReader.java new file mode 100644 index 0000000..60a6221 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/HelpYamlReader.java @@ -0,0 +1,119 @@ +package org.bukkit.craftbukkit.help; + +import org.bukkit.ChatColor; +import org.bukkit.Server; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.help.HelpTopic; + +import com.google.common.base.Charsets; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; + +/** + * HelpYamlReader is responsible for processing the contents of the help.yml file. + */ +public class HelpYamlReader { + + private YamlConfiguration helpYaml; + private final char ALT_COLOR_CODE = '&'; + private final Server server; + + public HelpYamlReader(Server server) { + this.server = server; + + File helpYamlFile = new File("help.yml"); + YamlConfiguration defaultConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("configurations/help.yml"), Charsets.UTF_8)); + + try { + helpYaml = YamlConfiguration.loadConfiguration(helpYamlFile); + helpYaml.options().copyDefaults(true); + helpYaml.setDefaults(defaultConfig); + + try { + if (!helpYamlFile.exists()) { + helpYaml.save(helpYamlFile); + } + } catch (IOException ex) { + server.getLogger().log(Level.SEVERE, "Could not save " + helpYamlFile, ex); + } + } catch (Exception ex) { + server.getLogger().severe("Failed to load help.yml. Verify the yaml indentation is correct. Reverting to default help.yml."); + helpYaml = defaultConfig; + } + } + + /** + * Extracts a list of all general help topics from help.yml + * + * @return A list of general topics. + */ + public List getGeneralTopics() { + List topics = new LinkedList(); + ConfigurationSection generalTopics = helpYaml.getConfigurationSection("general-topics"); + if (generalTopics != null) { + for (String topicName : generalTopics.getKeys(false)) { + ConfigurationSection section = generalTopics.getConfigurationSection(topicName); + String shortText = ChatColor.translateAlternateColorCodes(ALT_COLOR_CODE, section.getString("shortText", "")); + String fullText = ChatColor.translateAlternateColorCodes(ALT_COLOR_CODE, section.getString("fullText", "")); + String permission = section.getString("permission", ""); + topics.add(new CustomHelpTopic(topicName, shortText, fullText, permission)); + } + } + return topics; + } + + /** + * Extracts a list of all index topics from help.yml + * + * @return A list of index topics. + */ + public List getIndexTopics() { + List topics = new LinkedList(); + ConfigurationSection indexTopics = helpYaml.getConfigurationSection("index-topics"); + if (indexTopics != null) { + for (String topicName : indexTopics.getKeys(false)) { + ConfigurationSection section = indexTopics.getConfigurationSection(topicName); + String shortText = ChatColor.translateAlternateColorCodes(ALT_COLOR_CODE, section.getString("shortText", "")); + String preamble = ChatColor.translateAlternateColorCodes(ALT_COLOR_CODE, section.getString("preamble", "")); + String permission = ChatColor.translateAlternateColorCodes(ALT_COLOR_CODE, section.getString("permission", "")); + List commands = section.getStringList("commands"); + topics.add(new CustomIndexHelpTopic(server.getHelpMap(), topicName, shortText, permission, commands, preamble)); + } + } + return topics; + } + + /** + * Extracts a list of topic amendments from help.yml + * + * @return A list of amendments. + */ + public List getTopicAmendments() { + List amendments = new LinkedList(); + ConfigurationSection commandTopics = helpYaml.getConfigurationSection("amended-topics"); + if (commandTopics != null) { + for (String topicName : commandTopics.getKeys(false)) { + ConfigurationSection section = commandTopics.getConfigurationSection(topicName); + String description = ChatColor.translateAlternateColorCodes(ALT_COLOR_CODE, section.getString("shortText", "")); + String usage = ChatColor.translateAlternateColorCodes(ALT_COLOR_CODE, section.getString("fullText", "")); + String permission = section.getString("permission", ""); + amendments.add(new HelpTopicAmendment(topicName, description, usage, permission)); + } + } + return amendments; + } + + public List getIgnoredPlugins() { + return helpYaml.getStringList("ignore-plugins"); + } + + public boolean commandTopicsInMasterIndex() { + return helpYaml.getBoolean("command-topics-in-master-index", true); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopic.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopic.java new file mode 100644 index 0000000..6f4b22b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopic.java @@ -0,0 +1,54 @@ +package org.bukkit.craftbukkit.help; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.command.MultipleCommandAlias; +import org.bukkit.help.HelpTopic; + +/** + * This is a help topic implementation for {@link MultipleCommandAlias} commands. + */ +public class MultipleCommandAliasHelpTopic extends HelpTopic { + + private final MultipleCommandAlias alias; + + public MultipleCommandAliasHelpTopic(MultipleCommandAlias alias) { + this.alias = alias; + + name = "/" + alias.getLabel(); + + // Build short text + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < alias.getCommands().length; i++) { + if (i != 0) { + sb.append(ChatColor.GOLD + " > " + ChatColor.WHITE); + } + sb.append("/"); + sb.append(alias.getCommands()[i].getLabel()); + } + shortText = sb.toString(); + + // Build full text + fullText = ChatColor.GOLD + "Alias for: " + ChatColor.WHITE + getShortText(); + } + + public boolean canSee(CommandSender sender) { + if (amendedPermission == null) { + if (sender instanceof ConsoleCommandSender) { + return true; + } + + for (Command command : alias.getCommands()) { + if (!command.testPermissionSilent(sender)) { + return false; + } + } + + return true; + } else { + return sender.hasPermission(amendedPermission); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopicFactory.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopicFactory.java new file mode 100644 index 0000000..36ddc97 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopicFactory.java @@ -0,0 +1,15 @@ +package org.bukkit.craftbukkit.help; + +import org.bukkit.command.MultipleCommandAlias; +import org.bukkit.help.HelpTopic; +import org.bukkit.help.HelpTopicFactory; + +/** + * This class creates {@link MultipleCommandAliasHelpTopic} help topics from {@link MultipleCommandAlias} commands. + */ +public class MultipleCommandAliasHelpTopicFactory implements HelpTopicFactory { + + public HelpTopic createTopic(MultipleCommandAlias multipleCommandAlias) { + return new MultipleCommandAliasHelpTopic(multipleCommandAlias); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java new file mode 100644 index 0000000..7dd5afe --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java @@ -0,0 +1,219 @@ +package org.bukkit.craftbukkit.help; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Collections2; + +import org.bukkit.command.*; +import org.bukkit.command.defaults.BukkitCommand; +import org.bukkit.command.defaults.VanillaCommand; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.command.VanillaCommandWrapper; +import org.bukkit.help.*; + +import java.util.*; + +/** + * Standard implementation of {@link HelpMap} for CraftBukkit servers. + */ +public class SimpleHelpMap implements HelpMap { + + private HelpTopic defaultTopic; + private final Map helpTopics; + private final Map> topicFactoryMap; + private final CraftServer server; + private HelpYamlReader yaml; + + @SuppressWarnings("unchecked") + public SimpleHelpMap(CraftServer server) { + this.helpTopics = new TreeMap(HelpTopicComparator.topicNameComparatorInstance()); // Using a TreeMap for its explicit sorting on key + this.topicFactoryMap = new HashMap>(); + this.server = server; + this.yaml = new HelpYamlReader(server); + + Predicate indexFilter = Predicates.not(Predicates.instanceOf(CommandAliasHelpTopic.class)); + if (!yaml.commandTopicsInMasterIndex()) { + indexFilter = Predicates.and(indexFilter, Predicates.not(new IsCommandTopicPredicate())); + } + + this.defaultTopic = new IndexHelpTopic("Index", null, null, Collections2.filter(helpTopics.values(), indexFilter), "Use /help [n] to get page n of help."); + + registerHelpTopicFactory(MultipleCommandAlias.class, new MultipleCommandAliasHelpTopicFactory()); + } + + public synchronized HelpTopic getHelpTopic(String topicName) { + if (topicName.equals("")) { + return defaultTopic; + } + + if (helpTopics.containsKey(topicName)) { + return helpTopics.get(topicName); + } + + return null; + } + + public Collection getHelpTopics() { + return helpTopics.values(); + } + + public synchronized void addTopic(HelpTopic topic) { + // Existing topics take priority + if (!helpTopics.containsKey(topic.getName())) { + helpTopics.put(topic.getName(), topic); + } + } + + public synchronized void clear() { + helpTopics.clear(); + } + + public List getIgnoredPlugins() { + return yaml.getIgnoredPlugins(); + } + + /** + * Reads the general topics from help.yml and adds them to the help index. + */ + public synchronized void initializeGeneralTopics() { + yaml = new HelpYamlReader(server); + + // Initialize general help topics from the help.yml file + for (HelpTopic topic : yaml.getGeneralTopics()) { + addTopic(topic); + } + + // Initialize index help topics from the help.yml file + for (HelpTopic topic : yaml.getIndexTopics()) { + if (topic.getName().equals("Default")) { + defaultTopic = topic; + } else { + addTopic(topic); + } + } + } + + /** + * Processes all the commands registered in the server and creates help topics for them. + */ + public synchronized void initializeCommands() { + // ** Load topics from highest to lowest priority order ** + Set ignoredPlugins = new HashSet(yaml.getIgnoredPlugins()); + + // Don't load any automatic help topics if All is ignored + if (ignoredPlugins.contains("All")) { + return; + } + + // Initialize help topics from the server's command map + outer: for (Command command : server.getCommandMap().getCommands()) { + if (commandInIgnoredPlugin(command, ignoredPlugins)) { + continue; + } + + // Register a topic + for (Class c : topicFactoryMap.keySet()) { + if (c.isAssignableFrom(command.getClass())) { + HelpTopic t = topicFactoryMap.get(c).createTopic(command); + if (t != null) addTopic(t); + continue outer; + } + if (command instanceof PluginCommand && c.isAssignableFrom(((PluginCommand)command).getExecutor().getClass())) { + HelpTopic t = topicFactoryMap.get(c).createTopic(command); + if (t != null) addTopic(t); + continue outer; + } + } + addTopic(new GenericCommandHelpTopic(command)); + } + + // Initialize command alias help topics + for (Command command : server.getCommandMap().getCommands()) { + if (commandInIgnoredPlugin(command, ignoredPlugins)) { + continue; + } + for (String alias : command.getAliases()) { + // Only register if this command owns the alias + if (server.getCommandMap().getCommand(alias) == command) { + addTopic(new CommandAliasHelpTopic("/" + alias, "/" + command.getLabel(), this)); + } + } + } + + // Add alias sub-index + Collection filteredTopics = Collections2.filter(helpTopics.values(), Predicates.instanceOf(CommandAliasHelpTopic.class)); + if (!filteredTopics.isEmpty()) { + addTopic(new IndexHelpTopic("Aliases", "Lists command aliases", null, filteredTopics)); + } + + // Initialize plugin-level sub-topics + Map> pluginIndexes = new HashMap>(); + fillPluginIndexes(pluginIndexes, server.getCommandMap().getCommands()); + + for (Map.Entry> entry : pluginIndexes.entrySet()) { + addTopic(new IndexHelpTopic(entry.getKey(), "All commands for " + entry.getKey(), null, entry.getValue(), "Below is a list of all " + entry.getKey() + " commands:")); + } + + // Amend help topics from the help.yml file + for (HelpTopicAmendment amendment : yaml.getTopicAmendments()) { + if (helpTopics.containsKey(amendment.getTopicName())) { + helpTopics.get(amendment.getTopicName()).amendTopic(amendment.getShortText(), amendment.getFullText()); + if (amendment.getPermission() != null) { + helpTopics.get(amendment.getTopicName()).amendCanSee(amendment.getPermission()); + } + } + } + } + + private void fillPluginIndexes(Map> pluginIndexes, Collection commands) { + for (Command command : commands) { + String pluginName = getCommandPluginName(command); + if (pluginName != null) { + HelpTopic topic = getHelpTopic("/" + command.getLabel()); + if (topic != null) { + if (!pluginIndexes.containsKey(pluginName)) { + pluginIndexes.put(pluginName, new TreeSet(HelpTopicComparator.helpTopicComparatorInstance())); //keep things in topic order + } + pluginIndexes.get(pluginName).add(topic); + } + } + } + } + + private String getCommandPluginName(Command command) { + if (command instanceof VanillaCommandWrapper) { + return "Minecraft"; + } + if (command instanceof BukkitCommand || command instanceof VanillaCommand) { + return "Bukkit"; + } + if (command instanceof PluginIdentifiableCommand) { + return ((PluginIdentifiableCommand)command).getPlugin().getName(); + } + return null; + } + + private boolean commandInIgnoredPlugin(Command command, Set ignoredPlugins) { + if ((command instanceof BukkitCommand || command instanceof VanillaCommand) && ignoredPlugins.contains("Bukkit")) { + return true; + } + if (command instanceof PluginIdentifiableCommand && ignoredPlugins.contains(((PluginIdentifiableCommand)command).getPlugin().getName())) { + return true; + } + return false; + } + + public void registerHelpTopicFactory(Class commandClass, HelpTopicFactory factory) { + if (!Command.class.isAssignableFrom(commandClass) && !CommandExecutor.class.isAssignableFrom(commandClass)) { + throw new IllegalArgumentException("commandClass must implement either Command or CommandExecutor!"); + } + topicFactoryMap.put(commandClass, factory); + } + + private class IsCommandTopicPredicate implements Predicate { + + public boolean apply(HelpTopic topic) { + return topic.getName().charAt(0) == '/'; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java new file mode 100644 index 0000000..1dbc588 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java @@ -0,0 +1,305 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.ChatComponentText; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; + +import net.minecraft.server.Container; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.IInventory; +import net.minecraft.server.PacketPlayOutOpenWindow; +import net.minecraft.server.Slot; + +public class CraftContainer extends Container { + private final InventoryView view; + private InventoryType cachedType; + private String cachedTitle; + private final int cachedSize; + + public CraftContainer(InventoryView view, int id) { + this.view = view; + this.windowId = id; + // TODO: Do we need to check that it really is a CraftInventory? + IInventory top = ((CraftInventory)view.getTopInventory()).getInventory(); + IInventory bottom = ((CraftInventory)view.getBottomInventory()).getInventory(); + cachedType = view.getType(); + cachedTitle = view.getTitle(); + cachedSize = getSize(); + setupSlots(top, bottom); + } + + public CraftContainer(final Inventory inventory, final HumanEntity player, int id) { + this(new InventoryView() { + @Override + public Inventory getTopInventory() { + return inventory; + } + + @Override + public Inventory getBottomInventory() { + return player.getInventory(); + } + + @Override + public HumanEntity getPlayer() { + return player; + } + + @Override + public InventoryType getType() { + return inventory.getType(); + } + }, id); + } + + @Override + public InventoryView getBukkitView() { + return view; + } + + private int getSize() { + return view.getTopInventory().getSize(); + } + + @Override + public boolean c(EntityHuman entityhuman) { + if (cachedType == view.getType() && cachedSize == getSize() && cachedTitle.equals(view.getTitle())) { + return true; + } + // If the window type has changed for some reason, update the player + // This method will be called every tick or something, so it's + // as good a place as any to put something like this. + boolean typeChanged = (cachedType != view.getType()); + cachedType = view.getType(); + cachedTitle = view.getTitle(); + if (view.getPlayer() instanceof CraftPlayer) { + CraftPlayer player = (CraftPlayer) view.getPlayer(); + String type = getNotchInventoryType(cachedType); + IInventory top = ((CraftInventory)view.getTopInventory()).getInventory(); + IInventory bottom = ((CraftInventory)view.getBottomInventory()).getInventory(); + this.b.clear(); + this.c.clear(); + if (typeChanged) { + setupSlots(top, bottom); + } + int size = getSize(); + player.getHandle().playerConnection.sendPacket(new PacketPlayOutOpenWindow(this.windowId, type, new ChatComponentText(cachedTitle), size)); + player.updateInventory(); + } + return true; + } + + public static String getNotchInventoryType(InventoryType type) { + switch(type) { + case WORKBENCH: + return "minecraft:crafting_table"; + case FURNACE: + return "minecraft:furnace"; + case DISPENSER: + return "minecraft:dispenser"; + case ENCHANTING: + return "minecraft:enchanting_table"; + case BREWING: + return "minecraft:brewing_stand"; + case BEACON: + return "minecraft:beacon"; + case ANVIL: + return "minecraft:anvil"; + case HOPPER: + return "minecraft:hopper"; + default: + return "minecraft:chest"; + } + } + + private void setupSlots(IInventory top, IInventory bottom) { + switch(cachedType) { + case CREATIVE: + break; // TODO: This should be an error? + case PLAYER: + case CHEST: + setupChest(top, bottom); + break; + case DISPENSER: + setupDispenser(top, bottom); + break; + case FURNACE: + setupFurnace(top, bottom); + break; + case CRAFTING: // TODO: This should be an error? + case WORKBENCH: + setupWorkbench(top, bottom); + break; + case ENCHANTING: + setupEnchanting(top, bottom); + break; + case BREWING: + setupBrewing(top, bottom); + break; + case HOPPER: + setupHopper(top, bottom); + break; + } + } + + private void setupChest(IInventory top, IInventory bottom) { + int rows = top.getSize() / 9; + int row; + int col; + // This code copied from ContainerChest + int i = (rows - 4) * 18; + for (row = 0; row < rows; ++row) { + for (col = 0; col < 9; ++col) { + this.a(new Slot(top, col + row * 9, 8 + col * 18, 18 + row * 18)); + } + } + + for (row = 0; row < 3; ++row) { + for (col = 0; col < 9; ++col) { + this.a(new Slot(bottom, col + row * 9 + 9, 8 + col * 18, 103 + row * 18 + i)); + } + } + + for (col = 0; col < 9; ++col) { + this.a(new Slot(bottom, col, 8 + col * 18, 161 + i)); + } + // End copy from ContainerChest + } + + private void setupWorkbench(IInventory top, IInventory bottom) { + // This code copied from ContainerWorkbench + this.a(new Slot(top, 0, 124, 35)); + + int row; + int col; + + for (row = 0; row < 3; ++row) { + for (col = 0; col < 3; ++col) { + this.a(new Slot(top, 1 + col + row * 3, 30 + col * 18, 17 + row * 18)); + } + } + + for (row = 0; row < 3; ++row) { + for (col = 0; col < 9; ++col) { + this.a(new Slot(bottom, col + row * 9 + 9, 8 + col * 18, 84 + row * 18)); + } + } + + for (col = 0; col < 9; ++col) { + this.a(new Slot(bottom, col, 8 + col * 18, 142)); + } + // End copy from ContainerWorkbench + } + + private void setupFurnace(IInventory top, IInventory bottom) { + // This code copied from ContainerFurnace + this.a(new Slot(top, 0, 56, 17)); + this.a(new Slot(top, 1, 56, 53)); + this.a(new Slot(top, 2, 116, 35)); + + int row; + int col; + + for (row = 0; row < 3; ++row) { + for (col = 0; col < 9; ++col) { + this.a(new Slot(bottom, col + row * 9 + 9, 8 + col * 18, 84 + row * 18)); + } + } + + for (col = 0; col < 9; ++col) { + this.a(new Slot(bottom, col, 8 + col * 18, 142)); + } + // End copy from ContainerFurnace + } + + private void setupDispenser(IInventory top, IInventory bottom) { + // This code copied from ContainerDispenser + int row; + int col; + + for (row = 0; row < 3; ++row) { + for (col = 0; col < 3; ++col) { + this.a(new Slot(top, col + row * 3, 61 + col * 18, 17 + row * 18)); + } + } + + for (row = 0; row < 3; ++row) { + for (col = 0; col < 9; ++col) { + this.a(new Slot(bottom, col + row * 9 + 9, 8 + col * 18, 84 + row * 18)); + } + } + + for (col = 0; col < 9; ++col) { + this.a(new Slot(bottom, col, 8 + col * 18, 142)); + } + // End copy from ContainerDispenser + } + + private void setupEnchanting(IInventory top, IInventory bottom) { + // This code copied from ContainerEnchantTable + this.a((new Slot(top, 0, 25, 47))); + + int row; + + for (row = 0; row < 3; ++row) { + for (int i1 = 0; i1 < 9; ++i1) { + this.a(new Slot(bottom, i1 + row * 9 + 9, 8 + i1 * 18, 84 + row * 18)); + } + } + + for (row = 0; row < 9; ++row) { + this.a(new Slot(bottom, row, 8 + row * 18, 142)); + } + // End copy from ContainerEnchantTable + } + + private void setupBrewing(IInventory top, IInventory bottom) { + // This code copied from ContainerBrewingStand + this.a(new Slot(top, 0, 56, 46)); + this.a(new Slot(top, 1, 79, 53)); + this.a(new Slot(top, 2, 102, 46)); + this.a(new Slot(top, 3, 79, 17)); + + int i; + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(bottom, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(bottom, i, 8 + i * 18, 142)); + } + // End copy from ContainerBrewingStand + } + + private void setupHopper(IInventory top, IInventory bottom) { + // This code copied from ContainerHopper + byte b0 = 51; + + int i; + + for (i = 0; i < top.getSize(); ++i) { + this.a(new Slot(top, i, 44 + i * 18, 20)); + } + + for (i = 0; i < 3; ++i) { + for (int j = 0; j < 9; ++j) { + this.a(new Slot(bottom, j + i * 9 + 9, 8 + j * 18, i * 18 + b0)); + } + } + + for (i = 0; i < 9; ++i) { + this.a(new Slot(bottom, i, 8 + i * 18, 58 + b0)); + } + // End copy from ContainerHopper + } + + public boolean a(EntityHuman entity) { + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java new file mode 100644 index 0000000..2213482 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java @@ -0,0 +1,144 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.EntityInsentient; + +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; + +public class CraftEntityEquipment implements EntityEquipment { + private static final int WEAPON_SLOT = 0; + private static final int HELMET_SLOT = 4; + private static final int CHEST_SLOT = 3; + private static final int LEG_SLOT = 2; + private static final int BOOT_SLOT = 1; + private static final int INVENTORY_SLOTS = 5; + + private final CraftLivingEntity entity; + + public CraftEntityEquipment(CraftLivingEntity entity) { + this.entity = entity; + } + + public ItemStack getItemInHand() { + return getEquipment(WEAPON_SLOT); + } + + public void setItemInHand(ItemStack stack) { + setEquipment(WEAPON_SLOT, stack); + } + + public ItemStack getHelmet() { + return getEquipment(HELMET_SLOT); + } + + public void setHelmet(ItemStack helmet) { + setEquipment(HELMET_SLOT, helmet); + } + + public ItemStack getChestplate() { + return getEquipment(CHEST_SLOT); + } + + public void setChestplate(ItemStack chestplate) { + setEquipment(CHEST_SLOT, chestplate); + } + + public ItemStack getLeggings() { + return getEquipment(LEG_SLOT); + } + + public void setLeggings(ItemStack leggings) { + setEquipment(LEG_SLOT, leggings); + } + + public ItemStack getBoots() { + return getEquipment(BOOT_SLOT); + } + + public void setBoots(ItemStack boots) { + setEquipment(BOOT_SLOT, boots); + } + + public ItemStack[] getArmorContents() { + ItemStack[] armor = new ItemStack[INVENTORY_SLOTS - 1]; + for(int slot = WEAPON_SLOT + 1; slot < INVENTORY_SLOTS; slot++) { + armor[slot - 1] = getEquipment(slot); + } + return armor; + } + + public void setArmorContents(ItemStack[] items) { + for(int slot = WEAPON_SLOT + 1; slot < INVENTORY_SLOTS; slot++) { + ItemStack equipment = items != null && slot <= items.length ? items[slot - 1] : null; + setEquipment(slot, equipment); + } + } + + private ItemStack getEquipment(int slot) { + return CraftItemStack.asBukkitCopy(entity.getHandle().getEquipment(slot)); + } + + private void setEquipment(int slot, ItemStack stack) { + entity.getHandle().setEquipment(slot, CraftItemStack.asNMSCopy(stack)); + } + + public void clear() { + for(int i = 0; i < INVENTORY_SLOTS; i++) { + setEquipment(i, null); + } + } + + public Entity getHolder() { + return entity; + } + + public float getItemInHandDropChance() { + return getDropChance(WEAPON_SLOT); + } + + public void setItemInHandDropChance(float chance) { + setDropChance(WEAPON_SLOT, chance); + } + + public float getHelmetDropChance() { + return getDropChance(HELMET_SLOT); + } + + public void setHelmetDropChance(float chance) { + setDropChance(HELMET_SLOT, chance); + } + + public float getChestplateDropChance() { + return getDropChance(CHEST_SLOT); + } + + public void setChestplateDropChance(float chance) { + setDropChance(CHEST_SLOT, chance); + } + + public float getLeggingsDropChance() { + return getDropChance(LEG_SLOT); + } + + public void setLeggingsDropChance(float chance) { + setDropChance(LEG_SLOT, chance); + } + + public float getBootsDropChance() { + return getDropChance(BOOT_SLOT); + } + + public void setBootsDropChance(float chance) { + setDropChance(BOOT_SLOT, chance); + } + + private void setDropChance(int slot, float chance) { + ((EntityInsentient) entity.getHandle()).dropChances[slot] = chance - 0.1F; + } + + private float getDropChance(int slot) { + return ((EntityInsentient) entity.getHandle()).dropChances[slot] + 0.1F; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java new file mode 100644 index 0000000..69f17db --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java @@ -0,0 +1,27 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.RecipesFurnace; + +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.inventory.FurnaceRecipe; +import org.bukkit.inventory.ItemStack; + +public class CraftFurnaceRecipe extends FurnaceRecipe implements CraftRecipe { + public CraftFurnaceRecipe(ItemStack result, ItemStack source) { + super(result, source.getType(), source.getDurability()); + } + + public static CraftFurnaceRecipe fromBukkitRecipe(FurnaceRecipe recipe) { + if (recipe instanceof CraftFurnaceRecipe) { + return (CraftFurnaceRecipe) recipe; + } + return new CraftFurnaceRecipe(recipe.getResult(), recipe.getInput()); + } + + @Override + public void addToCraftingManager() { + ItemStack result = this.getResult(); + ItemStack input = this.getInput(); + RecipesFurnace.getInstance().registerRecipe(CraftItemStack.asNMSCopy(input), CraftItemStack.asNMSCopy(result)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java new file mode 100644 index 0000000..e9a3c50 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java @@ -0,0 +1,482 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; + +import net.minecraft.server.IHopper; +import net.minecraft.server.IInventory; +import net.minecraft.server.InventoryCrafting; +import net.minecraft.server.InventoryEnderChest; +import net.minecraft.server.InventoryMerchant; +import net.minecraft.server.PlayerInventory; +import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBrewingStand; +import net.minecraft.server.TileEntityDispenser; +import net.minecraft.server.TileEntityDropper; +import net.minecraft.server.TileEntityFurnace; + +import org.apache.commons.lang.Validate; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.Material; + +public class CraftInventory implements Inventory { + protected final IInventory inventory; + + public CraftInventory(IInventory inventory) { + this.inventory = inventory; + } + + public IInventory getInventory() { + return inventory; + } + + public int getSize() { + return getInventory().getSize(); + } + + public String getName() { + return getInventory().getName(); + } + + public ItemStack getItem(int index) { + net.minecraft.server.ItemStack item = getInventory().getItem(index); + return item == null ? null : CraftItemStack.asCraftMirror(item); + } + + public ItemStack[] getContents() { + ItemStack[] items = new ItemStack[getSize()]; + net.minecraft.server.ItemStack[] mcItems = getInventory().getContents(); + + int size = Math.min(items.length, mcItems.length); + for (int i = 0; i < size; i++) { + items[i] = mcItems[i] == null ? null : CraftItemStack.asCraftMirror(mcItems[i]); + } + return items; + } + + public void setContents(ItemStack[] items) { + if (getInventory().getContents().length < items.length) { + throw new IllegalArgumentException("Invalid inventory size; expected " + getInventory().getContents().length + " or less"); + } + + net.minecraft.server.ItemStack[] mcItems = getInventory().getContents(); + + for (int i = 0; i < mcItems.length; i++) { + if (i >= items.length) { + mcItems[i] = null; + } else { + mcItems[i] = CraftItemStack.asNMSCopy(items[i]); + } + } + } + + public void setItem(int index, ItemStack item) { + getInventory().setItem(index, ((item == null || item.getTypeId() == 0) ? null : CraftItemStack.asNMSCopy(item))); + } + + public boolean contains(int materialId) { + for (ItemStack item : getContents()) { + if (item != null && item.getTypeId() == materialId) { + return true; + } + } + return false; + } + + public boolean contains(Material material) { + Validate.notNull(material, "Material cannot be null"); + return contains(material.getId()); + } + + public boolean contains(ItemStack item) { + if (item == null) { + return false; + } + for (ItemStack i : getContents()) { + if (item.equals(i)) { + return true; + } + } + return false; + } + + public boolean contains(int materialId, int amount) { + if (amount <= 0) { + return true; + } + for (ItemStack item : getContents()) { + if (item != null && item.getTypeId() == materialId) { + if ((amount -= item.getAmount()) <= 0) { + return true; + } + } + } + return false; + } + + public boolean contains(Material material, int amount) { + Validate.notNull(material, "Material cannot be null"); + return contains(material.getId(), amount); + } + + public boolean contains(ItemStack item, int amount) { + if (item == null) { + return false; + } + if (amount <= 0) { + return true; + } + for (ItemStack i : getContents()) { + if (item.equals(i) && --amount <= 0) { + return true; + } + } + return false; + } + + public boolean containsAtLeast(ItemStack item, int amount) { + if (item == null) { + return false; + } + if (amount <= 0) { + return true; + } + for (ItemStack i : getContents()) { + if (item.isSimilar(i) && (amount -= i.getAmount()) <= 0) { + return true; + } + } + return false; + } + + public HashMap all(int materialId) { + HashMap slots = new HashMap(); + + ItemStack[] inventory = getContents(); + for (int i = 0; i < inventory.length; i++) { + ItemStack item = inventory[i]; + if (item != null && item.getTypeId() == materialId) { + slots.put(i, item); + } + } + return slots; + } + + public HashMap all(Material material) { + Validate.notNull(material, "Material cannot be null"); + return all(material.getId()); + } + + public HashMap all(ItemStack item) { + HashMap slots = new HashMap(); + if (item != null) { + ItemStack[] inventory = getContents(); + for (int i = 0; i < inventory.length; i++) { + if (item.equals(inventory[i])) { + slots.put(i, inventory[i]); + } + } + } + return slots; + } + + public int first(int materialId) { + ItemStack[] inventory = getContents(); + for (int i = 0; i < inventory.length; i++) { + ItemStack item = inventory[i]; + if (item != null && item.getTypeId() == materialId) { + return i; + } + } + return -1; + } + + public int first(Material material) { + Validate.notNull(material, "Material cannot be null"); + return first(material.getId()); + } + + public int first(ItemStack item) { + return first(item, true); + } + + private int first(ItemStack item, boolean withAmount) { + if (item == null) { + return -1; + } + ItemStack[] inventory = getContents(); + for (int i = 0; i < inventory.length; i++) { + if (inventory[i] == null) continue; + + if (withAmount ? item.equals(inventory[i]) : item.isSimilar(inventory[i])) { + return i; + } + } + return -1; + } + + public int firstEmpty() { + ItemStack[] inventory = getContents(); + for (int i = 0; i < inventory.length; i++) { + if (inventory[i] == null) { + return i; + } + } + return -1; + } + + public int firstPartial(int materialId) { + ItemStack[] inventory = getContents(); + for (int i = 0; i < inventory.length; i++) { + ItemStack item = inventory[i]; + if (item != null && item.getTypeId() == materialId && item.getAmount() < item.getMaxStackSize()) { + return i; + } + } + return -1; + } + + public int firstPartial(Material material) { + Validate.notNull(material, "Material cannot be null"); + return firstPartial(material.getId()); + } + + private int firstPartial(ItemStack item) { + ItemStack[] inventory = getContents(); + ItemStack filteredItem = CraftItemStack.asCraftCopy(item); + if (item == null) { + return -1; + } + for (int i = 0; i < inventory.length; i++) { + ItemStack cItem = inventory[i]; + if (cItem != null && cItem.getAmount() < cItem.getMaxStackSize() && cItem.isSimilar(filteredItem)) { + return i; + } + } + return -1; + } + + public HashMap addItem(ItemStack... items) { + Validate.noNullElements(items, "Item cannot be null"); + HashMap leftover = new HashMap(); + + /* TODO: some optimization + * - Create a 'firstPartial' with a 'fromIndex' + * - Record the lastPartial per Material + * - Cache firstEmpty result + */ + + for (int i = 0; i < items.length; i++) { + ItemStack item = items[i]; + while (true) { + // Do we already have a stack of it? + int firstPartial = firstPartial(item); + + // Drat! no partial stack + if (firstPartial == -1) { + // Find a free spot! + int firstFree = firstEmpty(); + + if (firstFree == -1) { + // No space at all! + leftover.put(i, item); + break; + } else { + // More than a single stack! + if (item.getAmount() > getMaxItemStack()) { + CraftItemStack stack = CraftItemStack.asCraftCopy(item); + stack.setAmount(getMaxItemStack()); + setItem(firstFree, stack); + item.setAmount(item.getAmount() - getMaxItemStack()); + } else { + // Just store it + setItem(firstFree, item); + break; + } + } + } else { + // So, apparently it might only partially fit, well lets do just that + ItemStack partialItem = getItem(firstPartial); + + int amount = item.getAmount(); + int partialAmount = partialItem.getAmount(); + int maxAmount = partialItem.getMaxStackSize(); + + // Check if it fully fits + if (amount + partialAmount <= maxAmount) { + partialItem.setAmount(amount + partialAmount); + // To make sure the packet is sent to the client + setItem(firstPartial, partialItem); + break; + } + + // It fits partially + partialItem.setAmount(maxAmount); + // To make sure the packet is sent to the client + setItem(firstPartial, partialItem); + item.setAmount(amount + partialAmount - maxAmount); + } + } + } + return leftover; + } + + public HashMap removeItem(ItemStack... items) { + Validate.notNull(items, "Items cannot be null"); + HashMap leftover = new HashMap(); + + // TODO: optimization + + for (int i = 0; i < items.length; i++) { + ItemStack item = items[i]; + int toDelete = item.getAmount(); + + while (true) { + int first = first(item, false); + + // Drat! we don't have this type in the inventory + if (first == -1) { + item.setAmount(toDelete); + leftover.put(i, item); + break; + } else { + ItemStack itemStack = getItem(first); + int amount = itemStack.getAmount(); + + if (amount <= toDelete) { + toDelete -= amount; + // clear the slot, all used up + clear(first); + } else { + // split the stack and store + itemStack.setAmount(amount - toDelete); + setItem(first, itemStack); + toDelete = 0; + } + } + + // Bail when done + if (toDelete <= 0) { + break; + } + } + } + return leftover; + } + + private int getMaxItemStack() { + return getInventory().getMaxStackSize(); + } + + public void remove(int materialId) { + ItemStack[] items = getContents(); + for (int i = 0; i < items.length; i++) { + if (items[i] != null && items[i].getTypeId() == materialId) { + clear(i); + } + } + } + + public void remove(Material material) { + Validate.notNull(material, "Material cannot be null"); + remove(material.getId()); + } + + public void remove(ItemStack item) { + ItemStack[] items = getContents(); + for (int i = 0; i < items.length; i++) { + if (items[i] != null && items[i].equals(item)) { + clear(i); + } + } + } + + public void clear(int index) { + setItem(index, null); + } + + public void clear() { + for (int i = 0; i < getSize(); i++) { + clear(i); + } + } + + public ListIterator iterator() { + return new InventoryIterator(this); + } + + public ListIterator iterator(int index) { + if (index < 0) { + index += getSize() + 1; // ie, with -1, previous() will return the last element + } + return new InventoryIterator(this, index); + } + + public List getViewers() { + return this.inventory.getViewers(); + } + + public String getTitle() { + return inventory.getName(); + } + + public InventoryType getType() { + // Thanks to Droppers extending Dispensers, order is important. + if (inventory instanceof InventoryCrafting) { + return inventory.getSize() >= 9 ? InventoryType.WORKBENCH : InventoryType.CRAFTING; + } else if (inventory instanceof PlayerInventory) { + return InventoryType.PLAYER; + } else if (inventory instanceof TileEntityDropper) { + return InventoryType.DROPPER; + } else if (inventory instanceof TileEntityDispenser) { + return InventoryType.DISPENSER; + } else if (inventory instanceof TileEntityFurnace) { + return InventoryType.FURNACE; + } else if (this instanceof CraftInventoryEnchanting) { + return InventoryType.ENCHANTING; + } else if (inventory instanceof TileEntityBrewingStand) { + return InventoryType.BREWING; + } else if (inventory instanceof CraftInventoryCustom.MinecraftInventory) { + return ((CraftInventoryCustom.MinecraftInventory) inventory).getType(); + } else if (inventory instanceof InventoryEnderChest) { + return InventoryType.ENDER_CHEST; + } else if (inventory instanceof InventoryMerchant) { + return InventoryType.MERCHANT; + } else if (inventory instanceof TileEntityBeacon) { + return InventoryType.BEACON; + } else if (this instanceof CraftInventoryAnvil) { + return InventoryType.ANVIL; + } else if (inventory instanceof IHopper) { + return InventoryType.HOPPER; + } else { + return InventoryType.CHEST; + } + } + + public InventoryHolder getHolder() { + return inventory.getOwner(); + } + + public int getMaxStackSize() { + return inventory.getMaxStackSize(); + } + + public void setMaxStackSize(int size) { + inventory.setMaxStackSize(size); + } + + @Override + public int hashCode() { + return inventory.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + return obj instanceof CraftInventory && ((CraftInventory) obj).inventory.equals(this.inventory); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java new file mode 100644 index 0000000..46a1d38 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java @@ -0,0 +1,48 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IInventory; + +import org.bukkit.inventory.AnvilInventory; +import org.bukkit.inventory.ItemStack; + +public class CraftInventoryAnvil extends CraftInventory implements AnvilInventory { + private final IInventory resultInventory; + + public CraftInventoryAnvil(IInventory inventory, IInventory resultInventory) { + super(inventory); + this.resultInventory = resultInventory; + } + + public IInventory getResultInventory() { + return resultInventory; + } + + public IInventory getIngredientsInventory() { + return inventory; + } + + @Override + public ItemStack getItem(int slot) { + if (slot < getIngredientsInventory().getSize()) { + net.minecraft.server.ItemStack item = getIngredientsInventory().getItem(slot); + return item == null ? null : CraftItemStack.asCraftMirror(item); + } else { + net.minecraft.server.ItemStack item = getResultInventory().getItem(slot - getIngredientsInventory().getSize()); + return item == null ? null : CraftItemStack.asCraftMirror(item); + } + } + + @Override + public void setItem(int index, ItemStack item) { + if (index < getIngredientsInventory().getSize()) { + getIngredientsInventory().setItem(index, (item == null ? null : CraftItemStack.asNMSCopy(item))); + } else { + getResultInventory().setItem((index - getIngredientsInventory().getSize()), (item == null ? null : CraftItemStack.asNMSCopy(item))); + } + } + + @Override + public int getSize() { + return getResultInventory().getSize() + getIngredientsInventory().getSize(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBeacon.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBeacon.java new file mode 100644 index 0000000..43c4107 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBeacon.java @@ -0,0 +1,19 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.TileEntityBeacon; +import org.bukkit.inventory.BeaconInventory; +import org.bukkit.inventory.ItemStack; + +public class CraftInventoryBeacon extends CraftInventory implements BeaconInventory { + public CraftInventoryBeacon(TileEntityBeacon beacon) { + super(beacon); + } + + public void setItem(ItemStack item) { + setItem(0, item); + } + + public ItemStack getItem() { + return getItem(0); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBrewer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBrewer.java new file mode 100644 index 0000000..6de6e6e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBrewer.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.inventory; + +import org.bukkit.block.BrewingStand; +import org.bukkit.inventory.BrewerInventory; +import org.bukkit.inventory.ItemStack; + +import net.minecraft.server.IInventory; + +public class CraftInventoryBrewer extends CraftInventory implements BrewerInventory { + public CraftInventoryBrewer(IInventory inventory) { + super(inventory); + } + + public ItemStack getIngredient() { + return getItem(3); + } + + public void setIngredient(ItemStack ingredient) { + setItem(3, ingredient); + } + + @Override + public BrewingStand getHolder() { + return (BrewingStand) inventory.getOwner(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java new file mode 100644 index 0000000..e155329 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java @@ -0,0 +1,138 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IRecipe; +import net.minecraft.server.IInventory; +import net.minecraft.server.InventoryCrafting; + +import org.bukkit.inventory.CraftingInventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; +import org.bukkit.util.Java15Compat; + +public class CraftInventoryCrafting extends CraftInventory implements CraftingInventory { + private final IInventory resultInventory; + + public CraftInventoryCrafting(InventoryCrafting inventory, IInventory resultInventory) { + super(inventory); + this.resultInventory = resultInventory; + } + + public IInventory getResultInventory() { + return resultInventory; + } + + public IInventory getMatrixInventory() { + return inventory; + } + + @Override + public int getSize() { + return getResultInventory().getSize() + getMatrixInventory().getSize(); + } + + @Override + public void setContents(ItemStack[] items) { + int resultLen = getResultInventory().getContents().length; + int len = getMatrixInventory().getContents().length + resultLen; + if (len > items.length) { + throw new IllegalArgumentException("Invalid inventory size; expected " + len + " or less"); + } + setContents(items[0], Java15Compat.Arrays_copyOfRange(items, 1, items.length)); + } + + @Override + public ItemStack[] getContents() { + ItemStack[] items = new ItemStack[getSize()]; + net.minecraft.server.ItemStack[] mcResultItems = getResultInventory().getContents(); + + int i = 0; + for (i = 0; i < mcResultItems.length; i++ ) { + items[i] = CraftItemStack.asCraftMirror(mcResultItems[i]); + } + + net.minecraft.server.ItemStack[] mcItems = getMatrixInventory().getContents(); + + for (int j = 0; j < mcItems.length; j++) { + items[i + j] = CraftItemStack.asCraftMirror(mcItems[j]); + } + + return items; + } + + public void setContents(ItemStack result, ItemStack[] contents) { + setResult(result); + setMatrix(contents); + } + + @Override + public CraftItemStack getItem(int index) { + if (index < getResultInventory().getSize()) { + net.minecraft.server.ItemStack item = getResultInventory().getItem(index); + return item == null ? null : CraftItemStack.asCraftMirror(item); + } else { + net.minecraft.server.ItemStack item = getMatrixInventory().getItem(index - getResultInventory().getSize()); + return item == null ? null : CraftItemStack.asCraftMirror(item); + } + } + + @Override + public void setItem(int index, ItemStack item) { + if (index < getResultInventory().getSize()) { + getResultInventory().setItem(index, (item == null ? null : CraftItemStack.asNMSCopy(item))); + } else { + getMatrixInventory().setItem((index - getResultInventory().getSize()), (item == null ? null : CraftItemStack.asNMSCopy(item))); + } + } + + public ItemStack[] getMatrix() { + ItemStack[] items = new ItemStack[getSize()]; + net.minecraft.server.ItemStack[] matrix = getMatrixInventory().getContents(); + + for (int i = 0; i < matrix.length; i++ ) { + items[i] = CraftItemStack.asCraftMirror(matrix[i]); + } + + return items; + } + + public ItemStack getResult() { + net.minecraft.server.ItemStack item = getResultInventory().getItem(0); + if(item != null) return CraftItemStack.asCraftMirror(item); + return null; + } + + public void setMatrix(ItemStack[] contents) { + if (getMatrixInventory().getContents().length > contents.length) { + throw new IllegalArgumentException("Invalid inventory size; expected " + getMatrixInventory().getContents().length + " or less"); + } + + net.minecraft.server.ItemStack[] mcItems = getMatrixInventory().getContents(); + + for (int i = 0; i < mcItems.length; i++ ) { + if (i < contents.length) { + ItemStack item = contents[i]; + if (item == null || item.getTypeId() <= 0) { + mcItems[i] = null; + } else { + mcItems[i] = CraftItemStack.asNMSCopy(item); + } + } else { + mcItems[i] = null; + } + } + } + + public void setResult(ItemStack item) { + net.minecraft.server.ItemStack[] contents = getResultInventory().getContents(); + if (item == null || item.getTypeId() <= 0) { + contents[0] = null; + } else { + contents[0] = CraftItemStack.asNMSCopy(item); + } + } + + public Recipe getRecipe() { + IRecipe recipe = ((InventoryCrafting)getInventory()).currentRecipe; + return recipe == null ? null : recipe.toBukkitRecipe(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java new file mode 100644 index 0000000..e99b8cc --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java @@ -0,0 +1,197 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.server.ChatComponentText; + +import net.minecraft.server.IChatBaseComponent; +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.InventoryHolder; + +import net.minecraft.server.EntityHuman; +import net.minecraft.server.IInventory; +import net.minecraft.server.ItemStack; + +public class CraftInventoryCustom extends CraftInventory { + public CraftInventoryCustom(InventoryHolder owner, InventoryType type) { + super(new MinecraftInventory(owner, type)); + } + + public CraftInventoryCustom(InventoryHolder owner, InventoryType type, String title) { + super(new MinecraftInventory(owner, type, title)); + } + + public CraftInventoryCustom(InventoryHolder owner, int size) { + super(new MinecraftInventory(owner, size)); + } + + public CraftInventoryCustom(InventoryHolder owner, int size, String title) { + super(new MinecraftInventory(owner, size, title)); + } + + static class MinecraftInventory implements IInventory { + private final ItemStack[] items; + private int maxStack = MAX_STACK; + private final List viewers; + private final String title; + private InventoryType type; + private final InventoryHolder owner; + + public MinecraftInventory(InventoryHolder owner, InventoryType type) { + this(owner, type.getDefaultSize(), type.getDefaultTitle()); + this.type = type; + } + + public MinecraftInventory(InventoryHolder owner, InventoryType type, String title) { + this(owner, type.getDefaultSize(), title); + this.type = type; + } + + public MinecraftInventory(InventoryHolder owner, int size) { + this(owner, size, "Chest"); + } + + public MinecraftInventory(InventoryHolder owner, int size, String title) { + Validate.notNull(title, "Title cannot be null"); + this.items = new ItemStack[size]; + this.title = title; + this.viewers = new ArrayList(); + this.owner = owner; + this.type = InventoryType.CHEST; + } + + public int getSize() { + return items.length; + } + + public ItemStack getItem(int i) { + return items[i]; + } + + public ItemStack splitStack(int i, int j) { + ItemStack stack = this.getItem(i); + ItemStack result; + if (stack == null) return null; + if (stack.count <= j) { + this.setItem(i, null); + result = stack; + } else { + result = CraftItemStack.copyNMSStack(stack, j); + stack.count -= j; + } + this.update(); + return result; + } + + public ItemStack splitWithoutUpdate(int i) { + ItemStack stack = this.getItem(i); + ItemStack result; + if (stack == null) return null; + if (stack.count <= 1) { + this.setItem(i, null); + result = stack; + } else { + result = CraftItemStack.copyNMSStack(stack, 1); + stack.count -= 1; + } + return result; + } + + public void setItem(int i, ItemStack itemstack) { + items[i] = itemstack; + if (itemstack != null && this.getMaxStackSize() > 0 && itemstack.count > this.getMaxStackSize()) { + itemstack.count = this.getMaxStackSize(); + } + } + + public int getMaxStackSize() { + return maxStack; + } + + public void setMaxStackSize(int size) { + maxStack = size; + } + + public void update() {} + + public boolean a(EntityHuman entityhuman) { + return true; + } + + public ItemStack[] getContents() { + return items; + } + + public void onOpen(CraftHumanEntity who) { + viewers.add(who); + } + + public void onClose(CraftHumanEntity who) { + viewers.remove(who); + } + + public List getViewers() { + return viewers; + } + + public InventoryType getType() { + return type; + } + + public InventoryHolder getOwner() { + return owner; + } + + public boolean b(int i, ItemStack itemstack) { + return true; + } + + @Override + public void startOpen(EntityHuman entityHuman) { + + } + + @Override + public void closeContainer(EntityHuman entityHuman) { + + } + + @Override + public int getProperty(int i) { + return 0; + } + + @Override + public void b(int i, int i1) { + + } + + @Override + public int g() { + return 0; + } + + @Override + public void l() { + + } + + @Override + public String getName() { + return title; + } + + @Override + public boolean hasCustomName() { + return title != null; + } + + @Override + public IChatBaseComponent getScoreboardDisplayName() { + return new ChatComponentText(title); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryDoubleChest.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryDoubleChest.java new file mode 100644 index 0000000..87252ca --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryDoubleChest.java @@ -0,0 +1,62 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.ITileEntityContainer; +import net.minecraft.server.ITileInventory; +import org.bukkit.block.DoubleChest; +import org.bukkit.inventory.DoubleChestInventory; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import net.minecraft.server.InventoryLargeChest; + +public class CraftInventoryDoubleChest extends CraftInventory implements DoubleChestInventory { + private final CraftInventory left; + private final CraftInventory right; + + public CraftInventoryDoubleChest(CraftInventory left, CraftInventory right) { + super(new InventoryLargeChest("Large chest", (ITileInventory) left.getInventory(), (ITileInventory) right.getInventory())); + this.left = left; + this.right = right; + } + + public CraftInventoryDoubleChest(InventoryLargeChest largeChest) { + super(largeChest); + if (largeChest.left instanceof InventoryLargeChest) { + left = new CraftInventoryDoubleChest((InventoryLargeChest) largeChest.left); + } else { + left = new CraftInventory(largeChest.left); + } + if (largeChest.right instanceof InventoryLargeChest) { + right = new CraftInventoryDoubleChest((InventoryLargeChest) largeChest.right); + } else { + right = new CraftInventory(largeChest.right); + } + } + + public Inventory getLeftSide() { + return left; + } + + public Inventory getRightSide() { + return right; + } + + @Override + public void setContents(ItemStack[] items) { + if (getInventory().getContents().length < items.length) { + throw new IllegalArgumentException("Invalid inventory size; expected " + getInventory().getContents().length + " or less"); + } + ItemStack[] leftItems = new ItemStack[left.getSize()], rightItems = new ItemStack[right.getSize()]; + System.arraycopy(items, 0, leftItems, 0, Math.min(left.getSize(),items.length)); + left.setContents(leftItems); + if (items.length >= left.getSize()) { + System.arraycopy(items, left.getSize(), rightItems, 0, Math.min(right.getSize(), items.length - left.getSize())); + right.setContents(rightItems); + } + } + + @Override + public DoubleChest getHolder() { + return new DoubleChest(this); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryEnchanting.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryEnchanting.java new file mode 100644 index 0000000..ec28e2e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryEnchanting.java @@ -0,0 +1,37 @@ +package org.bukkit.craftbukkit.inventory; + +import org.bukkit.inventory.EnchantingInventory; +import org.bukkit.inventory.ItemStack; + +import net.minecraft.server.InventorySubcontainer; + +public class CraftInventoryEnchanting extends CraftInventory implements EnchantingInventory { + public CraftInventoryEnchanting(InventorySubcontainer inventory) { + super(inventory); + } + + @Override + public void setItem(ItemStack item) { + setItem(0,item); + } + + @Override + public ItemStack getItem() { + return getItem(0); + } + + @Override + public InventorySubcontainer getInventory() { + return (InventorySubcontainer)inventory; + } + + @Override + public void setSecondary(ItemStack item) { + setItem(1, item); + } + + @Override + public ItemStack getSecondary() { + return getItem(1); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java new file mode 100644 index 0000000..37a631e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java @@ -0,0 +1,42 @@ +package org.bukkit.craftbukkit.inventory; + +import org.bukkit.block.Furnace; +import org.bukkit.inventory.FurnaceInventory; +import org.bukkit.inventory.ItemStack; + +import net.minecraft.server.TileEntityFurnace; + +public class CraftInventoryFurnace extends CraftInventory implements FurnaceInventory { + public CraftInventoryFurnace(TileEntityFurnace inventory) { + super(inventory); + } + + public ItemStack getResult() { + return getItem(2); + } + + public ItemStack getFuel() { + return getItem(1); + } + + public ItemStack getSmelting() { + return getItem(0); + } + + public void setFuel(ItemStack stack) { + setItem(1,stack); + } + + public void setResult(ItemStack stack) { + setItem(2,stack); + } + + public void setSmelting(ItemStack stack) { + setItem(0,stack); + } + + @Override + public Furnace getHolder() { + return (Furnace) inventory.getOwner(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java new file mode 100644 index 0000000..5adbd74 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java @@ -0,0 +1,28 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.IInventory; +import org.bukkit.inventory.HorseInventory; +import org.bukkit.inventory.ItemStack; + +public class CraftInventoryHorse extends CraftInventory implements HorseInventory { + + public CraftInventoryHorse(IInventory inventory) { + super(inventory); + } + + public ItemStack getSaddle() { + return getItem(0); + } + + public ItemStack getArmor() { + return getItem(1); + } + + public void setSaddle(ItemStack stack) { + setItem(0, stack); + } + + public void setArmor(ItemStack stack) { + setItem(1, stack); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryMerchant.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryMerchant.java new file mode 100644 index 0000000..7f89c2a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryMerchant.java @@ -0,0 +1,10 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.InventoryMerchant; +import org.bukkit.inventory.MerchantInventory; + +public class CraftInventoryMerchant extends CraftInventory implements MerchantInventory { + public CraftInventoryMerchant(InventoryMerchant merchant) { + super(merchant); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java new file mode 100644 index 0000000..dba8d5b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -0,0 +1,216 @@ +package org.bukkit.craftbukkit.inventory; + +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.PacketPlayOutHeldItemSlot; +import net.minecraft.server.PacketPlayOutSetSlot; +import net.minecraft.server.PlayerInventory; + +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; + +public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.inventory.PlayerInventory, EntityEquipment { + public CraftInventoryPlayer(net.minecraft.server.PlayerInventory inventory) { + super(inventory); + } + + @Override + public PlayerInventory getInventory() { + return (PlayerInventory) inventory; + } + + @Override + public int getSize() { + return super.getSize() - 4; + } + + public ItemStack getItemInHand() { + return CraftItemStack.asCraftMirror(getInventory().getItemInHand()); + } + + public void setItemInHand(ItemStack stack) { + setItem(getHeldItemSlot(), stack); + } + + @Override + public void setItem(int index, ItemStack item) { + super.setItem(index, item); + if (this.getHolder() == null) return; + EntityPlayer player = ((CraftPlayer) this.getHolder()).getHandle(); + if (player.playerConnection == null) return; + // PacketPlayOutSetSlot places the items differently than setItem() + // + // Between, and including, index 9 (the first index outside of the hotbar) and index 35 (the last index before + // armor slots) both PacketPlayOutSetSlot and setItem() places the items in the player's inventory the same way. + // Index 9 starts at the upper left corner of the inventory and moves to the right as it increases. When it + // reaches the end of the line it goes back to the left side of the new line in the inventory. Basically, it + // follows the path your eyes would follow as you read a book. + // + // The player's hotbar is indexed 0-8 in setItem(). The order goes: 0-8 hotbar, 9-35 normal inventory, 36 boots, + // 37 leggings, 38 chestplate, and 39 helmet. For indexes > 39 an ArrayIndexOutOfBoundsException will be thrown. + // + // PacketPlayOutSetSlot works very differently. Slots 0-8 are as follows: 0 crafting output, 1-4 crafting input, + // 5 helmet, 6 chestplate, 7 leggings, and 8 boots. Then, 9-35 work exactly the same as setItem(). The hotbar + // for PacketPlayOutSetSlot starts at index 36, and continues to index 44. Items placed where index is < 0 or + // > 44 have no action. Basically, the upper part of the player's inventory (crafting area and armor slots) is + // the first "row" of 9 slots for PacketPlayOutSetSlot. From there the rows work as normal, from left to right + // all the way down, including the hotbar. + // + // With this in mind, we have to modify the index we give PacketPlayOutSetSlot to match the index we intended + // with setItem(). First, if the index is 0-8, we need to add 36, or 4 rows worth of slots, to the index. This + // will push the item down to the correct spot in the hotbar. + // + // Now when index is > 35 (if index > 39 an ArrayIndexOutOfBoundsException will be thrown, so we need not worry + // about it) then we need to reset the index, and then count backwards from the "top" of the inventory. That is + // to say, we first find (index - 36), which will give us the index required for the armor slots. Now, we need + // to reverse the order of the index from 8. That means we need 0 to correspond to 8, 1 to correspond to 7, + // 2 to correspond to 6, and 3 to correspond to 5. We do this simply by taking the result of (index - 36) and + // subtracting that value from 8. + if (index < PlayerInventory.getHotbarSize()) + index = index + 36; + else if (index > 35) + index = 8 - (index - 36); + player.playerConnection.sendPacket(new PacketPlayOutSetSlot(player.defaultContainer.windowId, index, CraftItemStack.asNMSCopy(item))); + } + + public int getHeldItemSlot() { + return getInventory().itemInHandIndex; + } + + public void setHeldItemSlot(int slot) { + Validate.isTrue(slot >= 0 && slot < PlayerInventory.getHotbarSize(), "Slot is not between 0 and 8 inclusive"); + this.getInventory().itemInHandIndex = slot; + ((CraftPlayer) this.getHolder()).getHandle().playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(slot)); + } + + public ItemStack getHelmet() { + return getItem(getSize() + 3); + } + + public ItemStack getChestplate() { + return getItem(getSize() + 2); + } + + public ItemStack getLeggings() { + return getItem(getSize() + 1); + } + + public ItemStack getBoots() { + return getItem(getSize() + 0); + } + + public void setHelmet(ItemStack helmet) { + setItem(getSize() + 3, helmet); + } + + public void setChestplate(ItemStack chestplate) { + setItem(getSize() + 2, chestplate); + } + + public void setLeggings(ItemStack leggings) { + setItem(getSize() + 1, leggings); + } + + public void setBoots(ItemStack boots) { + setItem(getSize() + 0, boots); + } + + public ItemStack[] getArmorContents() { + net.minecraft.server.ItemStack[] mcItems = getInventory().getArmorContents(); + ItemStack[] ret = new ItemStack[mcItems.length]; + + for (int i = 0; i < mcItems.length; i++) { + ret[i] = CraftItemStack.asCraftMirror(mcItems[i]); + } + return ret; + } + + public void setArmorContents(ItemStack[] items) { + int cnt = getSize(); + + if (items == null) { + items = new ItemStack[4]; + } + for (ItemStack item : items) { + if (item == null || item.getTypeId() == 0) { + clear(cnt++); + } else { + setItem(cnt++, item); + } + } + } + + public int clear(int id, int data) { + int count = 0; + ItemStack[] items = getContents(); + ItemStack[] armor = getArmorContents(); + int armorSlot = getSize(); + + for (int i = 0; i < items.length; i++) { + ItemStack item = items[i]; + if (item == null) continue; + if (id > -1 && item.getTypeId() != id) continue; + if (data > -1 && item.getData().getData() != data) continue; + + count += item.getAmount(); + setItem(i, null); + } + + for (ItemStack item : armor) { + if (item == null) continue; + if (id > -1 && item.getTypeId() != id) continue; + if (data > -1 && item.getData().getData() != data) continue; + + count += item.getAmount(); + setItem(armorSlot++, null); + } + return count; + } + + @Override + public HumanEntity getHolder() { + return (HumanEntity) inventory.getOwner(); + } + + public float getItemInHandDropChance() { + return 1; + } + + public void setItemInHandDropChance(float chance) { + throw new UnsupportedOperationException(); + } + + public float getHelmetDropChance() { + return 1; + } + + public void setHelmetDropChance(float chance) { + throw new UnsupportedOperationException(); + } + + public float getChestplateDropChance() { + return 1; + } + + public void setChestplateDropChance(float chance) { + throw new UnsupportedOperationException(); + } + + public float getLeggingsDropChance() { + return 1; + } + + public void setLeggingsDropChance(float chance) { + throw new UnsupportedOperationException(); + } + + public float getBootsDropChance() { + return 1; + } + + public void setBootsDropChance(float chance) { + throw new UnsupportedOperationException(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java new file mode 100644 index 0000000..ae47a0e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java @@ -0,0 +1,142 @@ +package org.bukkit.craftbukkit.inventory; + +import org.bukkit.GameMode; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.InventoryType.SlotType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +import net.minecraft.server.Container; + +public class CraftInventoryView extends InventoryView { + private final Container container; + private final CraftHumanEntity player; + private final CraftInventory viewing; + + public CraftInventoryView(HumanEntity player, Inventory viewing, Container container) { + // TODO: Should we make sure it really IS a CraftHumanEntity first? And a CraftInventory? + this.player = (CraftHumanEntity) player; + this.viewing = (CraftInventory) viewing; + this.container = container; + } + + @Override + public Inventory getTopInventory() { + return viewing; + } + + @Override + public Inventory getBottomInventory() { + return player.getInventory(); + } + + @Override + public HumanEntity getPlayer() { + return player; + } + + @Override + public InventoryType getType() { + InventoryType type = viewing.getType(); + if (type == InventoryType.CRAFTING && player.getGameMode() == GameMode.CREATIVE) { + return InventoryType.CREATIVE; + } + return type; + } + + @Override + public void setItem(int slot, ItemStack item) { + net.minecraft.server.ItemStack stack = CraftItemStack.asNMSCopy(item); + if (slot != -999) { + container.getSlot(slot).set(stack); + } else { + player.getHandle().drop(stack, false); + } + } + + @Override + public ItemStack getItem(int slot) { + if (slot == -999) { + return null; + } + return CraftItemStack.asCraftMirror(container.getSlot(slot).getItem()); + } + + public boolean isInTop(int rawSlot) { + return rawSlot < viewing.getSize(); + } + + public Container getHandle() { + return container; + } + + public static SlotType getSlotType(InventoryView inventory, int slot) { + SlotType type = SlotType.CONTAINER; + if (slot >= 0 && slot < inventory.getTopInventory().getSize()) { + switch(inventory.getType()) { + case FURNACE: + if (slot == 2) { + type = SlotType.RESULT; + } else if(slot == 1) { + type = SlotType.FUEL; + } else { + type = SlotType.CRAFTING; + } + break; + case BREWING: + if (slot == 3) { + type = SlotType.FUEL; + } else { + type = SlotType.CRAFTING; + } + break; + case ENCHANTING: + type = SlotType.CRAFTING; + break; + case WORKBENCH: + case CRAFTING: + if (slot == 0) { + type = SlotType.RESULT; + } else { + type = SlotType.CRAFTING; + } + break; + case MERCHANT: + if (slot == 2) { + type = SlotType.RESULT; + } else { + type = SlotType.CRAFTING; + } + break; + case BEACON: + type = SlotType.CRAFTING; + break; + case ANVIL: + if (slot == 2) { + type = SlotType.RESULT; + } else { + type = SlotType.CRAFTING; + } + break; + default: + // Nothing to do, it's a CONTAINER slot + } + } else { + if (slot == -999) { + type = SlotType.OUTSIDE; + } else if (inventory.getType() == InventoryType.CRAFTING) { + if (slot < 9) { + type = SlotType.ARMOR; + } else if (slot > 35) { + type = SlotType.QUICKBAR; + } + } else if (slot >= (inventory.countSlots() - 9)) { + type = SlotType.QUICKBAR; + } + } + return type; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java new file mode 100644 index 0000000..5404ee9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -0,0 +1,165 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Collection; + +import org.apache.commons.lang.Validate; +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.google.common.collect.ImmutableSet; + +public final class CraftItemFactory implements ItemFactory { + static final Color DEFAULT_LEATHER_COLOR = Color.fromRGB(0xA06540); + static final Collection KNOWN_NBT_ATTRIBUTE_NAMES; + private static final CraftItemFactory instance; + + static { + instance = new CraftItemFactory(); + ConfigurationSerialization.registerClass(CraftMetaItem.SerializableMeta.class); + KNOWN_NBT_ATTRIBUTE_NAMES = ImmutableSet.builder() + .add("generic.attackDamage") + .add("generic.followRange") + .add("generic.knockbackResistance") + .add("generic.maxHealth") + .add("generic.movementSpeed") + .add("horse.jumpStrength") + .add("zombie.spawnReinforcements") + .build(); + } + + private CraftItemFactory() { + } + + public boolean isApplicable(ItemMeta meta, ItemStack itemstack) { + if (itemstack == null) { + return false; + } + return isApplicable(meta, itemstack.getType()); + } + + public boolean isApplicable(ItemMeta meta, Material type) { + if (type == null || meta == null) { + return false; + } + if (!(meta instanceof CraftMetaItem)) { + throw new IllegalArgumentException("Meta of " + meta.getClass().toString() + " not created by " + CraftItemFactory.class.getName()); + } + + return ((CraftMetaItem) meta).applicableTo(type); + } + + public ItemMeta getItemMeta(Material material) { + Validate.notNull(material, "Material cannot be null"); + return getItemMeta(material, null); + } + + private ItemMeta getItemMeta(Material material, CraftMetaItem meta) { + switch (material) { + case AIR: + return null; + case WRITTEN_BOOK: + return meta instanceof CraftMetaBookSigned ? meta : new CraftMetaBookSigned(meta); + case BOOK_AND_QUILL: + return meta != null && meta.getClass().equals(CraftMetaBook.class) ? meta : new CraftMetaBook(meta); + case SKULL_ITEM: + return meta instanceof CraftMetaSkull ? meta : new CraftMetaSkull(meta); + case LEATHER_HELMET: + case LEATHER_CHESTPLATE: + case LEATHER_LEGGINGS: + case LEATHER_BOOTS: + return meta instanceof CraftMetaLeatherArmor ? meta : new CraftMetaLeatherArmor(meta); + case POTION: + return meta instanceof CraftMetaPotion ? meta : new CraftMetaPotion(meta); + case MAP: + return meta instanceof CraftMetaMap ? meta : new CraftMetaMap(meta); + case FIREWORK: + return meta instanceof CraftMetaFirework ? meta : new CraftMetaFirework(meta); + case FIREWORK_CHARGE: + return meta instanceof CraftMetaCharge ? meta : new CraftMetaCharge(meta); + case ENCHANTED_BOOK: + return meta instanceof CraftMetaEnchantedBook ? meta : new CraftMetaEnchantedBook(meta); + case BANNER: + return meta instanceof CraftMetaBanner ? meta : new CraftMetaBanner(meta); + case FURNACE: + case CHEST: + case TRAPPED_CHEST: + case JUKEBOX: + case DISPENSER: + case DROPPER: + case SIGN: + case MOB_SPAWNER: + case NOTE_BLOCK: + case PISTON_BASE: + case BREWING_STAND_ITEM: + case ENCHANTMENT_TABLE: + case COMMAND: + case BEACON: + case DAYLIGHT_DETECTOR: + case DAYLIGHT_DETECTOR_INVERTED: + case HOPPER: + case REDSTONE_COMPARATOR: + case FLOWER_POT_ITEM: + return new CraftMetaBlockState(meta, material); + default: + return new CraftMetaItem(meta); + } + } + + public boolean equals(ItemMeta meta1, ItemMeta meta2) { + if (meta1 == meta2) { + return true; + } + if (meta1 != null && !(meta1 instanceof CraftMetaItem)) { + throw new IllegalArgumentException("First meta of " + meta1.getClass().getName() + " does not belong to " + CraftItemFactory.class.getName()); + } + if (meta2 != null && !(meta2 instanceof CraftMetaItem)) { + throw new IllegalArgumentException("Second meta " + meta2.getClass().getName() + " does not belong to " + CraftItemFactory.class.getName()); + } + if (meta1 == null) { + return ((CraftMetaItem) meta2).isEmpty(); + } + if (meta2 == null) { + return ((CraftMetaItem) meta1).isEmpty(); + } + + return equals((CraftMetaItem) meta1, (CraftMetaItem) meta2); + } + + boolean equals(CraftMetaItem meta1, CraftMetaItem meta2) { + /* + * This couldn't be done inside of the objects themselves, else force recursion. + * This is a fairly clean way of implementing it, by dividing the methods into purposes and letting each method perform its own function. + * + * The common and uncommon were split, as both could have variables not applicable to the other, like a skull and book. + * Each object needs its chance to say "hey wait a minute, we're not equal," but without the redundancy of using the 1.equals(2) && 2.equals(1) checking the 'commons' twice. + * + * Doing it this way fills all conditions of the .equals() method. + */ + return meta1.equalsCommon(meta2) && meta1.notUncommon(meta2) && meta2.notUncommon(meta1); + } + + public static CraftItemFactory instance() { + return instance; + } + + public ItemMeta asMetaFor(ItemMeta meta, ItemStack stack) { + Validate.notNull(stack, "Stack cannot be null"); + return asMetaFor(meta, stack.getType()); + } + + public ItemMeta asMetaFor(ItemMeta meta, Material material) { + Validate.notNull(material, "Material cannot be null"); + if (!(meta instanceof CraftMetaItem)) { + throw new IllegalArgumentException("Meta of " + (meta != null ? meta.getClass().toString() : "null") + " not created by " + CraftItemFactory.class.getName()); + } + return getItemMeta(material, (CraftMetaItem) meta); + } + + public Color getDefaultLeatherColor() { + return DEFAULT_LEATHER_COLOR; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java new file mode 100644 index 0000000..23f05f4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -0,0 +1,442 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.bukkit.craftbukkit.inventory.CraftMetaItem.ENCHANTMENTS; +import static org.bukkit.craftbukkit.inventory.CraftMetaItem.ENCHANTMENTS_ID; +import static org.bukkit.craftbukkit.inventory.CraftMetaItem.ENCHANTMENTS_LVL; + +import java.util.Map; + +import net.minecraft.server.EnchantmentManager; +import net.minecraft.server.Item; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; + +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import com.google.common.collect.ImmutableMap; +import net.minecraft.server.IChatBaseComponent.ChatSerializer; +import net.minecraft.server.Items; +import net.minecraft.server.NBTTagString; +import org.bukkit.craftbukkit.util.CraftChatMessage; + +@DelegateDeserialization(ItemStack.class) +public final class CraftItemStack extends ItemStack { + + public static net.minecraft.server.ItemStack asNMSCopy(ItemStack original) { + if (original instanceof CraftItemStack) { + CraftItemStack stack = (CraftItemStack) original; + return stack.handle == null ? null : stack.handle.cloneItemStack(); + } + if (original == null || original.getTypeId() <= 0) { + return null; + } + + Item item = CraftMagicNumbers.getItem(original.getType()); + + if (item == null) { + return null; + } + + net.minecraft.server.ItemStack stack = new net.minecraft.server.ItemStack(item, original.getAmount(), original.getDurability()); + if (original.hasItemMeta()) { + setItemMeta(stack, original.getItemMeta()); + } + return stack; + } + + public static net.minecraft.server.ItemStack copyNMSStack(net.minecraft.server.ItemStack original, int amount) { + net.minecraft.server.ItemStack stack = original.cloneItemStack(); + stack.count = amount; + return stack; + } + + /** + * Copies the NMS stack to return as a strictly-Bukkit stack + */ + public static ItemStack asBukkitCopy(net.minecraft.server.ItemStack original) { + if (original == null) { + return new ItemStack(Material.AIR); + } + ItemStack stack = new ItemStack(CraftMagicNumbers.getMaterial(original.getItem()), original.count, (short) original.getData()); + if (hasItemMeta(original)) { + stack.setItemMeta(getItemMeta(original)); + } + return stack; + } + + public static CraftItemStack asCraftMirror(net.minecraft.server.ItemStack original) { + return new CraftItemStack(original); + } + + public static CraftItemStack asCraftCopy(ItemStack original) { + if (original instanceof CraftItemStack) { + CraftItemStack stack = (CraftItemStack) original; + return new CraftItemStack(stack.handle == null ? null : stack.handle.cloneItemStack()); + } + return new CraftItemStack(original); + } + + public static CraftItemStack asNewCraftStack(Item item) { + return asNewCraftStack(item, 1); + } + + public static CraftItemStack asNewCraftStack(Item item, int amount) { + return new CraftItemStack(CraftMagicNumbers.getMaterial(item), amount, (short) 0, null); + } + + net.minecraft.server.ItemStack handle; + + /** + * Mirror + */ + private CraftItemStack(net.minecraft.server.ItemStack item) { + this.handle = item; + } + + private CraftItemStack(ItemStack item) { + this(item.getTypeId(), item.getAmount(), item.getDurability(), item.hasItemMeta() ? item.getItemMeta() : null); + } + + private CraftItemStack(Material type, int amount, short durability, ItemMeta itemMeta) { + setType(type); + setAmount(amount); + setDurability(durability); + setItemMeta(itemMeta); + } + + private CraftItemStack(int typeId, int amount, short durability, ItemMeta itemMeta) { + this(Material.getMaterial(typeId), amount, durability, itemMeta); + + } + + @Override + public int getTypeId() { + return handle != null ? CraftMagicNumbers.getId(handle.getItem()) : 0; + } + + @Override + public void setTypeId(int type) { + if (getTypeId() == type) { + return; + } else if (type == 0) { + handle = null; + } else if (CraftMagicNumbers.getItem(type) == null) { // :( + handle = null; + } else if (handle == null) { + handle = new net.minecraft.server.ItemStack(CraftMagicNumbers.getItem(type), 1, 0); + } else { + handle.setItem(CraftMagicNumbers.getItem(type)); + if (hasItemMeta()) { + // This will create the appropriate item meta, which will contain all the data we intend to keep + setItemMeta(handle, getItemMeta(handle)); + } + } + setData(null); + } + + @Override + public int getAmount() { + return handle != null ? handle.count : 0; + } + + @Override + public void setAmount(int amount) { + if (handle == null) { + return; + } + if (amount == 0) { + handle = null; + } else { + handle.count = amount; + } + } + + @Override + public void setDurability(final short durability) { + // Ignore damage if item is null + if (handle != null) { + handle.setData(durability); + } + } + + @Override + public short getDurability() { + if (handle != null) { + return (short) handle.getData(); + } else { + return -1; + } + } + + @Override + public int getMaxStackSize() { + return (handle == null) ? Material.AIR.getMaxStackSize() : handle.getItem().getMaxStackSize(); + } + + @Override + public void addUnsafeEnchantment(Enchantment ench, int level) { + Validate.notNull(ench, "Cannot add null enchantment"); + + if (!makeTag(handle)) { + return; + } + NBTTagList list = getEnchantmentList(handle); + if (list == null) { + list = new NBTTagList(); + handle.getTag().set(ENCHANTMENTS.NBT, list); + } + int size = list.size(); + + for (int i = 0; i < size; i++) { + NBTTagCompound tag = (NBTTagCompound) list.get(i); + short id = tag.getShort(ENCHANTMENTS_ID.NBT); + if (id == ench.getId()) { + tag.setShort(ENCHANTMENTS_LVL.NBT, (short) level); + return; + } + } + NBTTagCompound tag = new NBTTagCompound(); + tag.setShort(ENCHANTMENTS_ID.NBT, (short) ench.getId()); + tag.setShort(ENCHANTMENTS_LVL.NBT, (short) level); + list.add(tag); + } + + static boolean makeTag(net.minecraft.server.ItemStack item) { + if (item == null) { + return false; + } + + if (item.getTag() == null) { + item.setTag(new NBTTagCompound()); + } + + return true; + } + + @Override + public boolean containsEnchantment(Enchantment ench) { + return getEnchantmentLevel(ench) > 0; + } + + @Override + public int getEnchantmentLevel(Enchantment ench) { + Validate.notNull(ench, "Cannot find null enchantment"); + if (handle == null) { + return 0; + } + return EnchantmentManager.getEnchantmentLevel(ench.getId(), handle); + } + + @Override + public int removeEnchantment(Enchantment ench) { + Validate.notNull(ench, "Cannot remove null enchantment"); + + NBTTagList list = getEnchantmentList(handle), listCopy; + if (list == null) { + return 0; + } + int index = Integer.MIN_VALUE; + int level = Integer.MIN_VALUE; + int size = list.size(); + + for (int i = 0; i < size; i++) { + NBTTagCompound enchantment = (NBTTagCompound) list.get(i); + int id = 0xffff & enchantment.getShort(ENCHANTMENTS_ID.NBT); + if (id == ench.getId()) { + index = i; + level = 0xffff & enchantment.getShort(ENCHANTMENTS_LVL.NBT); + break; + } + } + + if (index == Integer.MIN_VALUE) { + return 0; + } + if (size == 1) { + handle.getTag().remove(ENCHANTMENTS.NBT); + if (handle.getTag().isEmpty()) { + handle.setTag(null); + } + return level; + } + + // This is workaround for not having an index removal + listCopy = new NBTTagList(); + for (int i = 0; i < size; i++) { + if (i != index) { + listCopy.add(list.get(i)); + } + } + handle.getTag().set(ENCHANTMENTS.NBT, listCopy); + + return level; + } + + @Override + public Map getEnchantments() { + return getEnchantments(handle); + } + + static Map getEnchantments(net.minecraft.server.ItemStack item) { + NBTTagList list = (item != null && item.hasEnchantments()) ? item.getEnchantments() : null; + + if (list == null || list.size() == 0) { + return ImmutableMap.of(); + } + + ImmutableMap.Builder result = ImmutableMap.builder(); + + for (int i = 0; i < list.size(); i++) { + int id = 0xffff & ((NBTTagCompound) list.get(i)).getShort(ENCHANTMENTS_ID.NBT); + int level = 0xffff & ((NBTTagCompound) list.get(i)).getShort(ENCHANTMENTS_LVL.NBT); + + result.put(Enchantment.getById(id), level); + } + + return result.build(); + } + + static NBTTagList getEnchantmentList(net.minecraft.server.ItemStack item) { + return (item != null && item.hasEnchantments()) ? item.getEnchantments() : null; + } + + @Override + public CraftItemStack clone() { + CraftItemStack itemStack = (CraftItemStack) super.clone(); + if (this.handle != null) { + itemStack.handle = this.handle.cloneItemStack(); + } + return itemStack; + } + + @Override + public ItemMeta getItemMeta() { + return getItemMeta(handle); + } + + public static ItemMeta getItemMeta(net.minecraft.server.ItemStack item) { + if (!hasItemMeta(item)) { + return CraftItemFactory.instance().getItemMeta(getType(item)); + } + switch (getType(item)) { + case WRITTEN_BOOK: + return new CraftMetaBookSigned(item.getTag()); + case BOOK_AND_QUILL: + return new CraftMetaBook(item.getTag()); + case SKULL_ITEM: + return new CraftMetaSkull(item.getTag()); + case LEATHER_HELMET: + case LEATHER_CHESTPLATE: + case LEATHER_LEGGINGS: + case LEATHER_BOOTS: + return new CraftMetaLeatherArmor(item.getTag()); + case POTION: + return new CraftMetaPotion(item.getTag()); + case MAP: + return new CraftMetaMap(item.getTag()); + case FIREWORK: + return new CraftMetaFirework(item.getTag()); + case FIREWORK_CHARGE: + return new CraftMetaCharge(item.getTag()); + case ENCHANTED_BOOK: + return new CraftMetaEnchantedBook(item.getTag()); + case BANNER: + return new CraftMetaBanner(item.getTag()); + case FURNACE: + case CHEST: + case TRAPPED_CHEST: + case JUKEBOX: + case DISPENSER: + case DROPPER: + case SIGN: + case MOB_SPAWNER: + case NOTE_BLOCK: + case PISTON_BASE: + case BREWING_STAND_ITEM: + case ENCHANTMENT_TABLE: + case COMMAND: + case BEACON: + case DAYLIGHT_DETECTOR: + case DAYLIGHT_DETECTOR_INVERTED: + case HOPPER: + case REDSTONE_COMPARATOR: + case FLOWER_POT_ITEM: + return new CraftMetaBlockState(item.getTag(), CraftMagicNumbers.getMaterial(item.getItem())); + default: + return new CraftMetaItem(item.getTag()); + } + } + + static Material getType(net.minecraft.server.ItemStack item) { + Material material = Material.getMaterial(item == null ? 0 : CraftMagicNumbers.getId(item.getItem())); + return material == null ? Material.AIR : material; + } + + @Override + public boolean setItemMeta(ItemMeta itemMeta) { + return setItemMeta(handle, itemMeta); + } + + public static boolean setItemMeta(net.minecraft.server.ItemStack item, ItemMeta itemMeta) { + if (item == null) { + return false; + } + if (CraftItemFactory.instance().equals(itemMeta, null)) { + item.setTag(null); + return true; + } + if (!CraftItemFactory.instance().isApplicable(itemMeta, getType(item))) { + return false; + } + + itemMeta = CraftItemFactory.instance().asMetaFor(itemMeta, getType(item)); + if (itemMeta == null) return true; + + NBTTagCompound tag = new NBTTagCompound(); + item.setTag(tag); + + ((CraftMetaItem) itemMeta).applyToItem(tag); + + return true; + } + + @Override + public boolean isSimilar(ItemStack stack) { + if (stack == null) { + return false; + } + if (stack == this) { + return true; + } + if (!(stack instanceof CraftItemStack)) { + return stack.getClass() == ItemStack.class && stack.isSimilar(this); + } + + CraftItemStack that = (CraftItemStack) stack; + if (handle == that.handle) { + return true; + } + if (handle == null || that.handle == null) { + return false; + } + if (!(that.getTypeId() == getTypeId() && getDurability() == that.getDurability())) { + return false; + } + return hasItemMeta() ? that.hasItemMeta() && handle.getTag().equals(that.handle.getTag()) : !that.hasItemMeta(); + } + + @Override + public boolean hasItemMeta() { + return hasItemMeta(handle); + } + + static boolean hasItemMeta(net.minecraft.server.ItemStack item) { + return !(item == null || item.getTag() == null || item.getTag().isEmpty()); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java new file mode 100644 index 0000000..80f9ffa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBanner.java @@ -0,0 +1,204 @@ +package org.bukkit.craftbukkit.inventory; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; +import org.bukkit.DyeColor; +import org.bukkit.Material; +import org.bukkit.block.banner.Pattern; +import org.bukkit.block.banner.PatternType; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.inventory.meta.BannerMeta; + +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +public class CraftMetaBanner extends CraftMetaItem implements BannerMeta { + + static final ItemMetaKey BASE = new ItemMetaKey("Base", "base-color"); + static final ItemMetaKey PATTERNS = new ItemMetaKey("Patterns", "patterns"); + static final ItemMetaKey COLOR = new ItemMetaKey("Color", "color"); + static final ItemMetaKey PATTERN = new ItemMetaKey("Pattern", "pattern"); + + private DyeColor base; + private List patterns = new ArrayList(); + + CraftMetaBanner(CraftMetaItem meta) { + super(meta); + + if (!(meta instanceof CraftMetaBanner)) { + return; + } + + CraftMetaBanner banner = (CraftMetaBanner) meta; + base = banner.base; + patterns = new ArrayList(banner.patterns); + } + + CraftMetaBanner(NBTTagCompound tag) { + super(tag); + + if (!tag.hasKey("BlockEntityTag")) { + return; + } + + NBTTagCompound entityTag = tag.getCompound("BlockEntityTag"); + + base = entityTag.hasKey(BASE.NBT) ? DyeColor.getByDyeData((byte) entityTag.getInt(BASE.NBT)) : null; + + if (entityTag.hasKey(PATTERNS.NBT)) { + NBTTagList patterns = entityTag.getList(PATTERNS.NBT, 10); + for (int i = 0; i < Math.min(patterns.size(), 20); i++) { + NBTTagCompound p = patterns.get(i); + this.patterns.add(new Pattern(DyeColor.getByDyeData((byte) p.getInt(COLOR.NBT)), PatternType.getByIdentifier(p.getString(PATTERN.NBT)))); + } + } + } + + CraftMetaBanner(Map map) { + super(map); + + String baseStr = SerializableMeta.getString(map, BASE.BUKKIT, true); + if (baseStr != null) { + base = DyeColor.valueOf(baseStr); + } + + Iterable rawPatternList = SerializableMeta.getObject(Iterable.class, map, PATTERNS.BUKKIT, true); + if (rawPatternList == null) { + return; + } + + for (Object obj : rawPatternList) { + if (!(obj instanceof Pattern)) { + throw new IllegalArgumentException("Object in pattern list is not valid. " + obj.getClass()); + } + addPattern((Pattern) obj); + } + } + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + + NBTTagCompound entityTag = new NBTTagCompound(); + if (base != null) { + entityTag.setInt(BASE.NBT, base.getDyeData()); + } + + NBTTagList newPatterns = new NBTTagList(); + + for (Pattern p : patterns) { + NBTTagCompound compound = new NBTTagCompound(); + compound.setInt(COLOR.NBT, p.getColor().getDyeData()); + compound.setString(PATTERN.NBT, p.getPattern().getIdentifier()); + newPatterns.add(compound); + } + entityTag.set(PATTERNS.NBT, newPatterns); + + tag.set("BlockEntityTag", entityTag); + } + + @Override + public DyeColor getBaseColor() { + return base; + } + + @Override + public void setBaseColor(DyeColor color) { + base = color; + } + + @Override + public List getPatterns() { + return new ArrayList(patterns); + } + + @Override + public void setPatterns(List patterns) { + this.patterns = new ArrayList(patterns); + } + + @Override + public void addPattern(Pattern pattern) { + patterns.add(pattern); + } + + @Override + public Pattern getPattern(int i) { + return patterns.get(i); + } + + @Override + public Pattern removePattern(int i) { + return patterns.remove(i); + } + + @Override + public void setPattern(int i, Pattern pattern) { + patterns.set(i, pattern); + } + + @Override + public int numberOfPatterns() { + return patterns.size(); + } + + @Override + ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { + super.serialize(builder); + + if(base != null){ + builder.put(BASE.BUKKIT, base.toString()); + } + + if(!patterns.isEmpty()){ + builder.put(PATTERNS.BUKKIT, ImmutableList.copyOf(patterns)); + } + + return builder; + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (base != null) { + hash = 31 * hash + base.hashCode(); + } + if (!patterns.isEmpty()) { + hash = 31 * hash + patterns.hashCode(); + } + return original != hash ? CraftMetaBanner.class.hashCode() ^ hash : hash; + } + + @Override + public boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaBanner) { + CraftMetaBanner that = (CraftMetaBanner) meta; + + return base == that.base && patterns.equals(that.patterns); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaBanner || (patterns.isEmpty() && base == null)); + } + + + @Override + boolean isEmpty() { + return super.isEmpty() && patterns.isEmpty() && base == null; + } + + + @Override + boolean applicableTo(Material type) { + return type == Material.BANNER; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java new file mode 100644 index 0000000..d60686d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java @@ -0,0 +1,338 @@ +package org.bukkit.craftbukkit.inventory; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import net.minecraft.server.BlockJukeBox; +import net.minecraft.server.NBTBase; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.TileEntity; +import net.minecraft.server.TileEntityBanner; +import net.minecraft.server.TileEntityBeacon; +import net.minecraft.server.TileEntityBrewingStand; +import net.minecraft.server.TileEntityChest; +import net.minecraft.server.TileEntityCommand; +import net.minecraft.server.TileEntityDispenser; +import net.minecraft.server.TileEntityDropper; +import net.minecraft.server.TileEntityFurnace; +import net.minecraft.server.TileEntityHopper; +import net.minecraft.server.TileEntityMobSpawner; +import net.minecraft.server.TileEntityNote; +import net.minecraft.server.TileEntitySign; +import net.minecraft.server.TileEntitySkull; +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.block.BlockState; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.block.CraftBanner; +import org.bukkit.craftbukkit.block.CraftBeacon; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.block.CraftBrewingStand; +import org.bukkit.craftbukkit.block.CraftChest; +import org.bukkit.craftbukkit.block.CraftCommandBlock; +import org.bukkit.craftbukkit.block.CraftCreatureSpawner; +import org.bukkit.craftbukkit.block.CraftDispenser; +import org.bukkit.craftbukkit.block.CraftDropper; +import org.bukkit.craftbukkit.block.CraftFurnace; +import org.bukkit.craftbukkit.block.CraftHopper; +import org.bukkit.craftbukkit.block.CraftJukebox; +import org.bukkit.craftbukkit.block.CraftNoteBlock; +import org.bukkit.craftbukkit.block.CraftSign; +import org.bukkit.craftbukkit.block.CraftSkull; +import org.bukkit.inventory.meta.BlockStateMeta; + +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta { + + @ItemMetaKey.Specific(ItemMetaKey.Specific.To.NBT) + static final ItemMetaKey BLOCK_ENTITY_TAG = new ItemMetaKey("BlockEntityTag"); + + final Material material; + NBTTagCompound blockEntityTag; + + CraftMetaBlockState(CraftMetaItem meta, Material material) { + super(meta); + this.material = material; + + if (!(meta instanceof CraftMetaBlockState) + || ((CraftMetaBlockState) meta).material != material + || material == Material.SIGN + || material == Material.COMMAND) { + blockEntityTag = null; + return; + } + + CraftMetaBlockState te = (CraftMetaBlockState) meta; + this.blockEntityTag = te.blockEntityTag; + } + + CraftMetaBlockState(NBTTagCompound tag, Material material) { + super(tag); + this.material = material; + + if (tag.hasKeyOfType(BLOCK_ENTITY_TAG.NBT, 10)) { + blockEntityTag = tag.getCompound(BLOCK_ENTITY_TAG.NBT); + } else { + blockEntityTag = null; + } + } + + CraftMetaBlockState(Map map) { + super(map); + String matName = SerializableMeta.getString(map, "blockMaterial", true); + Material m = Material.getMaterial(matName); + if (m != null) { + material = m; + } else { + material = Material.AIR; + } + } + + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + + if (blockEntityTag != null) { + tag.set(BLOCK_ENTITY_TAG.NBT, blockEntityTag); + } + } + + @Override + void deserializeInternal(NBTTagCompound tag) { + if (tag.hasKeyOfType(BLOCK_ENTITY_TAG.NBT, 10)) { + blockEntityTag = tag.getCompound(BLOCK_ENTITY_TAG.NBT); + } + } + + @Override + void serializeInternal(final Map internalTags) { + if (blockEntityTag != null) { + internalTags.put(BLOCK_ENTITY_TAG.NBT, blockEntityTag); + } + } + + @Override + ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { + super.serialize(builder); + builder.put("blockMaterial", material.name()); + return builder; + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (blockEntityTag != null) { + hash = 61 * hash + this.blockEntityTag.hashCode(); + } + return original != hash ? CraftMetaBlockState.class.hashCode() ^ hash : hash; + } + + @Override + public boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaBlockState) { + CraftMetaBlockState that = (CraftMetaBlockState) meta; + + return Objects.equal(this.blockEntityTag, that.blockEntityTag); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaBlockState || blockEntityTag == null); + } + + @Override + boolean isEmpty() { + return super.isEmpty() && blockEntityTag == null; + } + + @Override + boolean applicableTo(Material type) { + switch(type){ + case FURNACE: + case CHEST: + case TRAPPED_CHEST: + case JUKEBOX: + case DISPENSER: + case DROPPER: + case SIGN: + case MOB_SPAWNER: + case NOTE_BLOCK: + case PISTON_BASE: + case BREWING_STAND_ITEM: + case ENCHANTMENT_TABLE: + case COMMAND: + case BEACON: + case DAYLIGHT_DETECTOR: + case DAYLIGHT_DETECTOR_INVERTED: + case HOPPER: + case REDSTONE_COMPARATOR: + case FLOWER_POT_ITEM: + return true; + } + return false; + } + + @Override + public boolean hasBlockState() { + return blockEntityTag != null; + } + + @Override + public BlockState getBlockState() { + TileEntity te = blockEntityTag == null ? null : TileEntity.c(blockEntityTag); + + switch (material) { + case SIGN: + case SIGN_POST: + case WALL_SIGN: + if (te == null) { + te = new TileEntitySign(); + } + return new CraftSign(material, (TileEntitySign) te); + case CHEST: + case TRAPPED_CHEST: + if (te == null) { + te = new TileEntityChest(); + } + return new CraftChest(material, (TileEntityChest) te); + case BURNING_FURNACE: + case FURNACE: + if (te == null) { + te = new TileEntityFurnace(); + } + return new CraftFurnace(material, (TileEntityFurnace) te); + case DISPENSER: + if (te == null) { + te = new TileEntityDispenser(); + } + return new CraftDispenser(material, (TileEntityDispenser) te); + case DROPPER: + if (te == null) { + te = new TileEntityDispenser(); + } + return new CraftDropper(material, (TileEntityDropper) te); + case HOPPER: + if (te == null) { + te = new TileEntityHopper(); + } + return new CraftHopper(material, (TileEntityHopper) te); + case MOB_SPAWNER: + if (te == null) { + te = new TileEntityMobSpawner(); + } + return new CraftCreatureSpawner(material, (TileEntityMobSpawner) te); + case NOTE_BLOCK: + if (te == null) { + te = new TileEntityNote(); + } + return new CraftNoteBlock(material, (TileEntityNote) te); + case JUKEBOX: + if (te == null) { + te = new BlockJukeBox.TileEntityRecordPlayer(); + } + return new CraftJukebox(material, (BlockJukeBox.TileEntityRecordPlayer) te); + case BREWING_STAND: + if (te == null) { + te = new TileEntityBrewingStand(); + } + return new CraftBrewingStand(material, (TileEntityBrewingStand) te); + case SKULL: + if (te == null) { + te = new TileEntitySkull(); + } + return new CraftSkull(material, (TileEntitySkull) te); + case COMMAND: + if (te == null) { + te = new TileEntityCommand(); + } + return new CraftCommandBlock(material, (TileEntityCommand) te); + case BEACON: + if (te == null) { + te = new TileEntityBeacon(); + } + return new CraftBeacon(material, (TileEntityBeacon) te); + case BANNER: + case WALL_BANNER: + case STANDING_BANNER: + if (te == null) { + te = new TileEntityBanner(); + } + return new CraftBanner(material, (TileEntityBanner) te); + default: + throw new IllegalStateException("Missing blockState for " + material); + } + } + + @Override + public void setBlockState(BlockState blockState) { + Validate.notNull(blockState, "blockState must not be null"); + TileEntity te = ((CraftBlockState) blockState).getTileEntity(); + Validate.notNull(te, "Invalid blockState"); + + boolean valid; + switch (material) { + case SIGN: + case SIGN_POST: + case WALL_SIGN: + valid = te instanceof TileEntitySign; + break; + case CHEST: + case TRAPPED_CHEST: + valid = te instanceof TileEntityChest; + break; + case BURNING_FURNACE: + case FURNACE: + valid = te instanceof TileEntityFurnace; + break; + case DISPENSER: + valid = te instanceof TileEntityDispenser; + break; + case DROPPER: + valid = te instanceof TileEntityDropper; + break; + case HOPPER: + valid = te instanceof TileEntityHopper; + break; + case MOB_SPAWNER: + valid = te instanceof TileEntityMobSpawner; + break; + case NOTE_BLOCK: + valid = te instanceof TileEntityNote; + break; + case JUKEBOX: + valid = te instanceof BlockJukeBox.TileEntityRecordPlayer; + break; + case BREWING_STAND: + valid = te instanceof TileEntityBrewingStand; + break; + case SKULL: + valid = te instanceof TileEntitySkull; + break; + case COMMAND: + valid = te instanceof TileEntityCommand; + break; + case BEACON: + valid = te instanceof TileEntityBeacon; + break; + case BANNER: + case WALL_BANNER: + case STANDING_BANNER: + valid = te instanceof TileEntityBanner; + break; + default: + valid = false; + break; + } + + Validate.isTrue(valid, "Invalid blockState for " + material); + + blockEntityTag = new NBTTagCompound(); + te.b(blockEntityTag); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java new file mode 100644 index 0000000..1d73c8d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java @@ -0,0 +1,338 @@ +package org.bukkit.craftbukkit.inventory; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap.Builder; +import me.levansj01.mythicspigot.MythicConfiguration; +import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.IChatBaseComponent.ChatSerializer; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; +import net.minecraft.server.NBTTagString; +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.inventory.meta.BookMeta; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.spigotmc.ValidateUtils.limit; + +// Spigot start +// Spigot end + +@DelegateDeserialization(SerializableMeta.class) +public class CraftMetaBook extends CraftMetaItem implements BookMeta { + static final ItemMetaKey BOOK_TITLE = new ItemMetaKey("title"); + static final ItemMetaKey BOOK_AUTHOR = new ItemMetaKey("author"); + static final ItemMetaKey BOOK_PAGES = new ItemMetaKey("pages"); + static final ItemMetaKey RESOLVED = new ItemMetaKey("resolved"); + static final ItemMetaKey GENERATION = new ItemMetaKey("generation"); + static final int MAX_PAGE_LENGTH = Short.MAX_VALUE; // TODO: Check me + static final int MAX_TITLE_LENGTH = 0xffff; + + protected String title; + protected String author; + public List pages = new ArrayList(); + protected Integer generation; + + CraftMetaBook(CraftMetaItem meta) { + super(meta); + + if (meta instanceof CraftMetaBook) { + CraftMetaBook bookMeta = (CraftMetaBook) meta; + this.title = bookMeta.title; + this.author = bookMeta.author; + pages.addAll(bookMeta.pages); + this.generation = bookMeta.generation; + } + } + + CraftMetaBook(NBTTagCompound tag) { + this(tag, true); + } + + CraftMetaBook(NBTTagCompound tag, boolean handlePages) { + super(tag); + + if (tag.hasKey(BOOK_TITLE.NBT)) { + this.title = limit( tag.getString(BOOK_TITLE.NBT), 1024 ); // Spigot + } + + if (tag.hasKey(BOOK_AUTHOR.NBT)) { + this.author = limit( tag.getString(BOOK_AUTHOR.NBT), 1024 ); // Spigot + } + + boolean resolved = false; + if (tag.hasKey(RESOLVED.NBT)) { + resolved = tag.getBoolean(RESOLVED.NBT); + } + + if (tag.hasKey(GENERATION.NBT)) { + generation = tag.getInt(GENERATION.NBT); + } + + if (tag.hasKey(BOOK_PAGES.NBT) && handlePages && MythicConfiguration.Options.Server.Exploits.bookPages) { + NBTTagList pages = tag.getList(BOOK_PAGES.NBT, 8); + + for (int i = 0; i < pages.size(); i++) { + String page = pages.getString(i); + if (resolved) { + try { + this.pages.add(ChatSerializer.a(page)); + continue; + } catch (Exception e) { + // Ignore and treat as an old book + } + } + addPage( limit( page, 2048 ) ); // Spigot + } + } + } + + CraftMetaBook(Map map) { + super(map); + + setAuthor(SerializableMeta.getString(map, BOOK_AUTHOR.BUKKIT, true)); + + setTitle(SerializableMeta.getString(map, BOOK_TITLE.BUKKIT, true)); + + Iterable pages = SerializableMeta.getObject(Iterable.class, map, BOOK_PAGES.BUKKIT, true); + if(pages != null) { + for (Object page : pages) { + if (page instanceof String) { + addPage((String) page); + } + } + } + + generation = SerializableMeta.getObject(Integer.class, map, GENERATION.BUKKIT, true); + } + + @Override + void applyToItem(NBTTagCompound itemData) { + applyToItem(itemData, true); + } + + void applyToItem(NBTTagCompound itemData, boolean handlePages) { + super.applyToItem(itemData); + + if (hasTitle()) { + itemData.setString(BOOK_TITLE.NBT, this.title); + } + + if (hasAuthor()) { + itemData.setString(BOOK_AUTHOR.NBT, this.author); + } + + if (handlePages && MythicConfiguration.Options.Server.Exploits.bookPages) { + if (hasPages()) { + NBTTagList list = new NBTTagList(); + for (IChatBaseComponent page : pages) { + list.add(new NBTTagString(CraftChatMessage.fromComponent(page))); + } + itemData.set(BOOK_PAGES.NBT, list); + } + + itemData.remove(RESOLVED.NBT); + } + + if (generation != null) { + itemData.setInt(GENERATION.NBT, generation); + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isBookEmpty(); + } + + boolean isBookEmpty() { + return !(hasPages() || hasAuthor() || hasTitle()); + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case WRITTEN_BOOK: + case BOOK_AND_QUILL: + return true; + default: + return false; + } + } + + public boolean hasAuthor() { + return !Strings.isNullOrEmpty(author); + } + + public boolean hasTitle() { + return !Strings.isNullOrEmpty(title); + } + + public boolean hasPages() { + return !pages.isEmpty(); + } + + public String getTitle() { + return this.title; + } + + public boolean setTitle(final String title) { + if (title == null) { + this.title = null; + return true; + } else if (title.length() > MAX_TITLE_LENGTH) { + return false; + } + + this.title = title; + return true; + } + + public String getAuthor() { + return this.author; + } + + public void setAuthor(final String author) { + this.author = author; + } + + public String getPage(final int page) { + Validate.isTrue(isValidPage(page), "Invalid page number"); + return CraftChatMessage.fromComponent(pages.get(page - 1)); + } + + public void setPage(final int page, final String text) { + if (!isValidPage(page)) { + throw new IllegalArgumentException("Invalid page number " + page + "/" + pages.size()); + } + + String newText = text == null ? "" : text.length() > MAX_PAGE_LENGTH ? text.substring(0, MAX_PAGE_LENGTH) : text; + pages.set(page - 1, CraftChatMessage.fromString(newText, true)[0]); + } + + public void setPages(final String... pages) { + this.pages.clear(); + + addPage(pages); + } + + public void addPage(final String... pages) { + for (String page : pages) { + if (page == null) { + page = ""; + } else if (page.length() > MAX_PAGE_LENGTH) { + page = page.substring(0, MAX_PAGE_LENGTH); + } + + this.pages.add(CraftChatMessage.fromString(page, true)[0]); + } + } + + public int getPageCount() { + return pages.size(); + } + + public List getPages() { + final List copy = ImmutableList.copyOf(pages); + return new AbstractList() { + + @Override + public String get(int index) { + return CraftChatMessage.fromComponent(copy.get(index)); + } + + @Override + public int size() { + return copy.size(); + } + }; + } + + public void setPages(List pages) { + this.pages.clear(); + for (String page : pages) { + addPage(page); + } + } + + private boolean isValidPage(int page) { + return page > 0 && page <= pages.size(); + } + + @Override + public CraftMetaBook clone() { + CraftMetaBook meta = (CraftMetaBook) super.clone(); + meta.pages = new ArrayList(pages); + return meta; + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (hasTitle()) { + hash = 61 * hash + this.title.hashCode(); + } + if (hasAuthor()) { + hash = 61 * hash + 13 * this.author.hashCode(); + } + if (hasPages()) { + hash = 61 * hash + 17 * this.pages.hashCode(); + } + return original != hash ? CraftMetaBook.class.hashCode() ^ hash : hash; + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaBook) { + CraftMetaBook that = (CraftMetaBook) meta; + + return (hasTitle() ? that.hasTitle() && this.title.equals(that.title) : !that.hasTitle()) + && (hasAuthor() ? that.hasAuthor() && this.author.equals(that.author) : !that.hasAuthor()) + && (hasPages() ? that.hasPages() && this.pages.equals(that.pages) : !that.hasPages()); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaBook || isBookEmpty()); + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + if (hasTitle()) { + builder.put(BOOK_TITLE.BUKKIT, title); + } + + if (hasAuthor()) { + builder.put(BOOK_AUTHOR.BUKKIT, author); + } + + if (hasPages()) { + List pagesString = new ArrayList(); + for (IChatBaseComponent comp : pages) { + pagesString.add(CraftChatMessage.fromComponent(comp)); + } + builder.put(BOOK_PAGES.BUKKIT, pagesString); + } + + if (generation != null) { + builder.put(GENERATION.BUKKIT, generation); + } + + return builder; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java new file mode 100644 index 0000000..ae3341c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java @@ -0,0 +1,136 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; + +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.inventory.meta.BookMeta; + +import com.google.common.collect.ImmutableMap.Builder; +import net.minecraft.server.IChatBaseComponent.ChatSerializer; +import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.NBTTagString; +import org.bukkit.craftbukkit.util.CraftChatMessage; + +@DelegateDeserialization(SerializableMeta.class) +class CraftMetaBookSigned extends CraftMetaBook implements BookMeta { + + CraftMetaBookSigned(CraftMetaItem meta) { + super(meta); + } + + CraftMetaBookSigned(NBTTagCompound tag) { + super(tag, false); + + boolean resolved = true; + if (tag.hasKey(RESOLVED.NBT)) { + resolved = tag.getBoolean(RESOLVED.NBT); + } + + if (tag.hasKey(BOOK_PAGES.NBT)) { + NBTTagList pages = tag.getList(BOOK_PAGES.NBT, 8); + + for (int i = 0; i < pages.size(); i++) { + String page = pages.getString(i); + if (resolved) { + try { + this.pages.add(ChatSerializer.a(page)); + continue; + } catch (Exception e) { + // Ignore and treat as an old book + } + } + addPage(page); + } + } + } + + CraftMetaBookSigned(Map map) { + super(map); + } + + @Override + void applyToItem(NBTTagCompound itemData) { + super.applyToItem(itemData, false); + + if (hasTitle()) { + itemData.setString(BOOK_TITLE.NBT, this.title); + } else { + itemData.setString(BOOK_TITLE.NBT, " "); + } + + if (hasAuthor()) { + itemData.setString(BOOK_AUTHOR.NBT, this.author); + } else { + itemData.setString(BOOK_AUTHOR.NBT, " "); + } + + if (hasPages()) { + NBTTagList list = new NBTTagList(); + for (IChatBaseComponent page : pages) { + list.add(new NBTTagString( + ChatSerializer.a(page) + )); + } + itemData.set(BOOK_PAGES.NBT, list); + } + itemData.setBoolean(RESOLVED.NBT, true); + + if (generation != null) { + itemData.setInt(GENERATION.NBT, generation); + } else { + itemData.setInt(GENERATION.NBT, 0); + } + } + + @Override + boolean isEmpty() { + return super.isEmpty(); + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case WRITTEN_BOOK: + case BOOK_AND_QUILL: + return true; + default: + return false; + } + } + + @Override + public CraftMetaBookSigned clone() { + CraftMetaBookSigned meta = (CraftMetaBookSigned) super.clone(); + return meta; + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + return original != hash ? CraftMetaBookSigned.class.hashCode() ^ hash : hash; + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + return super.equalsCommon(meta); + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaBookSigned || isBookEmpty()); + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + return builder; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java new file mode 100644 index 0000000..6c6fde7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java @@ -0,0 +1,131 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Map; + +import net.minecraft.server.NBTTagCompound; + +import org.bukkit.FireworkEffect; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.inventory.meta.FireworkEffectMeta; + +import com.google.common.collect.ImmutableMap.Builder; + +@DelegateDeserialization(SerializableMeta.class) +class CraftMetaCharge extends CraftMetaItem implements FireworkEffectMeta { + static final ItemMetaKey EXPLOSION = new ItemMetaKey("Explosion", "firework-effect"); + + private FireworkEffect effect; + + CraftMetaCharge(CraftMetaItem meta) { + super(meta); + + if (meta instanceof CraftMetaCharge) { + effect = ((CraftMetaCharge) meta).effect; + } + } + + CraftMetaCharge(Map map) { + super(map); + + setEffect(SerializableMeta.getObject(FireworkEffect.class, map, EXPLOSION.BUKKIT, true)); + } + + CraftMetaCharge(NBTTagCompound tag) { + super(tag); + + if (tag.hasKey(EXPLOSION.NBT)) { + effect = CraftMetaFirework.getEffect(tag.getCompound(EXPLOSION.NBT)); + } + } + + @Override + public void setEffect(FireworkEffect effect) { + this.effect = effect; + } + + @Override + public boolean hasEffect() { + return effect != null; + } + + @Override + public FireworkEffect getEffect() { + return effect; + } + + @Override + void applyToItem(NBTTagCompound itemTag) { + super.applyToItem(itemTag); + + if (hasEffect()) { + itemTag.set(EXPLOSION.NBT, CraftMetaFirework.getExplosion(effect)); + } + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case FIREWORK_CHARGE: + return true; + default: + return false; + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && !hasChargeMeta(); + } + + boolean hasChargeMeta() { + return hasEffect(); + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaCharge) { + CraftMetaCharge that = (CraftMetaCharge) meta; + + return (hasEffect() ? that.hasEffect() && this.effect.equals(that.effect) : !that.hasEffect()); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaCharge || !hasChargeMeta()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + + if (hasEffect()) { + hash = 61 * hash + effect.hashCode(); + } + + return hash != original ? CraftMetaCharge.class.hashCode() ^ hash : hash; + } + + @Override + public CraftMetaCharge clone() { + return (CraftMetaCharge) super.clone(); + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + if (hasEffect()) { + builder.put(EXPLOSION.BUKKIT, effect); + } + + return builder; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java new file mode 100644 index 0000000..8d44e55 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java @@ -0,0 +1,168 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.HashMap; +import java.util.Map; + +import net.minecraft.server.NBTTagCompound; + +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; + +@DelegateDeserialization(SerializableMeta.class) +class CraftMetaEnchantedBook extends CraftMetaItem implements EnchantmentStorageMeta { + static final ItemMetaKey STORED_ENCHANTMENTS = new ItemMetaKey("StoredEnchantments", "stored-enchants"); + + private Map enchantments; + + CraftMetaEnchantedBook(CraftMetaItem meta) { + super(meta); + + if (!(meta instanceof CraftMetaEnchantedBook)) { + return; + } + + CraftMetaEnchantedBook that = (CraftMetaEnchantedBook) meta; + + if (that.hasEnchants()) { + this.enchantments = new HashMap(that.enchantments); + } + } + + CraftMetaEnchantedBook(NBTTagCompound tag) { + super(tag); + + if (!tag.hasKey(STORED_ENCHANTMENTS.NBT)) { + return; + } + + enchantments = buildEnchantments(tag, STORED_ENCHANTMENTS); + } + + CraftMetaEnchantedBook(Map map) { + super(map); + + enchantments = buildEnchantments(map, STORED_ENCHANTMENTS); + } + + @Override + void applyToItem(NBTTagCompound itemTag) { + super.applyToItem(itemTag); + + applyEnchantments(enchantments, itemTag, STORED_ENCHANTMENTS); + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case ENCHANTED_BOOK: + return true; + default: + return false; + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isEnchantedEmpty(); + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaEnchantedBook) { + CraftMetaEnchantedBook that = (CraftMetaEnchantedBook) meta; + + return (hasStoredEnchants() ? that.hasStoredEnchants() && this.enchantments.equals(that.enchantments) : !that.hasStoredEnchants()); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaEnchantedBook || isEnchantedEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + + if (hasStoredEnchants()) { + hash = 61 * hash + enchantments.hashCode(); + } + + return original != hash ? CraftMetaEnchantedBook.class.hashCode() ^ hash : hash; + } + + @Override + public CraftMetaEnchantedBook clone() { + CraftMetaEnchantedBook meta = (CraftMetaEnchantedBook) super.clone(); + + if (this.enchantments != null) { + meta.enchantments = new HashMap(this.enchantments); + } + + return meta; + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + serializeEnchantments(enchantments, builder, STORED_ENCHANTMENTS); + + return builder; + } + + boolean isEnchantedEmpty() { + return !hasStoredEnchants(); + } + + public boolean hasStoredEnchant(Enchantment ench) { + return hasStoredEnchants() && enchantments.containsKey(ench); + } + + public int getStoredEnchantLevel(Enchantment ench) { + Integer level = hasStoredEnchants() ? enchantments.get(ench) : null; + if (level == null) { + return 0; + } + return level; + } + + public Map getStoredEnchants() { + return hasStoredEnchants() ? ImmutableMap.copyOf(enchantments) : ImmutableMap.of(); + } + + public boolean addStoredEnchant(Enchantment ench, int level, boolean ignoreRestrictions) { + if (enchantments == null) { + enchantments = new HashMap(4); + } + + if (ignoreRestrictions || level >= ench.getStartLevel() && level <= ench.getMaxLevel()) { + Integer old = enchantments.put(ench, level); + return old == null || old != level; + } + return false; + } + + public boolean removeStoredEnchant(Enchantment ench) { + return hasStoredEnchants() && enchantments.remove(ench) != null; + } + + public boolean hasStoredEnchants() { + return !(enchantments == null || enchantments.isEmpty()); + } + + public boolean hasConflictingStoredEnchant(Enchantment ench) { + return checkConflictingEnchants(enchantments, ench); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java new file mode 100644 index 0000000..5a409ae --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java @@ -0,0 +1,386 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; + +import org.apache.commons.lang.Validate; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.ItemMetaKey.Specific; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.ItemMetaKey.Specific.To; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.inventory.meta.FireworkMeta; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap.Builder; + +@DelegateDeserialization(SerializableMeta.class) +class CraftMetaFirework extends CraftMetaItem implements FireworkMeta { + /* + "Fireworks", "Explosion", "Explosions", "Flight", "Type", "Trail", "Flicker", "Colors", "FadeColors"; + + Fireworks + - Compound: Fireworks + -- Byte: Flight + -- List: Explosions + --- Compound: Explosion + ---- IntArray: Colors + ---- Byte: Type + ---- Boolean: Trail + ---- Boolean: Flicker + ---- IntArray: FadeColors + */ + + @Specific(To.NBT) + static final ItemMetaKey FIREWORKS = new ItemMetaKey("Fireworks"); + static final ItemMetaKey FLIGHT = new ItemMetaKey("Flight", "power"); + static final ItemMetaKey EXPLOSIONS = new ItemMetaKey("Explosions", "firework-effects"); + @Specific(To.NBT) + static final ItemMetaKey EXPLOSION_COLORS = new ItemMetaKey("Colors"); + @Specific(To.NBT) + static final ItemMetaKey EXPLOSION_TYPE = new ItemMetaKey("Type"); + @Specific(To.NBT) + static final ItemMetaKey EXPLOSION_TRAIL = new ItemMetaKey("Trail"); + @Specific(To.NBT) + static final ItemMetaKey EXPLOSION_FLICKER = new ItemMetaKey("Flicker"); + @Specific(To.NBT) + static final ItemMetaKey EXPLOSION_FADE = new ItemMetaKey("FadeColors"); + + private List effects; + private int power; + + CraftMetaFirework(CraftMetaItem meta) { + super(meta); + + if (!(meta instanceof CraftMetaFirework)) { + return; + } + + CraftMetaFirework that = (CraftMetaFirework) meta; + + this.power = that.power; + + if (that.hasEffects()) { + this.effects = new ArrayList(that.effects); + } + } + + CraftMetaFirework(NBTTagCompound tag) { + super(tag); + + if (!tag.hasKey(FIREWORKS.NBT)) { + return; + } + + NBTTagCompound fireworks = tag.getCompound(FIREWORKS.NBT); + + power = 0xff & fireworks.getByte(FLIGHT.NBT); + + if (!fireworks.hasKey(EXPLOSIONS.NBT)) { + return; + } + + NBTTagList fireworkEffects = fireworks.getList(EXPLOSIONS.NBT, 10); + List effects = this.effects = new ArrayList(fireworkEffects.size()); + + for (int i = 0; i < fireworkEffects.size(); i++) { + effects.add(getEffect((NBTTagCompound) fireworkEffects.get(i))); + } + } + + static FireworkEffect getEffect(NBTTagCompound explosion) { + FireworkEffect.Builder effect = FireworkEffect.builder() + .flicker(explosion.getBoolean(EXPLOSION_FLICKER.NBT)) + .trail(explosion.getBoolean(EXPLOSION_TRAIL.NBT)) + .with(getEffectType(0xff & explosion.getByte(EXPLOSION_TYPE.NBT))); + + for (int color : explosion.getIntArray(EXPLOSION_COLORS.NBT)) { + effect.withColor(Color.fromRGB(color)); + } + + for (int color : explosion.getIntArray(EXPLOSION_FADE.NBT)) { + effect.withFade(Color.fromRGB(color)); + } + + return effect.build(); + } + + static NBTTagCompound getExplosion(FireworkEffect effect) { + NBTTagCompound explosion = new NBTTagCompound(); + + if (effect.hasFlicker()) { + explosion.setBoolean(EXPLOSION_FLICKER.NBT, true); + } + + if (effect.hasTrail()) { + explosion.setBoolean(EXPLOSION_TRAIL.NBT, true); + } + + addColors(explosion, EXPLOSION_COLORS, effect.getColors()); + addColors(explosion, EXPLOSION_FADE, effect.getFadeColors()); + + explosion.setByte(EXPLOSION_TYPE.NBT, (byte) getNBT(effect.getType())); + + return explosion; + } + + static int getNBT(Type type) { + switch (type) { + case BALL: + return 0; + case BALL_LARGE: + return 1; + case STAR: + return 2; + case CREEPER: + return 3; + case BURST: + return 4; + default: + throw new IllegalStateException(type.toString()); // Spigot + } + } + + static Type getEffectType(int nbt) { + switch (nbt) { + case 0: + return Type.BALL; + case 1: + return Type.BALL_LARGE; + case 2: + return Type.STAR; + case 3: + return Type.CREEPER; + case 4: + return Type.BURST; + default: + throw new IllegalStateException(Integer.toString(nbt)); // Spigot + } + } + + CraftMetaFirework(Map map) { + super(map); + + Integer power = SerializableMeta.getObject(Integer.class, map, FLIGHT.BUKKIT, true); + if (power != null) { + setPower(power); + } + + Iterable effects = SerializableMeta.getObject(Iterable.class, map, EXPLOSIONS.BUKKIT, true); + safelyAddEffects(effects); + } + + public boolean hasEffects() { + return !(effects == null || effects.isEmpty()); + } + + void safelyAddEffects(Iterable collection) { + if (collection == null || (collection instanceof Collection && ((Collection) collection).isEmpty())) { + return; + } + + List effects = this.effects; + if (effects == null) { + effects = this.effects = new ArrayList(); + } + + for (Object obj : collection) { + if (obj instanceof FireworkEffect) { + effects.add((FireworkEffect) obj); + } else { + throw new IllegalArgumentException(obj + " in " + collection + " is not a FireworkEffect"); + } + } + } + + @Override + void applyToItem(NBTTagCompound itemTag) { + super.applyToItem(itemTag); + if (isFireworkEmpty()) { + return; + } + + NBTTagCompound fireworks = itemTag.getCompound(FIREWORKS.NBT); + itemTag.set(FIREWORKS.NBT, fireworks); + + if (hasEffects()) { + NBTTagList effects = new NBTTagList(); + for (FireworkEffect effect : this.effects) { + effects.add(getExplosion(effect)); + } + + if (effects.size() > 0) { + fireworks.set(EXPLOSIONS.NBT, effects); + } + } + + if (hasPower()) { + fireworks.setByte(FLIGHT.NBT, (byte) power); + } + } + + static void addColors(NBTTagCompound compound, ItemMetaKey key, List colors) { + if (colors.isEmpty()) { + return; + } + + final int[] colorArray = new int[colors.size()]; + int i = 0; + for (Color color : colors) { + colorArray[i++] = color.asRGB(); + } + + compound.setIntArray(key.NBT, colorArray); + } + + @Override + boolean applicableTo(Material type) { + switch(type) { + case FIREWORK: + return true; + default: + return false; + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isFireworkEmpty(); + } + + boolean isFireworkEmpty() { + return !(hasEffects() || hasPower()); + } + + boolean hasPower() { + return power != 0; + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + + if (meta instanceof CraftMetaFirework) { + CraftMetaFirework that = (CraftMetaFirework) meta; + + return (hasPower() ? that.hasPower() && this.power == that.power : !that.hasPower()) + && (hasEffects() ? that.hasEffects() && this.effects.equals(that.effects) : !that.hasEffects()); + } + + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaFirework || isFireworkEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (hasPower()) { + hash = 61 * hash + power; + } + if (hasEffects()) { + hash = 61 * hash + 13 * effects.hashCode(); + } + return hash != original ? CraftMetaFirework.class.hashCode() ^ hash : hash; + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + if (hasEffects()) { + builder.put(EXPLOSIONS.BUKKIT, ImmutableList.copyOf(effects)); + } + + if (hasPower()) { + builder.put(FLIGHT.BUKKIT, power); + } + + return builder; + } + + @Override + public CraftMetaFirework clone() { + CraftMetaFirework meta = (CraftMetaFirework) super.clone(); + + if (this.effects != null) { + meta.effects = new ArrayList(this.effects); + } + + return meta; + } + + public void addEffect(FireworkEffect effect) { + Validate.notNull(effect, "Effect cannot be null"); + if (this.effects == null) { + this.effects = new ArrayList(); + } + this.effects.add(effect); + } + + public void addEffects(FireworkEffect...effects) { + Validate.notNull(effects, "Effects cannot be null"); + if (effects.length == 0) { + return; + } + + List list = this.effects; + if (list == null) { + list = this.effects = new ArrayList(); + } + + for (FireworkEffect effect : effects) { + Validate.notNull(effect, "Effect cannot be null"); + list.add(effect); + } + } + + public void addEffects(Iterable effects) { + Validate.notNull(effects, "Effects cannot be null"); + safelyAddEffects(effects); + } + + public List getEffects() { + return this.effects == null ? ImmutableList.of() : ImmutableList.copyOf(this.effects); + } + + public int getEffectsSize() { + return this.effects == null ? 0 : this.effects.size(); + } + + public void removeEffect(int index) { + if (this.effects == null) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: 0"); + } else { + this.effects.remove(index); + } + } + + public void clearEffects() { + this.effects = null; + } + + public int getPower() { + return this.power; + } + + public void setPower(int power) { + Validate.isTrue(power >= 0, "Power cannot be less than zero: ", power); + Validate.isTrue(power < 0x80, "Power cannot be more than 127: ", power); + this.power = power; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java new file mode 100644 index 0000000..eaaa6a1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -0,0 +1,1017 @@ +package org.bukkit.craftbukkit.inventory; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import net.minecraft.server.NBTBase; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; +import net.minecraft.server.NBTTagString; + +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.configuration.serialization.SerializableAs; +import org.bukkit.craftbukkit.Overridden; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.ItemMetaKey.Specific; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.Repairable; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.minecraft.server.NBTCompressedStreamTools; +import org.apache.commons.codec.binary.Base64; + +// Spigot start +import static org.spigotmc.ValidateUtils.*; +import net.minecraft.server.GenericAttributes; +import net.minecraft.server.IAttribute; +// Spigot end + +/** + * Children must include the following: + * + *
  • Constructor(CraftMetaItem meta) + *
  • Constructor(NBTTagCompound tag) + *
  • Constructor(Map map) + *

    + *
  • void applyToItem(NBTTagCompound tag) + *
  • boolean applicableTo(Material type) + *

    + *
  • boolean equalsCommon(CraftMetaItem meta) + *
  • boolean notUncommon(CraftMetaItem meta) + *

    + *
  • boolean isEmpty() + *
  • boolean is{Type}Empty() + *

    + *
  • int applyHash() + *
  • public Class clone() + *

    + *
  • Builder serialize(Builder builder) + *
  • SerializableMeta.Deserializers deserializer() + */ +@DelegateDeserialization(CraftMetaItem.SerializableMeta.class) +class CraftMetaItem implements ItemMeta, Repairable { + + static class ItemMetaKey { + + @Retention(RetentionPolicy.SOURCE) + @Target(ElementType.FIELD) + @interface Specific { + enum To { + BUKKIT, + NBT, + ; + } + To value(); + } + + final String BUKKIT; + final String NBT; + + ItemMetaKey(final String both) { + this(both, both); + } + + ItemMetaKey(final String nbt, final String bukkit) { + this.NBT = nbt; + this.BUKKIT = bukkit; + } + } + + @SerializableAs("ItemMeta") + public static class SerializableMeta implements ConfigurationSerializable { + static final String TYPE_FIELD = "meta-type"; + + static final ImmutableMap, String> classMap; + static final ImmutableMap> constructorMap; + + static { + classMap = ImmutableMap., String>builder() + .put(CraftMetaBanner.class, "BANNER") + .put(CraftMetaBlockState.class, "TILE_ENTITY") + .put(CraftMetaBook.class, "BOOK") + .put(CraftMetaBookSigned.class, "BOOK_SIGNED") + .put(CraftMetaSkull.class, "SKULL") + .put(CraftMetaLeatherArmor.class, "LEATHER_ARMOR") + .put(CraftMetaMap.class, "MAP") + .put(CraftMetaPotion.class, "POTION") + .put(CraftMetaEnchantedBook.class, "ENCHANTED") + .put(CraftMetaFirework.class, "FIREWORK") + .put(CraftMetaCharge.class, "FIREWORK_EFFECT") + .put(CraftMetaItem.class, "UNSPECIFIC") + .build(); + + final ImmutableMap.Builder> classConstructorBuilder = ImmutableMap.builder(); + for (Map.Entry, String> mapping : classMap.entrySet()) { + try { + classConstructorBuilder.put(mapping.getValue(), mapping.getKey().getDeclaredConstructor(Map.class)); + } catch (NoSuchMethodException e) { + throw new AssertionError(e); + } + } + constructorMap = classConstructorBuilder.build(); + } + + private SerializableMeta() { + } + + public static ItemMeta deserialize(Map map) throws Throwable { + Validate.notNull(map, "Cannot deserialize null map"); + + String type = getString(map, TYPE_FIELD, false); + Constructor constructor = constructorMap.get(type); + + if (constructor == null) { + throw new IllegalArgumentException(type + " is not a valid " + TYPE_FIELD); + } + + try { + return constructor.newInstance(map); + } catch (final InstantiationException e) { + throw new AssertionError(e); + } catch (final IllegalAccessException e) { + throw new AssertionError(e); + } catch (final InvocationTargetException e) { + throw e.getCause(); + } + } + + public Map serialize() { + throw new AssertionError(); + } + + static String getString(Map map, Object field, boolean nullable) { + return getObject(String.class, map, field, nullable); + } + + static boolean getBoolean(Map map, Object field) { + Boolean value = getObject(Boolean.class, map, field, true); + return value != null && value; + } + + static T getObject(Class clazz, Map map, Object field, boolean nullable) { + final Object object = map.get(field); + + if (clazz.isInstance(object)) { + return clazz.cast(object); + } + if (object == null) { + if (!nullable) { + throw new NoSuchElementException(map + " does not contain " + field); + } + return null; + } + throw new IllegalArgumentException(field + "(" + object + ") is not a valid " + clazz); + } + } + + static final ItemMetaKey NAME = new ItemMetaKey("Name", "display-name"); + @Specific(Specific.To.NBT) + static final ItemMetaKey DISPLAY = new ItemMetaKey("display"); + static final ItemMetaKey LORE = new ItemMetaKey("Lore", "lore"); + static final ItemMetaKey ENCHANTMENTS = new ItemMetaKey("ench", "enchants"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ENCHANTMENTS_ID = new ItemMetaKey("id"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ENCHANTMENTS_LVL = new ItemMetaKey("lvl"); + static final ItemMetaKey REPAIR = new ItemMetaKey("RepairCost", "repair-cost"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ATTRIBUTES = new ItemMetaKey("AttributeModifiers"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ATTRIBUTES_IDENTIFIER = new ItemMetaKey("AttributeName"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ATTRIBUTES_NAME = new ItemMetaKey("Name"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ATTRIBUTES_VALUE = new ItemMetaKey("Amount"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ATTRIBUTES_TYPE = new ItemMetaKey("Operation"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ATTRIBUTES_UUID_HIGH = new ItemMetaKey("UUIDMost"); + @Specific(Specific.To.NBT) + static final ItemMetaKey ATTRIBUTES_UUID_LOW = new ItemMetaKey("UUIDLeast"); + @Specific(Specific.To.NBT) + static final ItemMetaKey HIDEFLAGS = new ItemMetaKey("HideFlags", "ItemFlags"); + @Specific(Specific.To.NBT) + static final ItemMetaKey UNBREAKABLE = new ItemMetaKey("Unbreakable"); // Spigot + + private String displayName; + private List lore; + private Map enchantments; + private int repairCost; + private int hideFlag; + + private static final Set HANDLED_TAGS = Sets.newHashSet(); + + private final Map unhandledTags = new HashMap(); + + CraftMetaItem(CraftMetaItem meta) { + if (meta == null) { + return; + } + + this.displayName = meta.displayName; + + if (meta.hasLore()) { + this.lore = new ArrayList(meta.lore); + } + + if (meta.enchantments != null) { // Spigot + this.enchantments = new HashMap(meta.enchantments); + } + + this.repairCost = meta.repairCost; + this.hideFlag = meta.hideFlag; + this.unhandledTags.putAll(meta.unhandledTags); + spigot.setUnbreakable( meta.spigot.isUnbreakable() ); // Spigot + } + + CraftMetaItem(NBTTagCompound tag) { + if (tag.hasKey(DISPLAY.NBT)) { + NBTTagCompound display = tag.getCompound(DISPLAY.NBT); + + if (display.hasKey(NAME.NBT)) { + displayName = limit( display.getString(NAME.NBT), 1024 ); // Spigot + } + + if (display.hasKey(LORE.NBT)) { + NBTTagList list = display.getList(LORE.NBT, 8); + lore = new ArrayList(list.size()); + + for (int index = 0; index < list.size(); index++) { + String line = limit( list.getString(index), 1024 ); // Spigot + lore.add(line); + } + } + } + + this.enchantments = buildEnchantments(tag, ENCHANTMENTS); + + if (tag.hasKey(REPAIR.NBT)) { + repairCost = tag.getInt(REPAIR.NBT); + } + + if (tag.hasKey(HIDEFLAGS.NBT)) { + hideFlag = tag.getInt(HIDEFLAGS.NBT); + } + + if (tag.get(ATTRIBUTES.NBT) instanceof NBTTagList) { + NBTTagList save = null; + NBTTagList nbttaglist = tag.getList(ATTRIBUTES.NBT, 10); + + // Spigot start + gnu.trove.map.hash.TObjectDoubleHashMap attributeTracker = new gnu.trove.map.hash.TObjectDoubleHashMap(); + gnu.trove.map.hash.TObjectDoubleHashMap attributeTrackerX = new gnu.trove.map.hash.TObjectDoubleHashMap(); + Map attributesByName = new HashMap(); + attributeTracker.put( "generic.maxHealth", 20.0 ); + attributesByName.put( "generic.maxHealth", GenericAttributes.maxHealth ); + attributeTracker.put( "generic.followRange", 32.0 ); + attributesByName.put( "generic.followRange", GenericAttributes.FOLLOW_RANGE ); + attributeTracker.put( "generic.knockbackResistance", 0.0 ); + attributesByName.put( "generic.knockbackResistance", GenericAttributes.c ); + attributeTracker.put( "generic.movementSpeed", 0.7 ); + attributesByName.put( "generic.movementSpeed", GenericAttributes.MOVEMENT_SPEED ); + attributeTracker.put( "generic.attackDamage", 1.0 ); + attributesByName.put( "generic.attackDamage", GenericAttributes.ATTACK_DAMAGE ); + NBTTagList oldList = nbttaglist; + nbttaglist = new NBTTagList(); + + List op0 = new ArrayList(); + List op1 = new ArrayList(); + List op2 = new ArrayList(); + + for ( int i = 0; i < oldList.size(); ++i ) + { + NBTTagCompound nbttagcompound = oldList.get( i ); + if ( nbttagcompound == null ) continue; + + if ( !nbttagcompound.hasKeyOfType(ATTRIBUTES_UUID_HIGH.NBT, 99) ) + { + continue; + } + if ( !nbttagcompound.hasKeyOfType(ATTRIBUTES_UUID_LOW.NBT, 99) ) + { + continue; + } + if ( !( nbttagcompound.get( ATTRIBUTES_IDENTIFIER.NBT ) instanceof NBTTagString ) || !CraftItemFactory.KNOWN_NBT_ATTRIBUTE_NAMES.contains( nbttagcompound.getString( ATTRIBUTES_IDENTIFIER.NBT ) ) ) + { + continue; + } + if ( !( nbttagcompound.get( ATTRIBUTES_NAME.NBT ) instanceof NBTTagString ) || nbttagcompound.getString( ATTRIBUTES_NAME.NBT ).isEmpty() ) + { + continue; + } + if ( !nbttagcompound.hasKeyOfType(ATTRIBUTES_VALUE.NBT, 99) ) + { + continue; + } + if ( !nbttagcompound.hasKeyOfType(ATTRIBUTES_TYPE.NBT, 99) || nbttagcompound.getInt( ATTRIBUTES_TYPE.NBT ) < 0 || nbttagcompound.getInt( ATTRIBUTES_TYPE.NBT ) > 2 ) + { + continue; + } + + switch ( nbttagcompound.getInt( ATTRIBUTES_TYPE.NBT ) ) + { + case 0: + op0.add( nbttagcompound ); + break; + case 1: + op1.add( nbttagcompound ); + break; + case 2: + op2.add( nbttagcompound ); + break; + } + } + for ( NBTTagCompound nbtTagCompound : op0 ) + { + String name = nbtTagCompound.getString( ATTRIBUTES_IDENTIFIER.NBT ); + if ( attributeTracker.containsKey( name ) ) + { + double val = attributeTracker.get( name ); + val += nbtTagCompound.getDouble( ATTRIBUTES_VALUE.NBT ); + if ( val != attributesByName.get( name ).a( val ) ) + { + continue; + } + attributeTracker.put( name, val ); + } + nbttaglist.add( nbtTagCompound ); + } + for ( String name : attributeTracker.keySet() ) + { + attributeTrackerX.put( name, attributeTracker.get( name ) ); + } + for ( NBTTagCompound nbtTagCompound : op1 ) + { + String name = nbtTagCompound.getString( ATTRIBUTES_IDENTIFIER.NBT ); + if ( attributeTracker.containsKey( name ) ) + { + double val = attributeTracker.get( name ); + double valX = attributeTrackerX.get( name ); + val += valX * nbtTagCompound.getDouble( ATTRIBUTES_VALUE.NBT ); + if ( val != attributesByName.get( name ).a( val ) ) + { + continue; + } + attributeTracker.put( name, val ); + } + nbttaglist.add( nbtTagCompound ); + } + for ( NBTTagCompound nbtTagCompound : op2 ) + { + String name = nbtTagCompound.getString( ATTRIBUTES_IDENTIFIER.NBT ); + if ( attributeTracker.containsKey( name ) ) + { + double val = attributeTracker.get( name ); + val += val * nbtTagCompound.getDouble( ATTRIBUTES_VALUE.NBT ); + if ( val != attributesByName.get( name ).a( val ) ) + { + continue; + } + attributeTracker.put( name, val ); + } + nbttaglist.add( nbtTagCompound ); + } + + // Spigot end + + for (int i = 0; i < nbttaglist.size(); ++i) { + if (!(nbttaglist.get(i) instanceof NBTTagCompound)) { + continue; + } + NBTTagCompound nbttagcompound = (NBTTagCompound) nbttaglist.get(i); + + if (!nbttagcompound.hasKeyOfType(ATTRIBUTES_UUID_HIGH.NBT, 99)) { + continue; + } + if (!nbttagcompound.hasKeyOfType(ATTRIBUTES_UUID_LOW.NBT, 99)) { + continue; + } + if (!(nbttagcompound.get(ATTRIBUTES_IDENTIFIER.NBT) instanceof NBTTagString) || !CraftItemFactory.KNOWN_NBT_ATTRIBUTE_NAMES.contains(nbttagcompound.getString(ATTRIBUTES_IDENTIFIER.NBT))) { + continue; + } + if (!(nbttagcompound.get(ATTRIBUTES_NAME.NBT) instanceof NBTTagString) || nbttagcompound.getString(ATTRIBUTES_NAME.NBT).isEmpty()) { + continue; + } + if (!nbttagcompound.hasKeyOfType(ATTRIBUTES_VALUE.NBT, 99)) { + continue; + } + if (!nbttagcompound.hasKeyOfType(ATTRIBUTES_TYPE.NBT, 99) || nbttagcompound.getInt(ATTRIBUTES_TYPE.NBT) < 0 || nbttagcompound.getInt(ATTRIBUTES_TYPE.NBT) > 2) { + continue; + } + + if (save == null) { + save = new NBTTagList(); + } + + NBTTagCompound entry = new NBTTagCompound(); + entry.set(ATTRIBUTES_UUID_HIGH.NBT, nbttagcompound.get(ATTRIBUTES_UUID_HIGH.NBT)); + entry.set(ATTRIBUTES_UUID_LOW.NBT, nbttagcompound.get(ATTRIBUTES_UUID_LOW.NBT)); + entry.set(ATTRIBUTES_IDENTIFIER.NBT, nbttagcompound.get(ATTRIBUTES_IDENTIFIER.NBT)); + entry.set(ATTRIBUTES_NAME.NBT, nbttagcompound.get(ATTRIBUTES_NAME.NBT)); + entry.set(ATTRIBUTES_VALUE.NBT, nbttagcompound.get(ATTRIBUTES_VALUE.NBT)); + entry.set(ATTRIBUTES_TYPE.NBT, nbttagcompound.get(ATTRIBUTES_TYPE.NBT)); + save.add(entry); + } + + unhandledTags.put(ATTRIBUTES.NBT, save); + } + + Set keys = tag.c(); + for (String key : keys) { + if (!getHandledTags().contains(key)) { + unhandledTags.put(key, tag.get(key)); + } + } + // Spigot start + if ( tag.hasKey( UNBREAKABLE.NBT ) ) + { + spigot.setUnbreakable( tag.getBoolean( UNBREAKABLE.NBT ) ); + } + // Spigot end + } + + static Map buildEnchantments(NBTTagCompound tag, ItemMetaKey key) { + if (!tag.hasKey(key.NBT)) { + return null; + } + + NBTTagList ench = tag.getList(key.NBT, 10); + Map enchantments = new HashMap(ench.size()); + + for (int i = 0; i < ench.size(); i++) { + int id = 0xffff & ((NBTTagCompound) ench.get(i)).getShort(ENCHANTMENTS_ID.NBT); + int level = 0xffff & ((NBTTagCompound) ench.get(i)).getShort(ENCHANTMENTS_LVL.NBT); + + // Spigot start - skip invalid enchantments + Enchantment e = Enchantment.getById(id); + if (e == null) continue; + // Spigot end + enchantments.put(e, level); + } + + return enchantments; + } + + CraftMetaItem(Map map) { + setDisplayName(SerializableMeta.getString(map, NAME.BUKKIT, true)); + + Iterable lore = SerializableMeta.getObject(Iterable.class, map, LORE.BUKKIT, true); + if (lore != null) { + safelyAdd(lore, this.lore = new ArrayList(), Integer.MAX_VALUE); + } + + enchantments = buildEnchantments(map, ENCHANTMENTS); + + Integer repairCost = SerializableMeta.getObject(Integer.class, map, REPAIR.BUKKIT, true); + if (repairCost != null) { + setRepairCost(repairCost); + } + + Set hideFlags = SerializableMeta.getObject(Set.class, map, HIDEFLAGS.BUKKIT, true); + if (hideFlags != null) { + for (Object hideFlagObject : hideFlags) { + String hideFlagString = (String) hideFlagObject; + try { + ItemFlag hideFlatEnum = ItemFlag.valueOf(hideFlagString); + addItemFlags(hideFlatEnum); + } catch (IllegalArgumentException ex) { + // Ignore when we got a old String which does not map to a Enum value anymore + } + } + } + + // Spigot start + Boolean unbreakable = SerializableMeta.getObject( Boolean.class, map, UNBREAKABLE.BUKKIT, true ); + if ( unbreakable != null ) + { + spigot.setUnbreakable( unbreakable ); + } + // Spigot end + + String internal = SerializableMeta.getString(map, "internal", true); + if (internal != null) { + ByteArrayInputStream buf = new ByteArrayInputStream(Base64.decodeBase64(internal)); + try { + NBTTagCompound tag = NBTCompressedStreamTools.a(buf); + deserializeInternal(tag); + Set keys = tag.c(); + for (String key : keys) { + if (!getHandledTags().contains(key)) { + unhandledTags.put(key, tag.get(key)); + } + } + } catch (IOException ex) { + Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + + void deserializeInternal(NBTTagCompound tag) { + } + + static Map buildEnchantments(Map map, ItemMetaKey key) { + Map ench = SerializableMeta.getObject(Map.class, map, key.BUKKIT, true); + if (ench == null) { + return null; + } + + Map enchantments = new HashMap(ench.size()); + for (Map.Entry entry : ench.entrySet()) { + Enchantment enchantment = Enchantment.getByName(entry.getKey().toString()); + + if ((enchantment != null) && (entry.getValue() instanceof Integer)) { + enchantments.put(enchantment, (Integer) entry.getValue()); + } + } + + return enchantments; + } + + @Overridden + void applyToItem(NBTTagCompound itemTag) { + if (hasDisplayName()) { + setDisplayTag(itemTag, NAME.NBT, new NBTTagString(displayName)); + } + + if (hasLore()) { + setDisplayTag(itemTag, LORE.NBT, createStringList(lore)); + } + + if (hideFlag != 0) { + itemTag.setInt(HIDEFLAGS.NBT, hideFlag); + } + + applyEnchantments(enchantments, itemTag, ENCHANTMENTS); + + // Spigot start + if ( spigot.isUnbreakable() ) + { + itemTag.setBoolean( UNBREAKABLE.NBT, true ); + } + // Spigot end + + + if (hasRepairCost()) { + itemTag.setInt(REPAIR.NBT, repairCost); + } + + for (Map.Entry e : unhandledTags.entrySet()) { + itemTag.set(e.getKey(), e.getValue()); + } + } + + static NBTTagList createStringList(List list) { + if (list == null || list.isEmpty()) { + return null; + } + + NBTTagList tagList = new NBTTagList(); + for (String value : list) { + tagList.add(new NBTTagString(value)); + } + + return tagList; + } + + static void applyEnchantments(Map enchantments, NBTTagCompound tag, ItemMetaKey key) { + if (enchantments == null /*|| enchantments.size() == 0*/) { // Spigot - remove size check + return; + } + + NBTTagList list = new NBTTagList(); + + for (Map.Entry entry : enchantments.entrySet()) { + NBTTagCompound subtag = new NBTTagCompound(); + + subtag.setShort(ENCHANTMENTS_ID.NBT, (short) entry.getKey().getId()); + subtag.setShort(ENCHANTMENTS_LVL.NBT, entry.getValue().shortValue()); + + list.add(subtag); + } + + tag.set(key.NBT, list); + } + + void setDisplayTag(NBTTagCompound tag, String key, NBTBase value) { + final NBTTagCompound display = tag.getCompound(DISPLAY.NBT); + + if (!tag.hasKey(DISPLAY.NBT)) { + tag.set(DISPLAY.NBT, display); + } + + display.set(key, value); + } + + @Overridden + boolean applicableTo(Material type) { + return type != Material.AIR; + } + + @Overridden + boolean isEmpty() { + return !(hasDisplayName() || hasEnchants() || hasLore() || hasRepairCost() || !unhandledTags.isEmpty() || hideFlag != 0 || spigot.isUnbreakable()); // Spigot + } + + public String getDisplayName() { + return displayName; + } + + public final void setDisplayName(String name) { + this.displayName = name; + } + + public boolean hasDisplayName() { + return !Strings.isNullOrEmpty(displayName); + } + + public boolean hasLore() { + return this.lore != null && !this.lore.isEmpty(); + } + + public boolean hasRepairCost() { + return repairCost > 0; + } + + public boolean hasEnchant(Enchantment ench) { + return hasEnchants() && enchantments.containsKey(ench); + } + + public int getEnchantLevel(Enchantment ench) { + Integer level = hasEnchants() ? enchantments.get(ench) : null; + if (level == null) { + return 0; + } + return level; + } + + public Map getEnchants() { + return hasEnchants() ? ImmutableMap.copyOf(enchantments) : ImmutableMap.of(); + } + + public boolean addEnchant(Enchantment ench, int level, boolean ignoreRestrictions) { + if (enchantments == null) { + enchantments = new HashMap(4); + } + + if (ignoreRestrictions || level >= ench.getStartLevel() && level <= ench.getMaxLevel()) { + Integer old = enchantments.put(ench, level); + return old == null || old != level; + } + return false; + } + + public boolean removeEnchant(Enchantment ench) { + // Spigot start + boolean b = hasEnchants() && enchantments.remove( ench ) != null; + if ( enchantments != null && enchantments.isEmpty() ) + { + this.enchantments = null; + } + return b; + // Spigot end + } + + public boolean hasEnchants() { + return !(enchantments == null || enchantments.isEmpty()); + } + + public boolean hasConflictingEnchant(Enchantment ench) { + return checkConflictingEnchants(enchantments, ench); + } + + @Override + public void addItemFlags(ItemFlag... hideFlags) { + for (ItemFlag f : hideFlags) { + this.hideFlag |= getBitModifier(f); + } + } + + @Override + public void removeItemFlags(ItemFlag... hideFlags) { + for (ItemFlag f : hideFlags) { + this.hideFlag &= ~getBitModifier(f); + } + } + + @Override + public Set getItemFlags() { + Set currentFlags = EnumSet.noneOf(ItemFlag.class); + + for (ItemFlag f : ItemFlag.values()) { + if (hasItemFlag(f)) { + currentFlags.add(f); + } + } + + return currentFlags; + } + + @Override + public boolean hasItemFlag(ItemFlag flag) { + int bitModifier = getBitModifier(flag); + return (this.hideFlag & bitModifier) == bitModifier; + } + + private byte getBitModifier(ItemFlag hideFlag) { + return (byte) (1 << hideFlag.ordinal()); + } + + public List getLore() { + return this.lore == null ? null : new ArrayList(this.lore); + } + + public void setLore(List lore) { // too tired to think if .clone is better + if (lore == null) { + this.lore = null; + } else { + if (this.lore == null) { + safelyAdd(lore, this.lore = new ArrayList(lore.size()), Integer.MAX_VALUE); + } else { + this.lore.clear(); + safelyAdd(lore, this.lore, Integer.MAX_VALUE); + } + } + } + + public int getRepairCost() { + return repairCost; + } + + public void setRepairCost(int cost) { // TODO: Does this have limits? + repairCost = cost; + } + + @Override + public final boolean equals(Object object) { + if (object == null) { + return false; + } + if (object == this) { + return true; + } + if (!(object instanceof CraftMetaItem)) { + return false; + } + return CraftItemFactory.instance().equals(this, (ItemMeta) object); + } + + /** + * This method is almost as weird as notUncommon. + * Only return false if your common internals are unequal. + * Checking your own internals is redundant if you are not common, as notUncommon is meant for checking those 'not common' variables. + */ + @Overridden + boolean equalsCommon(CraftMetaItem that) { + return ((this.hasDisplayName() ? that.hasDisplayName() && this.displayName.equals(that.displayName) : !that.hasDisplayName())) + && (this.hasEnchants() ? that.hasEnchants() && this.enchantments.equals(that.enchantments) : !that.hasEnchants()) + && (this.hasLore() ? that.hasLore() && this.lore.equals(that.lore) : !that.hasLore()) + && (this.hasRepairCost() ? that.hasRepairCost() && this.repairCost == that.repairCost : !that.hasRepairCost()) + && (this.unhandledTags.equals(that.unhandledTags)) + && (this.hideFlag == that.hideFlag) + && (this.spigot.isUnbreakable() == that.spigot.isUnbreakable()); // Spigot + } + + /** + * This method is a bit weird... + * Return true if you are a common class OR your uncommon parts are empty. + * Empty uncommon parts implies the NBT data would be equivalent if both were applied to an item + */ + @Overridden + boolean notUncommon(CraftMetaItem meta) { + return true; + } + + @Override + public final int hashCode() { + return applyHash(); + } + + @Overridden + int applyHash() { + int hash = 3; + hash = 61 * hash + (hasDisplayName() ? this.displayName.hashCode() : 0); + hash = 61 * hash + (hasLore() ? this.lore.hashCode() : 0); + hash = 61 * hash + (hasEnchants() ? this.enchantments.hashCode() : 0); + hash = 61 * hash + (hasRepairCost() ? this.repairCost : 0); + hash = 61 * hash + unhandledTags.hashCode(); + hash = 61 * hash + hideFlag; + hash = 61 * hash + (spigot.isUnbreakable() ? 1231 : 1237); // Spigot + return hash; + } + + @Overridden + @Override + public CraftMetaItem clone() { + try { + CraftMetaItem clone = (CraftMetaItem) super.clone(); + if (this.lore != null) { + clone.lore = new ArrayList(this.lore); + } + if (this.enchantments != null) { + clone.enchantments = new HashMap(this.enchantments); + } + clone.hideFlag = this.hideFlag; + return clone; + } catch (CloneNotSupportedException e) { + throw new Error(e); + } + } + + public final Map serialize() { + ImmutableMap.Builder map = ImmutableMap.builder(); + map.put(SerializableMeta.TYPE_FIELD, SerializableMeta.classMap.get(getClass())); + serialize(map); + return map.build(); + } + + @Overridden + ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { + if (hasDisplayName()) { + builder.put(NAME.BUKKIT, displayName); + } + + if (hasLore()) { + builder.put(LORE.BUKKIT, ImmutableList.copyOf(lore)); + } + + serializeEnchantments(enchantments, builder, ENCHANTMENTS); + + if (hasRepairCost()) { + builder.put(REPAIR.BUKKIT, repairCost); + } + + // Spigot start + if ( spigot.isUnbreakable() ) + { + builder.put( UNBREAKABLE.BUKKIT, true ); + } + // Spigot end + + + Set hideFlags = new HashSet(); + for (ItemFlag hideFlagEnum : getItemFlags()) { + hideFlags.add(hideFlagEnum.name()); + } + if (!hideFlags.isEmpty()) { + builder.put(HIDEFLAGS.BUKKIT, hideFlags); + } + + final Map internalTags = new HashMap(unhandledTags); + serializeInternal(internalTags); + if (!internalTags.isEmpty()) { + NBTTagCompound internal = new NBTTagCompound(); + for (Map.Entry e : internalTags.entrySet()) { + internal.set(e.getKey(), e.getValue()); + } + try { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + NBTCompressedStreamTools.a(internal, buf); + builder.put("internal", Base64.encodeBase64String(buf.toByteArray())); + } catch (IOException ex) { + Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + } + } + + return builder; + } + + void serializeInternal(final Map unhandledTags) { + } + + static void serializeEnchantments(Map enchantments, ImmutableMap.Builder builder, ItemMetaKey key) { + if (enchantments == null || enchantments.isEmpty()) { + return; + } + + ImmutableMap.Builder enchants = ImmutableMap.builder(); + for (Map.Entry enchant : enchantments.entrySet()) { + enchants.put(enchant.getKey().getName(), enchant.getValue()); + } + + builder.put(key.BUKKIT, enchants.build()); + } + + static void safelyAdd(Iterable addFrom, Collection addTo, int maxItemLength) { + if (addFrom == null) { + return; + } + + for (Object object : addFrom) { + if (!(object instanceof String)) { + if (object != null) { + throw new IllegalArgumentException(addFrom + " cannot contain non-string " + object.getClass().getName()); + } + + addTo.add(""); + } else { + String page = object.toString(); + + if (page.length() > maxItemLength) { + page = page.substring(0, maxItemLength); + } + + addTo.add(page); + } + } + } + + static boolean checkConflictingEnchants(Map enchantments, Enchantment ench) { + if (enchantments == null || enchantments.isEmpty()) { + return false; + } + + for (Enchantment enchant : enchantments.keySet()) { + if (enchant.conflictsWith(ench)) { + return true; + } + } + + return false; + } + + @Override + public final String toString() { + return SerializableMeta.classMap.get(getClass()) + "_META:" + serialize(); // TODO: cry + } + + public static Set getHandledTags() { + synchronized (HANDLED_TAGS) { + if (HANDLED_TAGS.isEmpty()) { + HANDLED_TAGS.addAll(Arrays.asList( + UNBREAKABLE.NBT, // Spigot + DISPLAY.NBT, + REPAIR.NBT, + ENCHANTMENTS.NBT, + HIDEFLAGS.NBT, + CraftMetaMap.MAP_SCALING.NBT, + CraftMetaPotion.POTION_EFFECTS.NBT, + CraftMetaSkull.SKULL_OWNER.NBT, + CraftMetaSkull.SKULL_PROFILE.NBT, + CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT, + CraftMetaBook.BOOK_TITLE.NBT, + CraftMetaBook.BOOK_AUTHOR.NBT, + CraftMetaBook.BOOK_PAGES.NBT, + CraftMetaBook.RESOLVED.NBT, + CraftMetaBook.GENERATION.NBT, + CraftMetaFirework.FIREWORKS.NBT, + CraftMetaEnchantedBook.STORED_ENCHANTMENTS.NBT, + CraftMetaCharge.EXPLOSION.NBT, + CraftMetaBlockState.BLOCK_ENTITY_TAG.NBT + )); + } + return HANDLED_TAGS; + } + } + + // Spigot start + private final Spigot spigot = new Spigot() + { + private boolean unbreakable; + + @Override + public void setUnbreakable(boolean setUnbreakable) + { + unbreakable = setUnbreakable; + } + + @Override + public boolean isUnbreakable() + { + return unbreakable; + } + }; + + @Override + public Spigot spigot() + { + return spigot; + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java new file mode 100644 index 0000000..5478e9b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java @@ -0,0 +1,135 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.bukkit.craftbukkit.inventory.CraftItemFactory.DEFAULT_LEATHER_COLOR; + +import java.util.Map; + +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagInt; + +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; + +import com.google.common.collect.ImmutableMap.Builder; + +@DelegateDeserialization(SerializableMeta.class) +class CraftMetaLeatherArmor extends CraftMetaItem implements LeatherArmorMeta { + static final ItemMetaKey COLOR = new ItemMetaKey("color"); + + private Color color = DEFAULT_LEATHER_COLOR; + + CraftMetaLeatherArmor(CraftMetaItem meta) { + super(meta); + if (!(meta instanceof CraftMetaLeatherArmor)) { + return; + } + + CraftMetaLeatherArmor armorMeta = (CraftMetaLeatherArmor) meta; + this.color = armorMeta.color; + } + + CraftMetaLeatherArmor(NBTTagCompound tag) { + super(tag); + if (tag.hasKey(DISPLAY.NBT)) { + NBTTagCompound display = tag.getCompound(DISPLAY.NBT); + if (display.hasKey(COLOR.NBT)) { + color = Color.fromRGB(display.getInt(COLOR.NBT)); + } + } + } + + CraftMetaLeatherArmor(Map map) { + super(map); + setColor(SerializableMeta.getObject(Color.class, map, COLOR.BUKKIT, true)); + } + + @Override + void applyToItem(NBTTagCompound itemTag) { + super.applyToItem(itemTag); + + if (hasColor()) { + setDisplayTag(itemTag, COLOR.NBT, new NBTTagInt(color.asRGB())); + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isLeatherArmorEmpty(); + } + + boolean isLeatherArmorEmpty() { + return !(hasColor()); + } + + @Override + boolean applicableTo(Material type) { + switch(type) { + case LEATHER_HELMET: + case LEATHER_CHESTPLATE: + case LEATHER_LEGGINGS: + case LEATHER_BOOTS: + return true; + default: + return false; + } + } + + @Override + public CraftMetaLeatherArmor clone() { + return (CraftMetaLeatherArmor) super.clone(); + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color == null ? DEFAULT_LEATHER_COLOR : color; + } + + boolean hasColor() { + return !DEFAULT_LEATHER_COLOR.equals(color); + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + if (hasColor()) { + builder.put(COLOR.BUKKIT, color); + } + + return builder; + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaLeatherArmor) { + CraftMetaLeatherArmor that = (CraftMetaLeatherArmor) meta; + + return color.equals(that.color); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaLeatherArmor || isLeatherArmorEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (hasColor()) { + hash ^= color.hashCode(); + } + return original != hash ? CraftMetaSkull.class.hashCode() ^ hash : hash; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java new file mode 100644 index 0000000..d8af390 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java @@ -0,0 +1,135 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Map; + +import net.minecraft.server.NBTTagCompound; + +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.inventory.meta.MapMeta; + +import com.google.common.collect.ImmutableMap; + +@DelegateDeserialization(SerializableMeta.class) +class CraftMetaMap extends CraftMetaItem implements MapMeta { + static final ItemMetaKey MAP_SCALING = new ItemMetaKey("map_is_scaling", "scaling"); + static final byte SCALING_EMPTY = (byte) 0; + static final byte SCALING_TRUE = (byte) 1; + static final byte SCALING_FALSE = (byte) 2; + + private byte scaling = SCALING_EMPTY; + + CraftMetaMap(CraftMetaItem meta) { + super(meta); + + if (!(meta instanceof CraftMetaMap)) { + return; + } + + CraftMetaMap map = (CraftMetaMap) meta; + this.scaling = map.scaling; + } + + CraftMetaMap(NBTTagCompound tag) { + super(tag); + + if (tag.hasKey(MAP_SCALING.NBT)) { + this.scaling = tag.getBoolean(MAP_SCALING.NBT) ? SCALING_TRUE : SCALING_FALSE; + } + } + + CraftMetaMap(Map map) { + super(map); + + Boolean scaling = SerializableMeta.getObject(Boolean.class, map, MAP_SCALING.BUKKIT, true); + if (scaling != null) { + setScaling(scaling); + } + } + + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + + if (hasScaling()) { + tag.setBoolean(MAP_SCALING.NBT, isScaling()); + } + } + + @Override + boolean applicableTo(Material type) { + switch (type) { + case MAP: + return true; + default: + return false; + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isMapEmpty(); + } + + boolean isMapEmpty() { + return !hasScaling(); + } + + boolean hasScaling() { + return scaling != SCALING_EMPTY; + } + + public boolean isScaling() { + return scaling == SCALING_TRUE; + } + + public void setScaling(boolean scaling) { + this.scaling = scaling ? SCALING_TRUE : SCALING_FALSE; + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaMap) { + CraftMetaMap that = (CraftMetaMap) meta; + + return (this.scaling == that.scaling); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaMap || isMapEmpty()); + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + + if (hasScaling()) { + hash ^= 0x22222222 << (isScaling() ? 1 : -1); + } + + return original != hash ? CraftMetaMap.class.hashCode() ^ hash : hash; + } + + public CraftMetaMap clone() { + return (CraftMetaMap) super.clone(); + } + + @Override + ImmutableMap.Builder serialize(ImmutableMap.Builder builder) { + super.serialize(builder); + + if (hasScaling()) { + builder.put(MAP_SCALING.BUKKIT, isScaling()); + } + + return builder; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java new file mode 100644 index 0000000..5b2d12b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java @@ -0,0 +1,259 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.NBTTagList; + +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap.Builder; + +@DelegateDeserialization(SerializableMeta.class) +class CraftMetaPotion extends CraftMetaItem implements PotionMeta { + static final ItemMetaKey AMPLIFIER = new ItemMetaKey("Amplifier", "amplifier"); + static final ItemMetaKey AMBIENT = new ItemMetaKey("Ambient", "ambient"); + static final ItemMetaKey DURATION = new ItemMetaKey("Duration", "duration"); + static final ItemMetaKey SHOW_PARTICLES = new ItemMetaKey("ShowParticles", "has-particles"); + static final ItemMetaKey POTION_EFFECTS = new ItemMetaKey("CustomPotionEffects", "custom-effects"); + static final ItemMetaKey ID = new ItemMetaKey("Id", "potion-id"); + + private List customEffects; + + CraftMetaPotion(CraftMetaItem meta) { + super(meta); + if (!(meta instanceof CraftMetaPotion)) { + return; + } + CraftMetaPotion potionMeta = (CraftMetaPotion) meta; + if (potionMeta.hasCustomEffects()) { + this.customEffects = new ArrayList(potionMeta.customEffects); + } + } + + CraftMetaPotion(NBTTagCompound tag) { + super(tag); + + if (tag.hasKey(POTION_EFFECTS.NBT)) { + NBTTagList list = tag.getList(POTION_EFFECTS.NBT, 10); + int length = list.size(); + customEffects = new ArrayList(length); + + for (int i = 0; i < length; i++) { + NBTTagCompound effect = list.get(i); + PotionEffectType type = PotionEffectType.getById(effect.getByte(ID.NBT)); + int amp = effect.getByte(AMPLIFIER.NBT); + int duration = effect.getInt(DURATION.NBT); + boolean ambient = effect.getBoolean(AMBIENT.NBT); + boolean particles = effect.getBoolean(SHOW_PARTICLES.NBT); + customEffects.add(new PotionEffect(type, duration, amp, ambient, particles)); + } + } + } + + CraftMetaPotion(Map map) { + super(map); + + Iterable rawEffectList = SerializableMeta.getObject(Iterable.class, map, POTION_EFFECTS.BUKKIT, true); + if (rawEffectList == null) { + return; + } + + for (Object obj : rawEffectList) { + if (!(obj instanceof PotionEffect)) { + throw new IllegalArgumentException("Object in effect list is not valid. " + obj.getClass()); + } + addCustomEffect((PotionEffect) obj, true); + } + } + + @Override + void applyToItem(NBTTagCompound tag) { + super.applyToItem(tag); + if (customEffects != null) { + NBTTagList effectList = new NBTTagList(); + tag.set(POTION_EFFECTS.NBT, effectList); + + for (PotionEffect effect : customEffects) { + NBTTagCompound effectData = new NBTTagCompound(); + effectData.setByte(ID.NBT, (byte) effect.getType().getId()); + effectData.setByte(AMPLIFIER.NBT, (byte) effect.getAmplifier()); + effectData.setInt(DURATION.NBT, effect.getDuration()); + effectData.setBoolean(AMBIENT.NBT, effect.isAmbient()); + effectData.setBoolean(SHOW_PARTICLES.NBT, effect.hasParticles()); + effectList.add(effectData); + } + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isPotionEmpty(); + } + + boolean isPotionEmpty() { + return !(hasCustomEffects()); + } + + @Override + boolean applicableTo(Material type) { + switch(type) { + case POTION: + return true; + default: + return false; + } + } + + @Override + public CraftMetaPotion clone() { + CraftMetaPotion clone = (CraftMetaPotion) super.clone(); + if (this.customEffects != null) { + clone.customEffects = new ArrayList(this.customEffects); + } + return clone; + } + + public boolean hasCustomEffects() { + return customEffects != null; + } + + public List getCustomEffects() { + if (hasCustomEffects()) { + return ImmutableList.copyOf(customEffects); + } + return ImmutableList.of(); + } + + public boolean addCustomEffect(PotionEffect effect, boolean overwrite) { + Validate.notNull(effect, "Potion effect must not be null"); + + int index = indexOfEffect(effect.getType()); + if (index != -1) { + if (overwrite) { + PotionEffect old = customEffects.get(index); + if (old.getAmplifier() == effect.getAmplifier() && old.getDuration() == effect.getDuration() && old.isAmbient() == effect.isAmbient()) { + return false; + } + customEffects.set(index, effect); + return true; + } else { + return false; + } + } else { + if (customEffects == null) { + customEffects = new ArrayList(); + } + customEffects.add(effect); + return true; + } + } + + public boolean removeCustomEffect(PotionEffectType type) { + Validate.notNull(type, "Potion effect type must not be null"); + + if (!hasCustomEffects()) { + return false; + } + + boolean changed = false; + Iterator iterator = customEffects.iterator(); + while (iterator.hasNext()) { + PotionEffect effect = iterator.next(); + if (effect.getType() == type) { + iterator.remove(); + changed = true; + } + } + if (customEffects.isEmpty()) { + customEffects = null; + } + return changed; + } + + public boolean hasCustomEffect(PotionEffectType type) { + Validate.notNull(type, "Potion effect type must not be null"); + return indexOfEffect(type) != -1; + } + + public boolean setMainEffect(PotionEffectType type) { + Validate.notNull(type, "Potion effect type must not be null"); + int index = indexOfEffect(type); + if (index == -1 || index == 0) { + return false; + } + + PotionEffect old = customEffects.get(0); + customEffects.set(0, customEffects.get(index)); + customEffects.set(index, old); + return true; + } + + private int indexOfEffect(PotionEffectType type) { + if (!hasCustomEffects()) { + return -1; + } + + for (int i = 0; i < customEffects.size(); i++) { + if (customEffects.get(i).getType().equals(type)) { + return i; + } + } + return -1; + } + + public boolean clearCustomEffects() { + boolean changed = hasCustomEffects(); + customEffects = null; + return changed; + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (hasCustomEffects()) { + hash = 73 * hash + customEffects.hashCode(); + } + return original != hash ? CraftMetaPotion.class.hashCode() ^ hash : hash; + } + + @Override + public boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaPotion) { + CraftMetaPotion that = (CraftMetaPotion) meta; + + return (this.hasCustomEffects() ? that.hasCustomEffects() && this.customEffects.equals(that.customEffects) : !that.hasCustomEffects()); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaPotion || isPotionEmpty()); + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + + if (hasCustomEffects()) { + builder.put(POTION_EFFECTS.BUKKIT, ImmutableList.copyOf(this.customEffects)); + } + + return builder; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java new file mode 100644 index 0000000..55bbad7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java @@ -0,0 +1,185 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Map; + +import net.minecraft.server.GameProfileSerializer; +import net.minecraft.server.NBTBase; +import net.minecraft.server.NBTTagCompound; + +// PaperSpigot start +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.MinecraftServer; +// PaperSpigot end + +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.inventory.CraftMetaItem.SerializableMeta; +import org.bukkit.inventory.meta.SkullMeta; + +import com.google.common.collect.ImmutableMap.Builder; +import com.mojang.authlib.GameProfile; + +@DelegateDeserialization(SerializableMeta.class) +class CraftMetaSkull extends CraftMetaItem implements SkullMeta { + + @ItemMetaKey.Specific(ItemMetaKey.Specific.To.NBT) + static final ItemMetaKey SKULL_PROFILE = new ItemMetaKey("SkullProfile"); + + static final ItemMetaKey SKULL_OWNER = new ItemMetaKey("SkullOwner", "skull-owner"); + static final int MAX_OWNER_LENGTH = 16; + + private GameProfile profile; + + CraftMetaSkull(CraftMetaItem meta) { + super(meta); + if (!(meta instanceof CraftMetaSkull)) { + return; + } + CraftMetaSkull skullMeta = (CraftMetaSkull) meta; + this.profile = skullMeta.profile; + } + + CraftMetaSkull(NBTTagCompound tag) { + super(tag); + + if (tag.hasKeyOfType(SKULL_OWNER.NBT, 10)) { + profile = GameProfileSerializer.deserialize(tag.getCompound(SKULL_OWNER.NBT)); + } else if (tag.hasKeyOfType(SKULL_OWNER.NBT, 8) && !tag.getString(SKULL_OWNER.NBT).isEmpty()) { + profile = new GameProfile(null, tag.getString(SKULL_OWNER.NBT)); + } + } + + CraftMetaSkull(Map map) { + super(map); + if (profile == null) { + setOwner(SerializableMeta.getString(map, SKULL_OWNER.BUKKIT, true)); + } + } + + @Override + void deserializeInternal(NBTTagCompound tag) { + if (tag.hasKeyOfType(SKULL_PROFILE.NBT, 10)) { + profile = GameProfileSerializer.deserialize(tag.getCompound(SKULL_PROFILE.NBT)); + } + } + + @Override + void serializeInternal(final Map internalTags) { + if (profile != null) { + NBTTagCompound nbtData = new NBTTagCompound(); + GameProfileSerializer.serialize(nbtData, profile); + internalTags.put(SKULL_PROFILE.NBT, nbtData); + } + } + + @Override + void applyToItem(final NBTTagCompound tag) { // Spigot - make final + super.applyToItem(tag); + + if (profile != null) { + NBTTagCompound owner = new NBTTagCompound(); + GameProfileSerializer.serialize(owner, profile); + tag.set( SKULL_OWNER.NBT, owner ); + // Spigot start - do an async lookup of the profile. + // Unfortunately there is not way to refresh the holding + // inventory, so that responsibility is left to the user. + net.minecraft.server.TileEntitySkull.b(profile, new com.google.common.base.Predicate() { + + @Override + public boolean apply(GameProfile input) { + NBTTagCompound owner = new NBTTagCompound(); + GameProfileSerializer.serialize( owner, input ); + tag.set( SKULL_OWNER.NBT, owner ); + return false; + } + }); + // Spigot end + } + } + + @Override + boolean isEmpty() { + return super.isEmpty() && isSkullEmpty(); + } + + boolean isSkullEmpty() { + return profile == null; + } + + @Override + boolean applicableTo(Material type) { + switch(type) { + case SKULL_ITEM: + return true; + default: + return false; + } + } + + @Override + public CraftMetaSkull clone() { + return (CraftMetaSkull) super.clone(); + } + + public boolean hasOwner() { + return profile != null && profile.getName() != null; + } + + public String getOwner() { + return hasOwner() ? profile.getName() : null; + } + + public boolean setOwner(String name) { + if (name != null && name.length() > MAX_OWNER_LENGTH) { + return false; + } + + if (name == null) { + profile = null; + } else { + // PaperSpigot start - Check usercache if the player is online + EntityPlayer player = MinecraftServer.getServer().getPlayerList().getPlayer(name); + profile = player != null ? player.getProfile() : new GameProfile(null, name); + // PaperSpigot end + } + + return true; + } + + @Override + int applyHash() { + final int original; + int hash = original = super.applyHash(); + if (hasOwner()) { + hash = 61 * hash + profile.hashCode(); + } + return original != hash ? CraftMetaSkull.class.hashCode() ^ hash : hash; + } + + @Override + boolean equalsCommon(CraftMetaItem meta) { + if (!super.equalsCommon(meta)) { + return false; + } + if (meta instanceof CraftMetaSkull) { + CraftMetaSkull that = (CraftMetaSkull) meta; + + return (this.hasOwner() ? that.hasOwner() && this.profile.equals(that.profile) : !that.hasOwner()); + } + return true; + } + + @Override + boolean notUncommon(CraftMetaItem meta) { + return super.notUncommon(meta) && (meta instanceof CraftMetaSkull || isSkullEmpty()); + } + + @Override + Builder serialize(Builder builder) { + super.serialize(builder); + if (hasOwner()) { + return builder.put(SKULL_OWNER.BUKKIT, this.profile.getName()); + } + return builder; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java new file mode 100644 index 0000000..d3e03e2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java @@ -0,0 +1,7 @@ +package org.bukkit.craftbukkit.inventory; + +import org.bukkit.inventory.Recipe; + +public interface CraftRecipe extends Recipe { + void addToCraftingManager(); +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java new file mode 100644 index 0000000..baea759 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java @@ -0,0 +1,65 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Map; + +import net.minecraft.server.CraftingManager; +import net.minecraft.server.ShapedRecipes; + +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ShapedRecipe; + +public class CraftShapedRecipe extends ShapedRecipe implements CraftRecipe { + // TODO: Could eventually use this to add a matches() method or some such + private ShapedRecipes recipe; + + public CraftShapedRecipe(ItemStack result) { + super(result); + } + + public CraftShapedRecipe(ItemStack result, ShapedRecipes recipe) { + this(result); + this.recipe = recipe; + } + + public static CraftShapedRecipe fromBukkitRecipe(ShapedRecipe recipe) { + if (recipe instanceof CraftShapedRecipe) { + return (CraftShapedRecipe) recipe; + } + CraftShapedRecipe ret = new CraftShapedRecipe(recipe.getResult()); + String[] shape = recipe.getShape(); + ret.shape(shape); + Map ingredientMap = recipe.getIngredientMap(); + for (char c : ingredientMap.keySet()) { + ItemStack stack = ingredientMap.get(c); + if (stack != null) { + ret.setIngredient(c, stack.getType(), stack.getDurability()); + } + } + return ret; + } + + public void addToCraftingManager() { + Object[] data; + String[] shape = this.getShape(); + Map ingred = this.getIngredientMap(); + int datalen = shape.length; + datalen += ingred.size() * 2; + int i = 0; + data = new Object[datalen]; + for (; i < shape.length; i++) { + data[i] = shape[i]; + } + for (char c : ingred.keySet()) { + ItemStack mdata = ingred.get(c); + if (mdata == null) continue; + data[i] = c; + i++; + int id = mdata.getTypeId(); + short dmg = mdata.getDurability(); + data[i] = new net.minecraft.server.ItemStack(CraftMagicNumbers.getItem(id), 1, dmg); + i++; + } + CraftingManager.getInstance().registerShapedRecipe(CraftItemStack.asNMSCopy(this.getResult()), data); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java new file mode 100644 index 0000000..53479c7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java @@ -0,0 +1,48 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.List; + +import net.minecraft.server.CraftingManager; +import net.minecraft.server.ShapelessRecipes; + +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ShapelessRecipe; + +public class CraftShapelessRecipe extends ShapelessRecipe implements CraftRecipe { + // TODO: Could eventually use this to add a matches() method or some such + private ShapelessRecipes recipe; + + public CraftShapelessRecipe(ItemStack result) { + super(result); + } + + public CraftShapelessRecipe(ItemStack result, ShapelessRecipes recipe) { + this(result); + this.recipe = recipe; + } + + public static CraftShapelessRecipe fromBukkitRecipe(ShapelessRecipe recipe) { + if (recipe instanceof CraftShapelessRecipe) { + return (CraftShapelessRecipe) recipe; + } + CraftShapelessRecipe ret = new CraftShapelessRecipe(recipe.getResult()); + for (ItemStack ingred : recipe.getIngredientList()) { + ret.addIngredient(ingred.getType(), ingred.getDurability()); + } + return ret; + } + + public void addToCraftingManager() { + List ingred = this.getIngredientList(); + Object[] data = new Object[ingred.size()]; + int i = 0; + for (ItemStack mdata : ingred) { + int id = mdata.getTypeId(); + short dmg = mdata.getDurability(); + data[i] = new net.minecraft.server.ItemStack(CraftMagicNumbers.getItem(id), 1, dmg); + i++; + } + CraftingManager.getInstance().registerShapelessRecipe(CraftItemStack.asNMSCopy(this.getResult()), data); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/InventoryIterator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/InventoryIterator.java new file mode 100644 index 0000000..e3b5f42 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/InventoryIterator.java @@ -0,0 +1,64 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.ListIterator; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class InventoryIterator implements ListIterator { + private final Inventory inventory; + private int nextIndex; + private Boolean lastDirection; // true = forward, false = backward, null = haven't moved yet + + InventoryIterator(Inventory craftInventory) { + this.inventory = craftInventory; + this.nextIndex = 0; + } + + InventoryIterator(Inventory craftInventory, int index) { + this.inventory = craftInventory; + this.nextIndex = index; + } + + public boolean hasNext() { + return nextIndex < inventory.getSize(); + } + + public ItemStack next() { + lastDirection = true; + return inventory.getItem(nextIndex++); + } + + public int nextIndex() { + return nextIndex; + } + + public boolean hasPrevious() { + return nextIndex > 0; + } + + public ItemStack previous() { + lastDirection = false; + return inventory.getItem(--nextIndex); + } + + public int previousIndex() { + return nextIndex - 1; + } + + public void set(ItemStack item) { + if (lastDirection == null) { + throw new IllegalStateException("No current item!"); + } + int i = lastDirection ? nextIndex - 1 : nextIndex; + inventory.setItem(i, item); + } + + public void add(ItemStack item) { + throw new UnsupportedOperationException("Can't change the size of an inventory!"); + } + + public void remove() { + throw new UnsupportedOperationException("Can't change the size of an inventory!"); + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/InventoryWrapper.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/InventoryWrapper.java new file mode 100644 index 0000000..5e44966 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/InventoryWrapper.java @@ -0,0 +1,173 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.ArrayList; +import java.util.List; +import net.minecraft.server.EntityHuman; +import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.IInventory; +import net.minecraft.server.ItemStack; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +public class InventoryWrapper implements IInventory { + + private final Inventory inventory; + private final List viewers = new ArrayList(); + + public InventoryWrapper(Inventory inventory) { + this.inventory = inventory; + } + + @Override + public int getSize() { + return inventory.getSize(); + } + + @Override + public ItemStack getItem(int i) { + return CraftItemStack.asNMSCopy(inventory.getItem(i)); + } + + @Override + public ItemStack splitStack(int i, int j) { + // Copied from CraftItemStack + ItemStack stack = getItem(i); + ItemStack result; + if (stack == null) { + return null; + } + if (stack.count <= j) { + this.setItem(i, null); + result = stack; + } else { + result = CraftItemStack.copyNMSStack(stack, j); + stack.count -= j; + } + this.update(); + return result; + } + + @Override + public ItemStack splitWithoutUpdate(int i) { + // Copied from CraftItemStack + ItemStack stack = getItem(i); + ItemStack result; + if (stack == null) { + return null; + } + if (stack.count <= 1) { + this.setItem(i, null); + result = stack; + } else { + result = CraftItemStack.copyNMSStack(stack, 1); + stack.count -= 1; + } + return result; + } + + @Override + public void setItem(int i, ItemStack itemstack) { + inventory.setItem(i, CraftItemStack.asBukkitCopy(itemstack)); + } + + @Override + public int getMaxStackSize() { + return inventory.getMaxStackSize(); + } + + @Override + public void update() { + } + + @Override + public boolean a(EntityHuman entityhuman) { + return true; + } + + @Override + public void startOpen(EntityHuman entityhuman) { + } + + @Override + public void closeContainer(EntityHuman entityhuman) { + } + + @Override + public boolean b(int i, ItemStack itemstack) { + return true; + } + + @Override + public int getProperty(int i) { + return 0; + } + + @Override + public void b(int i, int j) { + } + + @Override + public int g() { + return 0; + } + + @Override + public void l() { + inventory.clear(); + } + + @Override + public ItemStack[] getContents() { + int size = getSize(); + ItemStack[] items = new ItemStack[size]; + + for (int i = 0; i < size; i++) { + items[i] = getItem(i); + } + + return items; + } + + @Override + public void onOpen(CraftHumanEntity who) { + viewers.add(who); + } + + @Override + public void onClose(CraftHumanEntity who) { + viewers.remove(who); + } + + @Override + public List getViewers() { + return viewers; + } + + @Override + public InventoryHolder getOwner() { + return inventory.getHolder(); + } + + @Override + public void setMaxStackSize(int size) { + inventory.setMaxStackSize(size); + } + + @Override + public String getName() { + return inventory.getName(); + } + + @Override + public boolean hasCustomName() { + return getName() != null; + } + + @Override + public IChatBaseComponent getScoreboardDisplayName() { + return CraftChatMessage.fromString(getName())[0]; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java new file mode 100644 index 0000000..53b53b7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java @@ -0,0 +1,53 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Iterator; + +import org.bukkit.inventory.Recipe; + +import net.minecraft.server.CraftingManager; +import net.minecraft.server.IRecipe; +import net.minecraft.server.RecipesFurnace; + +public class RecipeIterator implements Iterator { + private final Iterator recipes; + private final Iterator smeltingCustom; + private final Iterator smeltingVanilla; + private Iterator removeFrom = null; + + public RecipeIterator() { + this.recipes = CraftingManager.getInstance().getRecipes().iterator(); + this.smeltingCustom = RecipesFurnace.getInstance().customRecipes.keySet().iterator(); + this.smeltingVanilla = RecipesFurnace.getInstance().recipes.keySet().iterator(); + } + + public boolean hasNext() { + return recipes.hasNext() || smeltingCustom.hasNext() || smeltingVanilla.hasNext(); + } + + public Recipe next() { + if (recipes.hasNext()) { + removeFrom = recipes; + return recipes.next().toBukkitRecipe(); + } else { + net.minecraft.server.ItemStack item; + if (smeltingCustom.hasNext()) { + removeFrom = smeltingCustom; + item = smeltingCustom.next(); + } else { + removeFrom = smeltingVanilla; + item = smeltingVanilla.next(); + } + + CraftItemStack stack = CraftItemStack.asCraftMirror(RecipesFurnace.getInstance().getResult(item)); + + return new CraftFurnaceRecipe(stack, CraftItemStack.asCraftMirror(item)); + } + } + + public void remove() { + if (removeFrom == null) { + throw new IllegalStateException(); + } + removeFrom.remove(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java new file mode 100644 index 0000000..1c3e198 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java @@ -0,0 +1,110 @@ +package org.bukkit.craftbukkit.map; + +import java.awt.Image; +import java.util.Arrays; +import org.bukkit.map.MapCanvas; +import org.bukkit.map.MapCursorCollection; +import org.bukkit.map.MapFont; +import org.bukkit.map.MapFont.CharacterSprite; +import org.bukkit.map.MapPalette; + +public class CraftMapCanvas implements MapCanvas { + + private final byte[] buffer = new byte[128 * 128]; + private final CraftMapView mapView; + private byte[] base; + private MapCursorCollection cursors = new MapCursorCollection(); + + protected CraftMapCanvas(CraftMapView mapView) { + this.mapView = mapView; + Arrays.fill(buffer, (byte) -1); + } + + public CraftMapView getMapView() { + return mapView; + } + + public MapCursorCollection getCursors() { + return cursors; + } + + public void setCursors(MapCursorCollection cursors) { + this.cursors = cursors; + } + + public void setPixel(int x, int y, byte color) { + if (x < 0 || y < 0 || x >= 128 || y >= 128) + return; + if (buffer[y * 128 + x] != color) { + buffer[y * 128 + x] = color; + mapView.worldMap.flagDirty(x, y); + } + } + + public byte getPixel(int x, int y) { + if (x < 0 || y < 0 || x >= 128 || y >= 128) + return 0; + return buffer[y * 128 + x]; + } + + public byte getBasePixel(int x, int y) { + if (x < 0 || y < 0 || x >= 128 || y >= 128) + return 0; + return base[y * 128 + x]; + } + + protected void setBase(byte[] base) { + this.base = base; + } + + protected byte[] getBuffer() { + return buffer; + } + + public void drawImage(int x, int y, Image image) { + byte[] bytes = MapPalette.imageToBytes(image); + for (int x2 = 0; x2 < image.getWidth(null); ++x2) { + for (int y2 = 0; y2 < image.getHeight(null); ++y2) { + setPixel(x + x2, y + y2, bytes[y2 * image.getWidth(null) + x2]); + } + } + } + + public void drawText(int x, int y, MapFont font, String text) { + int xStart = x; + byte color = MapPalette.DARK_GRAY; + if (!font.isValid(text)) { + throw new IllegalArgumentException("text contains invalid characters"); + } + + for (int i = 0; i < text.length(); ++i) { + char ch = text.charAt(i); + if (ch == '\n') { + x = xStart; + y += font.getHeight() + 1; + continue; + } else if (ch == '\u00A7') { + int j = text.indexOf(';', i); + if (j >= 0) { + try { + color = Byte.parseByte(text.substring(i + 1, j)); + i = j; + continue; + } + catch (NumberFormatException ex) {} + } + } + + CharacterSprite sprite = font.getChar(text.charAt(i)); + for (int r = 0; r < font.getHeight(); ++r) { + for (int c = 0; c < sprite.getWidth(); ++c) { + if (sprite.get(r, c)) { + setPixel(x + c, y + r, color); + } + } + } + x += sprite.getWidth() + 1; + } + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java new file mode 100644 index 0000000..ad47bdd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java @@ -0,0 +1,50 @@ +package org.bukkit.craftbukkit.map; + +import java.util.UUID; +import net.minecraft.server.WorldMap; +import net.minecraft.server.MapIcon; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.map.MapCanvas; +import org.bukkit.map.MapCursorCollection; +import org.bukkit.map.MapRenderer; +import org.bukkit.map.MapView; + +public class CraftMapRenderer extends MapRenderer { + + private final WorldMap worldMap; + + public CraftMapRenderer(CraftMapView mapView, WorldMap worldMap) { + super(false); + this.worldMap = worldMap; + } + + @Override + public void render(MapView map, MapCanvas canvas, Player player) { + // Map + for (int x = 0; x < 128; ++x) { + for (int y = 0; y < 128; ++y) { + canvas.setPixel(x, y, worldMap.colors[y * 128 + x]); + } + } + + // Cursors + MapCursorCollection cursors = canvas.getCursors(); + while (cursors.size() > 0) { + cursors.removeCursor(cursors.getCursor(0)); + } + + for (UUID key : worldMap.decorations.keySet()) { // Spigot string -> uuid. + // If this cursor is for a player check visibility with vanish system + Player other = Bukkit.getPlayer(key); // Spigot + if (other != null && !player.canSee(other)) { + continue; + } + + MapIcon decoration = (MapIcon) worldMap.decorations.get(key); + cursors.addCursor(decoration.getX(), decoration.getY(), (byte) (decoration.getRotation() & 15), decoration.getType()); + } + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java new file mode 100644 index 0000000..1a150d9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java @@ -0,0 +1,163 @@ +package org.bukkit.craftbukkit.map; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.WorldMap; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.map.MapRenderer; +import org.bukkit.map.MapView; + +public final class CraftMapView implements MapView { + + private final Map renderCache = new HashMap(); + private final List renderers = new ArrayList(); + private final Map> canvases = new HashMap>(); + protected final WorldMap worldMap; + + public CraftMapView(WorldMap worldMap) { + this.worldMap = worldMap; + addRenderer(new CraftMapRenderer(this, worldMap)); + } + + public short getId() { + String text = worldMap.id; + if (text.startsWith("map_")) { + try { + return Short.parseShort(text.substring("map_".length())); + } + catch (NumberFormatException ex) { + throw new IllegalStateException("Map has non-numeric ID"); + } + } else { + throw new IllegalStateException("Map has invalid ID"); + } + } + + public boolean isVirtual() { + return renderers.size() > 0 && !(renderers.get(0) instanceof CraftMapRenderer); + } + + public Scale getScale() { + return Scale.valueOf(worldMap.scale); + } + + public void setScale(Scale scale) { + worldMap.scale = scale.getValue(); + } + + public World getWorld() { + byte dimension = worldMap.map; + for (World world : Bukkit.getServer().getWorlds()) { + if (((CraftWorld) world).getHandle().dimension == dimension) { + return world; + } + } + return null; + } + + public void setWorld(World world) { + worldMap.map = (byte) ((CraftWorld) world).getHandle().dimension; + } + + public int getCenterX() { + return worldMap.centerX; + } + + public int getCenterZ() { + return worldMap.centerZ; + } + + public void setCenterX(int x) { + worldMap.centerX = x; + } + + public void setCenterZ(int z) { + worldMap.centerZ = z; + } + + public List getRenderers() { + return new ArrayList(renderers); + } + + public void addRenderer(MapRenderer renderer) { + if (!renderers.contains(renderer)) { + renderers.add(renderer); + canvases.put(renderer, new HashMap()); + renderer.initialize(this); + } + } + + public boolean removeRenderer(MapRenderer renderer) { + if (renderers.contains(renderer)) { + renderers.remove(renderer); + for (Map.Entry entry : canvases.get(renderer).entrySet()) { + for (int x = 0; x < 128; ++x) { + for (int y = 0; y < 128; ++y) { + entry.getValue().setPixel(x, y, (byte) -1); + } + } + } + canvases.remove(renderer); + return true; + } else { + return false; + } + } + + private boolean isContextual() { + for (MapRenderer renderer : renderers) { + if (renderer.isContextual()) return true; + } + return false; + } + + public RenderData render(CraftPlayer player) { + boolean context = isContextual(); + RenderData render = renderCache.get(context ? player : null); + + if (render == null) { + render = new RenderData(); + renderCache.put(context ? player : null, render); + } + + if (context && renderCache.containsKey(null)) { + renderCache.remove(null); + } + + Arrays.fill(render.buffer, (byte) 0); + render.cursors.clear(); + + for (MapRenderer renderer : renderers) { + CraftMapCanvas canvas = canvases.get(renderer).get(renderer.isContextual() ? player : null); + if (canvas == null) { + canvas = new CraftMapCanvas(this); + canvases.get(renderer).put(renderer.isContextual() ? player : null, canvas); + } + + canvas.setBase(render.buffer); + renderer.render(this, canvas, player); + + byte[] buf = canvas.getBuffer(); + for (int i = 0; i < buf.length; ++i) { + byte color = buf[i]; + // There are 143 valid color id's, 0 -> 127 and -128 -> -113 + if (color >= 0 || color <= -113) render.buffer[i] = color; + } + + for (int i = 0; i < canvas.getCursors().size(); ++i) { + render.cursors.add(canvas.getCursors().getCursor(i)); + } + } + + return render; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/RenderData.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/RenderData.java new file mode 100644 index 0000000..256a131 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/map/RenderData.java @@ -0,0 +1,16 @@ +package org.bukkit.craftbukkit.map; + +import java.util.ArrayList; +import org.bukkit.map.MapCursor; + +public class RenderData { + + public final byte[] buffer; + public final ArrayList cursors; + + public RenderData() { + this.buffer = new byte[128 * 128]; + this.cursors = new ArrayList(); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/BlockMetadataStore.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/BlockMetadataStore.java new file mode 100644 index 0000000..6f7102f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/BlockMetadataStore.java @@ -0,0 +1,94 @@ +package org.bukkit.craftbukkit.metadata; + +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.metadata.MetadataStore; +import org.bukkit.metadata.MetadataStoreBase; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.plugin.Plugin; + +import java.util.List; + +/** + * A BlockMetadataStore stores metadata values for {@link Block} objects. + */ +public class BlockMetadataStore extends MetadataStoreBase implements MetadataStore { + + private final World owningWorld; + + /** + * Initializes a BlockMetadataStore. + * @param owningWorld The world to which this BlockMetadataStore belongs. + */ + public BlockMetadataStore(World owningWorld) { + this.owningWorld = owningWorld; + } + + /** + * Generates a unique metadata key for a {@link Block} object based on its coordinates in the world. + * @see MetadataStoreBase#disambiguate(Object, String) + * @param block the block + * @param metadataKey The name identifying the metadata value + * @return a unique metadata key + */ + @Override + protected String disambiguate(Block block, String metadataKey) { + return Integer.toString(block.getX()) + ":" + Integer.toString(block.getY()) + ":" + Integer.toString(block.getZ()) + ":" + metadataKey; + } + + /** + * Retrieves the metadata for a {@link Block}, ensuring the block being asked for actually belongs to this BlockMetadataStore's + * owning world. + * @see MetadataStoreBase#getMetadata(Object, String) + */ + @Override + public List getMetadata(Block block, String metadataKey) { + if(block.getWorld() == owningWorld) { + return super.getMetadata(block, metadataKey); + } else { + throw new IllegalArgumentException("Block does not belong to world " + owningWorld.getName()); + } + } + + /** + * Tests to see if a metadata value has been added to a {@link Block}, ensuring the block being interrogated belongs + * to this BlockMetadataStore's owning world. + * @see MetadataStoreBase#hasMetadata(Object, String) + */ + @Override + public boolean hasMetadata(Block block, String metadataKey) { + if(block.getWorld() == owningWorld) { + return super.hasMetadata(block, metadataKey); + } else { + throw new IllegalArgumentException("Block does not belong to world " + owningWorld.getName()); + } + } + + /** + * Removes metadata from from a {@link Block} belonging to a given {@link Plugin}, ensuring the block being deleted from belongs + * to this BlockMetadataStore's owning world. + * @see MetadataStoreBase#removeMetadata(Object, String, org.bukkit.plugin.Plugin) + */ + @Override + public void removeMetadata(Block block, String metadataKey, Plugin owningPlugin) { + if(block.getWorld() == owningWorld) { + super.removeMetadata(block, metadataKey, owningPlugin); + } else { + throw new IllegalArgumentException("Block does not belong to world " + owningWorld.getName()); + } + } + + /** + * Sets or overwrites a metadata value on a {@link Block} from a given {@link Plugin}, ensuring the target block belongs + * to this BlockMetadataStore's owning world. + * @see MetadataStoreBase#setMetadata(Object, String, org.bukkit.metadata.MetadataValue) + */ + @Override + public void setMetadata(Block block, String metadataKey, MetadataValue newMetadataValue) { + if(block.getWorld() == owningWorld) { + super.setMetadata(block, metadataKey, newMetadataValue); + } else { + throw new IllegalArgumentException("Block does not belong to world " + owningWorld.getName()); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/EntityMetadataStore.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/EntityMetadataStore.java new file mode 100644 index 0000000..35c484f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/EntityMetadataStore.java @@ -0,0 +1,23 @@ +package org.bukkit.craftbukkit.metadata; + +import org.bukkit.entity.Entity; +import org.bukkit.metadata.MetadataStore; +import org.bukkit.metadata.MetadataStoreBase; + +/** + * An EntityMetadataStore stores metadata values for all {@link Entity} classes an their descendants. + */ +public class EntityMetadataStore extends MetadataStoreBase implements MetadataStore { + /** + * Generates a unique metadata key for an {@link Entity} UUID. + * + * @see MetadataStoreBase#disambiguate(Object, String) + * @param entity the entity + * @param metadataKey The name identifying the metadata value + * @return a unique metadata key + */ + @Override + protected String disambiguate(Entity entity, String metadataKey) { + return entity.getUniqueId().toString() + ":" + metadataKey; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/PlayerMetadataStore.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/PlayerMetadataStore.java new file mode 100644 index 0000000..d4d7f38 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/PlayerMetadataStore.java @@ -0,0 +1,23 @@ +package org.bukkit.craftbukkit.metadata; + +import org.bukkit.OfflinePlayer; +import org.bukkit.metadata.MetadataStore; +import org.bukkit.metadata.MetadataStoreBase; + +/** + * A PlayerMetadataStore stores metadata for {@link org.bukkit.entity.Player} and {@link OfflinePlayer} objects. + */ +public class PlayerMetadataStore extends MetadataStoreBase implements MetadataStore { + /** + * Generates a unique metadata key for {@link org.bukkit.entity.Player} and {@link OfflinePlayer} using the player + * name. + * @see MetadataStoreBase#disambiguate(Object, String) + * @param player the player + * @param metadataKey The name identifying the metadata value + * @return a unique metadata key + */ + @Override + protected String disambiguate(OfflinePlayer player, String metadataKey) { + return player.getName().toLowerCase() + ":" + metadataKey; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/WorldMetadataStore.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/WorldMetadataStore.java new file mode 100644 index 0000000..dd37ed2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/metadata/WorldMetadataStore.java @@ -0,0 +1,22 @@ +package org.bukkit.craftbukkit.metadata; + +import org.bukkit.World; +import org.bukkit.metadata.MetadataStore; +import org.bukkit.metadata.MetadataStoreBase; + +/** + * An WorldMetadataStore stores metadata values for {@link World} objects. + */ +public class WorldMetadataStore extends MetadataStoreBase implements MetadataStore { + /** + * Generates a unique metadata key for a {@link World} object based on the world UID. + * @see WorldMetadataStore#disambiguate(Object, String) + * @param world the world + * @param metadataKey The name identifying the metadata value + * @return a unique metadata key + */ + @Override + protected String disambiguate(World world, String metadataKey) { + return world.getUID().toString() + ":" + metadataKey; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java new file mode 100644 index 0000000..bb16958 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java @@ -0,0 +1,47 @@ +package org.bukkit.craftbukkit.potion; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.MobEffect; + +import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionBrewer; +import org.bukkit.potion.PotionEffect; + +import com.google.common.collect.Maps; + +public class CraftPotionBrewer implements PotionBrewer { + private static final Map> cache = Maps.newHashMap(); + + public Collection getEffectsFromDamage(int damage) { + if (cache.containsKey(damage)) + return cache.get(damage); + + List mcEffects = net.minecraft.server.PotionBrewer.getEffects(damage, false); + List effects = new ArrayList(); + if (mcEffects == null) + return effects; + + for (Object raw : mcEffects) { + if (raw == null || !(raw instanceof MobEffect)) + continue; + MobEffect mcEffect = (MobEffect) raw; + PotionEffect effect = new PotionEffect(PotionEffectType.getById(mcEffect.getEffectId()), + mcEffect.getDuration(), mcEffect.getAmplifier()); + // Minecraft PotionBrewer applies duration modifiers automatically. + effects.add(effect); + } + + cache.put(damage, effects); + + return effects; + } + + public PotionEffect createEffect(PotionEffectType potion, int duration, int amplifier) { + return new PotionEffect(potion, potion.isInstant() ? 1 : (int) (duration * potion.getDurationModifier()), + amplifier); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java new file mode 100644 index 0000000..b59d142 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java @@ -0,0 +1,82 @@ +package org.bukkit.craftbukkit.potion; + +import net.minecraft.server.MobEffectList; + +import org.bukkit.potion.PotionEffectType; + +public class CraftPotionEffectType extends PotionEffectType { + private final MobEffectList handle; + + public CraftPotionEffectType(MobEffectList handle) { + super(handle.id); + this.handle = handle; + } + + @Override + public double getDurationModifier() { + return handle.getDurationModifier(); + } + + public MobEffectList getHandle() { + return handle; + } + + @Override + public String getName() { + switch (handle.id) { + case 1: + return "SPEED"; + case 2: + return "SLOW"; + case 3: + return "FAST_DIGGING"; + case 4: + return "SLOW_DIGGING"; + case 5: + return "INCREASE_DAMAGE"; + case 6: + return "HEAL"; + case 7: + return "HARM"; + case 8: + return "JUMP"; + case 9: + return "CONFUSION"; + case 10: + return "REGENERATION"; + case 11: + return "DAMAGE_RESISTANCE"; + case 12: + return "FIRE_RESISTANCE"; + case 13: + return "WATER_BREATHING"; + case 14: + return "INVISIBILITY"; + case 15: + return "BLINDNESS"; + case 16: + return "NIGHT_VISION"; + case 17: + return "HUNGER"; + case 18: + return "WEAKNESS"; + case 19: + return "POISON"; + case 20: + return "WITHER"; + case 21: + return "HEALTH_BOOST"; + case 22: + return "ABSORPTION"; + case 23: + return "SATURATION"; + default: + return "UNKNOWN_EFFECT_TYPE_" + handle.id; + } + } + + @Override + public boolean isInstant() { + return handle.isInstant(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java new file mode 100644 index 0000000..b8bf754 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java @@ -0,0 +1,142 @@ +package org.bukkit.craftbukkit.projectiles; + +import java.util.Random; + +import org.apache.commons.lang.Validate; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Arrow; +import org.bukkit.entity.Egg; +import org.bukkit.entity.EnderPearl; +import org.bukkit.entity.Fireball; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.SmallFireball; +import org.bukkit.entity.Snowball; +import org.bukkit.entity.ThrownExpBottle; +import org.bukkit.entity.ThrownPotion; +import org.bukkit.entity.WitherSkull; +import org.bukkit.inventory.ItemStack; +import org.bukkit.projectiles.BlockProjectileSource; +import org.bukkit.util.Vector; + +import net.minecraft.server.BlockDispenser; +import net.minecraft.server.EntityArrow; +import net.minecraft.server.EntityEgg; +import net.minecraft.server.EntityEnderPearl; +import net.minecraft.server.EntityFireball; +import net.minecraft.server.EntityLargeFireball; +import net.minecraft.server.EntityPotion; +import net.minecraft.server.EntityProjectile; +import net.minecraft.server.EntitySmallFireball; +import net.minecraft.server.EntitySnowball; +import net.minecraft.server.EntityThrownExpBottle; +import net.minecraft.server.EntityWitherSkull; +import net.minecraft.server.EnumDirection; +import net.minecraft.server.IPosition; +import net.minecraft.server.IProjectile; +import net.minecraft.server.MathHelper; +import net.minecraft.server.SourceBlock; +import net.minecraft.server.TileEntityDispenser; + +public class CraftBlockProjectileSource implements BlockProjectileSource { + private final TileEntityDispenser dispenserBlock; + + public CraftBlockProjectileSource(TileEntityDispenser dispenserBlock) { + this.dispenserBlock = dispenserBlock; + } + + @Override + public Block getBlock() { + return dispenserBlock.getWorld().getWorld().getBlockAt(dispenserBlock.getPosition().getX(), dispenserBlock.getPosition().getY(), dispenserBlock.getPosition().getZ()); + } + + @Override + public T launchProjectile(Class projectile) { + return launchProjectile(projectile, null); + } + + @Override + public T launchProjectile(Class projectile, Vector velocity) { + Validate.isTrue(getBlock().getType() == Material.DISPENSER, "Block is no longer dispenser"); + // Copied from BlockDispenser.dispense() + SourceBlock isourceblock = new SourceBlock(dispenserBlock.getWorld(), dispenserBlock.getPosition()); + // Copied from DispenseBehaviorProjectile + IPosition iposition = BlockDispenser.a(isourceblock); + EnumDirection enumdirection = BlockDispenser.b(isourceblock.f()); + net.minecraft.server.World world = dispenserBlock.getWorld(); + net.minecraft.server.Entity launch = null; + + if (Snowball.class.isAssignableFrom(projectile)) { + launch = new EntitySnowball(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } else if (Egg.class.isAssignableFrom(projectile)) { + launch = new EntityEgg(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } else if (EnderPearl.class.isAssignableFrom(projectile)) { + launch = new EntityEnderPearl(world, null); + launch.setPosition(iposition.getX(), iposition.getY(), iposition.getZ()); + } else if (ThrownExpBottle.class.isAssignableFrom(projectile)) { + launch = new EntityThrownExpBottle(world, iposition.getX(), iposition.getY(), iposition.getZ()); + } else if (ThrownPotion.class.isAssignableFrom(projectile)) { + launch = new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), CraftItemStack.asNMSCopy(new ItemStack(Material.POTION, 1))); + } else if (Arrow.class.isAssignableFrom(projectile)) { + launch = new EntityArrow(world, iposition.getX(), iposition.getY(), iposition.getZ()); + ((EntityArrow) launch).fromPlayer = 1; + ((EntityArrow) launch).projectileSource = this; + } else if (Fireball.class.isAssignableFrom(projectile)) { + double d0 = iposition.getX() + (double) ((float) enumdirection.getAdjacentX() * 0.3F); + double d1 = iposition.getY() + (double) ((float) enumdirection.getAdjacentY() * 0.3F); + double d2 = iposition.getZ() + (double) ((float) enumdirection.getAdjacentZ() * 0.3F); + Random random = world.random; + double d3 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentX(); + double d4 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentY(); + double d5 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentZ(); + + if (SmallFireball.class.isAssignableFrom(projectile)) { + launch = new EntitySmallFireball(world, d0, d1, d2, d3, d4, d5); + } else if (WitherSkull.class.isAssignableFrom(projectile)) { + launch = new EntityWitherSkull(world); + launch.setPosition(d0, d1, d2); + double d6 = (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); + + ((EntityFireball) launch).dirX = d3 / d6 * 0.1D; + ((EntityFireball) launch).dirY = d4 / d6 * 0.1D; + ((EntityFireball) launch).dirZ = d5 / d6 * 0.1D; + } else { + launch = new EntityLargeFireball(world); + launch.setPosition(d0, d1, d2); + double d6 = (double) MathHelper.sqrt(d3 * d3 + d4 * d4 + d5 * d5); + + ((EntityFireball) launch).dirX = d3 / d6 * 0.1D; + ((EntityFireball) launch).dirY = d4 / d6 * 0.1D; + ((EntityFireball) launch).dirZ = d5 / d6 * 0.1D; + } + + ((EntityFireball) launch).projectileSource = this; + } + + Validate.notNull(launch, "Projectile not supported"); + + if (launch instanceof IProjectile) { + if (launch instanceof EntityProjectile) { + ((EntityProjectile) launch).projectileSource = this; + } + // Values from DispenseBehaviorProjectile + float a = 6.0F; + float b = 1.1F; + if (launch instanceof EntityPotion || launch instanceof ThrownExpBottle) { + // Values from respective DispenseBehavior classes + a *= 0.5F; + b *= 1.25F; + } + // Copied from DispenseBehaviorProjectile + ((IProjectile) launch).shoot((double) enumdirection.getAdjacentX(), (double) ((float) enumdirection.getAdjacentY() + 0.1F), (double) enumdirection.getAdjacentZ(), b, a); + } + + if (velocity != null) { + ((T) launch.getBukkitEntity()).setVelocity(velocity); + } + + world.addEntity(launch); + return (T) launch.getBukkitEntity(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncDebugger.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncDebugger.java new file mode 100644 index 0000000..d80ae50 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncDebugger.java @@ -0,0 +1,37 @@ +package org.bukkit.craftbukkit.scheduler; + +import org.bukkit.plugin.Plugin; + + +class CraftAsyncDebugger { + private CraftAsyncDebugger next = null; + private final int expiry; + private final Plugin plugin; + private final Class clazz; + + CraftAsyncDebugger(final int expiry, final Plugin plugin, final Class clazz) { + this.expiry = expiry; + this.plugin = plugin; + this.clazz = clazz; + + } + + final CraftAsyncDebugger getNextHead(final int time) { + CraftAsyncDebugger next, current = this; + while (time > current.expiry && (next = current.next) != null) { + current = next; + } + return current; + } + + final CraftAsyncDebugger setNext(final CraftAsyncDebugger next) { + return this.next = next; + } + + StringBuilder debugTo(final StringBuilder string) { + for (CraftAsyncDebugger next = this; next != null; next = next.next) { + string.append(next.plugin.getDescription().getName()).append(':').append(next.clazz.getName()).append('@').append(next.expiry).append(','); + } + return string; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java new file mode 100644 index 0000000..f3da84a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java @@ -0,0 +1,109 @@ +package org.bukkit.craftbukkit.scheduler; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; + +import org.apache.commons.lang.UnhandledException; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitWorker; + + +class CraftAsyncTask extends CraftTask { + + private final LinkedList workers = new LinkedList(); + private final Map runners; + + CraftAsyncTask(final Map runners, final Plugin plugin, final Runnable task, final int id, final long delay) { + super(plugin, task, id, delay); + this.runners = runners; + } + + @Override + public boolean isSync() { + return false; + } + + @Override + public void run() { + final Thread thread = Thread.currentThread(); + synchronized(workers) { + if (getPeriod() == -2) { + // Never continue running after cancelled. + // Checking this with the lock is important! + return; + } + workers.add( + new BukkitWorker() { + public Thread getThread() { + return thread; + } + + public int getTaskId() { + return CraftAsyncTask.this.getTaskId(); + } + + public Plugin getOwner() { + return CraftAsyncTask.this.getOwner(); + } + }); + } + Throwable thrown = null; + try { + super.run(); + } catch (final Throwable t) { + thrown = t; + throw new UnhandledException( + String.format( + "Plugin %s generated an exception while executing task %s", + getOwner().getDescription().getFullName(), + getTaskId()), + thrown); + } finally { + // Cleanup is important for any async task, otherwise ghost tasks are everywhere + synchronized(workers) { + try { + final Iterator workers = this.workers.iterator(); + boolean removed = false; + while (workers.hasNext()) { + if (workers.next().getThread() == thread) { + workers.remove(); + removed = true; // Don't throw exception + break; + } + } + if (!removed) { + throw new IllegalStateException( + String.format( + "Unable to remove worker %s on task %s for %s", + thread.getName(), + getTaskId(), + getOwner().getDescription().getFullName()), + thrown); // We don't want to lose the original exception, if any + } + } finally { + if (getPeriod() < 0 && workers.isEmpty()) { + // At this spot, we know we are the final async task being executed! + // Because we have the lock, nothing else is running or will run because delay < 0 + runners.remove(getTaskId()); + } + } + } + } + } + + LinkedList getWorkers() { + return workers; + } + + boolean cancel0() { + synchronized (workers) { + // Synchronizing here prevents race condition for a completing task + setPeriod(-2l); + if (workers.isEmpty()) { + runners.remove(getTaskId()); + } + } + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java new file mode 100644 index 0000000..1baec56 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java @@ -0,0 +1,108 @@ +package org.bukkit.craftbukkit.scheduler; + +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.bukkit.plugin.Plugin; + +class CraftFuture extends CraftTask implements Future { + + private final Callable callable; + private T value; + private Exception exception = null; + + CraftFuture(final Callable callable, final Plugin plugin, final int id) { + super(plugin, null, id, -1l); + this.callable = callable; + } + + public synchronized boolean cancel(final boolean mayInterruptIfRunning) { + if (getPeriod() != -1l) { + return false; + } + setPeriod(-2l); + return true; + } + + public boolean isCancelled() { + return getPeriod() == -2l; + } + + public boolean isDone() { + final long period = this.getPeriod(); + return period != -1l && period != -3l; + } + + public T get() throws CancellationException, InterruptedException, ExecutionException { + try { + return get(0, TimeUnit.MILLISECONDS); + } catch (final TimeoutException e) { + throw new Error(e); + } + } + + public synchronized T get(long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + timeout = unit.toMillis(timeout); + long period = this.getPeriod(); + long timestamp = timeout > 0 ? System.currentTimeMillis() : 0l; + while (true) { + if (period == -1l || period == -3l) { + this.wait(timeout); + period = this.getPeriod(); + if (period == -1l || period == -3l) { + if (timeout == 0l) { + continue; + } + timeout += timestamp - (timestamp = System.currentTimeMillis()); + if (timeout > 0) { + continue; + } + throw new TimeoutException(); + } + } + if (period == -2l) { + throw new CancellationException(); + } + if (period == -4l) { + if (exception == null) { + return value; + } + throw new ExecutionException(exception); + } + throw new IllegalStateException("Expected " + -1l + " to " + -4l + ", got " + period); + } + } + + @Override + public void run() { + synchronized (this) { + if (getPeriod() == -2l) { + return; + } + setPeriod(-3l); + } + try { + value = callable.call(); + } catch (final Exception e) { + exception = e; + } finally { + synchronized (this) { + setPeriod(-4l); + this.notifyAll(); + } + } + } + + synchronized boolean cancel0() { + if (getPeriod() != -1l) { + return false; + } + setPeriod(-2l); + notifyAll(); + return true; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java new file mode 100644 index 0000000..d76ec40 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java @@ -0,0 +1,492 @@ +package org.bukkit.craftbukkit.scheduler; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.PriorityQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Level; + +import org.apache.commons.lang.Validate; +import org.bukkit.plugin.IllegalPluginAccessException; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.scheduler.BukkitWorker; + +/** + * The fundamental concepts for this implementation: + *
  • Main thread owns {@link #head} and {@link #currentTick}, but it may be read from any thread
  • + *
  • Main thread exclusively controls {@link #temp} and {@link #pending}. + * They are never to be accessed outside of the main thread; alternatives exist to prevent locking.
  • + *
  • {@link #head} to {@link #tail} act as a linked list/queue, with 1 consumer and infinite producers. + * Adding to the tail is atomic and very efficient; utility method is {@link #handle(CraftTask, long)} or {@link #addTask(CraftTask)}.
  • + *
  • Changing the period on a task is delicate. + * Any future task needs to notify waiting threads. + * Async tasks must be synchronized to make sure that any thread that's finishing will remove itself from {@link #runners}. + * Another utility method is provided for this, {@link #cancelTask(CraftTask)}
  • + *
  • {@link #runners} provides a moderately up-to-date view of active tasks. + * If the linked head to tail set is read, all remaining tasks that were active at the time execution started will be located in runners.
  • + *
  • Async tasks are responsible for removing themselves from runners
  • + *
  • Sync tasks are only to be removed from runners on the main thread when coupled with a removal from pending and temp.
  • + *
  • Most of the design in this scheduler relies on queuing special tasks to perform any data changes on the main thread. + * When executed from inside a synchronous method, the scheduler will be updated before next execution by virtue of the frequent {@link #parsePending()} calls.
  • + */ +public class CraftScheduler implements BukkitScheduler { + + /** + * Counter for IDs. Order doesn't matter, only uniqueness. + */ + private final AtomicInteger ids = new AtomicInteger(1); + /** + * Current head of linked-list. This reference is always stale, {@link CraftTask#next} is the live reference. + */ + private volatile CraftTask head = new CraftTask(); + /** + * Tail of a linked-list. AtomicReference only matters when adding to queue + */ + private final AtomicReference tail = new AtomicReference(head); + /** + * Main thread logic only + */ + private final PriorityQueue pending = new PriorityQueue(10, + new Comparator() { + public int compare(final CraftTask o1, final CraftTask o2) { + return (int) (o1.getNextRun() - o2.getNextRun()); + } + }); + /** + * Main thread logic only + */ + private final List temp = new ArrayList(); + /** + * These are tasks that are currently active. It's provided for 'viewing' the current state. + */ + private final ConcurrentHashMap runners = new ConcurrentHashMap(); + private volatile int currentTick = -1; + private final Executor executor = Executors.newCachedThreadPool(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build()); // Spigot + private CraftAsyncDebugger debugHead = new CraftAsyncDebugger(-1, null, null) {@Override StringBuilder debugTo(StringBuilder string) {return string;}}; + private CraftAsyncDebugger debugTail = debugHead; + private static final int RECENT_TICKS; + + static { + RECENT_TICKS = 30; + } + + public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable task) { + return this.scheduleSyncDelayedTask(plugin, task, 0l); + } + + public BukkitTask runTask(Plugin plugin, Runnable runnable) { + return runTaskLater(plugin, runnable, 0l); + } + + @Deprecated + public int scheduleAsyncDelayedTask(final Plugin plugin, final Runnable task) { + return this.scheduleAsyncDelayedTask(plugin, task, 0l); + } + + public BukkitTask runTaskAsynchronously(Plugin plugin, Runnable runnable) { + return runTaskLaterAsynchronously(plugin, runnable, 0l); + } + + public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable task, final long delay) { + return this.scheduleSyncRepeatingTask(plugin, task, delay, -1l); + } + + public BukkitTask runTaskLater(Plugin plugin, Runnable runnable, long delay) { + return runTaskTimer(plugin, runnable, delay, -1l); + } + + @Deprecated + public int scheduleAsyncDelayedTask(final Plugin plugin, final Runnable task, final long delay) { + return this.scheduleAsyncRepeatingTask(plugin, task, delay, -1l); + } + + public BukkitTask runTaskLaterAsynchronously(Plugin plugin, Runnable runnable, long delay) { + return runTaskTimerAsynchronously(plugin, runnable, delay, -1l); + } + + public int scheduleSyncRepeatingTask(final Plugin plugin, final Runnable runnable, long delay, long period) { + return runTaskTimer(plugin, runnable, delay, period).getTaskId(); + } + + public BukkitTask runTaskTimer(Plugin plugin, Runnable runnable, long delay, long period) { + validate(plugin, runnable); + if (delay < 0l) { + delay = 0; + } + if (period == 0l) { + period = 1l; + } else if (period < -1l) { + period = -1l; + } + return handle(new CraftTask(plugin, runnable, nextId(), period), delay); + } + + @Deprecated + public int scheduleAsyncRepeatingTask(final Plugin plugin, final Runnable runnable, long delay, long period) { + return runTaskTimerAsynchronously(plugin, runnable, delay, period).getTaskId(); + } + + public BukkitTask runTaskTimerAsynchronously(Plugin plugin, Runnable runnable, long delay, long period) { + validate(plugin, runnable); + if (delay < 0l) { + delay = 0; + } + if (period == 0l) { + period = 1l; + } else if (period < -1l) { + period = -1l; + } + return handle(new CraftAsyncTask(runners, plugin, runnable, nextId(), period), delay); + } + + public Future callSyncMethod(final Plugin plugin, final Callable task) { + validate(plugin, task); + final CraftFuture future = new CraftFuture(task, plugin, nextId()); + handle(future, 0l); + return future; + } + + public void cancelTask(final int taskId) { + if (taskId <= 0) { + return; + } + CraftTask task = runners.get(taskId); + if (task != null) { + task.cancel0(); + } + task = new CraftTask( + new Runnable() { + public void run() { + if (!check(CraftScheduler.this.temp)) { + check(CraftScheduler.this.pending); + } + } + private boolean check(final Iterable collection) { + final Iterator tasks = collection.iterator(); + while (tasks.hasNext()) { + final CraftTask task = tasks.next(); + if (task.getTaskId() == taskId) { + task.cancel0(); + tasks.remove(); + if (task.isSync()) { + runners.remove(taskId); + } + return true; + } + } + return false; + }}){{this.timings=co.aikar.timings.SpigotTimings.getCancelTasksTimer();}}; // Spigot + handle(task, 0l); + for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) { + if (taskPending == task) { + return; + } + if (taskPending.getTaskId() == taskId) { + taskPending.cancel0(); + } + } + } + + public void cancelTasks(final Plugin plugin) { + Validate.notNull(plugin, "Cannot cancel tasks of null plugin"); + final CraftTask task = new CraftTask( + new Runnable() { + public void run() { + check(CraftScheduler.this.pending); + check(CraftScheduler.this.temp); + } + void check(final Iterable collection) { + final Iterator tasks = collection.iterator(); + while (tasks.hasNext()) { + final CraftTask task = tasks.next(); + if (task.getOwner().equals(plugin)) { + task.cancel0(); + tasks.remove(); + if (task.isSync()) { + runners.remove(task.getTaskId()); + } + } + } + } + }){{this.timings=co.aikar.timings.SpigotTimings.getCancelTasksTimer(plugin);}}; // Spigot + handle(task, 0l); + for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) { + if (taskPending == task) { + return; + } + if (taskPending.getTaskId() != -1 && taskPending.getOwner().equals(plugin)) { + taskPending.cancel0(); + } + } + for (CraftTask runner : runners.values()) { + if (runner.getOwner().equals(plugin)) { + runner.cancel0(); + } + } + } + + public void cancelAllTasks() { + final CraftTask task = new CraftTask( + new Runnable() { + public void run() { + Iterator it = CraftScheduler.this.runners.values().iterator(); + while (it.hasNext()) { + CraftTask task = it.next(); + task.cancel0(); + if (task.isSync()) { + it.remove(); + } + } + CraftScheduler.this.pending.clear(); + CraftScheduler.this.temp.clear(); + } + }){{this.timings=co.aikar.timings.SpigotTimings.getCancelTasksTimer();}}; // Spigot + handle(task, 0l); + for (CraftTask taskPending = head.getNext(); taskPending != null; taskPending = taskPending.getNext()) { + if (taskPending == task) { + break; + } + taskPending.cancel0(); + } + for (CraftTask runner : runners.values()) { + runner.cancel0(); + } + } + + public boolean isCurrentlyRunning(final int taskId) { + final CraftTask task = runners.get(taskId); + if (task == null || task.isSync()) { + return false; + } + final CraftAsyncTask asyncTask = (CraftAsyncTask) task; + synchronized (asyncTask.getWorkers()) { + return asyncTask.getWorkers().isEmpty(); + } + } + + public boolean isQueued(final int taskId) { + if (taskId <= 0) { + return false; + } + for (CraftTask task = head.getNext(); task != null; task = task.getNext()) { + if (task.getTaskId() == taskId) { + return task.getPeriod() >= -1l; // The task will run + } + } + CraftTask task = runners.get(taskId); + return task != null && task.getPeriod() >= -1l; + } + + public List getActiveWorkers() { + final ArrayList workers = new ArrayList(); + for (final CraftTask taskObj : runners.values()) { + // Iterator will be a best-effort (may fail to grab very new values) if called from an async thread + if (taskObj.isSync()) { + continue; + } + final CraftAsyncTask task = (CraftAsyncTask) taskObj; + synchronized (task.getWorkers()) { + // This will never have an issue with stale threads; it's state-safe + workers.addAll(task.getWorkers()); + } + } + return workers; + } + + public List getPendingTasks() { + final ArrayList truePending = new ArrayList(); + for (CraftTask task = head.getNext(); task != null; task = task.getNext()) { + if (task.getTaskId() != -1) { + // -1 is special code + truePending.add(task); + } + } + + final ArrayList pending = new ArrayList(); + for (CraftTask task : runners.values()) { + if (task.getPeriod() >= -1l) { + pending.add(task); + } + } + + for (final CraftTask task : truePending) { + if (task.getPeriod() >= -1l && !pending.contains(task)) { + pending.add(task); + } + } + return pending; + } + + /** + * This method is designed to never block or wait for locks; an immediate execution of all current tasks. + */ + public void mainThreadHeartbeat(final int currentTick) { + this.currentTick = currentTick; + final List temp = this.temp; + parsePending(); + while (isReady(currentTick)) { + final CraftTask task = pending.remove(); + if (task.getPeriod() < -1l) { + if (task.isSync()) { + runners.remove(task.getTaskId(), task); + } + parsePending(); + continue; + } + if (task.isSync()) { + try { + task.run(); + } catch (final Throwable throwable) { + task.getOwner().getLogger().log( + Level.WARNING, + String.format( + "Task #%s for %s generated an exception", + task.getTaskId(), + task.getOwner().getDescription().getFullName()), + throwable); + } + parsePending(); + } else { + debugTail = debugTail.setNext(new CraftAsyncDebugger(currentTick + RECENT_TICKS, task.getOwner(), task.getTaskClass())); + executor.execute(task); + // We don't need to parse pending + // (async tasks must live with race-conditions if they attempt to cancel between these few lines of code) + } + final long period = task.getPeriod(); // State consistency + if (period > 0) { + task.setNextRun(currentTick + period); + temp.add(task); + } else if (task.isSync()) { + runners.remove(task.getTaskId()); + } + } + pending.addAll(temp); + temp.clear(); + debugHead = debugHead.getNextHead(currentTick); + } + + private void addTask(final CraftTask task) { + final AtomicReference tail = this.tail; + CraftTask tailTask = tail.get(); + while (!tail.compareAndSet(tailTask, task)) { + tailTask = tail.get(); + } + tailTask.setNext(task); + } + + private CraftTask handle(final CraftTask task, final long delay) { + task.setNextRun(currentTick + delay); + addTask(task); + return task; + } + + private static void validate(final Plugin plugin, final Object task) { + Validate.notNull(plugin, "Plugin cannot be null"); + Validate.notNull(task, "Task cannot be null"); + if (!plugin.isEnabled()) { + throw new IllegalPluginAccessException("Plugin attempted to register task while disabled"); + } + } + + private int nextId() { + return ids.incrementAndGet(); + } + + private void parsePending() { + CraftTask head = this.head; + CraftTask task = head.getNext(); + CraftTask lastTask = head; + for (; task != null; task = (lastTask = task).getNext()) { + if (task.getTaskId() == -1) { + task.run(); + } else if (task.getPeriod() >= -1l) { + pending.add(task); + runners.put(task.getTaskId(), task); + } + } + // We split this because of the way things are ordered for all of the async calls in CraftScheduler + // (it prevents race-conditions) + for (task = head; task != lastTask; task = head) { + head = task.getNext(); + task.setNext(null); + } + this.head = lastTask; + } + + private boolean isReady(final int currentTick) { + return !pending.isEmpty() && pending.peek().getNextRun() <= currentTick; + } + + @Override + public String toString() { + int debugTick = currentTick; + StringBuilder string = new StringBuilder("Recent tasks from ").append(debugTick - RECENT_TICKS).append('-').append(debugTick).append('{'); + debugHead.debugTo(string); + return string.append('}').toString(); + } + + @Deprecated + @Override + public int scheduleSyncDelayedTask(Plugin plugin, BukkitRunnable task, long delay) { + return scheduleSyncDelayedTask(plugin, (Runnable) task, delay); + } + + @Deprecated + @Override + public int scheduleSyncDelayedTask(Plugin plugin, BukkitRunnable task) { + return scheduleSyncDelayedTask(plugin, (Runnable) task); + } + + @Deprecated + @Override + public int scheduleSyncRepeatingTask(Plugin plugin, BukkitRunnable task, long delay, long period) { + return scheduleSyncRepeatingTask(plugin, (Runnable) task, delay, period); + } + + @Deprecated + @Override + public BukkitTask runTask(Plugin plugin, BukkitRunnable task) throws IllegalArgumentException { + return runTask(plugin, (Runnable) task); + } + + @Deprecated + @Override + public BukkitTask runTaskAsynchronously(Plugin plugin, BukkitRunnable task) throws IllegalArgumentException { + return runTaskAsynchronously(plugin, (Runnable) task); + } + + @Deprecated + @Override + public BukkitTask runTaskLater(Plugin plugin, BukkitRunnable task, long delay) throws IllegalArgumentException { + return runTaskLater(plugin, (Runnable) task, delay); + } + + @Deprecated + @Override + public BukkitTask runTaskLaterAsynchronously(Plugin plugin, BukkitRunnable task, long delay) throws IllegalArgumentException { + return runTaskLaterAsynchronously(plugin, (Runnable) task, delay); + } + + @Deprecated + @Override + public BukkitTask runTaskTimer(Plugin plugin, BukkitRunnable task, long delay, long period) throws IllegalArgumentException { + return runTaskTimer(plugin, (Runnable) task, delay, period); + } + + @Deprecated + @Override + public BukkitTask runTaskTimerAsynchronously(Plugin plugin, BukkitRunnable task, long delay, long period) throws IllegalArgumentException { + return runTaskTimerAsynchronously(plugin, (Runnable) task, delay, period); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java new file mode 100644 index 0000000..4b1e352 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java @@ -0,0 +1,105 @@ +package org.bukkit.craftbukkit.scheduler; + +import org.bukkit.Bukkit; +import co.aikar.timings.SpigotTimings; // Spigot +import co.aikar.timings.Timing; // Spigot +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitTask; + + +public class CraftTask implements BukkitTask, Runnable { // Spigot + + private volatile CraftTask next = null; + /** + * -1 means no repeating
    + * -2 means cancel
    + * -3 means processing for Future
    + * -4 means done for Future
    + * Never 0
    + * >0 means number of ticks to wait between each execution + */ + private volatile long period; + private long nextRun; + public final Runnable task; //Spigot + public Timing timings; // Spigot + private final Plugin plugin; + private final int id; + + CraftTask() { + this(null, null, -1, -1); + } + + CraftTask(final Runnable task) { + this(null, task, -1, -1); + } + + // Spigot start + CraftTask(final Plugin plugin, final Runnable task, final int id, final long period) { + this.plugin = plugin; + this.task = task; + this.id = id; + this.period = period; + timings = task != null ? SpigotTimings.getPluginTaskTimings(this, period) : null; // Spigot + } + + public final int getTaskId() { + return id; + } + + public final Plugin getOwner() { + return plugin; + } + + public boolean isSync() { + return true; + } + + public void run() { + if (timings != null && isSync()) timings.startTiming(); // Spigot + task.run(); + if (timings != null && isSync()) timings.stopTiming(); // Spigot + } + + long getPeriod() { + return period; + } + + void setPeriod(long period) { + this.period = period; + } + + long getNextRun() { + return nextRun; + } + + void setNextRun(long nextRun) { + this.nextRun = nextRun; + } + + CraftTask getNext() { + return next; + } + + void setNext(CraftTask next) { + this.next = next; + } + + Class getTaskClass() { + return task.getClass(); + } + + public void cancel() { + Bukkit.getScheduler().cancelTask(id); + } + + /** + * This method properly sets the status to cancelled, synchronizing when required. + * + * @return false if it is a craft future task that has already begun execution, true otherwise + */ + boolean cancel0() { + setPeriod(-2l); + return true; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java new file mode 100644 index 0000000..7dedd02 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java @@ -0,0 +1,65 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.Map; + +import net.minecraft.server.IScoreboardCriteria; +import net.minecraft.server.ScoreboardObjective; + +import com.google.common.collect.ImmutableMap; + +final class CraftCriteria { + static final Map DEFAULTS; + static final CraftCriteria DUMMY; + + static { + ImmutableMap.Builder defaults = ImmutableMap.builder(); + + for (Map.Entry entry : ((Map ) IScoreboardCriteria.criteria).entrySet()) { + String name = entry.getKey().toString(); + IScoreboardCriteria criteria = (IScoreboardCriteria) entry.getValue(); + + defaults.put(name, new CraftCriteria(criteria)); + } + + DEFAULTS = defaults.build(); + DUMMY = DEFAULTS.get("dummy"); + } + + final IScoreboardCriteria criteria; + final String bukkitName; + + private CraftCriteria(String bukkitName) { + this.bukkitName = bukkitName; + this.criteria = DUMMY.criteria; + } + + private CraftCriteria(IScoreboardCriteria criteria) { + this.criteria = criteria; + this.bukkitName = criteria.getName(); + } + + static CraftCriteria getFromNMS(ScoreboardObjective objective) { + return DEFAULTS.get(objective.getCriteria().getName()); + } + + static CraftCriteria getFromBukkit(String name) { + final CraftCriteria criteria = DEFAULTS.get(name); + if (criteria != null) { + return criteria; + } + return new CraftCriteria(name); + } + + @Override + public boolean equals(Object that) { + if (!(that instanceof CraftCriteria)) { + return false; + } + return ((CraftCriteria) that).bukkitName.equals(this.bukkitName); + } + + @Override + public int hashCode() { + return this.bukkitName.hashCode() ^ CraftCriteria.class.hashCode(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java new file mode 100644 index 0000000..5bd8cf9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java @@ -0,0 +1,138 @@ +package org.bukkit.craftbukkit.scoreboard; + +import net.minecraft.server.Scoreboard; +import net.minecraft.server.ScoreboardObjective; + +import org.apache.commons.lang.Validate; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; + +final class CraftObjective extends CraftScoreboardComponent implements Objective { + private final ScoreboardObjective objective; + private final CraftCriteria criteria; + + CraftObjective(CraftScoreboard scoreboard, ScoreboardObjective objective) { + super(scoreboard); + this.objective = objective; + this.criteria = CraftCriteria.getFromNMS(objective); + } + + ScoreboardObjective getHandle() { + return objective; + } + + public String getName() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return objective.getName(); + } + + public String getDisplayName() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return objective.getDisplayName(); + } + + public void setDisplayName(String displayName) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(displayName, "Display name cannot be null"); + Validate.isTrue(displayName.length() <= 32, "Display name '" + displayName + "' is longer than the limit of 32 characters"); + CraftScoreboard scoreboard = checkState(); + + objective.setDisplayName(displayName); + } + + public String getCriteria() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return criteria.bukkitName; + } + + public boolean isModifiable() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return !criteria.criteria.isReadOnly(); + } + + public void setDisplaySlot(DisplaySlot slot) throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + Scoreboard board = scoreboard.board; + ScoreboardObjective objective = this.objective; + + for (int i = 0; i < CraftScoreboardTranslations.MAX_DISPLAY_SLOT; i++) { + if (board.getObjectiveForSlot(i) == objective) { + board.setDisplaySlot(i, null); + } + } + if (slot != null) { + int slotNumber = CraftScoreboardTranslations.fromBukkitSlot(slot); + board.setDisplaySlot(slotNumber, getHandle()); + } + } + + public DisplaySlot getDisplaySlot() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + Scoreboard board = scoreboard.board; + ScoreboardObjective objective = this.objective; + + for (int i = 0; i < CraftScoreboardTranslations.MAX_DISPLAY_SLOT; i++) { + if (board.getObjectiveForSlot(i) == objective) { + return CraftScoreboardTranslations.toBukkitSlot(i); + } + } + return null; + } + + public Score getScore(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException { + Validate.notNull(player, "Player cannot be null"); + CraftScoreboard scoreboard = checkState(); + + return new CraftScore(this, player.getName()); + } + + public Score getScore(String entry) throws IllegalArgumentException, IllegalStateException { + Validate.notNull(entry, "Entry cannot be null"); + if (entry.length() > 40) throw new IllegalArgumentException("Entry cannot be longer than 40 characters!"); // Spigot + CraftScoreboard scoreboard = checkState(); + + return new CraftScore(this, entry); + } + + @Override + public void unregister() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + scoreboard.board.unregisterObjective(objective); + } + + @Override + CraftScoreboard checkState() throws IllegalStateException { + if (getScoreboard().board.getObjective(objective.getName()) == null) { + throw new IllegalStateException("Unregistered scoreboard component"); + } + + return getScoreboard(); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + (this.objective != null ? this.objective.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final CraftObjective other = (CraftObjective) obj; + return !(this.objective != other.objective && (this.objective == null || !this.objective.equals(other.objective))); + } + + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java new file mode 100644 index 0000000..ee9d2ae --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java @@ -0,0 +1,71 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.Map; + +import net.minecraft.server.Scoreboard; +import net.minecraft.server.ScoreboardObjective; +import net.minecraft.server.ScoreboardScore; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; + +/** + * TL;DR: This class is special and lazily grabs a handle... + * ...because a handle is a full fledged (I think permanent) hashMap for the associated name. + *

    + * Also, as an added perk, a CraftScore will (intentionally) stay a valid reference so long as objective is valid. + */ +final class CraftScore implements Score { + private final String entry; + private final CraftObjective objective; + + CraftScore(CraftObjective objective, String entry) { + this.objective = objective; + this.entry = entry; + } + + public OfflinePlayer getPlayer() { + return Bukkit.getOfflinePlayer(entry); + } + + public String getEntry() { + return entry; + } + + public Objective getObjective() { + return objective; + } + + public int getScore() throws IllegalStateException { + Scoreboard board = objective.checkState().board; + + if (board.getPlayers().contains(entry)) { // Lazy + Map scores = board.getPlayerObjectives(entry); + ScoreboardScore score = scores.get(objective.getHandle()); + if (score != null) { // Lazy + return score.getScore(); + } + } + + return 0; // Lazy + } + + public void setScore(int score) throws IllegalStateException { + objective.checkState().board.getPlayerScoreForObjective(entry, objective.getHandle()).setScore(score); + } + + public CraftScoreboard getScoreboard() { + return objective.getScoreboard(); + } + + // Spigot start + @Override + public boolean isScoreSet() throws IllegalStateException { + Scoreboard board = objective.checkState().board; + + return board.getPlayers().contains(entry) && board.getPlayerObjectives(entry).containsKey(objective.getHandle()); + } + // Spigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java new file mode 100644 index 0000000..00b30f8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java @@ -0,0 +1,170 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.Collection; +import net.minecraft.server.Scoreboard; +import net.minecraft.server.ScoreboardObjective; +import net.minecraft.server.ScoreboardTeam; + +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.DisplaySlot; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Score; +import org.bukkit.scoreboard.Team; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +public final class CraftScoreboard implements org.bukkit.scoreboard.Scoreboard { + final Scoreboard board; + + CraftScoreboard(Scoreboard board) { + this.board = board; + } + + public CraftObjective registerNewObjective(String name, String criteria) throws IllegalArgumentException { + Validate.notNull(name, "Objective name cannot be null"); + Validate.notNull(criteria, "Criteria cannot be null"); + Validate.isTrue(name.length() <= 16, "The name '" + name + "' is longer than the limit of 16 characters"); + Validate.isTrue(board.getObjective(name) == null, "An objective of name '" + name + "' already exists"); + + CraftCriteria craftCriteria = CraftCriteria.getFromBukkit(criteria); + ScoreboardObjective objective = board.registerObjective(name, craftCriteria.criteria); + return new CraftObjective(this, objective); + } + + public Objective getObjective(String name) throws IllegalArgumentException { + Validate.notNull(name, "Name cannot be null"); + ScoreboardObjective nms = board.getObjective(name); + return nms == null ? null : new CraftObjective(this, nms); + } + + public ImmutableSet getObjectivesByCriteria(String criteria) throws IllegalArgumentException { + Validate.notNull(criteria, "Criteria cannot be null"); + + ImmutableSet.Builder objectives = ImmutableSet.builder(); + for (ScoreboardObjective netObjective : (Collection) this.board.getObjectives()) { + CraftObjective objective = new CraftObjective(this, netObjective); + if (objective.getCriteria().equals(criteria)) { + objectives.add(objective); + } + } + return objectives.build(); + } + + public ImmutableSet getObjectives() { + return ImmutableSet.copyOf(Iterables.transform((Collection) this.board.getObjectives(), new Function() { + + @Override + public Objective apply(ScoreboardObjective input) { + return new CraftObjective(CraftScoreboard.this, input); + } + })); + } + + public Objective getObjective(DisplaySlot slot) throws IllegalArgumentException { + Validate.notNull(slot, "Display slot cannot be null"); + ScoreboardObjective objective = board.getObjectiveForSlot(CraftScoreboardTranslations.fromBukkitSlot(slot)); + if (objective == null) { + return null; + } + return new CraftObjective(this, objective); + } + + public ImmutableSet getScores(OfflinePlayer player) throws IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + + return getScores(player.getName()); + } + + public ImmutableSet getScores(String entry) throws IllegalArgumentException { + Validate.notNull(entry, "Entry cannot be null"); + + ImmutableSet.Builder scores = ImmutableSet.builder(); + for (ScoreboardObjective objective : (Collection) this.board.getObjectives()) { + scores.add(new CraftScore(new CraftObjective(this, objective), entry)); + } + return scores.build(); + } + + public void resetScores(OfflinePlayer player) throws IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + + resetScores(player.getName()); + } + + public void resetScores(String entry) throws IllegalArgumentException { + Validate.notNull(entry, "Entry cannot be null"); + + for (ScoreboardObjective objective : (Collection) this.board.getObjectives()) { + board.resetPlayerScores(entry, objective); + } + } + + public Team getPlayerTeam(OfflinePlayer player) throws IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + + ScoreboardTeam team = board.getPlayerTeam(player.getName()); + return team == null ? null : new CraftTeam(this, team); + } + + public Team getEntryTeam(String entry) throws IllegalArgumentException { + Validate.notNull(entry, "Entry cannot be null"); + + ScoreboardTeam team = board.getPlayerTeam(entry); + return team == null ? null : new CraftTeam(this, team); + } + + public Team getTeam(String teamName) throws IllegalArgumentException { + Validate.notNull(teamName, "Team name cannot be null"); + + ScoreboardTeam team = board.getTeam(teamName); + return team == null ? null : new CraftTeam(this, team); + } + + public ImmutableSet getTeams() { + return ImmutableSet.copyOf(Iterables.transform((Collection) this.board.getTeams(), new Function() { + + @Override + public Team apply(ScoreboardTeam input) { + return new CraftTeam(CraftScoreboard.this, input); + } + })); + } + + public Team registerNewTeam(String name) throws IllegalArgumentException { + Validate.notNull(name, "Team name cannot be null"); + Validate.isTrue(name.length() <= 16, "Team name '" + name + "' is longer than the limit of 16 characters"); + Validate.isTrue(board.getTeam(name) == null, "Team name '" + name + "' is already in use"); + + return new CraftTeam(this, board.createTeam(name)); + } + + public ImmutableSet getPlayers() { + ImmutableSet.Builder players = ImmutableSet.builder(); + for (Object playerName : board.getPlayers()) { + players.add(Bukkit.getOfflinePlayer(playerName.toString())); + } + return players.build(); + } + + public ImmutableSet getEntries() { + ImmutableSet.Builder entries = ImmutableSet.builder(); + for (Object entry : board.getPlayers()) { + entries.add(entry.toString()); + } + return entries.build(); + } + + public void clearSlot(DisplaySlot slot) throws IllegalArgumentException { + Validate.notNull(slot, "Slot cannot be null"); + board.setDisplaySlot(CraftScoreboardTranslations.fromBukkitSlot(slot), null); + } + + // CraftBukkit method + public Scoreboard getHandle() { + return board; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardComponent.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardComponent.java new file mode 100644 index 0000000..d26d09d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardComponent.java @@ -0,0 +1,17 @@ +package org.bukkit.craftbukkit.scoreboard; + +abstract class CraftScoreboardComponent { + private CraftScoreboard scoreboard; + + CraftScoreboardComponent(CraftScoreboard scoreboard) { + this.scoreboard = scoreboard; + } + + abstract CraftScoreboard checkState() throws IllegalStateException; + + public CraftScoreboard getScoreboard() { + return scoreboard; + } + + abstract void unregister() throws IllegalStateException; +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java new file mode 100644 index 0000000..fbea5db --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java @@ -0,0 +1,119 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.IScoreboardCriteria; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PacketPlayOutScoreboardObjective; +import net.minecraft.server.PacketPlayOutScoreboardTeam; +import net.minecraft.server.Scoreboard; +import net.minecraft.server.ScoreboardObjective; +import net.minecraft.server.ScoreboardScore; +import net.minecraft.server.ScoreboardServer; +import net.minecraft.server.ScoreboardTeam; + +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.util.WeakCollection; +import org.bukkit.entity.Player; +import org.bukkit.scoreboard.ScoreboardManager; + +public final class CraftScoreboardManager implements ScoreboardManager { + private final CraftScoreboard mainScoreboard; + private final MinecraftServer server; + private final Collection scoreboards = new WeakCollection(); + private final Map playerBoards = new HashMap(); + + public CraftScoreboardManager(MinecraftServer minecraftserver, net.minecraft.server.Scoreboard scoreboardServer) { + mainScoreboard = new CraftScoreboard(scoreboardServer); + server = minecraftserver; + scoreboards.add(mainScoreboard); + } + + public CraftScoreboard getMainScoreboard() { + return mainScoreboard; + } + + public CraftScoreboard getNewScoreboard() { + org.spigotmc.AsyncCatcher.catchOp( "scoreboard creation"); // Spigot + CraftScoreboard scoreboard = new CraftScoreboard(new ScoreboardServer(server)); + scoreboards.add(scoreboard); + return scoreboard; + } + + // CraftBukkit method + public CraftScoreboard getPlayerBoard(CraftPlayer player) { + CraftScoreboard board = playerBoards.get(player); + return (CraftScoreboard) (board == null ? getMainScoreboard() : board); + } + + // CraftBukkit method + public void setPlayerBoard(CraftPlayer player, org.bukkit.scoreboard.Scoreboard bukkitScoreboard) throws IllegalArgumentException { + Validate.isTrue(bukkitScoreboard instanceof CraftScoreboard, "Cannot set player scoreboard to an unregistered Scoreboard"); + + CraftScoreboard scoreboard = (CraftScoreboard) bukkitScoreboard; + net.minecraft.server.Scoreboard oldboard = getPlayerBoard(player).getHandle(); + net.minecraft.server.Scoreboard newboard = scoreboard.getHandle(); + EntityPlayer entityplayer = player.getHandle(); + + if (oldboard == newboard) { + return; + } + + if (scoreboard == mainScoreboard) { + playerBoards.remove(player); + } else { + playerBoards.put(player, (CraftScoreboard) scoreboard); + } + + // Old objective tracking + HashSet removed = new HashSet(); + for (int i = 0; i < 3; ++i) { + ScoreboardObjective scoreboardobjective = oldboard.getObjectiveForSlot(i); + if (scoreboardobjective != null && !removed.contains(scoreboardobjective)) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutScoreboardObjective(scoreboardobjective, 1)); + removed.add(scoreboardobjective); + } + } + + // Old team tracking + Iterator iterator = oldboard.getTeams().iterator(); + while (iterator.hasNext()) { + ScoreboardTeam scoreboardteam = (ScoreboardTeam) iterator.next(); + entityplayer.playerConnection.sendPacket(new PacketPlayOutScoreboardTeam(scoreboardteam, 1)); + } + + // The above is the reverse of the below method. + server.getPlayerList().sendScoreboard((ScoreboardServer) newboard, player.getHandle()); + } + + // CraftBukkit method + public void removePlayer(Player player) { + playerBoards.remove(player); + } + + // CraftBukkit method + public Collection getScoreboardScores(IScoreboardCriteria criteria, String name, Collection collection) { + for (CraftScoreboard scoreboard : scoreboards) { + Scoreboard board = scoreboard.board; + for (ScoreboardObjective objective : (Iterable) board.getObjectivesForCriteria(criteria)) { + collection.add(board.getPlayerScoreForObjective(name, objective)); + } + } + return collection; + } + + // CraftBukkit method + public void updateAllScoresForList(IScoreboardCriteria criteria, String name, List of) { + for (ScoreboardScore score : getScoreboardScores(criteria, name, new ArrayList())) { + score.updateForList((List) of); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java new file mode 100644 index 0000000..d08e5a2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.scoreboard; + +import net.minecraft.server.Scoreboard; + +import org.bukkit.scoreboard.DisplaySlot; + +import com.google.common.collect.ImmutableBiMap; + +class CraftScoreboardTranslations { + static final int MAX_DISPLAY_SLOT = 3; + static ImmutableBiMap SLOTS = ImmutableBiMap.of( + DisplaySlot.BELOW_NAME, "belowName", + DisplaySlot.PLAYER_LIST, "list", + DisplaySlot.SIDEBAR, "sidebar"); + + private CraftScoreboardTranslations() {} + + static DisplaySlot toBukkitSlot(int i) { + return SLOTS.inverse().get(Scoreboard.getSlotName(i)); + } + + static int fromBukkitSlot(DisplaySlot slot) { + return Scoreboard.getSlotForName(SLOTS.get(slot)); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java new file mode 100644 index 0000000..f5ff0f7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java @@ -0,0 +1,242 @@ +package org.bukkit.craftbukkit.scoreboard; + +import java.util.Set; + +import net.minecraft.server.ScoreboardTeamBase.EnumNameTagVisibility; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.scoreboard.NameTagVisibility; +import org.bukkit.scoreboard.Team; + +import com.google.common.collect.ImmutableSet; + +import net.minecraft.server.ScoreboardTeam; + +final class CraftTeam extends CraftScoreboardComponent implements Team { + private final ScoreboardTeam team; + + CraftTeam(CraftScoreboard scoreboard, ScoreboardTeam team) { + super(scoreboard); + this.team = team; + } + + public String getName() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getName(); + } + + public String getDisplayName() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getDisplayName(); + } + + public void setDisplayName(String displayName) throws IllegalStateException { + Validate.notNull(displayName, "Display name cannot be null"); + Validate.isTrue(displayName.length() <= 32, "Display name '" + displayName + "' is longer than the limit of 32 characters"); + CraftScoreboard scoreboard = checkState(); + + team.setDisplayName(displayName); + } + + public String getPrefix() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getPrefix(); + } + + public void setPrefix(String prefix) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(prefix, "Prefix cannot be null"); + Validate.isTrue(prefix.length() <= 32, "Prefix '" + prefix + "' is longer than the limit of 32 characters"); + CraftScoreboard scoreboard = checkState(); + + team.setPrefix(prefix); + } + + public String getSuffix() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getSuffix(); + } + + public void setSuffix(String suffix) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(suffix, "Suffix cannot be null"); + Validate.isTrue(suffix.length() <= 32, "Suffix '" + suffix + "' is longer than the limit of 32 characters"); + CraftScoreboard scoreboard = checkState(); + + team.setSuffix(suffix); + } + + public boolean allowFriendlyFire() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.allowFriendlyFire(); + } + + public void setAllowFriendlyFire(boolean enabled) throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + team.setAllowFriendlyFire(enabled); + } + + public boolean canSeeFriendlyInvisibles() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.canSeeFriendlyInvisibles(); + } + + public void setCanSeeFriendlyInvisibles(boolean enabled) throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + team.setCanSeeFriendlyInvisibles(enabled); + } + + public NameTagVisibility getNameTagVisibility() throws IllegalArgumentException { + CraftScoreboard scoreboard = checkState(); + + return notchToBukkit(team.getNameTagVisibility()); + } + + public void setNameTagVisibility(NameTagVisibility visibility) throws IllegalArgumentException { + CraftScoreboard scoreboard = checkState(); + + team.setNameTagVisibility(bukkitToNotch(visibility)); + } + + public Set getPlayers() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + ImmutableSet.Builder players = ImmutableSet.builder(); + for (String playerName : team.getPlayerNameSet()) { + players.add(Bukkit.getOfflinePlayer(playerName)); + } + return players.build(); + } + + @Override + public Set getEntries() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + ImmutableSet.Builder entries = ImmutableSet.builder(); + for (String playerName: team.getPlayerNameSet()){ + entries.add(playerName); + } + return entries.build(); + } + + public int getSize() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + return team.getPlayerNameSet().size(); + } + + public void addPlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + addEntry(player.getName()); + } + + public void addEntry(String entry) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(entry, "Entry cannot be null"); + CraftScoreboard scoreboard = checkState(); + + scoreboard.board.addPlayerToTeam(entry, team.getName()); + } + + public boolean removePlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + return removeEntry(player.getName()); + } + + public boolean removeEntry(String entry) throws IllegalStateException, IllegalArgumentException { + Validate.notNull(entry, "Entry cannot be null"); + CraftScoreboard scoreboard = checkState(); + + if (!team.getPlayerNameSet().contains(entry)) { + return false; + } + + scoreboard.board.removePlayerFromTeam(entry, team); + return true; + } + + public boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException { + Validate.notNull(player, "OfflinePlayer cannot be null"); + return hasEntry(player.getName()); + } + + public boolean hasEntry(String entry) throws IllegalArgumentException, IllegalStateException { + Validate.notNull("Entry cannot be null"); + + CraftScoreboard scoreboard = checkState(); + + return team.getPlayerNameSet().contains(entry); + } + + @Override + public void unregister() throws IllegalStateException { + CraftScoreboard scoreboard = checkState(); + + scoreboard.board.removeTeam(team); + } + + public static EnumNameTagVisibility bukkitToNotch(NameTagVisibility visibility) { + switch (visibility) { + case ALWAYS: + return EnumNameTagVisibility.ALWAYS; + case NEVER: + return EnumNameTagVisibility.NEVER; + case HIDE_FOR_OTHER_TEAMS: + return EnumNameTagVisibility.HIDE_FOR_OTHER_TEAMS; + case HIDE_FOR_OWN_TEAM: + return EnumNameTagVisibility.HIDE_FOR_OWN_TEAM; + default: + throw new IllegalArgumentException("Unknown visibility level " + visibility); + } + } + + public static NameTagVisibility notchToBukkit(EnumNameTagVisibility visibility) { + switch (visibility) { + case ALWAYS: + return NameTagVisibility.ALWAYS; + case NEVER: + return NameTagVisibility.NEVER; + case HIDE_FOR_OTHER_TEAMS: + return NameTagVisibility.HIDE_FOR_OTHER_TEAMS; + case HIDE_FOR_OWN_TEAM: + return NameTagVisibility.HIDE_FOR_OWN_TEAM; + default: + throw new IllegalArgumentException("Unknown visibility level " + visibility); + } + } + + @Override + CraftScoreboard checkState() throws IllegalStateException { + if (getScoreboard().board.getTeam(team.getName()) == null) { + throw new IllegalStateException("Unregistered scoreboard component"); + } + + return getScoreboard(); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 43 * hash + (this.team != null ? this.team.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final CraftTeam other = (CraftTeam) obj; + return !(this.team != other.team && (this.team == null || !this.team.equals(other.team))); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java new file mode 100644 index 0000000..193c362 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java @@ -0,0 +1,354 @@ +package org.bukkit.craftbukkit.util; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + +import org.apache.commons.lang.Validate; + +/** + * Executes tasks using a multi-stage process executor. Synchronous executions are via {@link AsynchronousExecutor#finishActive()} or the {@link AsynchronousExecutor#get(Object)} methods. + *

  • Stage 1 creates the object from a parameter, and is usually called asynchronously. + *
  • Stage 2 takes the parameter and object from stage 1 and does any synchronous processing to prepare it. + *
  • Stage 3 takes the parameter and object from stage 1, as well as a callback that was registered, and performs any synchronous calculations. + * + * @param

    The type of parameter you provide to make the object that will be created. It should implement {@link Object#hashCode()} and {@link Object#equals(Object)} if you want to get the value early. + * @param The type of object you provide. This is created in stage 1, and passed to stage 2, 3, and returned if get() is called. + * @param The type of callback you provide. You may register many of these to be passed to the provider in stage 3, one at a time. + * @param A type of exception you may throw and expect to be handled by the main thread + * @author Wesley Wolfe (c) 2012, 2014 + */ +public final class AsynchronousExecutor { + + public static interface CallBackProvider extends ThreadFactory { + + /** + * Normally an asynchronous call, but can be synchronous + * + * @param parameter parameter object provided + * @return the created object + */ + T callStage1(P parameter) throws E; + + /** + * Synchronous call + * + * @param parameter parameter object provided + * @param object the previously created object + */ + void callStage2(P parameter, T object) throws E; + + /** + * Synchronous call, called multiple times, once per registered callback + * + * @param parameter parameter object provided + * @param object the previously created object + * @param callback the current callback to execute + */ + void callStage3(P parameter, T object, C callback) throws E; + } + + @SuppressWarnings("rawtypes") + static final AtomicIntegerFieldUpdater STATE_FIELD = AtomicIntegerFieldUpdater.newUpdater(AsynchronousExecutor.Task.class, "state"); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static boolean set(AsynchronousExecutor.Task $this, int expected, int value) { + return STATE_FIELD.compareAndSet($this, expected, value); + } + + class Task implements Runnable { + static final int PENDING = 0x0; + static final int STAGE_1_ASYNC = PENDING + 1; + static final int STAGE_1_SYNC = STAGE_1_ASYNC + 1; + static final int STAGE_1_COMPLETE = STAGE_1_SYNC + 1; + static final int FINISHED = STAGE_1_COMPLETE + 1; + + volatile int state = PENDING; + final P parameter; + T object; + final List callbacks = new LinkedList(); + E t = null; + + Task(final P parameter) { + this.parameter = parameter; + } + + public void run() { + if (initAsync()) { + finished.add(this); + } + } + + boolean initAsync() { + if (set(this, PENDING, STAGE_1_ASYNC)) { + boolean ret = true; + + try { + init(); + } finally { + if (set(this, STAGE_1_ASYNC, STAGE_1_COMPLETE)) { + // No one is/will be waiting + } else { + // We know that the sync thread will be waiting + synchronized (this) { + if (state != STAGE_1_SYNC) { + // They beat us to the synchronized block + this.notifyAll(); + } else { + // We beat them to the synchronized block + } + state = STAGE_1_COMPLETE; // They're already synchronized, atomic locks are not needed + } + // We want to return false, because we know a synchronous task already handled the finish() + ret = false; // Don't return inside finally; VERY bad practice. + } + } + + return ret; + } else { + return false; + } + } + + void initSync() { + if (set(this, PENDING, STAGE_1_COMPLETE)) { + // If we succeed that variable switch, good as done + init(); + } else if (set(this, STAGE_1_ASYNC, STAGE_1_SYNC)) { + // Async thread is running, but this shouldn't be likely; we need to sync to wait on them because of it. + synchronized (this) { + if (set(this, STAGE_1_SYNC, PENDING)) { // They might NOT synchronized yet, atomic lock IS needed + // We are the first into the lock + while (state != STAGE_1_COMPLETE) { + try { + this.wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Unable to handle interruption on " + parameter, e); + } + } + } else { + // They beat us to the synchronized block + } + } + } else { + // Async thread is not pending, the more likely situation for a task not pending + } + } + + @SuppressWarnings("unchecked") + void init() { + try { + object = provider.callStage1(parameter); + } catch (final Throwable t) { + this.t = (E) t; + } + } + + @SuppressWarnings("unchecked") + T get() throws E { + initSync(); + if (callbacks.isEmpty()) { + // 'this' is a placeholder to prevent callbacks from being empty during finish call + // See get method below + callbacks.add((C) this); + } + finish(); + return object; + } + + void finish() throws E { + switch (state) { + default: + case PENDING: + case STAGE_1_ASYNC: + case STAGE_1_SYNC: + throw new IllegalStateException("Attempting to finish unprepared(" + state + ") task(" + parameter + ")"); + case STAGE_1_COMPLETE: + try { + if (t != null) { + throw t; + } + if (callbacks.isEmpty()) { + return; + } + + final CallBackProvider provider = AsynchronousExecutor.this.provider; + final P parameter = this.parameter; + final T object = this.object; + + provider.callStage2(parameter, object); + for (C callback : callbacks) { + if (callback == this) { + // 'this' is a placeholder to prevent callbacks from being empty on a get() call + // See get method above + continue; + } + provider.callStage3(parameter, object, callback); + } + } finally { + tasks.remove(parameter); + state = FINISHED; + } + case FINISHED: + } + } + + boolean drop() { + if (set(this, PENDING, FINISHED)) { + // If we succeed that variable switch, good as forgotten + tasks.remove(parameter); + return true; + } else { + // We need the async thread to finish normally to properly dispose of the task + return false; + } + } + } + + final CallBackProvider provider; + final Queue finished = new ConcurrentLinkedQueue(); + final Map tasks = new HashMap(); + final ThreadPoolExecutor pool; + + /** + * Uses a thread pool to pass executions to the provider. + * @see AsynchronousExecutor + */ + public AsynchronousExecutor(final CallBackProvider provider, final int coreSize) { + Validate.notNull(provider, "Provider cannot be null"); + this.provider = provider; + + // We have an unbound queue size so do not need a max thread size + pool = new ThreadPoolExecutor(coreSize, Integer.MAX_VALUE, 60l, TimeUnit.SECONDS, new LinkedBlockingQueue(), provider); + } + + /** + * Adds a callback to the parameter provided, adding parameter to the queue if needed. + *

    + * This should always be synchronous. + */ + public void add(P parameter, C callback) { + Task task = tasks.get(parameter); + if (task == null) { + tasks.put(parameter, task = new Task(parameter)); + pool.execute(task); + } + task.callbacks.add(callback); + } + + /** + * This removes a particular callback from the specified parameter. + *

    + * If no callbacks remain for a given parameter, then the {@link CallBackProvider CallBackProvider's} stages may be omitted from execution. + * Stage 3 will have no callbacks, stage 2 will be skipped unless a {@link #get(Object)} is used, and stage 1 will be avoided on a best-effort basis. + *

    + * Subsequent calls to {@link #getSkipQueue(Object)} will always work. + *

    + * Subsequent calls to {@link #get(Object)} might work. + *

    + * This should always be synchronous + * @return true if no further execution for the parameter is possible, such that, no exceptions will be thrown in {@link #finishActive()} for the parameter, and {@link #get(Object)} will throw an {@link IllegalStateException}, false otherwise + * @throws IllegalStateException if parameter is not in the queue anymore + * @throws IllegalStateException if the callback was not specified for given parameter + */ + public boolean drop(P parameter, C callback) throws IllegalStateException { + final Task task = tasks.get(parameter); + if (task == null) { + return true; + } + if (!task.callbacks.remove(callback)) { + throw new IllegalStateException("Unknown " + callback + " for " + parameter); + } + if (task.callbacks.isEmpty()) { + return task.drop(); + } + return false; + } + + /** + * This method attempts to skip the waiting period for said parameter. + *

    + * This should always be synchronous. + * @throws IllegalStateException if the parameter is not in the queue anymore, or sometimes if called from asynchronous thread + */ + public T get(P parameter) throws E, IllegalStateException { + final Task task = tasks.get(parameter); + if (task == null) { + throw new IllegalStateException("Unknown " + parameter); + } + return task.get(); + } + + /** + * Processes a parameter as if it was in the queue, without ever passing to another thread. + */ + public T getSkipQueue(P parameter) throws E { + return skipQueue(parameter); + } + + /** + * Processes a parameter as if it was in the queue, without ever passing to another thread. + */ + public T getSkipQueue(P parameter, C callback) throws E { + final T object = skipQueue(parameter); + provider.callStage3(parameter, object, callback); + return object; + } + + /** + * Processes a parameter as if it was in the queue, without ever passing to another thread. + */ + public T getSkipQueue(P parameter, C...callbacks) throws E { + final CallBackProvider provider = this.provider; + final T object = skipQueue(parameter); + for (C callback : callbacks) { + provider.callStage3(parameter, object, callback); + } + return object; + } + + /** + * Processes a parameter as if it was in the queue, without ever passing to another thread. + */ + public T getSkipQueue(P parameter, Iterable callbacks) throws E { + final CallBackProvider provider = this.provider; + final T object = skipQueue(parameter); + for (C callback : callbacks) { + provider.callStage3(parameter, object, callback); + } + return object; + } + + private T skipQueue(P parameter) throws E { + Task task = tasks.get(parameter); + if (task != null) { + return task.get(); + } + T object = provider.callStage1(parameter); + provider.callStage2(parameter, object); + return object; + } + + /** + * This is the 'heartbeat' that should be called synchronously to finish any pending tasks + */ + public void finishActive() throws E { + final Queue finished = this.finished; + while (!finished.isEmpty()) { + finished.poll().finish(); + } + } + + public void setActiveThreads(final int coreSize) { + pool.setCorePoolSize(coreSize); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java new file mode 100644 index 0000000..2dbedd2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java @@ -0,0 +1,66 @@ +package org.bukkit.craftbukkit.util; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.server.Block; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.IBlockData; + +import org.bukkit.World; +import org.bukkit.block.BlockState; + +public class BlockStateListPopulator { + private final World world; + private final List list; + + public BlockStateListPopulator(World world) { + this(world, new ArrayList()); + } + + public BlockStateListPopulator(World world, List list) { + this.world = world; + this.list = list; + } + + public void setTypeAndData(int x, int y, int z, Block block, int data, int light) { + BlockState state = world.getBlockAt(x, y, z).getState(); + state.setTypeId(Block.getId(block)); + state.setRawData((byte) data); + list.add(state); + } + public void setTypeId(int x, int y, int z, int type) { + BlockState state = world.getBlockAt(x, y, z).getState(); + state.setTypeId(type); + list.add(state); + } + + public void setTypeUpdate(int x, int y, int z, Block block) { + this.setType(x, y, z, block); + } + + public void setTypeUpdate(BlockPosition position, IBlockData data) { + setTypeAndData(position.getX(), position.getY(), position.getZ(), data.getBlock(), data.getBlock().toLegacyData(data), 0); + + } + + public void setType(int x, int y, int z, Block block) { + BlockState state = world.getBlockAt(x, y, z).getState(); + state.setTypeId(Block.getId(block)); + list.add(state); + } + + public void updateList() { + for (BlockState state : list) { + state.update(true); + } + } + + public List getList() { + return list; + } + + public World getWorld() { + return world; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java new file mode 100644 index 0000000..38ef821 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -0,0 +1,248 @@ +package org.bukkit.craftbukkit.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import net.minecraft.server.ChatClickable; +import net.minecraft.server.ChatComponentText; +import net.minecraft.server.ChatModifier; +import net.minecraft.server.EnumChatFormat; +import net.minecraft.server.ChatClickable.EnumClickAction; +import net.minecraft.server.IChatBaseComponent; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import net.minecraft.server.ChatMessage; + +public final class CraftChatMessage { + + private static final Pattern LINK_PATTERN = Pattern.compile("((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " \\n]|$))))"); + private static class StringMessage { + private static final Map formatMap; + private static final Pattern INCREMENTAL_PATTERN = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-or])|(\\n)|((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " \\n]|$))))", Pattern.CASE_INSENSITIVE); + + static { + Builder builder = ImmutableMap.builder(); + for (EnumChatFormat format : EnumChatFormat.values()) { + builder.put(Character.toLowerCase(format.toString().charAt(1)), format); + } + formatMap = builder.build(); + } + + private final List list = new ArrayList(); + private IChatBaseComponent currentChatComponent = new ChatComponentText(""); + private ChatModifier modifier = new ChatModifier(); + private final IChatBaseComponent[] output; + private int currentIndex; + private final String message; + + private StringMessage(String message, boolean keepNewlines) { + this.message = message; + if (message == null) { + output = new IChatBaseComponent[] { currentChatComponent }; + return; + } + list.add(currentChatComponent); + + Matcher matcher = INCREMENTAL_PATTERN.matcher(message); + String match = null; + while (matcher.find()) { + int groupId = 0; + while ((match = matcher.group(++groupId)) == null) { + // NOOP + } + appendNewComponent(matcher.start(groupId)); + switch (groupId) { + case 1: + EnumChatFormat format = formatMap.get(match.toLowerCase().charAt(1)); + if (format == EnumChatFormat.RESET) { + modifier = new ChatModifier(); + } else if (format.isFormat()) { + switch (format) { + case BOLD: + modifier.setBold(Boolean.TRUE); + break; + case ITALIC: + modifier.setItalic(Boolean.TRUE); + break; + case STRIKETHROUGH: + modifier.setStrikethrough(Boolean.TRUE); + break; + case UNDERLINE: + modifier.setUnderline(Boolean.TRUE); + break; + case OBFUSCATED: + modifier.setRandom(Boolean.TRUE); + break; + default: + throw new AssertionError("Unexpected message format"); + } + } else { // Color resets formatting + modifier = new ChatModifier().setColor(format); + } + break; + case 2: + if (keepNewlines) { + currentChatComponent.addSibling(new ChatComponentText("\n")); + } else { + currentChatComponent = null; + } + break; + case 3: + if ( !( match.startsWith( "http://" ) || match.startsWith( "https://" ) ) ) { + match = "http://" + match; + } + modifier.setChatClickable(new ChatClickable(EnumClickAction.OPEN_URL, match)); + appendNewComponent(matcher.end(groupId)); + modifier.setChatClickable((ChatClickable) null); + } + currentIndex = matcher.end(groupId); + } + + if (currentIndex < message.length()) { + appendNewComponent(message.length()); + } + + output = list.toArray(new IChatBaseComponent[list.size()]); + } + + private void appendNewComponent(int index) { + if (index <= currentIndex) { + return; + } + IChatBaseComponent addition = new ChatComponentText(message.substring(currentIndex, index)).setChatModifier(modifier); + currentIndex = index; + modifier = modifier.clone(); + if (currentChatComponent == null) { + currentChatComponent = new ChatComponentText(""); + list.add(currentChatComponent); + } + currentChatComponent.addSibling(addition); + } + + private IChatBaseComponent[] getOutput() { + return output; + } + } + + public static IChatBaseComponent[] fromString(String message) { + return fromString(message, false); + } + + public static IChatBaseComponent[] fromString(String message, boolean keepNewlines) { + return new StringMessage(message, keepNewlines).getOutput(); + } + + public static String fromComponent(IChatBaseComponent component) { + return fromComponent(component, EnumChatFormat.BLACK); + } + + public static String fromComponent(IChatBaseComponent component, EnumChatFormat defaultColor) { + if (component == null) return ""; + StringBuilder out = new StringBuilder(); + + for (IChatBaseComponent c : (Iterable) component) { + ChatModifier modi = c.getChatModifier(); + out.append(modi.getColor() == null ? defaultColor : modi.getColor()); + if (modi.isBold()) { + out.append(EnumChatFormat.BOLD); + } + if (modi.isItalic()) { + out.append(EnumChatFormat.ITALIC); + } + if (modi.isUnderlined()) { + out.append(EnumChatFormat.UNDERLINE); + } + if (modi.isStrikethrough()) { + out.append(EnumChatFormat.STRIKETHROUGH); + } + if (modi.isRandom()) { + out.append(EnumChatFormat.OBFUSCATED); + } + out.append(c.getText()); + } + return out.toString().replaceFirst("^(" + defaultColor + ")*", ""); + } + + public static IChatBaseComponent fixComponent(IChatBaseComponent component) { + Matcher matcher = LINK_PATTERN.matcher(""); + return fixComponent(component, matcher); + } + + private static IChatBaseComponent fixComponent(IChatBaseComponent component, Matcher matcher) { + if (component instanceof ChatComponentText) { + ChatComponentText text = ((ChatComponentText) component); + String msg = text.g(); + if (matcher.reset(msg).find()) { + matcher.reset(); + + ChatModifier modifier = text.getChatModifier() != null ? + text.getChatModifier() : new ChatModifier(); + List extras = new ArrayList(); + List extrasOld = new ArrayList(text.a()); + component = text = new ChatComponentText(""); + + int pos = 0; + while (matcher.find()) { + String match = matcher.group(); + + if ( !( match.startsWith( "http://" ) || match.startsWith( "https://" ) ) ) { + match = "http://" + match; + } + + ChatComponentText prev = new ChatComponentText(msg.substring(pos, matcher.start())); + prev.setChatModifier(modifier); + extras.add(prev); + + ChatComponentText link = new ChatComponentText(matcher.group()); + ChatModifier linkModi = modifier.clone(); + linkModi.setChatClickable(new ChatClickable(EnumClickAction.OPEN_URL, match)); + link.setChatModifier(linkModi); + extras.add(link); + + pos = matcher.end(); + } + + ChatComponentText prev = new ChatComponentText(msg.substring(pos)); + prev.setChatModifier(modifier); + extras.add(prev); + extras.addAll(extrasOld); + + for (IChatBaseComponent c : extras) { + text.addSibling(c); + } + } + } + + List extras = component.a(); + for (int i = 0; i < extras.size(); i++) { + IChatBaseComponent comp = (IChatBaseComponent) extras.get(i); + if (comp.getChatModifier() != null && comp.getChatModifier().h() == null) { + extras.set(i, fixComponent(comp, matcher)); + } + } + + if (component instanceof ChatMessage) { + Object[] subs = ((ChatMessage) component).j(); + for (int i = 0; i < subs.length; i++) { + Object comp = subs[i]; + if (comp instanceof IChatBaseComponent) { + IChatBaseComponent c = (IChatBaseComponent) comp; + if (c.getChatModifier() != null && c.getChatModifier().h() == null) { + subs[i] = fixComponent(c, matcher); + } + } else if (comp instanceof String && matcher.reset((String)comp).find()) { + subs[i] = fixComponent(new ChatComponentText((String) comp), matcher); + } + } + } + + return component; + } + + private CraftChatMessage() { + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftDamageSource.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftDamageSource.java new file mode 100644 index 0000000..a8e2b5e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftDamageSource.java @@ -0,0 +1,31 @@ +package org.bukkit.craftbukkit.util; + +import net.minecraft.server.DamageSource; + +// Util class to create custom DamageSources. +public final class CraftDamageSource extends DamageSource { + public static DamageSource copyOf(final DamageSource original) { + CraftDamageSource newSource = new CraftDamageSource(original.translationIndex); + + // Check ignoresArmor + if (original.ignoresArmor()) { + newSource.setIgnoreArmor(); + } + + // Check magic + if (original.isMagic()) { + newSource.setMagic(); + } + + // Check fire + if (original.isExplosion()) { + newSource.setExplosion(); + } + + return newSource; + } + + private CraftDamageSource(String identifier) { + super(identifier); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java new file mode 100644 index 0000000..bd0b887 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java @@ -0,0 +1,12 @@ +package org.bukkit.craftbukkit.util; + +import org.bukkit.util.CachedServerIcon; + +public class CraftIconCache implements CachedServerIcon { + public final String value; + + public String getData() { return value; } // Spigot + public CraftIconCache(final String value) { + this.value = value; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java new file mode 100644 index 0000000..589dba7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -0,0 +1,146 @@ +package org.bukkit.craftbukkit.util; + +import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.minecraft.server.Block; +import net.minecraft.server.Blocks; +import net.minecraft.server.Item; +import net.minecraft.server.MinecraftKey; +import net.minecraft.server.MojangsonParseException; +import net.minecraft.server.MojangsonParser; +import net.minecraft.server.NBTTagCompound; +import net.minecraft.server.StatisticList; + +import org.bukkit.Achievement; +import org.bukkit.Material; +import org.bukkit.Statistic; +import org.bukkit.UnsafeValues; +import org.bukkit.craftbukkit.CraftStatistic; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.StringUtil; + +@SuppressWarnings("deprecation") +public final class CraftMagicNumbers implements UnsafeValues { + public static final UnsafeValues INSTANCE = new CraftMagicNumbers(); + + private CraftMagicNumbers() {} + + public static Block getBlock(org.bukkit.block.Block block) { + return getBlock(block.getType()); + } + + @Deprecated + // A bad method for bad magic. + public static Block getBlock(int id) { + return getBlock(Material.getMaterial(id)); + } + + @Deprecated + // A bad method for bad magic. + public static int getId(Block block) { + return Block.getId(block); + } + + public static Material getMaterial(Block block) { + return Material.getMaterial(Block.getId(block)); + } + + public static Item getItem(Material material) { + // TODO: Don't use ID + Item item = Item.getById(material.getId()); + return item; + } + + @Deprecated + // A bad method for bad magic. + public static Item getItem(int id) { + return Item.getById(id); + } + + @Deprecated + // A bad method for bad magic. + public static int getId(Item item) { + return Item.getId(item); + } + + public static Material getMaterial(Item item) { + // TODO: Don't use ID + Material material = Material.getMaterial(Item.getId(item)); + + if (material == null) { + return Material.AIR; + } + + return material; + } + + public static Block getBlock(Material material) { + // TODO: Don't use ID + Block block = Block.getById(material.getId()); + + if (block == null) { + return Blocks.AIR; + } + + return block; + } + + @Override + public Material getMaterialFromInternalName(String name) { + return getMaterial((Item) Item.REGISTRY.get(new MinecraftKey(name))); + } + + @Override + public List tabCompleteInternalMaterialName(String token, List completions) { + ArrayList results = Lists.newArrayList(); + for (MinecraftKey key : (Set)Item.REGISTRY.keySet()) { + results.add(key.toString()); + } + return StringUtil.copyPartialMatches(token, results, completions); + } + + @Override + public ItemStack modifyItemStack(ItemStack stack, String arguments) { + net.minecraft.server.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); + + try { + nmsStack.setTag((NBTTagCompound) MojangsonParser.parse(arguments)); + } catch (MojangsonParseException ex) { + Logger.getLogger(CraftMagicNumbers.class.getName()).log(Level.SEVERE, null, ex); + } + + stack.setItemMeta(CraftItemStack.getItemMeta(nmsStack)); + + return stack; + } + + @Override + public Statistic getStatisticFromInternalName(String name) { + return CraftStatistic.getBukkitStatisticByName(name); + } + + @Override + public Achievement getAchievementFromInternalName(String name) { + return CraftStatistic.getBukkitAchievementByName(name); + } + + @Override + public List tabCompleteInternalStatisticOrAchievementName(String token, List completions) { + List matches = new ArrayList(); + Iterator iterator = StatisticList.stats.iterator(); + while (iterator.hasNext()) { + String statistic = ((net.minecraft.server.Statistic) iterator.next()).name; + if (statistic.startsWith(token)) { + matches.add(statistic); + } + } + return matches; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/DatFileFilter.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/DatFileFilter.java new file mode 100644 index 0000000..712c44f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/DatFileFilter.java @@ -0,0 +1,10 @@ +package org.bukkit.craftbukkit.util; + +import java.io.File; +import java.io.FilenameFilter; + +public class DatFileFilter implements FilenameFilter { + public boolean accept(File dir, String name) { + return name.endsWith(".dat"); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ForwardLogHandler.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ForwardLogHandler.java new file mode 100644 index 0000000..74ce4b2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ForwardLogHandler.java @@ -0,0 +1,52 @@ +package org.bukkit.craftbukkit.util; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +public class ForwardLogHandler extends ConsoleHandler { + private Map cachedLoggers = new ConcurrentHashMap(); + + private Logger getLogger(String name) { + Logger logger = cachedLoggers.get(name); + if (logger == null) { + logger = LogManager.getLogger(name); + cachedLoggers.put(name, logger); + } + + return logger; + } + + @Override + public void publish(LogRecord record) { + Logger logger = getLogger(String.valueOf(record.getLoggerName())); // See SPIGOT-1230 + Throwable exception = record.getThrown(); + Level level = record.getLevel(); + String message = getFormatter().formatMessage(record); + + if (level == Level.SEVERE) { + logger.error(message, exception); + } else if (level == Level.WARNING) { + logger.warn(message, exception); + } else if (level == Level.INFO) { + logger.info(message, exception); + } else if (level == Level.CONFIG) { + logger.debug(message, exception); + } else { + logger.trace(message, exception); + } + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/HashTreeSet.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/HashTreeSet.java new file mode 100644 index 0000000..80a5c29 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/HashTreeSet.java @@ -0,0 +1,117 @@ +package org.bukkit.craftbukkit.util; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; + +public class HashTreeSet implements Set { + + private HashSet hash = new HashSet(); + private TreeSet tree = new TreeSet(); + + public HashTreeSet() { + + } + + @Override + public int size() { + return hash.size(); + } + + @Override + public boolean isEmpty() { + return hash.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return hash.contains(o); + } + + @Override + public Iterator iterator() { + return new Iterator() { + + private Iterator it = tree.iterator(); + private V last; + + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public V next() { + return last = it.next(); + } + + @Override + public void remove() { + if (last == null) { + throw new IllegalStateException(); + } + it.remove(); + hash.remove(last); + last = null; + } + }; + } + + @Override + public Object[] toArray() { + return hash.toArray(); + } + + @Override + public Object[] toArray(Object[] a) { + return hash.toArray(a); + } + + @Override + public boolean add(V e) { + hash.add(e); + return tree.add(e); + } + + @Override + public boolean remove(Object o) { + hash.remove(o); + return tree.remove(o); + } + + @Override + public boolean containsAll(Collection c) { + return hash.containsAll(c); + } + + @Override + public boolean addAll(Collection c) { + tree.addAll(c); + return hash.addAll(c); + } + + @Override + public boolean retainAll(Collection c) { + tree.retainAll(c); + return hash.retainAll(c); + } + + @Override + public boolean removeAll(Collection c) { + tree.removeAll(c); + return hash.removeAll(c); + } + + @Override + public void clear() { + hash.clear(); + tree.clear(); + } + + public V first() { + return tree.first(); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LazyHashSet.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LazyHashSet.java new file mode 100644 index 0000000..d106c0a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LazyHashSet.java @@ -0,0 +1,98 @@ +package org.bukkit.craftbukkit.util; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + + +public abstract class LazyHashSet implements Set { + Set reference = null; + + public int size() { + return getReference().size(); + } + + public boolean isEmpty() { + return getReference().isEmpty(); + } + + public boolean contains(Object o) { + return getReference().contains(o); + } + + public Iterator iterator() { + return getReference().iterator(); + } + + public Object[] toArray() { + return getReference().toArray(); + } + + public T[] toArray(T[] a) { + return getReference().toArray(a); + } + + public boolean add(E o) { + return getReference().add(o); + } + + public boolean remove(Object o) { + return getReference().remove(o); + } + + public boolean containsAll(Collection c) { + return getReference().containsAll(c); + } + + public boolean addAll(Collection c) { + return getReference().addAll(c); + } + + public boolean retainAll(Collection c) { + return getReference().retainAll(c); + } + + public boolean removeAll(Collection c) { + return getReference().removeAll(c); + } + + public void clear() { + getReference().clear(); + } + + public Set getReference() { + Set reference = this.reference ; + if (reference != null) { + return reference; + } + return this.reference = makeReference(); + } + + abstract Set makeReference(); + + public boolean isLazy() { + return reference == null; + } + + @Override + public int hashCode() { + return 157 * getReference().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || this.getClass() != obj.getClass()) { + return false; + } + LazyHashSet that = (LazyHashSet) obj; + return (this.isLazy() && that.isLazy()) || this.getReference().equals(that.getReference()); + } + + @Override + public String toString() { + return getReference().toString(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java new file mode 100644 index 0000000..ae19da4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java @@ -0,0 +1,25 @@ +package org.bukkit.craftbukkit.util; + +import java.util.HashSet; +import java.util.List; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.MinecraftServer; + +import org.bukkit.entity.Player; + +public class LazyPlayerSet extends LazyHashSet { + + @Override + HashSet makeReference() { + if (reference != null) { + throw new IllegalStateException("Reference already created!"); + } + List players = MinecraftServer.getServer().getPlayerList().players; + HashSet reference = new HashSet(players.size()); + for (EntityPlayer player : players) { + reference.add(player.getBukkitEntity()); + } + return reference; + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongHash.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongHash.java new file mode 100644 index 0000000..691cafd --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongHash.java @@ -0,0 +1,15 @@ +package org.bukkit.craftbukkit.util; + +public class LongHash { + public static long toLong(int msw, int lsw) { + return ((long) msw << 32) + lsw - Integer.MIN_VALUE; + } + + public static int msw(long l) { + return (int) (l >> 32); + } + + public static int lsw(long l) { + return (int) (l & 0xFFFFFFFF) + Integer.MIN_VALUE; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java new file mode 100644 index 0000000..a213579 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java @@ -0,0 +1,302 @@ +/* + Based on CompactHashSet Copyright 2011 Ontopia Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package org.bukkit.craftbukkit.util; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.ConcurrentModificationException; +import java.util.NoSuchElementException; + +public class LongHashSet { + private final static int INITIAL_SIZE = 3; + private final static double LOAD_FACTOR = 0.75; + + private final static long FREE = 0; + private final static long REMOVED = Long.MIN_VALUE; + + private int freeEntries; + private int elements; + private long[] values; + private int modCount; + + public LongHashSet() { + this(INITIAL_SIZE); + } + + public LongHashSet(int size) { + values = new long[(size==0 ? 1 : size)]; + elements = 0; + freeEntries = values.length; + modCount = 0; + } + + public Iterator iterator() { + return new Itr(); + } + + public int size() { + return elements; + } + + public boolean isEmpty() { + return elements == 0; + } + + public boolean contains(int msw, int lsw) { + return contains(LongHash.toLong(msw, lsw)); + } + + public boolean contains(long value) { + int hash = hash(value); + int index = (hash & 0x7FFFFFFF) % values.length; + int offset = 1; + + // search for the object (continue while !null and !this object) + while(values[index] != FREE && !(hash(values[index]) == hash && values[index] == value)) { + index = ((index + offset) & 0x7FFFFFFF) % values.length; + offset = offset * 2 + 1; + + if (offset == -1) { + offset = 2; + } + } + + return values[index] != FREE; + } + + public boolean add(int msw, int lsw) { + return add(LongHash.toLong(msw, lsw)); + } + + public boolean add(long value) { + int hash = hash(value); + int index = (hash & 0x7FFFFFFF) % values.length; + int offset = 1; + int deletedix = -1; + + // search for the object (continue while !null and !this object) + while(values[index] != FREE && !(hash(values[index]) == hash && values[index] == value)) { + // if there's a deleted object here we can put this object here, + // provided it's not in here somewhere else already + if (values[index] == REMOVED) { + deletedix = index; + } + + index = ((index + offset) & 0x7FFFFFFF) % values.length; + offset = offset * 2 + 1; + + if (offset == -1) { + offset = 2; + } + } + + if (values[index] == FREE) { + if (deletedix != -1) { // reusing a deleted cell + index = deletedix; + } else { + freeEntries--; + } + + modCount++; + elements++; + values[index] = value; + + if (1 - (freeEntries / (double) values.length) > LOAD_FACTOR) { + rehash(); + } + + return true; + } else { + return false; + } + } + + public void remove(int msw, int lsw) { + remove(LongHash.toLong(msw, lsw)); + } + + public boolean remove(long value) { + int hash = hash(value); + int index = (hash & 0x7FFFFFFF) % values.length; + int offset = 1; + + // search for the object (continue while !null and !this object) + while(values[index] != FREE && !(hash(values[index]) == hash && values[index] == value)) { + index = ((index + offset) & 0x7FFFFFFF) % values.length; + offset = offset * 2 + 1; + + if (offset == -1) { + offset = 2; + } + } + + if (values[index] != FREE) { + values[index] = REMOVED; + modCount++; + elements--; + return true; + } else { + return false; + } + } + + public void clear() { + elements = 0; + for (int ix = 0; ix < values.length; ix++) { + values[ix] = FREE; + } + + freeEntries = values.length; + modCount++; + } + + public long[] toArray() { + long[] result = new long[elements]; + long[] values = Arrays.copyOf(this.values, this.values.length); + int pos = 0; + + for (long value : values) { + if (value != FREE && value != REMOVED) { + result[pos++] = value; + } + } + + return result; + } + + public long popFirst() { + for (long value : values) { + if (value != FREE && value != REMOVED) { + remove(value); + return value; + } + } + + return 0; + } + + public long[] popAll() { + long[] ret = toArray(); + clear(); + return ret; + } + + // This method copied from Murmur3, written by Austin Appleby released under Public Domain + private int hash(long value) { + value ^= value >>> 33; + value *= 0xff51afd7ed558ccdL; + value ^= value >>> 33; + value *= 0xc4ceb9fe1a85ec53L; + value ^= value >>> 33; + return (int) value; + } + + private void rehash() { + int gargagecells = values.length - (elements + freeEntries); + if (gargagecells / (double) values.length > 0.05) { + rehash(values.length); + } else { + rehash(values.length * 2 + 1); + } + } + + private void rehash(int newCapacity) { + long[] newValues = new long[newCapacity]; + + for (long value : values) { + if (value == FREE || value == REMOVED) { + continue; + } + + int hash = hash(value); + int index = (hash & 0x7FFFFFFF) % newCapacity; + int offset = 1; + + // search for the object + while (newValues[index] != FREE) { + index = ((index + offset) & 0x7FFFFFFF) % newCapacity; + offset = offset * 2 + 1; + + if (offset == -1) { + offset = 2; + } + } + + newValues[index] = value; + } + + values = newValues; + freeEntries = values.length - elements; + } + + private class Itr implements Iterator { + private int index; + private int lastReturned = -1; + private int expectedModCount; + + public Itr() { + for (index = 0; index < values.length && (values[index] == FREE || values[index] == REMOVED); index++) { + // This is just to drive the index forward to the first valid entry + } + expectedModCount = modCount; + } + + public boolean hasNext() { + return index != values.length; + } + + public Long next() { + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + + int length = values.length; + if (index >= length) { + lastReturned = -2; + throw new NoSuchElementException(); + } + + lastReturned = index; + for (index += 1; index < length && (values[index] == FREE || values[index] == REMOVED); index++) { + // This is just to drive the index forward to the next valid entry + } + + if (values[lastReturned] == FREE) { + return FREE; + } else { + return values[lastReturned]; + } + } + + public void remove() { + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + + if (lastReturned == -1 || lastReturned == -2) { + throw new IllegalStateException(); + } + + if (values[lastReturned] != FREE && values[lastReturned] != REMOVED) { + values[lastReturned] = REMOVED; + elements--; + modCount++; + expectedModCount = modCount; + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java new file mode 100644 index 0000000..0cd430a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java @@ -0,0 +1,422 @@ +package org.bukkit.craftbukkit.util; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.AbstractCollection; +import java.util.AbstractSet; +import java.util.Arrays; +import java.util.Collection; +import java.util.ConcurrentModificationException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +@SuppressWarnings("unchecked") +public class LongObjectHashMap implements Cloneable, Serializable { + static final long serialVersionUID = 2841537710170573815L; + + private static final long EMPTY_KEY = Long.MIN_VALUE; + private static final int BUCKET_SIZE = 4096; + + private transient long[][] keys; + private transient V[][] values; + private transient int modCount; + private transient int size; + + public LongObjectHashMap() { + initialize(); + } + + public LongObjectHashMap(Map map) { + this(); + putAll(map); + } + + public int size() { + return size; + } + + public boolean isEmpty() { + return size == 0; + } + + public boolean containsKey(long key) { + return get(key) != null; + } + + public boolean containsValue(V value) { + for (V val : values()) { + if (val == value || val.equals(value)) { + return true; + } + } + + return false; + } + + public V get(long key) { + int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); + long[] inner = keys[index]; + if (inner == null) return null; + + for (int i = 0; i < inner.length; i++) { + long innerKey = inner[i]; + if (innerKey == EMPTY_KEY) { + return null; + } else if (innerKey == key) { + return values[index][i]; + } + } + + return null; + } + + public V put(long key, V value) { + int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); + long[] innerKeys = keys[index]; + V[] innerValues = values[index]; + modCount++; + + if (innerKeys == null) { + // need to make a new chain + keys[index] = innerKeys = new long[8]; + Arrays.fill(innerKeys, EMPTY_KEY); + values[index] = innerValues = (V[]) new Object[8]; + innerKeys[0] = key; + innerValues[0] = value; + size++; + } else { + int i; + for (i = 0; i < innerKeys.length; i++) { + // found an empty spot in the chain to put this + if (innerKeys[i] == EMPTY_KEY) { + size++; + innerKeys[i] = key; + innerValues[i] = value; + return null; + } + + // found an existing entry in the chain with this key, replace it + if (innerKeys[i] == key) { + V oldValue = innerValues[i]; + innerKeys[i] = key; + innerValues[i] = value; + return oldValue; + } + } + + // chain is full, resize it and add our new entry + keys[index] = innerKeys = Arrays.copyOf(innerKeys, i << 1); + Arrays.fill(innerKeys, i, innerKeys.length, EMPTY_KEY); + values[index] = innerValues = Arrays.copyOf(innerValues, i << 1); + innerKeys[i] = key; + innerValues[i] = value; + size++; + } + + return null; + } + + public V remove(long key) { + int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1)); + long[] inner = keys[index]; + if (inner == null) { + return null; + } + + for (int i = 0; i < inner.length; i++) { + // hit the end of the chain, didn't find this entry + if (inner[i] == EMPTY_KEY) { + break; + } + + if (inner[i] == key) { + V value = values[index][i]; + + for (i++; i < inner.length; i++) { + if (inner[i] == EMPTY_KEY) { + break; + } + + inner[i - 1] = inner[i]; + values[index][i - 1] = values[index][i]; + } + + inner[i - 1] = EMPTY_KEY; + values[index][i - 1] = null; + size--; + modCount++; + return value; + } + } + + return null; + } + + public void putAll(Map map) { + for (Map.Entry entry : map.entrySet()) { + put((Long) entry.getKey(), (V) entry.getValue()); + } + } + + public void clear() { + if (size == 0) { + return; + } + + modCount++; + size = 0; + Arrays.fill(keys, null); + Arrays.fill(values, null); + } + + public Set keySet() { + return new KeySet(); + } + + public Collection values() { + return new ValueCollection(); + } + + /** + * Returns a Set of Entry objects for the HashMap. This is not how the internal + * implementation is laid out so this constructs the entire Set when called. For + * this reason it should be avoided if at all possible. + * + * @return Set of Entry objects + * @deprecated + */ + @Deprecated + public Set> entrySet() { + HashSet> set = new HashSet>(); + for (long key : keySet()) { + set.add(new Entry(key, get(key))); + } + + return set; + } + + public Object clone() throws CloneNotSupportedException { + LongObjectHashMap clone = (LongObjectHashMap) super.clone(); + // Make sure we clear any existing information from the clone + clone.clear(); + // Make sure the clone is properly setup for new entries + clone.initialize(); + + // Iterate through the data normally to do a safe clone + for (long key : keySet()) { + final V value = get(key); + clone.put(key, value); + } + + return clone; + } + + private void initialize() { + keys = new long[BUCKET_SIZE][]; + values = (V[][]) new Object[BUCKET_SIZE][]; + } + + private long keyIndex(long key) { + key ^= key >>> 33; + key *= 0xff51afd7ed558ccdL; + key ^= key >>> 33; + key *= 0xc4ceb9fe1a85ec53L; + key ^= key >>> 33; + return key; + } + + private void writeObject(ObjectOutputStream outputStream) throws IOException { + outputStream.defaultWriteObject(); + + for (long key : keySet()) { + V value = get(key); + outputStream.writeLong(key); + outputStream.writeObject(value); + } + + outputStream.writeLong(EMPTY_KEY); + outputStream.writeObject(null); + } + + private void readObject(ObjectInputStream inputStream) throws ClassNotFoundException, IOException { + inputStream.defaultReadObject(); + initialize(); + + while (true) { + long key = inputStream.readLong(); + V value = (V) inputStream.readObject(); + if (key == EMPTY_KEY && value == null) { + break; + } + + put(key, value); + } + } + + + private class ValueIterator implements Iterator { + private int count; + private int index; + private int innerIndex; + private int expectedModCount; + private long lastReturned = EMPTY_KEY; + + long prevKey = EMPTY_KEY; + V prevValue; + + ValueIterator() { + expectedModCount = LongObjectHashMap.this.modCount; + } + + public boolean hasNext() { + return count < LongObjectHashMap.this.size; + } + + public void remove() { + if (LongObjectHashMap.this.modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + + if (lastReturned == EMPTY_KEY) { + throw new IllegalStateException(); + } + + count--; + LongObjectHashMap.this.remove(lastReturned); + lastReturned = EMPTY_KEY; + expectedModCount = LongObjectHashMap.this.modCount; + } + + public V next() { + if (LongObjectHashMap.this.modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + + if (!hasNext()) { + throw new NoSuchElementException(); + } + + long[][] keys = LongObjectHashMap.this.keys; + count++; + + if (prevKey != EMPTY_KEY) { + innerIndex++; + } + + for (; index < keys.length; index++) { + if (keys[index] != null) { + for (; innerIndex < keys[index].length; innerIndex++) { + long key = keys[index][innerIndex]; + V value = values[index][innerIndex]; + if (key == EMPTY_KEY) { + break; + } + + lastReturned = key; + prevKey = key; + prevValue = value; + return prevValue; + } + innerIndex = 0; + } + } + + throw new NoSuchElementException(); + } + } + + private class KeyIterator implements Iterator { + final ValueIterator iterator; + + public KeyIterator() { + iterator = new ValueIterator(); + } + + public void remove() { + iterator.remove(); + } + + public boolean hasNext() { + return iterator.hasNext(); + } + + public Long next() { + iterator.next(); + return iterator.prevKey; + } + } + + + private class KeySet extends AbstractSet { + public void clear() { + LongObjectHashMap.this.clear(); + } + + public int size() { + return LongObjectHashMap.this.size(); + } + + public boolean contains(Object key) { + return key instanceof Long && LongObjectHashMap.this.containsKey((Long) key); + + } + + public boolean remove(Object key) { + return LongObjectHashMap.this.remove((Long) key) != null; + } + + public Iterator iterator() { + return new KeyIterator(); + } + } + + + private class ValueCollection extends AbstractCollection { + public void clear() { + LongObjectHashMap.this.clear(); + } + + public int size() { + return LongObjectHashMap.this.size(); + } + + public boolean contains(Object value) { + return LongObjectHashMap.this.containsValue((V) value); + } + + public Iterator iterator() { + return new ValueIterator(); + } + } + + + private class Entry implements Map.Entry { + private final Long key; + private V value; + + Entry(long k, V v) { + key = k; + value = v; + } + + public Long getKey() { + return key; + } + + public V getValue() { + return value; + } + + public V setValue(V v) { + V old = value; + value = v; + put(key, v); + return old; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/MojangNameLookup.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/MojangNameLookup.java new file mode 100644 index 0000000..93a8f0b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/MojangNameLookup.java @@ -0,0 +1,63 @@ +package org.bukkit.craftbukkit.util; + +import com.google.common.base.Charsets; +import com.google.gson.Gson; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.UUID; +import org.apache.commons.io.IOUtils; + +public class MojangNameLookup { + private static final Logger logger = LogManager.getFormatterLogger(MojangNameLookup.class); + + public static String lookupName(UUID id) { + if (id == null) { + return null; + } + + InputStream inputStream = null; + try { + URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + id.toString().replace("-", "")); + URLConnection connection = url.openConnection(); + connection.setConnectTimeout(15000); + connection.setReadTimeout(15000); + connection.setUseCaches(false); + inputStream = connection.getInputStream(); + String result = IOUtils.toString(inputStream, Charsets.UTF_8); + Gson gson = new Gson(); + Response response = gson.fromJson(result, Response.class); + if (response == null || response.name == null) { + logger.warn("Failed to lookup name from UUID"); + return null; + } + + if (response.cause != null && response.cause.length() > 0) { + logger.warn("Failed to lookup name from UUID: %s", response.errorMessage); + return null; + } + + return response.name; + } catch (MalformedURLException ex) { + logger.warn("Malformed URL in UUID lookup"); + return null; + } catch (IOException ex) { + IOUtils.closeQuietly(inputStream); + } finally { + IOUtils.closeQuietly(inputStream); + } + + return null; + } + + private class Response { + String errorMessage; + String cause; + String name; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java new file mode 100644 index 0000000..ae3481b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java @@ -0,0 +1,26 @@ +package org.bukkit.craftbukkit.util; + +import net.minecraft.server.ExceptionWorldConflict; +import net.minecraft.server.MinecraftServer; + +public class ServerShutdownThread extends Thread { + private final MinecraftServer server; + + public ServerShutdownThread(MinecraftServer server) { + this.server = server; + } + + @Override + public void run() { + try { + server.stop(); + } catch (ExceptionWorldConflict ex) { + ex.printStackTrace(); + } finally { + try { + server.reader.getTerminal().restore(); + } catch (Exception e) { + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java new file mode 100644 index 0000000..2dbfef9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java @@ -0,0 +1,61 @@ +package org.bukkit.craftbukkit.util; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.SimpleDateFormat; +import java.util.logging.Formatter; +import java.util.logging.LogRecord; +import joptsimple.OptionException; +import joptsimple.OptionSet; +import net.minecraft.server.MinecraftServer; + +public class ShortConsoleLogFormatter extends Formatter { + private final SimpleDateFormat date; + + public ShortConsoleLogFormatter(MinecraftServer server) { + OptionSet options = server.options; + SimpleDateFormat date = null; + + if (options.has("date-format")) { + try { + Object object = options.valueOf("date-format"); + + if ((object != null) && (object instanceof SimpleDateFormat)) { + date = (SimpleDateFormat) object; + } + } catch (OptionException ex) { + System.err.println("Given date format is not valid. Falling back to default."); + } + } else if (options.has("nojline")) { + date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + + if (date == null) { + date = new SimpleDateFormat("HH:mm:ss"); + } + + this.date = date; + } + + @Override + public String format(LogRecord record) { + StringBuilder builder = new StringBuilder(); + Throwable ex = record.getThrown(); + + builder.append(date.format(record.getMillis())); + builder.append(" ["); + builder.append(record.getLevel().getLocalizedName().toUpperCase()); + builder.append("] "); + builder.append(formatMessage(record)); + builder.append('\n'); + + if (ex != null) { + StringWriter writer = new StringWriter(); + ex.printStackTrace(new PrintWriter(writer)); + builder.append(writer); + } + + return builder.toString(); + } + +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/StructureGrowDelegate.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/StructureGrowDelegate.java new file mode 100644 index 0000000..f9cc7d6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/StructureGrowDelegate.java @@ -0,0 +1,70 @@ +package org.bukkit.craftbukkit.util; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.server.Block; +import net.minecraft.server.Blocks; +import net.minecraft.server.World; + +import org.bukkit.BlockChangeDelegate; +import org.bukkit.block.BlockState; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.material.MaterialData; + +public class StructureGrowDelegate implements BlockChangeDelegate { + private final CraftWorld world; + private final List blocks = new ArrayList(); + + public StructureGrowDelegate(World world) { + this.world = world.getWorld(); + } + + public boolean setRawTypeId(int x, int y, int z, int type) { + return setRawTypeIdAndData(x, y, z, type, 0); + } + + public boolean setRawTypeIdAndData(int x, int y, int z, int type, int data) { + BlockState state = world.getBlockAt(x, y, z).getState(); + state.setTypeId(type); + state.setData(new MaterialData(type, (byte) data)); + blocks.add(state); + return true; + } + + public boolean setTypeId(int x, int y, int z, int typeId) { + return setRawTypeId(x, y, z, typeId); + } + + public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data) { + return setRawTypeIdAndData(x, y, z, typeId, data); + } + + public int getTypeId(int x, int y, int z) { + for (BlockState state : blocks) { + if (state.getX() == x && state.getY() == y && state.getZ() == z) { + return state.getTypeId(); + } + } + + return world.getBlockTypeIdAt(x, y, z); + } + + public int getHeight() { + return world.getMaxHeight(); + } + + public List getBlocks() { + return blocks; + } + + public boolean isEmpty(int x, int y, int z) { + for (BlockState state : blocks) { + if (state.getX() == x && state.getY() == y && state.getZ() == z) { + return Block.getById(state.getTypeId()) == Blocks.AIR; + } + } + + return world.getBlockAt(x, y, z).isEmpty(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java new file mode 100644 index 0000000..772f730 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java @@ -0,0 +1,52 @@ +package org.bukkit.craftbukkit.util; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; +import jline.console.ConsoleReader; +import com.mojang.util.QueueLogAppender; +import org.bukkit.craftbukkit.Main; + +public class TerminalConsoleWriterThread implements Runnable { + final private ConsoleReader reader; + final private OutputStream output; + + public TerminalConsoleWriterThread(OutputStream output, ConsoleReader reader) { + this.output = output; + this.reader = reader; + } + + public void run() { + String message; + + // Using name from log4j config in vanilla jar + while (true) { + message = QueueLogAppender.getNextLogEvent("TerminalConsole"); + if (message == null) { + continue; + } + + try { + if (Main.useJline) { + reader.print(ConsoleReader.RESET_LINE + ""); + reader.flush(); + output.write(message.getBytes()); + output.flush(); + + try { + reader.drawLine(); + } catch (Throwable ex) { + reader.getCursorBuffer().clear(); + } + reader.flush(); + } else { + output.write(message.getBytes()); + output.flush(); + } + } catch (IOException ex) { + Logger.getLogger(TerminalConsoleWriterThread.class.getName()).log(Level.SEVERE, null, ex); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java new file mode 100644 index 0000000..08d1056 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java @@ -0,0 +1,278 @@ +package org.bukkit.craftbukkit.util; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.AbstractList; +import java.util.Arrays; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.RandomAccess; + +// implementation of an ArrayList that offers a getter without range checks +@SuppressWarnings("unchecked") +public class UnsafeList extends AbstractList implements List, RandomAccess, Cloneable, Serializable { + private static final long serialVersionUID = 8683452581112892191L; + + private transient Object[] data; + private int size; + private int initialCapacity; + + private Iterator[] iterPool = new Iterator[1]; + private int maxPool; + private int poolCounter; + + public UnsafeList(int capacity, int maxIterPool) { + super(); + if (capacity < 0) capacity = 32; + int rounded = Integer.highestOneBit(capacity - 1) << 1; + data = new Object[rounded]; + initialCapacity = rounded; + maxPool = maxIterPool; + iterPool[0] = new Itr(); + } + + public UnsafeList(int capacity) { + this(capacity, 5); + } + + public UnsafeList() { + this(32); + } + + public E get(int index) { + rangeCheck(index); + + return (E) data[index]; + } + + public E unsafeGet(int index) { + return (E) data[index]; + } + + public E set(int index, E element) { + rangeCheck(index); + + E old = (E) data[index]; + data[index] = element; + return old; + } + + public boolean add(E element) { + growIfNeeded(); + data[size++] = element; + return true; + } + + public void add(int index, E element) { + growIfNeeded(); + System.arraycopy(data, index, data, index + 1, size - index); + data[index] = element; + size++; + } + + public E remove(int index) { + rangeCheck(index); + + E old = (E) data[index]; + int movedCount = size - index - 1; + if (movedCount > 0) { + System.arraycopy(data, index + 1, data, index, movedCount); + } + data[--size] = null; + + return old; + } + + public boolean remove(Object o) { + int index = indexOf(o); + if (index >= 0) { + remove(index); + return true; + } + + return false; + } + + public int indexOf(Object o) { + for (int i = 0; i < size; i++) { + if (o == data[i] || o.equals(data[i])) { + return i; + } + } + + return -1; + } + + public boolean contains(Object o) { + return indexOf(o) >= 0; + } + + public void clear() { + // Create new array to reset memory usage to initial capacity + size = 0; + + // If array has grown too large create new one, otherwise just clear it + if (data.length > initialCapacity << 3) { + data = new Object[initialCapacity]; + } else { + for (int i = 0; i < data.length; i++) { + data[i] = null; + } + } + } + + // actually rounds up to nearest power of two + public void trimToSize() { + int old = data.length; + int rounded = Integer.highestOneBit(size - 1) << 1; + if (rounded < old) { + data = Arrays.copyOf(data, rounded); + } + } + + public int size() { + return size; + } + + public boolean isEmpty() { + return size == 0; + } + + public Object clone() throws CloneNotSupportedException { + UnsafeList copy = (UnsafeList) super.clone(); + copy.data = Arrays.copyOf(data, size); + copy.size = size; + copy.initialCapacity = initialCapacity; + copy.iterPool = new Iterator[1]; + copy.iterPool[0] = new Itr(); + copy.maxPool = maxPool; + copy.poolCounter = 0; + return copy; + } + + public Iterator iterator() { + // Try to find an iterator that isn't in use + for (Iterator iter : iterPool) { + if (!((Itr) iter).valid) { + Itr iterator = (Itr) iter; + iterator.reset(); + return iterator; + } + } + + // Couldn't find one, see if we can grow our pool size + if (iterPool.length < maxPool) { + Iterator[] newPool = new Iterator[iterPool.length + 1]; + System.arraycopy(iterPool, 0, newPool, 0, iterPool.length); + iterPool = newPool; + + iterPool[iterPool.length - 1] = new Itr(); + return iterPool[iterPool.length - 1]; + } + + // Still couldn't find a free one, round robin replace one with a new iterator + // This is done in the hope that the new one finishes so can be reused + poolCounter = ++poolCounter % iterPool.length; + iterPool[poolCounter] = new Itr(); + return iterPool[poolCounter]; + } + + private void rangeCheck(int index) { + if (index >= size || index < 0) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + } + + private void growIfNeeded() { + if (size == data.length) { + Object[] newData = new Object[data.length << 1]; + System.arraycopy(data, 0, newData, 0, size); + data = newData; + } + } + + private void writeObject(ObjectOutputStream os) throws IOException { + os.defaultWriteObject(); + + os.writeInt(size); + os.writeInt(initialCapacity); + for (int i = 0; i < size; i++) { + os.writeObject(data[i]); + } + os.writeInt(maxPool); + } + + private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException { + is.defaultReadObject(); + + size = is.readInt(); + initialCapacity = is.readInt(); + data = new Object[Integer.highestOneBit(size - 1) << 1]; + for (int i = 0; i < size; i++) { + data[i] = is.readObject(); + } + maxPool = is.readInt(); + iterPool = new Iterator[1]; + iterPool[0] = new Itr(); + } + + public class Itr implements Iterator { + int index; + int lastRet = -1; + int expectedModCount = modCount; + public boolean valid = true; + + public void reset() { + index = 0; + lastRet = -1; + expectedModCount = modCount; + valid = true; + } + + public boolean hasNext() { + valid = index != size; + return valid; + } + + public E next() { + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + + int i = index; + if (i >= size) { + throw new NoSuchElementException(); + } + + if (i >= data.length) { + throw new ConcurrentModificationException(); + } + + index = i + 1; + return (E) data[lastRet = i]; + } + + public void remove() { + if (lastRet < 0) { + throw new IllegalStateException(); + } + + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + + try { + UnsafeList.this.remove(lastRet); + index = lastRet; + lastRet = -1; + expectedModCount = modCount; + } catch (IndexOutOfBoundsException ex) { + throw new ConcurrentModificationException(); + } + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/Versioning.java new file mode 100644 index 0000000..bbf4f6e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/Versioning.java @@ -0,0 +1,29 @@ +package org.bukkit.craftbukkit.util; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.Bukkit; + +public final class Versioning { + public static String getBukkitVersion() { + String result = "1.8.8"; + + InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/net.techcable.tacospigot/api/pom.properties"); + Properties properties = new Properties(); + + if (stream != null) { + try { + properties.load(stream); + + result = properties.getProperty("version"); + } catch (IOException ex) { + Logger.getLogger(Versioning.class.getName()).log(Level.SEVERE, "Could not get Bukkit version!", ex); + } + } + + return result; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/Waitable.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/Waitable.java new file mode 100644 index 0000000..5cd1154 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/Waitable.java @@ -0,0 +1,46 @@ +package org.bukkit.craftbukkit.util; + +import java.util.concurrent.ExecutionException; + + +public abstract class Waitable implements Runnable { + private enum Status { + WAITING, + RUNNING, + FINISHED, + } + Throwable t = null; + T value = null; + Status status = Status.WAITING; + + public final void run() { + synchronized (this) { + if (status != Status.WAITING) { + throw new IllegalStateException("Invalid state " + status); + } + status = Status.RUNNING; + } + try { + value = evaluate(); + } catch (Throwable t) { + this.t = t; + } finally { + synchronized (this) { + status = Status.FINISHED; + this.notifyAll(); + } + } + } + + protected abstract T evaluate(); + + public synchronized T get() throws InterruptedException, ExecutionException { + while (status != Status.FINISHED) { + this.wait(); + } + if (t != null) { + throw new ExecutionException(t); + } + return value; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java new file mode 100644 index 0000000..7e7363f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java @@ -0,0 +1,169 @@ +package org.bukkit.craftbukkit.util; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; + +import org.apache.commons.lang.Validate; + +public final class WeakCollection implements Collection { + static final Object NO_VALUE = new Object(); + private final Collection> collection; + + public WeakCollection() { + collection = new ArrayList>(); + } + + public boolean add(T value) { + Validate.notNull(value, "Cannot add null value"); + return collection.add(new WeakReference(value)); + } + + public boolean addAll(Collection collection) { + Collection> values = this.collection; + boolean ret = false; + for (T value : collection) { + Validate.notNull(value, "Cannot add null value"); + ret |= values.add(new WeakReference(value)); + } + return ret; + } + + public void clear() { + collection.clear(); + } + + public boolean contains(Object object) { + if (object == null) { + return false; + } + for (T compare : this) { + if (object.equals(compare)) { + return true; + } + } + return false; + } + + public boolean containsAll(Collection collection) { + return toCollection().containsAll(collection); + } + + public boolean isEmpty() { + return !iterator().hasNext(); + } + + public Iterator iterator() { + return new Iterator() { + Iterator> it = collection.iterator(); + Object value = NO_VALUE; + + public boolean hasNext() { + Object value = this.value; + if (value != null && value != NO_VALUE) { + return true; + } + + Iterator> it = this.it; + value = null; + + while (it.hasNext()) { + WeakReference ref = it.next(); + value = ref.get(); + if (value == null) { + it.remove(); + } else { + this.value = value; + return true; + } + } + return false; + } + + public T next() throws NoSuchElementException { + if (!hasNext()) { + throw new NoSuchElementException("No more elements"); + } + + @SuppressWarnings("unchecked") + T value = (T) this.value; + this.value = NO_VALUE; + return value; + } + + public void remove() throws IllegalStateException { + if (value != NO_VALUE) { + throw new IllegalStateException("No last element"); + } + + value = null; + it.remove(); + } + }; + } + + public boolean remove(Object object) { + if (object == null) { + return false; + } + + Iterator it = this.iterator(); + while (it.hasNext()) { + if (object.equals(it.next())) { + it.remove(); + return true; + } + } + return false; + } + + public boolean removeAll(Collection collection) { + Iterator it = this.iterator(); + boolean ret = false; + while (it.hasNext()) { + if (collection.contains(it.next())) { + ret = true; + it.remove(); + } + } + return ret; + } + + public boolean retainAll(Collection collection) { + Iterator it = this.iterator(); + boolean ret = false; + while (it.hasNext()) { + if (!collection.contains(it.next())) { + ret = true; + it.remove(); + } + } + return ret; + } + + public int size() { + int s = 0; + for (T value : this) { + s++; + } + return s; + } + + public Object[] toArray() { + return this.toArray(new Object[0]); + } + + public T[] toArray(T[] array) { + return toCollection().toArray(array); + } + + private Collection toCollection() { + ArrayList collection = new ArrayList(); + for (T value : this) { + collection.add(value); + } + return collection; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java new file mode 100644 index 0000000..c93498e --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java @@ -0,0 +1,36 @@ +package org.bukkit.craftbukkit.util.permissions; + +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.util.permissions.DefaultPermissions; + +public final class CommandPermissions { + private static final String ROOT = "minecraft.command"; + private static final String PREFIX = ROOT + "."; + + private CommandPermissions() {} + + public static Permission registerPermissions(Permission parent) { + Permission commands = DefaultPermissions.registerPermission(ROOT, "Gives the user the ability to use all vanilla minecraft commands", parent); + + DefaultPermissions.registerPermission(PREFIX + "kill", "Allows the user to commit suicide", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "me", "Allows the user to perform a chat action", PermissionDefault.TRUE, commands); + DefaultPermissions.registerPermission(PREFIX + "tell", "Allows the user to privately message another player", PermissionDefault.TRUE, commands); + DefaultPermissions.registerPermission(PREFIX + "say", "Allows the user to talk as the console", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "give", "Allows the user to give items to players", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "teleport", "Allows the user to teleport players", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "kick", "Allows the user to kick players", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "stop", "Allows the user to stop the server", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "list", "Allows the user to list all online players", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "gamemode", "Allows the user to change the gamemode of another player", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "xp", "Allows the user to give themselves or others arbitrary values of experience", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "toggledownfall", "Allows the user to toggle rain on/off for a given world", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "defaultgamemode", "Allows the user to change the default gamemode of the server", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "seed", "Allows the user to view the seed of the world", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "effect", "Allows the user to add/remove effects on players", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(PREFIX + "selector", "Allows the use of selectors", PermissionDefault.OP, commands); + + commands.recalculatePermissibles(); + return commands; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java new file mode 100644 index 0000000..6bea250 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/bukkit/craftbukkit/util/permissions/CraftDefaultPermissions.java @@ -0,0 +1,16 @@ +package org.bukkit.craftbukkit.util.permissions; + +import org.bukkit.permissions.Permission; +import org.bukkit.util.permissions.DefaultPermissions; + +public final class CraftDefaultPermissions { + private static final String ROOT= "minecraft"; + + private CraftDefaultPermissions() {} + + public static void registerCorePermissions() { + Permission parent = DefaultPermissions.registerPermission(ROOT, "Gives the user the ability to use all vanilla utilities and commands"); + CommandPermissions.registerPermissions(parent); + parent.recalculatePermissibles(); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotConfig.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotConfig.java new file mode 100644 index 0000000..a7bb45f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotConfig.java @@ -0,0 +1,225 @@ +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 java.util.*; +import java.util.logging.Level; + +import net.minecraft.server.Item; +import net.minecraft.server.Items; +import net.minecraft.server.MinecraftServer; +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) + { + 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 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 ); + } + + 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) + { + // TODO: Figure out why getFloat() always returns the default value. + return (float) getDouble( path, (double) def ); + } + + 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 (List) 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 double babyZombieMovementSpeed; + private static void babyZombieMovementSpeed() + { + babyZombieMovementSpeed = getDouble( "settings.baby-zombie-movement-speed", 0.5D ); // Player moves at 0.1F, for reference + } + + public static boolean interactLimitEnabled; + private static void interactLimitEnabled() + { + interactLimitEnabled = getBoolean( "settings.limit-player-interactions", true ); + if ( !interactLimitEnabled ) + { + Bukkit.getLogger().log( Level.INFO, "Disabling player interaction limiter, your server may be more vulnerable to malicious users" ); + } + } + + public static double strengthEffectModifier; + public static double weaknessEffectModifier; + private static void effectModifiers() + { + strengthEffectModifier = getDouble( "effect-modifiers.strength", 0.15D ); + weaknessEffectModifier = getDouble( "effect-modifiers.weakness", -0.5D ); + } + + public static Set dataValueAllowedItems; + private static void dataValueAllowedItems() + { + dataValueAllowedItems = new HashSet( getList( "data-value-allowed-items", Collections.emptyList() ) ); + Bukkit.getLogger().info( "Data value allowed items: " + StringUtils.join(dataValueAllowedItems, ", ") ); + } + + public static boolean stackableLavaBuckets; + public static boolean stackableWaterBuckets; + public static boolean stackableMilkBuckets; + private static void stackableBuckets() + { + stackableLavaBuckets = getBoolean( "stackable-buckets.lava", false ); + stackableWaterBuckets = getBoolean( "stackable-buckets.water", false ); + stackableMilkBuckets = getBoolean( "stackable-buckets.milk", false ); + + Field maxStack; + + try { + maxStack = Material.class.getDeclaredField("maxStack"); + maxStack.setAccessible(true); + + Field modifiers = Field.class.getDeclaredField("modifiers"); + modifiers.setAccessible(true); + modifiers.setInt(maxStack, maxStack.getModifiers() & ~Modifier.FINAL); + } catch (Exception e) { + e.printStackTrace(); + return; + } + + try { + if (stackableLavaBuckets) { + maxStack.set(Material.LAVA_BUCKET, Material.BUCKET.getMaxStackSize()); + Items.LAVA_BUCKET.c(Material.BUCKET.getMaxStackSize()); + } + + if (stackableWaterBuckets) { + maxStack.set(Material.WATER_BUCKET, Material.BUCKET.getMaxStackSize()); + Items.WATER_BUCKET.c(Material.BUCKET.getMaxStackSize()); + } + + if (stackableMilkBuckets) { + maxStack.set(Material.MILK_BUCKET, Material.BUCKET.getMaxStackSize()); + Items.MILK_BUCKET.c(Material.BUCKET.getMaxStackSize()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static boolean warnForExcessiveVelocity; + private static void excessiveVelocityWarning() + { + warnForExcessiveVelocity = getBoolean("warnWhenSettingExcessiveVelocity", true); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java new file mode 100644 index 0000000..6ad8e81 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/github/paperspigot/PaperSpigotWorldConfig.java @@ -0,0 +1,405 @@ +package org.github.paperspigot; + +import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; + +public class PaperSpigotWorldConfig +{ + + private final String worldName; + private final YamlConfiguration config; + private boolean verbose; + + public PaperSpigotWorldConfig(String worldName) + { + this.worldName = worldName; + this.config = PaperSpigotConfig.config; + init(); + } + + public void init() + { + this.verbose = getBoolean( "verbose", true ); + + log( "-------- World Settings For [" + worldName + "] --------" ); + PaperSpigotConfig.readConfig( PaperSpigotWorldConfig.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) + { + // TODO: Figure out why getFloat() always returns the default value. + return (float) getDouble( path, (double) def ); + } + + private List getList(String path, T def) + { + config.addDefault( "world-settings.default." + path, def ); + return (List) 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 allowUndeadHorseLeashing; + private 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() + { + 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() + { + 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() + { + 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() + { + fishingMinTicks = getInt( "fishing-time-range.MinimumTicks", 100 ); + fishingMaxTicks = getInt( "fishing-time-range.MaximumTicks", 900 ); + } + + public float blockBreakExhaustion; + public float playerSwimmingExhaustion; + private 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() + { + softDespawnDistance = getInt( "despawn-ranges.soft", 32 ); // 32^2 = 1024, Minecraft Default + hardDespawnDistance = getInt( "despawn-ranges.hard", 128 ); // 128^2 = 16384, Minecraft Default; + + if ( softDespawnDistance > hardDespawnDistance ) { + softDespawnDistance = hardDespawnDistance; + } + + log( "Living Entity Despawn Ranges: Soft: " + softDespawnDistance + " Hard: " + hardDespawnDistance ); + + softDespawnDistance = softDespawnDistance*softDespawnDistance; + hardDespawnDistance = hardDespawnDistance*hardDespawnDistance; + } + + public boolean keepSpawnInMemory; + private void keepSpawnInMemory() + { + keepSpawnInMemory = getBoolean( "keep-spawn-loaded", true ); + log( "Keep spawn chunk loaded: " + keepSpawnInMemory ); + } + + public int fallingBlockHeightNerf; + private void fallingBlockheightNerf() + { + fallingBlockHeightNerf = getInt( "falling-block-height-nerf", 0 ); + if ( fallingBlockHeightNerf != 0 ) + { + log( "Falling Block Height Limit set to Y: " + fallingBlockHeightNerf ); + } + } + + public int tntEntityHeightNerf; + private void tntEntityHeightNerf() + { + tntEntityHeightNerf = getInt( "tnt-entity-height-nerf", 0 ); + if ( tntEntityHeightNerf != 0 ) + { + log( "TNT Entity Height Limit set to Y: " + tntEntityHeightNerf ); + } + } + + public int waterOverLavaFlowSpeed; + private void waterOverLavaFlowSpeed() + { + waterOverLavaFlowSpeed = getInt( "water-over-lava-flow-speed", 5 ); + log( "Water over lava flow speed: " + waterOverLavaFlowSpeed ); + } + + public boolean removeInvalidMobSpawnerTEs; + private 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() + { + 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() + { + 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() + { + netherVoidTopDamage = getBoolean( "nether-ceiling-void-damage", false ); + } + + public int tickNextTickCap; + public boolean tickNextTickListCapIgnoresRedstone; + private 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. + log( "WorldServer TickNextTick cap set at " + tickNextTickCap ); + log( "WorldServer TickNextTickList cap always processes redstone: " + tickNextTickListCapIgnoresRedstone ); + } + + public boolean useAsyncLighting; + private void useAsyncLighting() + { + useAsyncLighting = getBoolean( "use-async-lighting", false ); + log( "World async lighting: " + useAsyncLighting ); + } + + public boolean disableEndCredits; + private void disableEndCredits() + { + disableEndCredits = getBoolean( "game-mechanics.disable-end-credits", false ); + } + + public boolean loadUnloadedEnderPearls; + public boolean loadUnloadedTNTEntities; + public boolean loadUnloadedFallingBlocks; + private 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() + { + generateCanyon = getBoolean( "generator-settings.canyon", true ); + generateCaves = getBoolean( "generator-settings.caves", true ); + generateDungeon = getBoolean( "generator-settings.dungeon", true ); + generateFortress = getBoolean( "generator-settings.fortress", true ); + generateMineshaft = getBoolean( "generator-settings.mineshaft", true ); + generateMonument = getBoolean( "generator-settings.monument", true ); + generateStronghold = getBoolean( "generator-settings.stronghold", true ); + generateTemple = getBoolean( "generator-settings.temple", true ); + generateVillage = getBoolean( "generator-settings.village", true ); + generateFlatBedrock = getBoolean( "generator-settings.flat-bedrock", false ); + } + + public boolean fixCannons; + private 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() + { + fallingBlocksCollideWithSigns = getBoolean( "falling-blocks-collide-with-signs", false ); + } + + public boolean optimizeExplosions; + private void optimizeExplosions() + { + optimizeExplosions = getBoolean( "optimize-explosions", false ); + } + + public boolean fastDrainLava; + public boolean fastDrainWater; + private void fastDraining() + { + fastDrainLava = getBoolean( "fast-drain.lava", false ); + fastDrainWater = getBoolean( "fast-drain.water", false ); + } + + public int lavaFlowSpeedNormal; + public int lavaFlowSpeedNether; + private void lavaFlowSpeed() + { + lavaFlowSpeedNormal = getInt( "lava-flow-speed.normal", 30 ); + lavaFlowSpeedNether = getInt( "lava-flow-speed.nether", 10 ); + } + + public boolean disableExplosionKnockback; + private void disableExplosionKnockback() + { + disableExplosionKnockback = getBoolean( "disable-explosion-knockback", false ); + } + + public boolean disableThunder; + private void disableThunder() + { + disableThunder = getBoolean( "disable-thunder", false ); + } + + public boolean disableIceAndSnow; + private void disableIceAndSnow() + { + disableIceAndSnow = getBoolean( "disable-ice-and-snow", false ); + } + + public boolean disableMoodSounds; + private void disableMoodSounds() + { + disableMoodSounds = getBoolean( "disable-mood-sounds", false ); + } + + public int mobSpawnerTickRate; + private void mobSpawnerTickRate() + { + mobSpawnerTickRate = getInt( "mob-spawner-tick-rate", 1 ); + } + + public boolean cacheChunkMaps; + private void cacheChunkMaps() + { + cacheChunkMaps = getBoolean( "cache-chunk-maps", false ); + } + + public int containerUpdateTickRate; + private void containerUpdateTickRate() + { + containerUpdateTickRate = getInt( "container-update-tick-rate", 1 ); + } + + public float tntExplosionVolume; + private void tntExplosionVolume() + { + tntExplosionVolume = getFloat( "tnt-explosion-volume", 4.0F ); + } + + public boolean useHopperCheck; + private void useHopperCheck() + { + useHopperCheck = getBoolean( "use-hopper-check", false ); + } + + public boolean allChunksAreSlimeChunks; + private void allChunksAreSlimeChunks() + { + allChunksAreSlimeChunks = getBoolean( "all-chunks-are-slime-chunks", false ); + } + + public boolean allowBlockLocationTabCompletion; + private void allowBlockLocationTabCompletion() + { + allowBlockLocationTabCompletion = getBoolean( "allow-block-location-tab-completion", true ); + } + + public int portalSearchRadius; + private void portalSearchRadius() + { + portalSearchRadius = getInt("portal-search-radius", 128); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/ActivationRange.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/ActivationRange.java new file mode 100644 index 0000000..242d7c4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/ActivationRange.java @@ -0,0 +1,279 @@ +package org.spigotmc; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import me.levansj01.mythicspigot.MythicConfiguration; +import me.levansj01.mythicspigot.MythicCore; +import net.jafama.FastMath; +import net.minecraft.server.*; +import co.aikar.timings.SpigotTimings; + + +public class ActivationRange +{ + + static AxisAlignedBB maxBB = AxisAlignedBB.a( 0, 0, 0, 0, 0, 0 ); + static AxisAlignedBB miscBB = AxisAlignedBB.a( 0, 0, 0, 0, 0, 0 ); + static AxisAlignedBB animalBB = AxisAlignedBB.a( 0, 0, 0, 0, 0, 0 ); + static AxisAlignedBB monsterBB = AxisAlignedBB.a( 0, 0, 0, 0, 0, 0 ); + + /** + * Initializes an entities type on construction to specify what group this + * entity is in for activation ranges. + * + * @param entity + * @return group id + */ + public static byte initializeEntityActivationType(Entity entity) + { + if ( entity instanceof EntityMonster || entity instanceof EntitySlime ) + { + return 1; // Monster + } else if ( entity instanceof EntityCreature || entity instanceof EntityAmbient ) + { + return 2; // Animal + } else + { + return 3; // Misc + } + } + + /** + * These entities are excluded from Activation range checks. + * + * @param entity + * @param world + * @return boolean If it should always tick. + */ + public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config) + { + if ( ( entity.activationType == 3 && config.miscActivationRange == 0 ) + || ( entity.activationType == 2 && config.animalActivationRange == 0 ) + || ( entity.activationType == 1 && config.monsterActivationRange == 0 ) + || entity instanceof EntityHuman + || entity instanceof EntityProjectile + || entity instanceof EntityEnderDragon + || entity instanceof EntityComplexPart + || entity instanceof EntityWither + || entity instanceof EntityFireball + || entity instanceof EntityWeather + || entity instanceof EntityTNTPrimed + || entity instanceof EntityFallingBlock // PaperSpigot - Always tick falling blocks + || entity instanceof EntityEnderCrystal + || entity instanceof EntityFireworks ) + { + return true; + } + + return false; + } + + /** + * Find what entities are in range of the players in the world and set + * active if in range. + * + * @param world + */ + public static void activateEntities(World world) + { + SpigotTimings.entityActivationCheckTimer.startTiming(); + final int miscActivationRange = world.spigotConfig.miscActivationRange; + final int animalActivationRange = world.spigotConfig.animalActivationRange; + final int monsterActivationRange = world.spigotConfig.monsterActivationRange; + + int maxRange = FastMath.max( monsterActivationRange, animalActivationRange ); + maxRange = FastMath.max( maxRange, miscActivationRange ); + maxRange = FastMath.min( ( world.spigotConfig.viewDistance << 4 ) - 8, maxRange ); + + for ( Entity player : (List) (List) world.players ) + { + + player.activatedTick = MinecraftServer.currentTick; + maxBB = player.getBoundingBox().grow( maxRange, 256, maxRange ); + miscBB = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange ); + animalBB = player.getBoundingBox().grow( animalActivationRange, 256, animalActivationRange ); + monsterBB = player.getBoundingBox().grow( monsterActivationRange, 256, monsterActivationRange ); + + int i = MathHelper.floor( maxBB.a / 16.0D ); + int j = MathHelper.floor( maxBB.d / 16.0D ); + int k = MathHelper.floor( maxBB.c / 16.0D ); + int l = MathHelper.floor( maxBB.f / 16.0D ); + + for ( int i1 = i; i1 <= j; ++i1 ) + { + for ( int j1 = k; j1 <= l; ++j1 ) + { + if ( world.getWorld().isChunkLoaded( i1, j1 ) ) + { + activateChunkEntities( world.getChunkAt( i1, j1 ) ); + } + } + } + } + SpigotTimings.entityActivationCheckTimer.stopTiming(); + } + + /** + * Checks for the activation state of all entities in this chunk. + * + * @param chunk + */ + private static void activateChunkEntities(Chunk chunk) + { + for ( List slice : chunk.entitySlices ) + { + for ( Entity entity : slice ) + { + if ( MinecraftServer.currentTick > entity.activatedTick ) + { + if ( entity.defaultActivationState ) + { + entity.activatedTick = MinecraftServer.currentTick; + continue; + } + switch ( entity.activationType ) + { + case 1: + if ( monsterBB.b( entity.getBoundingBox() ) ) + { + entity.activatedTick = MinecraftServer.currentTick; + } + break; + case 2: + if ( animalBB.b( entity.getBoundingBox() ) ) + { + entity.activatedTick = MinecraftServer.currentTick; + } + break; + case 3: + default: + if ( miscBB.b( entity.getBoundingBox() ) ) + { + entity.activatedTick = MinecraftServer.currentTick; + } + } + } + } + } + } + + /** + * If an entity is not in range, do some more checks to see if we should + * give it a shot. + * + * @param entity + * @return + */ + public static boolean checkEntityImmunities(Entity entity) + { + // quick checks. + if ( entity.inWater || entity.fireTicks > 0 ) + { + return true; + } + if ( !( entity instanceof EntityArrow ) ) + { + if ( !entity.onGround || entity.passenger != null + || entity.vehicle != null ) + { + return true; + } + } else if ( !( (EntityArrow) entity ).inGround ) + { + return true; + } + // special cases. + if ( entity instanceof EntityLiving ) + { + EntityLiving living = (EntityLiving) entity; + if ( /*TODO: Missed mapping? living.attackTicks > 0 || */ living.hurtTicks > 0 || living.effects.size() > 0 ) + { + return true; + } + if ( entity instanceof EntityCreature && ( (EntityCreature) entity ).getGoalTarget() != null ) + { + return true; + } + if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).cm() /* Getter for first boolean */ ) + { + return true; + } + if ( entity instanceof EntityAnimal ) + { + EntityAnimal animal = (EntityAnimal) entity; + if ( animal.isBaby() || animal.isInLove() ) + { + return true; + } + if ( entity instanceof EntitySheep && ( (EntitySheep) entity ).isSheared() ) + { + return true; + } + } + if (entity instanceof EntityCreeper && ((EntityCreeper) entity).cn()) { // isExplosive + return true; + } + } + return false; + } + + + /** + * Checks if the entity is active for this tick. + * + * @param entity + * @return + */ + public static boolean checkIfActive(Entity entity) + { + SpigotTimings.checkIfActiveTimer.startTiming(); + // Never safe to skip fireworks or entities not yet added to chunk + if ( !entity.isAddedToChunk() || entity instanceof EntityFireworks || entity.loadChunks ) { // PaperSpigot + SpigotTimings.checkIfActiveTimer.stopTiming(); + return true; + } + + boolean isActive = entity.activatedTick >= MinecraftServer.currentTick || entity.defaultActivationState; + + // Should this entity tick? + if ( !isActive ) + { + if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 ) + { + // Check immunities every 20 ticks. + if ( checkEntityImmunities( entity ) ) + { + // Triggered some sort of immunity, give 20 full ticks before we check again. + entity.activatedTick = MinecraftServer.currentTick + 20; + } + isActive = true; + } + // Add a little performance juice to active entities. Skip 1/4 if not immune. + } else if ( !entity.defaultActivationState && entity.ticksLived % 4 == 0 && !checkEntityImmunities( entity ) ) + { + isActive = false; + } + int x = MathHelper.floor( entity.locX ); + int z = MathHelper.floor( entity.locZ ); + // Make sure not on edge of unloaded chunk + Chunk chunk = entity.world.getChunkIfLoaded( x >> 4, z >> 4 ); + if ( isActive && !( chunk != null && chunk.areNeighborsLoaded( 1 ) ) ) + { + isActive = false; + } + SpigotTimings.checkIfActiveTimer.stopTiming(); + return isActive; + } + + public static boolean cancelAI(Entity entity) { + return !MythicConfiguration.Options.Server.mobAi && (entity instanceof EntityChicken + || entity instanceof EntityCow + || entity instanceof EntityHorse + || entity instanceof EntityZombie + || entity instanceof EntityPig + || entity instanceof EntitySpider + || entity instanceof EntityBlaze); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/AntiXray.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/AntiXray.java new file mode 100644 index 0000000..b9d0fb6 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/AntiXray.java @@ -0,0 +1,316 @@ +package org.spigotmc; + +import co.aikar.timings.SpigotTimings; +import gnu.trove.set.TByteSet; +import gnu.trove.set.hash.TByteHashSet; +import me.levansj01.mythicspigot.MythicConfiguration; +import net.minecraft.server.*; +import net.techcable.tacospigot.utils.BlockHelper; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; + +import java.util.HashSet; +import java.util.Set; + +// PaperSpigot start +// PaperSpigot end +// TacoSpigot start +// TacoSpigot end + +public class AntiXray +{ + + // Used to keep track of which blocks to obfuscate + private final boolean[] obfuscateBlocks = new boolean[ Short.MAX_VALUE ]; + // Used to select a random replacement ore + private final byte[] replacementOres; + // PaperSpigot start + public boolean queueUpdates = true; + public final Set pendingUpdates = new HashSet(); + // PaperSpigot end + + public AntiXray(SpigotWorldConfig config) + { + // Set all listed blocks as true to be obfuscated + for ( int id : ( config.engineMode == 1 ) ? config.hiddenBlocks : config.replaceBlocks ) + { + obfuscateBlocks[id] = true; + } + + // For every block + TByteSet blocks = new TByteHashSet(); + for ( Integer i : config.hiddenBlocks ) + { + Block block = Block.getById( i ); + // Check it exists and is not a tile entity + if ( block != null && !block.isTileEntity() ) + { + // Add it to the set of replacement blocks + blocks.add( (byte) (int) i ); + } + } + // Bake it to a flat array of replacements + replacementOres = blocks.toArray(); + } + + /** + * PaperSpigot - Flush queued block updates for world. + */ + public void flushUpdates(World world) + { + if ( world.spigotConfig.antiXray && !pendingUpdates.isEmpty() ) + { + queueUpdates = false; + + for ( BlockPosition position : pendingUpdates ) + { + updateNearbyBlocks( world, position ); + } + + pendingUpdates.clear(); + queueUpdates = true; + } + } + + /** + * Starts the timings handler, then updates all blocks within the set radius + * of the given coordinate, revealing them if they are hidden ores. + */ + public void updateNearbyBlocks(World world, BlockPosition position) + { + if(!MythicConfiguration.Options.World.antiXray) return; + + if ( world.spigotConfig.antiXray ) { + // PaperSpigot start + if ( queueUpdates ) + { + pendingUpdates.add( position ); + return; + } + // PaperSpigot end + SpigotTimings.antiXrayUpdateTimer.startTiming(); + updateNearbyBlocks( world, position, 2, false ); // 2 is the radius, we shouldn't change it as that would make it exponentially slower + SpigotTimings.antiXrayUpdateTimer.stopTiming(); + } + } + + /** + * Starts the timings handler, and then removes all non exposed ores from + * the chunk buffer. + */ + public void obfuscateSync(int chunkX, int chunkY, int bitmask, byte[] buffer, World world) + { + if(!MythicConfiguration.Options.World.antiXray) return; + + if ( world.spigotConfig.antiXray ) + { + SpigotTimings.antiXrayObfuscateTimer.startTiming(); + obfuscate( chunkX, chunkY, bitmask, buffer, world ); + SpigotTimings.antiXrayObfuscateTimer.stopTiming(); + } + } + + /** + * Removes all non exposed ores from the chunk buffer. + */ + public void obfuscate(int chunkX, int chunkY, int bitmask, byte[] buffer, World world) + { + if(!MythicConfiguration.Options.World.antiXray) return; + + // If the world is marked as obfuscated + if ( world.spigotConfig.antiXray ) + { + // Initial radius to search around for air + int initialRadius = 1; + // Which block in the buffer we are looking at, anywhere from 0 to 16^4 + int index = 0; + // The iterator marking which random ore we should use next + int randomOre = 0; + + // Chunk corner X and Z blocks + int startX = chunkX << 4; + int startZ = chunkY << 4; + + byte replaceWithTypeId; + switch ( world.getWorld().getEnvironment() ) + { + case NETHER: + replaceWithTypeId = (byte) CraftMagicNumbers.getId(Blocks.NETHERRACK); + break; + case THE_END: + replaceWithTypeId = (byte) CraftMagicNumbers.getId(Blocks.END_STONE); + break; + default: + replaceWithTypeId = (byte) CraftMagicNumbers.getId(Blocks.STONE); + break; + } + + BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(); // TacoSpigot - preallocate MutableBlockPosition + // Chunks can have up to 16 sections + for ( int i = 0; i < 16; i++ ) + { + // If the bitmask indicates this chunk is sent... + if ( ( bitmask & 1 << i ) != 0 ) + { + // Work through all blocks in the chunk, y,z,x + for ( int y = 0; y < 16; y++ ) + { + for ( int z = 0; z < 16; z++ ) + { + for ( int x = 0; x < 16; x++ ) + { + // For some reason we can get too far ahead of ourselves (concurrent modification on bulk chunks?) so if we do, just abort and move on + if ( index >= buffer.length ) + { + index++; + continue; + } + // Grab the block ID in the buffer. + // TODO: extended IDs are not yet supported + int blockId = (buffer[index << 1] & 0xFF) + | ((buffer[(index << 1) + 1] & 0xFF) << 8); + blockId >>>= 4; + // Check if the block should be obfuscated + if ( obfuscateBlocks[blockId] ) + { + // The world isn't loaded, bail out + // TacoSpigot start + pos.setValues(startX + x, ( i << 4 ) + y, startZ + z); + if ( !isLoaded( world, /* new BlockPosition( startX + x, ( i << 4 ) + y, startZ + z ) */ pos, initialRadius ) ) + { + // TacoSpigot end + index++; + continue; + } + // On the otherhand, if radius is 0, or the nearby blocks are all non air, we can obfuscate + if ( !hasTransparentBlockAdjacent( world, /* new BlockPosition( startX + x, ( i << 4 ) + y, startZ + z ) */ pos, initialRadius ) ) // TacoSpigot - use prexisting MutableBlockPosition + { + int newId = blockId; + switch ( world.spigotConfig.engineMode ) + { + case 1: + // Replace with replacement material + newId = replaceWithTypeId & 0xFF; + break; + case 2: + // Replace with random ore. + if ( randomOre >= replacementOres.length ) + { + randomOre = 0; + } + newId = replacementOres[randomOre++] & 0xFF; + break; + } + newId <<= 4; + buffer[index << 1] = (byte) (newId & 0xFF); + buffer[(index << 1) + 1] = (byte) ((newId >> 8) & 0xFF); + } + } + + index++; + } + } + } + } + } + } + } + + // TacoSpigot start + private void updateNearbyBlocks(World world, final BlockPosition startPos, int radius, boolean updateSelf) { + int startX = startPos.getX() - radius; + int endX = startPos.getX() + radius; + int startY = Math.max(0, startPos.getY() - radius); + int endY = Math.min(255, startPos.getY() + radius); + int startZ = startPos.getZ() - radius; + int endZ = startPos.getZ() + radius; + BlockPosition.MutableBlockPosition adjacent = new BlockPosition.MutableBlockPosition(); + for (int x = startX; x <= endX; x++) { + for (int y = startY; y <= endY; y++) { + for (int z = startZ; z <= endZ; z++) { + adjacent.setValues(x, y, z); + if (!updateSelf && x == startPos.getX() & y == startPos.getY() & z == startPos.getZ()) continue; + if (world.isLoaded(adjacent)) updateBlock(world, adjacent); + } + } + } + } + + private void updateBlock(World world, BlockPosition position) + { + // If the block in question is loaded + if ( true ) // TacoSpigot - caller checked + { + // Get block id + Block block = getType(world, position); // TacoSpigot - directly access the underlying data + + // See if it needs update + if ( obfuscateBlocks[Block.getId( block )] ) // TacoSpigot - always update + { + // Send the update + world.notify( position ); + } + + // TacoSpigot start + /* + // Check other blocks for updates + if ( radius > 0 ) + { + updateNearbyBlocks( world, position.east(), radius - 1, true ); + updateNearbyBlocks( world, position.west(), radius - 1, true ); + updateNearbyBlocks( world, position.up(), radius - 1, true ); + updateNearbyBlocks( world, position.down(), radius - 1, true ); + updateNearbyBlocks( world, position.south(), radius - 1, true ); + updateNearbyBlocks( world, position.north(), radius - 1, true ); + } + */ + // TacoSpigot end + } + } + + private static boolean isLoaded(World world, BlockPosition position, int radius) + { + // TacoSpigot start + return BlockHelper.isAllAdjacentBlocksLoaded(world, position, radius); + // TacoSpigot end + } + + // TacoSpigot start + private static boolean hasTransparentBlockAdjacent(World w, BlockPosition startPos, int radius) + { + // !(solid blocks all around) + return !BlockHelper.isAllAdjacentBlocksFillPredicate(w, startPos, radius, (world, position) -> { + Block block = getType(world, position); + return isSolidBlock(block); + }); /* isSolidBlock */ + // TacoSpigot end + } + + private static boolean isSolidBlock(Block block) { + // Mob spawners are treated as solid blocks as far as the + // game is concerned for lighting and other tasks but for + // rendering they can be seen through therefor we special + // case them so that the antixray doesn't show the fake + // blocks around them. + return block.isOccluding() && block != Blocks.MOB_SPAWNER && block != Blocks.BARRIER; + } + + // TacoSpigot start + public static Block getType(World world, BlockPosition pos) { + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + Chunk chunk = world.getChunkIfLoaded(x >> 4, z >> 4); + if (chunk == null) return Blocks.AIR; + int sectionId = y >> 4; + if (sectionId < 0 || sectionId > 15) return Blocks.AIR; + ChunkSection section = chunk.getSections()[sectionId]; + if (section == null) return Blocks.AIR; // Handle empty chunks + x &= 0xF; + y &= 0xF; + z &= 0xF; + int combinedId = section.getIdArray()[(y << 8) | (z << 4) | x]; + int blockId = combinedId >> 4; + return BlockHelper.getBlock(blockId); + } + // TacoSpigot end +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/AsyncCatcher.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/AsyncCatcher.java new file mode 100644 index 0000000..51f443c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/AsyncCatcher.java @@ -0,0 +1,18 @@ +package org.spigotmc; + +import me.levansj01.mythicspigot.MythicConfiguration; +import net.minecraft.server.MinecraftServer; + +public class AsyncCatcher +{ + + public static boolean enabled = MythicConfiguration.Options.Server.asyncCatcher; + + public static void catchOp(String reason) + { + if ( enabled && Thread.currentThread() != MinecraftServer.getServer().primaryThread ) + { + throw new IllegalStateException( "Asynchronous " + reason + "!" ); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/CaseInsensitiveHashingStrategy.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/CaseInsensitiveHashingStrategy.java new file mode 100644 index 0000000..aafdd36 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/CaseInsensitiveHashingStrategy.java @@ -0,0 +1,18 @@ +package org.spigotmc; + +import gnu.trove.strategy.HashingStrategy; + +class CaseInsensitiveHashingStrategy implements HashingStrategy { + + static final CaseInsensitiveHashingStrategy INSTANCE = new CaseInsensitiveHashingStrategy(); + + @Override + public int computeHashCode(Object object) { + return ((String) object).toLowerCase().hashCode(); + } + + @Override + public boolean equals(Object o1, Object o2) { + return o1.equals(o2) || (o1 instanceof String && o2 instanceof String && ((String) o1).toLowerCase().equals(((String) o2).toLowerCase())); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/CaseInsensitiveMap.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/CaseInsensitiveMap.java new file mode 100644 index 0000000..1934fd5 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/CaseInsensitiveMap.java @@ -0,0 +1,15 @@ +package org.spigotmc; + +import gnu.trove.map.hash.TCustomHashMap; +import java.util.Map; + +public class CaseInsensitiveMap extends TCustomHashMap { + + public CaseInsensitiveMap() { + super(CaseInsensitiveHashingStrategy.INSTANCE); + } + + public CaseInsensitiveMap(Map map) { + super(CaseInsensitiveHashingStrategy.INSTANCE, map); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/LimitStream.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/LimitStream.java new file mode 100644 index 0000000..8c32e8b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/LimitStream.java @@ -0,0 +1,39 @@ +package org.spigotmc; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import net.minecraft.server.NBTReadLimiter; + +public class LimitStream extends FilterInputStream +{ + + private final NBTReadLimiter limit; + + public LimitStream(InputStream is, NBTReadLimiter limit) + { + super( is ); + this.limit = limit; + } + + @Override + public int read() throws IOException + { + limit.a( 8 ); + return super.read(); + } + + @Override + public int read(byte[] b) throws IOException + { + limit.a( b.length * 8 ); + return super.read( b ); + } + + @Override + public int read(byte[] b, int off, int len) throws IOException + { + limit.a( len * 8 ); + return super.read( b, off, len ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/Metrics.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/Metrics.java new file mode 100644 index 0000000..f653050 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/Metrics.java @@ -0,0 +1,645 @@ +/* + * Copyright 2011-2013 Tyler Blair. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and contributors and should not be interpreted as representing official policies, + * either expressed or implied, of anybody else. + */ +package org.spigotmc; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.scheduler.BukkitTask; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.net.Proxy; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import net.minecraft.server.MinecraftServer; + +/** + *

    The metrics class obtains data about a plugin and submits statistics about it to the metrics backend.

    + * Public methods provided by this class:

    + * + * Graph createGraph(String name);
    + * void addCustomData(BukkitMetrics.Plotter plotter);
    + * void start();
    + *
    + */ +public class Metrics { + + /** + * The current revision number + */ + private final static int REVISION = 6; + /** + * The base url of the metrics domain + */ + private static final String BASE_URL = "http://mcstats.org"; + /** + * The url used to report a server's status + */ + private static final String REPORT_URL = "/report/%s"; + /** + * The separator to use for custom data. This MUST NOT change unless you are hosting your own version of metrics and + * want to change it. + */ + private static final String CUSTOM_DATA_SEPARATOR = "~~"; + /** + * Interval of time to ping (in minutes) + */ + private static final int PING_INTERVAL = 10; + /** + * All of the custom graphs to submit to metrics + */ + private final Set graphs = Collections.synchronizedSet(new HashSet()); + /** + * The default graph, used for addCustomData when you don't want a specific graph + */ + private final Graph defaultGraph = new Graph("Default"); + /** + * The plugin configuration file + */ + private final YamlConfiguration configuration; + /** + * The plugin configuration file + */ + private final File configurationFile; + /** + * Unique server id + */ + private final String guid; + /** + * Debug mode + */ + private final boolean debug; + /** + * Lock for synchronization + */ + private final Object optOutLock = new Object(); + /** + * The scheduled task + */ + private volatile Timer task = null; + + public Metrics() throws IOException { + // load the config + configurationFile = getConfigFile(); + configuration = YamlConfiguration.loadConfiguration(configurationFile); + + // add some defaults + configuration.addDefault("opt-out", false); + configuration.addDefault("guid", UUID.randomUUID().toString()); + configuration.addDefault("debug", false); + + // Do we need to create the file? + if (configuration.get("guid", null) == null) { + configuration.options().header("http://mcstats.org").copyDefaults(true); + configuration.save(configurationFile); + } + + // Load the guid then + guid = configuration.getString("guid"); + debug = configuration.getBoolean("debug", false); + } + + /** + * Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics + * website. Plotters can be added to the graph object returned. + * + * @param name The name of the graph + * @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given + */ + public Graph createGraph(final String name) { + if (name == null) { + throw new IllegalArgumentException("Graph name cannot be null"); + } + + // Construct the graph object + final Graph graph = new Graph(name); + + // Now we can add our graph + graphs.add(graph); + + // and return back + return graph; + } + + /** + * Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend + * + * @param graph The name of the graph + */ + public void addGraph(final Graph graph) { + if (graph == null) { + throw new IllegalArgumentException("Graph cannot be null"); + } + + graphs.add(graph); + } + + /** + * Adds a custom data plotter to the default graph + * + * @param plotter The plotter to use to plot custom data + */ + public void addCustomData(final Plotter plotter) { + if (plotter == null) { + throw new IllegalArgumentException("Plotter cannot be null"); + } + + // Add the plotter to the graph o/ + defaultGraph.addPlotter(plotter); + + // Ensure the default graph is included in the submitted graphs + graphs.add(defaultGraph); + } + + /** + * Start measuring statistics. This will immediately create an async repeating task as the plugin and send the + * initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200 + * ticks. + * + * @return True if statistics measuring is running, otherwise false. + */ + public boolean start() { + synchronized (optOutLock) { + // Did we opt out? + if (isOptOut()) { + return false; + } + + // Is metrics already running? + if (task != null) { + return true; + } + + // Begin hitting the server with glorious data + task = new Timer("Spigot Metrics Thread", true); + + task.scheduleAtFixedRate(new TimerTask() { + private boolean firstPost = true; + + public void run() { + try { + // This has to be synchronized or it can collide with the disable method. + synchronized (optOutLock) { + // Disable Task, if it is running and the server owner decided to opt-out + if (isOptOut() && task != null) { + task.cancel(); + task = null; + // Tell all plotters to stop gathering information. + for (Graph graph : graphs) { + graph.onOptOut(); + } + } + } + + // We use the inverse of firstPost because if it is the first time we are posting, + // it is not a interval ping, so it evaluates to FALSE + // Each time thereafter it will evaluate to TRUE, i.e PING! + postPlugin(!firstPost); + + // After the first post we set firstPost to false + // Each post thereafter will be a ping + firstPost = false; + } catch (IOException e) { + if (debug) { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage()); + } + } + } + }, 0, TimeUnit.MINUTES.toMillis(PING_INTERVAL)); + + return true; + } + } + + /** + * Has the server owner denied plugin metrics? + * + * @return true if metrics should be opted out of it + */ + public boolean isOptOut() { + synchronized (optOutLock) { + try { + // Reload the metrics file + configuration.load(getConfigFile()); + } catch (IOException ex) { + if (debug) { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); + } + return true; + } catch (InvalidConfigurationException ex) { + if (debug) { + Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); + } + return true; + } + return configuration.getBoolean("opt-out", false); + } + } + + /** + * Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task. + * + * @throws java.io.IOException + */ + public void enable() throws IOException { + // This has to be synchronized or it can collide with the check in the task. + synchronized (optOutLock) { + // Check if the server owner has already set opt-out, if not, set it. + if (isOptOut()) { + configuration.set("opt-out", false); + configuration.save(configurationFile); + } + + // Enable Task, if it is not running + if (task == null) { + start(); + } + } + } + + /** + * Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task. + * + * @throws java.io.IOException + */ + public void disable() throws IOException { + // This has to be synchronized or it can collide with the check in the task. + synchronized (optOutLock) { + // Check if the server owner has already set opt-out, if not, set it. + if (!isOptOut()) { + configuration.set("opt-out", true); + configuration.save(configurationFile); + } + + // Disable Task, if it is running + if (task != null) { + task.cancel(); + task = null; + } + } + } + + /** + * Gets the File object of the config file that should be used to store data such as the GUID and opt-out status + * + * @return the File object for the config file + */ + public File getConfigFile() { + // I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use + // is to abuse the plugin object we already have + // plugin.getDataFolder() => base/plugins/PluginA/ + // pluginsFolder => base/plugins/ + // The base is not necessarily relative to the startup directory. + // File pluginsFolder = plugin.getDataFolder().getParentFile(); + + // return => base/plugins/PluginMetrics/config.yml + return new File(new File((File) MinecraftServer.getServer().options.valueOf("plugins"), "PluginMetrics"), "config.yml"); + } + + /** + * Generic method that posts a plugin to the metrics website + */ + private void postPlugin(final boolean isPing) throws IOException { + // Server software specific section + String pluginName = "TacoSpigot"; // PaperSpigot - We need some usage data // TacoSpigot - its *my* usage data + boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled + String pluginVersion = (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown"; + String serverVersion = Bukkit.getVersion(); + int playersOnline = Bukkit.getServer().getOnlinePlayers().size(); + + // END server software specific section -- all code below does not use any code outside of this class / Java + + // Construct the post data + final StringBuilder data = new StringBuilder(); + + // The plugin's description file containg all of the plugin data such as name, version, author, etc + data.append(encode("guid")).append('=').append(encode(guid)); + encodeDataPair(data, "version", pluginVersion); + encodeDataPair(data, "server", serverVersion); + encodeDataPair(data, "players", Integer.toString(playersOnline)); + encodeDataPair(data, "revision", String.valueOf(REVISION)); + + // New data as of R6 + String osname = System.getProperty("os.name"); + String osarch = System.getProperty("os.arch"); + String osversion = System.getProperty("os.version"); + String java_version = System.getProperty("java.version"); + int coreCount = Runtime.getRuntime().availableProcessors(); + + // normalize os arch .. amd64 -> x86_64 + if (osarch.equals("amd64")) { + osarch = "x86_64"; + } + + encodeDataPair(data, "osname", osname); + encodeDataPair(data, "osarch", osarch); + encodeDataPair(data, "osversion", osversion); + encodeDataPair(data, "cores", Integer.toString(coreCount)); + encodeDataPair(data, "online-mode", Boolean.toString(onlineMode)); + encodeDataPair(data, "java_version", java_version); + + // If we're pinging, append it + if (isPing) { + encodeDataPair(data, "ping", "true"); + } + + // Acquire a lock on the graphs, which lets us make the assumption we also lock everything + // inside of the graph (e.g plotters) + synchronized (graphs) { + final Iterator iter = graphs.iterator(); + + while (iter.hasNext()) { + final Graph graph = iter.next(); + + for (Plotter plotter : graph.getPlotters()) { + // The key name to send to the metrics server + // The format is C-GRAPHNAME-PLOTTERNAME where separator - is defined at the top + // Legacy (R4) submitters use the format Custom%s, or CustomPLOTTERNAME + final String key = String.format("C%s%s%s%s", CUSTOM_DATA_SEPARATOR, graph.getName(), CUSTOM_DATA_SEPARATOR, plotter.getColumnName()); + + // The value to send, which for the foreseeable future is just the string + // value of plotter.getValue() + final String value = Integer.toString(plotter.getValue()); + + // Add it to the http post data :) + encodeDataPair(data, key, value); + } + } + } + + // Create the url + URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(pluginName))); + + // Connect to the website + URLConnection connection; + + // Mineshafter creates a socks proxy, so we can safely bypass it + // It does not reroute POST requests so we need to go around it + if (isMineshafterPresent()) { + connection = url.openConnection(Proxy.NO_PROXY); + } else { + connection = url.openConnection(); + } + + connection.setDoOutput(true); + + // Write the data + final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); + writer.write(data.toString()); + writer.flush(); + + // Now read the response + final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + final String response = reader.readLine(); + + // close resources + writer.close(); + reader.close(); + + if (response == null || response.startsWith("ERR")) { + throw new IOException(response); //Throw the exception + } else { + // Is this the first update this hour? + if (response.contains("OK This is your first update this hour")) { + synchronized (graphs) { + final Iterator iter = graphs.iterator(); + + while (iter.hasNext()) { + final Graph graph = iter.next(); + + for (Plotter plotter : graph.getPlotters()) { + plotter.reset(); + } + } + } + } + } + } + + /** + * Check if mineshafter is present. If it is, we need to bypass it to send POST requests + * + * @return true if mineshafter is installed on the server + */ + private boolean isMineshafterPresent() { + try { + Class.forName("mineshafter.MineServer"); + return true; + } catch (Exception e) { + return false; + } + } + + /** + *

    Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first key/value pair + * MUST be included manually, e.g:

    + * + * StringBuffer data = new StringBuffer(); + * data.append(encode("guid")).append('=').append(encode(guid)); + * encodeDataPair(data, "version", description.getVersion()); + * + * + * @param buffer the stringbuilder to append the data pair onto + * @param key the key value + * @param value the value + */ + private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException { + buffer.append('&').append(encode(key)).append('=').append(encode(value)); + } + + /** + * Encode text as UTF-8 + * + * @param text the text to encode + * @return the encoded text, as UTF-8 + */ + private static String encode(final String text) throws UnsupportedEncodingException { + return URLEncoder.encode(text, "UTF-8"); + } + + /** + * Represents a custom graph on the website + */ + public static class Graph { + + /** + * The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is + * rejected + */ + private final String name; + /** + * The set of plotters that are contained within this graph + */ + private final Set plotters = new LinkedHashSet(); + + private Graph(final String name) { + this.name = name; + } + + /** + * Gets the graph's name + * + * @return the Graph's name + */ + public String getName() { + return name; + } + + /** + * Add a plotter to the graph, which will be used to plot entries + * + * @param plotter the plotter to add to the graph + */ + public void addPlotter(final Plotter plotter) { + plotters.add(plotter); + } + + /** + * Remove a plotter from the graph + * + * @param plotter the plotter to remove from the graph + */ + public void removePlotter(final Plotter plotter) { + plotters.remove(plotter); + } + + /** + * Gets an unmodifiable set of the plotter objects in the graph + * + * @return an unmodifiable {@link java.util.Set} of the plotter objects + */ + public Set getPlotters() { + return Collections.unmodifiableSet(plotters); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(final Object object) { + if (!(object instanceof Graph)) { + return false; + } + + final Graph graph = (Graph) object; + return graph.name.equals(name); + } + + /** + * Called when the server owner decides to opt-out of BukkitMetrics while the server is running. + */ + protected void onOptOut() { + } + } + + /** + * Interface used to collect custom data for a plugin + */ + public static abstract class Plotter { + + /** + * The plot's name + */ + private final String name; + + /** + * Construct a plotter with the default plot name + */ + public Plotter() { + this("Default"); + } + + /** + * Construct a plotter with a specific plot name + * + * @param name the name of the plotter to use, which will show up on the website + */ + public Plotter(final String name) { + this.name = name; + } + + /** + * Get the current value for the plotted point. Since this function defers to an external function it may or may + * not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called + * from any thread so care should be taken when accessing resources that need to be synchronized. + * + * @return the current value for the point to be plotted. + */ + public abstract int getValue(); + + /** + * Get the column name for the plotted point + * + * @return the plotted point's column name + */ + public String getColumnName() { + return name; + } + + /** + * Called after the website graphs have been updated + */ + public void reset() { + } + + @Override + public int hashCode() { + return getColumnName().hashCode(); + } + + @Override + public boolean equals(final Object object) { + if (!(object instanceof Plotter)) { + return false; + } + + final Plotter plotter = (Plotter) object; + return plotter.name.equals(name) && plotter.getValue() == getValue(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/RestartCommand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/RestartCommand.java new file mode 100644 index 0000000..429c258 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/RestartCommand.java @@ -0,0 +1,124 @@ +package org.spigotmc; + +import java.io.File; +import java.util.List; +import net.minecraft.server.EntityPlayer; +import net.minecraft.server.MinecraftServer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class RestartCommand extends Command +{ + + public RestartCommand(String name) + { + super( name ); + this.description = "Restarts the server"; + this.usageMessage = "/restart"; + this.setPermission( "bukkit.command.restart" ); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) + { + if ( testPermission( sender ) ) + { + MinecraftServer.getServer().processQueue.add( new Runnable() + { + @Override + public void run() + { + restart(); + } + } ); + } + return true; + } + + public static void restart() + { + restart( new File( SpigotConfig.restartScript ) ); + } + + public static void restart(final File script) + { + AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us + try + { + if ( script.isFile() ) + { + System.out.println( "Attempting to restart with " + SpigotConfig.restartScript ); + + // Disable Watchdog + WatchdogThread.doStop(); + + // Kick all players + for ( EntityPlayer p : (List< EntityPlayer>) MinecraftServer.getServer().getPlayerList().players ) + { + p.playerConnection.disconnect(SpigotConfig.restartMessage); + } + // Give the socket a chance to send the packets + try + { + Thread.sleep( 100 ); + } catch ( InterruptedException ex ) + { + } + // Close the socket so we can rebind with the new process + MinecraftServer.getServer().getServerConnection().b(); + + // Give time for it to kick in + try + { + Thread.sleep( 100 ); + } catch ( InterruptedException ex ) + { + } + + // Actually shutdown + try + { + MinecraftServer.getServer().stop(); + } catch ( Throwable t ) + { + } + + // This will be done AFTER the server has completely halted + Thread shutdownHook = new Thread() + { + @Override + public void run() + { + try + { + String os = System.getProperty( "os.name" ).toLowerCase(); + if ( os.contains( "win" ) ) + { + Runtime.getRuntime().exec( "cmd /c start " + script.getPath() ); + } else + { + Runtime.getRuntime().exec( new String[] + { + "sh", script.getPath() + } ); + } + } catch ( Exception e ) + { + e.printStackTrace(); + } + } + }; + + shutdownHook.setDaemon( true ); + Runtime.getRuntime().addShutdownHook( shutdownHook ); + } else + { + System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." ); + } + System.exit( 0 ); + } catch ( Exception ex ) + { + ex.printStackTrace(); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SneakyThrow.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SneakyThrow.java new file mode 100644 index 0000000..31fc0a9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SneakyThrow.java @@ -0,0 +1,15 @@ +package org.spigotmc; + +public class SneakyThrow +{ + + public static void sneaky(Throwable t) + { + throw SneakyThrow.superSneaky( t ); + } + + private static T superSneaky(Throwable t) throws T + { + throw (T) t; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java new file mode 100644 index 0000000..b9d185d --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SpigotConfig.java @@ -0,0 +1,427 @@ +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.concurrent.TimeUnit; +import java.util.logging.Level; +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; +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) + { + 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 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 ); + } + + private static boolean getBoolean(String path, boolean def) + { + config.addDefault( path, def ); + return config.getBoolean( path, config.getBoolean( 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 (List) 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 ) ); + } + + private static double getDouble(String path, double def) + { + config.addDefault( path, def ); + return config.getDouble( path, config.getDouble( path ) ); + } + + public static boolean logCommands; + private static void logCommands() + { + logCommands = getBoolean( "commands.log", true ); + } + + 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 serverFullMessage; + public static String outdatedClientMessage = "Outdated client! Please use {0}"; + public static String outdatedServerMessage = "Outdated server! I\'m still on {0}"; + private static String transform(String s) + { + return ChatColor.translateAlternateColorCodes( '&', s ).replaceAll( "\\n", "\n" ); + } + 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." ) ); + serverFullMessage = transform( getString( "messages.server-full", "The server is full!" ) ); + outdatedClientMessage = transform( getString( "messages.outdated-client", outdatedClientMessage ) ); + outdatedServerMessage = transform( getString( "messages.outdated-server", outdatedServerMessage ) ); + } + + public static int timeoutTime = 60; + public static boolean restartOnCrash = true; + public static String restartScript = "./start.sh"; + public static String restartMessage; + private static void watchdog() + { + timeoutTime = getInt( "settings.timeout-time", timeoutTime ); + restartOnCrash = getBoolean( "settings.restart-on-crash", restartOnCrash ); + restartScript = getString( "settings.restart-script", restartScript ); + restartMessage = transform( getString( "messages.restart", "Server is restarting" ) ); + commands.put( "restart", new RestartCommand( "restart" ) ); + WatchdogThread.doStart( timeoutTime, restartOnCrash ); + } + + 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 ); + } + + private static void timings() + { + boolean timings = getBoolean( "timings.enabled", true ); + boolean verboseTimings = getBoolean( "timings.verbose", true ); + TimingsManager.privacy = getBoolean( "timings.server-name-privacy", false ); + TimingsManager.hiddenConfigs = getList( "timings.hidden-config-entries", Lists.newArrayList("database", "settings.bungeecord-addresses")); + int timingHistoryInterval = getInt( "timings.history-interval", 300 ); + int timingHistoryLength = getInt( "timings.history-length", 3600 ); + + + Timings.setVerboseTimingsEnabled( verboseTimings ); + Timings.setTimingsEnabled( timings ); + Timings.setHistoryInterval( timingHistoryInterval * 20 ); + Timings.setHistoryLength( timingHistoryLength * 20 ); + + Bukkit.getLogger().log( Level.INFO, "Spigot Timings: " + timings + + " - Verbose: " + verboseTimings + + " - Interval: " + timeSummary(Timings.getHistoryInterval() / 20) + + " - Length: " + timeSummary(Timings.getHistoryLength() / 20)); + } + protected static String timeSummary(int seconds) { + String time = ""; + if (seconds > 60*60) { + time += TimeUnit.SECONDS.toHours(seconds) + "h"; + seconds /= 60; + } + + if (seconds > 0) { + time += TimeUnit.SECONDS.toMinutes(seconds) + "m"; + } + return time; + } + + private static void nettyThreads() + { + int count = getInt( "settings.netty-threads", 4 ); + System.setProperty( "io.netty.eventLoopThreads", Integer.toString( count ) ); + Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count ); + } + + public static boolean lateBind; + private static void lateBind() { + lateBind = getBoolean( "settings.late-bind", false ); + } + + public static boolean disableStatSaving; + 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" ); + } + + ConfigurationSection section = config.getConfigurationSection( "stats.forced-stats" ); + for ( String name : section.getKeys( true ) ) + { + if ( section.isInt( name ) ) + { + forcedStats.put( name, section.getInt( name ) ); + } + } + + if ( disableStatSaving && section.getInt( "achievement.openInventory", 0 ) < 1 ) + { + Bukkit.getLogger().warning( "*** WARNING *** stats.disable-saving is true but stats.forced-stats.achievement.openInventory" + + " isn't set to 1. Disabling stat saving without forcing the achievement may cause it to get stuck on the player's " + + "screen." ); + } + } + + private static void tpsCommand() + { + commands.put( "tps", new TicksPerSecondCommand( "tps" ) ); + } + + public static int playerSample; + private static void playerSample() + { + playerSample = getInt( "settings.sample-count", 12 ); + System.out.println( "Server Ping Player Sample Count: " + playerSample ); + } + + public static int playerShuffle; + private static void playerShuffle() + { + playerShuffle = getInt( "settings.player-shuffle", 0 ); + } + + public static List spamExclusions; + private static void spamExclusions() + { + spamExclusions = getList( "commands.spam-exclusions", Arrays.asList( new String[] + { + "/skill" + } ) ); + } + + public static boolean silentCommandBlocks; + private static void silentCommandBlocks() + { + silentCommandBlocks = getBoolean( "commands.silent-commandblock-console", false ); + } + + public static boolean filterCreativeItems; + private static void filterCreativeItems() + { + filterCreativeItems = getBoolean( "settings.filter-creative-items", true ); + } + + 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" ) ) ); + } + + public static int userCacheCap; + private static void userCacheCap() + { + userCacheCap = getInt( "settings.user-cache-size", 1000 ); + } + + public static boolean saveUserCacheOnStopOnly; + private static void saveUserCacheOnStopOnly() + { + saveUserCacheOnStopOnly = getBoolean( "settings.save-user-cache-on-stop-only", false ); + } + + public static int intCacheLimit; + private static void intCacheLimit() + { + intCacheLimit = getInt( "settings.int-cache-limit", 1024 ); + } + + public static double movedWronglyThreshold; + private static void movedWronglyThreshold() + { + movedWronglyThreshold = getDouble( "settings.moved-wrongly-threshold", 0.0625D ); + } + + public static double movedTooQuicklyThreshold; + private static void movedTooQuicklyThreshold() + { + movedTooQuicklyThreshold = getDouble( "settings.moved-too-quickly-threshold", 100.0D ); + } + + public static double maxHealth = 2048; + public static double movementSpeed = 2048; + public static double attackDamage = 2048; + private static void attributeMaxes() + { + maxHealth = getDouble( "settings.attribute.maxHealth.max", maxHealth ); + ( (AttributeRanged) GenericAttributes.maxHealth ).b = maxHealth; + movementSpeed = getDouble( "settings.attribute.movementSpeed.max", movementSpeed ); + ( (AttributeRanged) GenericAttributes.MOVEMENT_SPEED ).b = movementSpeed; + attackDamage = getDouble( "settings.attribute.attackDamage.max", attackDamage ); + ( (AttributeRanged) GenericAttributes.ATTACK_DAMAGE ).b = attackDamage; + } + + public static boolean debug; + private static void debug() + { + debug = getBoolean( "settings.debug", false ); + + if ( debug && !LogManager.getRootLogger().isTraceEnabled() ) + { + // Enable debug logging + LoggerContext ctx = (LoggerContext) LogManager.getContext( false ); + Configuration conf = ctx.getConfiguration(); + conf.getLoggerConfig( LogManager.ROOT_LOGGER_NAME ).setLevel( org.apache.logging.log4j.Level.ALL ); + ctx.updateLoggers( conf ); + } + + if ( LogManager.getRootLogger().isTraceEnabled() ) + { + Bukkit.getLogger().info( "Debug logging is enabled" ); + } else + { + Bukkit.getLogger().info( "Debug logging is disabled" ); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SpigotWorldConfig.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SpigotWorldConfig.java new file mode 100644 index 0000000..8e86212 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -0,0 +1,344 @@ +package org.spigotmc; + +import java.util.Arrays; +import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; + +public class SpigotWorldConfig +{ + + private final String worldName; + private final YamlConfiguration config; + private boolean verbose; + + public SpigotWorldConfig(String worldName) + { + this.worldName = worldName; + this.config = SpigotConfig.config; + init(); + } + + public void init() + { + this.verbose = getBoolean( "verbose", true ); + + log( "-------- World Settings For [" + worldName + "] --------" ); + SpigotConfig.readConfig( SpigotWorldConfig.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 List getList(String path, T def) + { + config.addDefault( "world-settings.default." + path, def ); + return (List) 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 int chunksPerTick; + public boolean clearChunksOnTick; + private void chunksPerTick() + { + chunksPerTick = getInt( "chunks-per-tick", 650 ); + log( "Chunks to Grow per Tick: " + chunksPerTick ); + + clearChunksOnTick = getBoolean( "clear-tick-list", false ); + log( "Clear tick list: " + clearChunksOnTick ); + } + + // 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) + { + int modifier = getInt( "growth." + crop.toLowerCase() + "-modifier", 100 ); + if ( modifier == 0 ) + { + log( "Cannot set " + crop + " growth to zero, defaulting to 100" ); + modifier = 100; + } + log( crop + " Growth Modifier: " + modifier + "%" ); + + return modifier; + } + private void growthModifiers() + { + cactusModifier = getAndValidateGrowth( "Cactus" ); + caneModifier = getAndValidateGrowth( "Cane" ); + melonModifier = getAndValidateGrowth( "Melon" ); + mushroomModifier = getAndValidateGrowth( "Mushroom" ); + pumpkinModifier = getAndValidateGrowth( "Pumpkin" ); + saplingModifier = getAndValidateGrowth( "Sapling" ); + wheatModifier = getAndValidateGrowth( "Wheat" ); + wartModifier = getAndValidateGrowth( "NetherWart" ); + } + + public double itemMerge; + private void itemMerge() + { + itemMerge = getDouble("merge-radius.item", 2.5 ); + log( "Item Merge Radius: " + itemMerge ); + } + + public double expMerge; + private void expMerge() + { + expMerge = getDouble("merge-radius.exp", 3.0 ); + log( "Experience Merge Radius: " + expMerge ); + } + + public int viewDistance; + private void viewDistance() + { + viewDistance = getInt( "view-distance", Bukkit.getViewDistance() ); + log( "View Distance: " + viewDistance ); + } + + public byte mobSpawnRange; + private 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() + { + animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange ); + monsterActivationRange = getInt( "entity-activation-range.monsters", monsterActivationRange ); + miscActivationRange = getInt( "entity-activation-range.misc", miscActivationRange ); + 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() + { + playerTrackingRange = getInt( "entity-tracking-range.players", playerTrackingRange ); + animalTrackingRange = getInt( "entity-tracking-range.animals", animalTrackingRange ); + monsterTrackingRange = getInt( "entity-tracking-range.monsters", monsterTrackingRange ); + miscTrackingRange = getInt( "entity-tracking-range.misc", miscTrackingRange ); + otherTrackingRange = getInt( "entity-tracking-range.other", otherTrackingRange ); + 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() + { + // Set the tick delay between hopper item movements + hopperTransfer = getInt( "ticks-per.hopper-transfer", 8 ); + // Set the tick delay between checking for items after the associated + // container is empty. Default to the hopperTransfer value to prevent + // hopper sorting machines from becoming out of sync. + hopperCheck = getInt( "ticks-per.hopper-check", hopperTransfer ); + hopperAmount = getInt( "hopper-amount", 1 ); + log( "Hopper Transfer: " + hopperTransfer + " Hopper Check: " + hopperCheck + " Hopper Amount: " + hopperAmount ); + } + + public boolean randomLightUpdates; + private void lightUpdates() + { + randomLightUpdates = getBoolean( "random-light-updates", false ); + log( "Random Lighting Updates: " + randomLightUpdates ); + } + + public boolean saveStructureInfo; + private void structureInfo() + { + saveStructureInfo = getBoolean( "save-structure-info", true ); + log( "Structure Info Saving: " + saveStructureInfo ); + if ( !saveStructureInfo ) + { + log( "*** WARNING *** You have selected to NOT save structure info. This may cause structures such as fortresses to not spawn mobs!" ); + log( "*** WARNING *** Please use this option with caution, SpigotMC is not responsible for any issues this option may cause in the future!" ); + } + } + + public int itemDespawnRate; + private void itemDespawnRate() + { + itemDespawnRate = getInt( "item-despawn-rate", 6000 ); + log( "Item Despawn Rate: " + itemDespawnRate ); + } + + public int arrowDespawnRate; + private 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() + { + antiXray = getBoolean( "anti-xray.enabled", true ); + 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 + } ) ); + log( "\tHidden Blocks: " + hiddenBlocks ); + + replaceBlocks = getList( "anti-xray.replace-blocks", Arrays.asList( new Integer[] + { + 1, 5 + } ) ); + log( "\tReplace Blocks: " + replaceBlocks ); + + antiXrayInstance = new AntiXray( this ); + } + + public boolean zombieAggressiveTowardsVillager; + private void zombieAggressiveTowardsVillager() + { + zombieAggressiveTowardsVillager = getBoolean( "zombie-aggressive-towards-villager", true ); + log( "Zombie Aggressive Towards Villager: " + zombieAggressiveTowardsVillager ); + } + + public boolean nerfSpawnerMobs; + private void nerfSpawnerMobs() + { + nerfSpawnerMobs = getBoolean( "nerf-spawner-mobs", false ); + log( "Nerfing mobs spawned from spawners: " + nerfSpawnerMobs ); + } + + public boolean enableZombiePigmenPortalSpawns; + private 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() + { + maxBulkChunk = getInt( "max-bulk-chunks", 10 ); + log( "Sending up to " + maxBulkChunk + " chunks per packet" ); + } + + public int maxCollisionsPerEntity; + private void maxEntityCollision() + { + maxCollisionsPerEntity = getInt( "max-entity-collisions", 8 ); + log( "Max Entity Collisions: " + maxCollisionsPerEntity ); + } + + public int dragonDeathSoundRadius; + private void keepDragonDeathPerWorld() + { + dragonDeathSoundRadius = getInt( "dragon-death-sound-radius", 0 ); + } + + public int witherSpawnSoundRadius; + private void witherSpawnSoundRadius() + { + witherSpawnSoundRadius = getInt( "wither-spawn-sound-radius", 0 ); + } + + public int villageSeed; + public int largeFeatureSeed; + private 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() + { + walkExhaustion = (float) getDouble( "hunger.walk-exhaustion", 0.2 ); + sprintExhaustion = (float) getDouble( "hunger.sprint-exhaustion", 0.8 ); + combatExhaustion = (float) getDouble( "hunger.combat-exhaustion", 0.3 ); + 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 ); + } + maxTntTicksPerTick = getInt( "max-tnt-per-tick", 100 ); + log( "Max TNT Explosions: " + maxTntTicksPerTick ); + } + + public int hangingTickFrequency; + private void hangingTickFrequency() + { + hangingTickFrequency = getInt( "hanging-tick-frequency", 100 ); + } + + public int tileMaxTickTime; + public int entityMaxTickTime; + private void maxTickTimes() + { + tileMaxTickTime = getInt("max-tick-time.tile", 50); + entityMaxTickTime = getInt("max-tick-time.entity", 50); + log("Tile Max Tick Time: " + tileMaxTickTime + "ms Entity max Tick Time: " + entityMaxTickTime + "ms"); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TickLimiter.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TickLimiter.java new file mode 100644 index 0000000..23a3938 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TickLimiter.java @@ -0,0 +1,20 @@ +package org.spigotmc; + +public class TickLimiter { + + private final int maxTime; + private long startTime; + + public TickLimiter(int maxtime) { + this.maxTime = maxtime; + } + + public void initTick() { + startTime = System.currentTimeMillis(); + } + + public boolean shouldContinue() { + long remaining = System.currentTimeMillis() - startTime; + return remaining < maxTime; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TicksPerSecondCommand.java new file mode 100644 index 0000000..3343e55 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TicksPerSecondCommand.java @@ -0,0 +1,43 @@ +package org.spigotmc; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; + +public class TicksPerSecondCommand extends Command +{ + + public TicksPerSecondCommand(String name) + { + super( name ); + this.description = "Gets the current ticks per second for the server"; + this.usageMessage = "/tps"; + this.setPermission( "group.trainee" ); + } + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) + { + if ( !testPermission( sender ) ) + { + return true; + } + + // PaperSpigot start - Further improve tick handling + double[] tps = org.bukkit.Bukkit.spigot().getTPS(); + String[] tpsAvg = new String[tps.length]; + + for ( int i = 0; i < tps.length; i++) { + tpsAvg[i] = format( tps[i] ); + } + sender.sendMessage( ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " + org.apache.commons.lang.StringUtils.join(tpsAvg, ", ")); + + return true; + } + + private static String format(double tps) // PaperSpigot - made static + { + return ( ( tps > 18.0 ) ? ChatColor.GREEN : ( tps > 16.0 ) ? ChatColor.YELLOW : ChatColor.RED ).toString() + + ( ( tps > 20.0 ) ? "*" : "" ) + Math.min( Math.round( tps * 100.0 ) / 100.0, 20.0 ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TrackingRange.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TrackingRange.java new file mode 100644 index 0000000..4bf4d2a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/TrackingRange.java @@ -0,0 +1,51 @@ +package org.spigotmc; + +import net.minecraft.server.Entity; +import net.minecraft.server.EntityExperienceOrb; +import net.minecraft.server.EntityGhast; +import net.minecraft.server.EntityItem; +import net.minecraft.server.EntityItemFrame; +import net.minecraft.server.EntityPainting; +import net.minecraft.server.EntityPlayer; + +public class TrackingRange +{ + + /** + * Gets the range an entity should be 'tracked' by players and visible in + * the client. + * + * @param entity + * @param defaultRange Default range defined by Mojang + * @return + */ + public static int getEntityTrackingRange(Entity entity, int defaultRange) + { + SpigotWorldConfig config = entity.world.spigotConfig; + if ( entity instanceof EntityPlayer ) + { + return config.playerTrackingRange; + } else if ( entity.activationType == 1 ) + { + return config.monsterTrackingRange; + } else if ( entity instanceof EntityGhast ) + { + if ( config.monsterTrackingRange > config.monsterActivationRange ) + { + return config.monsterTrackingRange; + } else + { + return config.monsterActivationRange; + } + } else if ( entity.activationType == 2 ) + { + return config.animalTrackingRange; + } else if ( entity instanceof EntityItemFrame || entity instanceof EntityPainting || entity instanceof EntityItem || entity instanceof EntityExperienceOrb ) + { + return config.miscTrackingRange; + } else + { + return config.otherTrackingRange; + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/ValidateUtils.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/ValidateUtils.java new file mode 100644 index 0000000..58a9534 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/ValidateUtils.java @@ -0,0 +1,14 @@ +package org.spigotmc; + +public class ValidateUtils +{ + + public static String limit(String str, int limit) + { + if ( str.length() > limit ) + { + return str.substring( 0, limit ); + } + return str; + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/WatchdogThread.java b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/WatchdogThread.java new file mode 100644 index 0000000..c8f619a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/java/org/spigotmc/WatchdogThread.java @@ -0,0 +1,124 @@ +package org.spigotmc; + +import java.lang.management.ManagementFactory; +import java.lang.management.MonitorInfo; +import java.lang.management.ThreadInfo; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.minecraft.server.MinecraftServer; +import org.bukkit.Bukkit; + +public class WatchdogThread extends Thread +{ + + private static WatchdogThread instance; + private final long timeoutTime; + private final boolean restart; + private volatile long lastTick; + private volatile boolean stopping; + + private WatchdogThread(long timeoutTime, boolean restart) + { + super( "PaperSpigot Watchdog Thread" ); + this.timeoutTime = timeoutTime; + this.restart = restart; + } + + public static void doStart(int timeoutTime, boolean restart) + { + if ( instance == null ) + { + instance = new WatchdogThread( timeoutTime * 1000L, restart ); + instance.start(); + } + } + + public static void tick() + { + instance.lastTick = System.currentTimeMillis(); + } + + public static void doStop() + { + if ( instance != null ) + { + instance.stopping = true; + } + } + + @Override + public void run() + { + while ( !stopping ) + { + // + if ( lastTick != 0 && System.currentTimeMillis() > lastTick + timeoutTime ) + { + Logger log = Bukkit.getServer().getLogger(); + log.log( Level.SEVERE, "The server has stopped responding!" ); + log.log( Level.SEVERE, "Please report this to PaperSpigot directly!" ); + log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" ); + log.log( Level.SEVERE, "PaperSpigot version: " + Bukkit.getServer().getVersion() ); + // + if(net.minecraft.server.World.haveWeSilencedAPhysicsCrash) + { + log.log( Level.SEVERE, "------------------------------" ); + log.log( Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed" ); + log.log( Level.SEVERE, "near " + net.minecraft.server.World.blockLocation); + } + // + log.log( Level.SEVERE, "------------------------------" ); + log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to PaperSpigot!):" ); + dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().primaryThread.getId(), Integer.MAX_VALUE ), log ); + log.log( Level.SEVERE, "------------------------------" ); + // + log.log( Level.SEVERE, "Entire Thread Dump:" ); + ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true ); + for ( ThreadInfo thread : threads ) + { + dumpThread( thread, log ); + } + log.log( Level.SEVERE, "------------------------------" ); + + if ( restart ) + { + RestartCommand.restart(); + } + break; + } + + try + { + sleep( 10000 ); + } catch ( InterruptedException ex ) + { + interrupt(); + } + } + } + + private static void dumpThread(ThreadInfo thread, Logger log) + { + log.log( Level.SEVERE, "------------------------------" ); + // + log.log( Level.SEVERE, "Current Thread: " + thread.getThreadName() ); + log.log( Level.SEVERE, "\tPID: " + thread.getThreadId() + + " | Suspended: " + thread.isSuspended() + + " | Native: " + thread.isInNative() + + " | State: " + thread.getThreadState() ); + if ( thread.getLockedMonitors().length != 0 ) + { + log.log( Level.SEVERE, "\tThread is waiting on monitor(s):" ); + for ( MonitorInfo monitor : thread.getLockedMonitors() ) + { + log.log( Level.SEVERE, "\t\tLocked on:" + monitor.getLockedStackFrame() ); + } + } + log.log( Level.SEVERE, "\tStack:" ); + // + for ( StackTraceElement stack : thread.getStackTrace() ) + { + log.log( Level.SEVERE, "\t\t" + stack ); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/bukkit.yml b/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/bukkit.yml new file mode 100644 index 0000000..8bbb835 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/bukkit.yml @@ -0,0 +1,43 @@ +# This is the main configuration file for Bukkit. +# As you can see, there's actually not that much to configure without any plugins. +# For a reference for any variable inside this file, check out the Bukkit Wiki at +# http://wiki.bukkit.org/Bukkit.yml +# +# If you need help on this file, feel free to join us on irc or leave a message +# on the forums asking for advice. +# +# IRC: #spigot @ irc.spi.gt +# (If this means nothing to you, just go to http://www.spigotmc.org/pages/irc/ ) +# Forums: http://www.spigotmc.org/ +# Bug tracker: http://www.spigotmc.org/go/bugs + + +settings: + allow-end: true + warn-on-overload: true + permissions-file: permissions.yml + update-folder: update + plugin-profiling: false + connection-throttle: 4000 + query-plugins: true + deprecated-verbose: default + shutdown-message: Server closed +spawn-limits: + monsters: 70 + animals: 15 + water-animals: 5 + ambient: 15 +chunk-gc: + period-in-ticks: 600 + load-threshold: 0 +ticks-per: + animal-spawns: 400 + monster-spawns: 1 + autosave: 6000 +aliases: now-in-commands.yml +database: + username: bukkit + isolation: SERIALIZABLE + driver: org.sqlite.JDBC + password: walrus + url: jdbc:sqlite:{DIR}{NAME}.db diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/commands.yml b/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/commands.yml new file mode 100644 index 0000000..733307c --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/commands.yml @@ -0,0 +1,16 @@ +# This is the commands configuration file for Bukkit. +# For documentation on how to make use of this file, check out the Bukkit Wiki at +# http://wiki.bukkit.org/Commands.yml +# +# If you need help on this file, feel free to join us on irc or leave a message +# on the forums asking for advice. +# +# IRC: #spigot @ irc.spi.gt +# (If this means nothing to you, just go to http://www.spigotmc.org/pages/irc/ ) +# Forums: http://www.spigotmc.org/ +# Bug tracker: http://www.spigotmc.org/go/bugs + +command-block-overrides: [] +aliases: + icanhasbukkit: + - "version $1-" diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/help.yml b/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/help.yml new file mode 100644 index 0000000..15c3d07 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/resources/configurations/help.yml @@ -0,0 +1,55 @@ +# This is the help configuration file for Bukkit. +# +# By default you do not need to modify this file. Help topics for all plugin commands are automatically provided by +# or extracted from your installed plugins. You only need to modify this file if you wish to add new help pages to +# your server or override the help pages of existing plugin commands. +# +# This file is divided up into the following parts: +# -- general-topics: lists admin defined help topics +# -- index-topics: lists admin defined index topics +# -- amend-topics: lists topic amendments to apply to existing help topics +# -- ignore-plugins: lists any plugins that should be excluded from help +# +# Examples are given below. When amending command topic, the string will be replaced with the existing value +# in the help topic. Color codes can be used in topic text. The color code character is & followed by 0-F. +# ================================================================ +# +# Set this to true to list the individual command help topics in the master help. +# command-topics-in-master-index: true +# +# Each general topic will show up as a separate topic in the help index along with all the plugin command topics. +# general-topics: +# Rules: +# shortText: Rules of the server +# fullText: | +# &61. Be kind to your fellow players. +# &B2. No griefing. +# &D3. No swearing. +# permission: topics.rules +# +# Each index topic will show up as a separate sub-index in the help index along with all the plugin command topics. +# To override the default help index (displayed when the user executes /help), name the index topic "Default". +# index-topics: +# Ban Commands: +# shortText: Player banning commands +# preamble: Moderator - do not abuse these commands +# permission: op +# commands: +# - /ban +# - /ban-ip +# - /banlist +# +# Topic amendments are used to change the content of automatically generated plugin command topics. +# amended-topics: +# /stop: +# shortText: Stops the server cold....in its tracks! +# fullText: - This kills the server. +# permission: you.dont.have +# +# Any plugin in the ignored plugins list will be excluded from help. The name must match the name displayed by +# the /plugins command. Ignore "Bukkit" to remove the standard bukkit commands from the index. Ignore "All" +# to completely disable automatic help topic generation. +# ignore-plugins: +# - PluginNameOne +# - PluginNameTwo +# - PluginNameThree diff --git a/MythicSpigot-master/TacoSpigot-Server/src/main/resources/log4j2.xml b/MythicSpigot-master/TacoSpigot-Server/src/main/resources/log4j2.xml new file mode 100644 index 0000000..f37d1c2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/main/resources/log4j2.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/ArtTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/ArtTest.java new file mode 100644 index 0000000..7f40288 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/ArtTest.java @@ -0,0 +1,65 @@ +package org.bukkit; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +import net.minecraft.server.EntityPainting.EnumArt; + +import org.bukkit.craftbukkit.CraftArt; +import org.junit.Test; + +import com.google.common.collect.Lists; + +public class ArtTest { + private static final int UNIT_MULTIPLIER = 16; + + @Test + public void verifyMapping() { + List arts = Lists.newArrayList(Art.values()); + + for (EnumArt enumArt : EnumArt.values()) { + int id = enumArt.ordinal(); + String name = enumArt.B; + int width = enumArt.C / UNIT_MULTIPLIER; + int height = enumArt.D / UNIT_MULTIPLIER; + + Art subject = Art.getById(id); + + String message = String.format("org.bukkit.Art is missing id: %d named: '%s'", id, name); + assertNotNull(message, subject); + + assertThat(Art.getByName(name), is(subject)); + assertThat("Art." + subject + "'s width", subject.getBlockWidth(), is(width)); + assertThat("Art." + subject + "'s height", subject.getBlockHeight(), is(height)); + + arts.remove(subject); + } + + assertThat("org.bukkit.Art has too many arts", arts, is(Collections.EMPTY_LIST)); + } + + @Test + public void testCraftArtToNotch() { + Map cache = new EnumMap(EnumArt.class); + for (Art art : Art.values()) { + EnumArt enumArt = CraftArt.BukkitToNotch(art); + assertNotNull(art.name(), enumArt); + assertThat(art.name(), cache.put(enumArt, art), is(nullValue())); + } + } + + @Test + public void testCraftArtToBukkit() { + Map cache = new EnumMap(Art.class); + for (EnumArt enumArt : EnumArt.values()) { + Art art = CraftArt.NotchToBukkit(enumArt); + assertNotNull(enumArt.name(), art); + assertThat(enumArt.name(), cache.put(art, enumArt), is(nullValue())); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/DyeColorsTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/DyeColorsTest.java new file mode 100644 index 0000000..f0b889b --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/DyeColorsTest.java @@ -0,0 +1,48 @@ +package org.bukkit; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.server.EntitySheep; +import net.minecraft.server.EnumColor; +import net.minecraft.server.ItemDye; + +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class DyeColorsTest extends AbstractTestingBase { + + @Parameters(name= "{index}: {0}") + public static List data() { + List list = new ArrayList(); + for (DyeColor dye : DyeColor.values()) { + list.add(new Object[] {dye}); + } + return list; + } + + @Parameter public DyeColor dye; + + @Test + public void checkColor() { + Color color = dye.getColor(); + float[] nmsColorArray = EntitySheep.a(EnumColor.fromColorIndex(dye.getWoolData())); + Color nmsColor = Color.fromRGB((int) (nmsColorArray[0] * 255), (int) (nmsColorArray[1] * 255), (int) (nmsColorArray[2] * 255)); + assertThat(color, is(nmsColor)); + } + + @Test + public void checkFireworkColor() { + Color color = dye.getFireworkColor(); + int nmsColor = ItemDye.a[dye.getDyeData()]; + assertThat(color, is(Color.fromRGB(nmsColor))); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/MaterialTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/MaterialTest.java new file mode 100644 index 0000000..a63c0f4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/MaterialTest.java @@ -0,0 +1,48 @@ +package org.bukkit; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.Collections; +import java.util.Map; + +import net.minecraft.server.Item; + +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; + +import com.google.common.collect.Maps; +import java.util.Iterator; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; + +public class MaterialTest extends AbstractTestingBase { + + @Test + public void verifyMapping() { + Map materials = Maps.newHashMap(); + for (Material material : Material.values()) { + if (INVALIDATED_MATERIALS.contains(material)) { + continue; + } + + materials.put(material.getId(), material); + } + materials.remove(0); // Purge air. + + Iterator items = Item.REGISTRY.iterator(); + + while (items.hasNext()) { + Item item = items.next(); + if (item == null) continue; + + int id = CraftMagicNumbers.getId(item); + String name = item.getName(); + + Material material = materials.remove(id); + + assertThat("Missing " + name + "(" + id + ")", material, is(not(nullValue()))); + } + + assertThat(materials, is(Collections.EMPTY_MAP)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/PerMaterialTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/PerMaterialTest.java new file mode 100644 index 0000000..2cbf4ec --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/PerMaterialTest.java @@ -0,0 +1,149 @@ +package org.bukkit; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.List; + +import net.minecraft.server.BlockFalling; +import net.minecraft.server.BlockFire; +import net.minecraft.server.Item; +import net.minecraft.server.ItemFood; +import net.minecraft.server.ItemRecord; + +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; +import org.bukkit.support.AbstractTestingBase; +import org.bukkit.support.Util; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.collect.Lists; +import java.util.Map; +import net.minecraft.server.Block; +import net.minecraft.server.Blocks; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; + +@RunWith(Parameterized.class) +public class PerMaterialTest extends AbstractTestingBase { + private static Map fireValues; + + @BeforeClass + public static void getFireValues() { + fireValues = Util.getInternalState(BlockFire.class, Blocks.FIRE, "flameChances"); + } + + @Parameters(name= "{index}: {0}") + public static List data() { + List list = Lists.newArrayList(); + for (Material material : Material.values()) { + list.add(new Object[] {material}); + } + return list; + } + + @Parameter public Material material; + + @Test + public void isSolid() { + if (material == Material.AIR) { + assertFalse(material.isSolid()); + } else if (material.isBlock()) { + assertThat(material.isSolid(), is(CraftMagicNumbers.getBlock(material).getMaterial().isSolid())); + } else { + assertFalse(material.isSolid()); + } + } + + @Test + public void isEdible() { + assertThat(material.isEdible(), is(CraftMagicNumbers.getItem(material) instanceof ItemFood)); + } + + @Test + public void isRecord() { + assertThat(material.isRecord(), is(CraftMagicNumbers.getItem(material) instanceof ItemRecord)); + } + + @Test + public void maxDurability() { + if (INVALIDATED_MATERIALS.contains(material)) return; + + if (material == Material.AIR) { + assertThat((int) material.getMaxDurability(), is(0)); + } else if (material.isBlock()){ + Item item = CraftMagicNumbers.getItem(material); + assertThat((int) material.getMaxDurability(), is(item.getMaxDurability())); + } + } + + @Test + public void maxStackSize() { + if (INVALIDATED_MATERIALS.contains(material)) return; + + final ItemStack bukkit = new ItemStack(material); + final CraftItemStack craft = CraftItemStack.asCraftCopy(bukkit); + if (material == Material.AIR) { + final int MAX_AIR_STACK = 0 /* Why can't I hold all of these AIR? */; + assertThat(material.getMaxStackSize(), is(MAX_AIR_STACK)); + assertThat(bukkit.getMaxStackSize(), is(MAX_AIR_STACK)); + assertThat(craft.getMaxStackSize(), is(MAX_AIR_STACK)); + } else { + assertThat(material.getMaxStackSize(), is(CraftMagicNumbers.getItem(material).getMaxStackSize())); + assertThat(bukkit.getMaxStackSize(), is(material.getMaxStackSize())); + assertThat(craft.getMaxStackSize(), is(material.getMaxStackSize())); + } + } + + @Test + public void isTransparent() { + if (material == Material.AIR) { + assertTrue(material.isTransparent()); + } else if (material.isBlock()) { + assertThat(material.isTransparent(), is(not(CraftMagicNumbers.getBlock(material).getMaterial().blocksLight()))); + } else { + assertFalse(material.isTransparent()); + } + } + + @Test + public void isFlammable() { + if (material != Material.AIR && material.isBlock()) { + assertThat(material.isFlammable(), is(CraftMagicNumbers.getBlock(material).getMaterial().isBurnable())); + } else { + assertFalse(material.isFlammable()); + } + } + + @Test + public void isBurnable() { + if (material.isBlock()) { + Block block = CraftMagicNumbers.getBlock(material); + assertThat(material.isBurnable(), is(fireValues.containsKey(block) && fireValues.get(block) > 0)); + } else { + assertFalse(material.isBurnable()); + } + } + + @Test + public void isOccluding() { + if (material.isBlock()) { + assertThat(material.isOccluding(), is(CraftMagicNumbers.getBlock(material).isOccluding())); + } else { + assertFalse(material.isOccluding()); + } + } + + @Test + public void hasGravity() { + if (material.isBlock()) { + assertThat(material.hasGravity(), is(CraftMagicNumbers.getBlock(material) instanceof BlockFalling)); + } else { + assertFalse(material.hasGravity()); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/SoundTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/SoundTest.java new file mode 100644 index 0000000..c9865fa --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/SoundTest.java @@ -0,0 +1,18 @@ +package org.bukkit; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import org.bukkit.craftbukkit.CraftSound; +import org.junit.Test; + + +public class SoundTest { + + @Test + public void testGetSound() { + for (Sound sound : Sound.values()) { + assertThat(sound.name(), CraftSound.getSound(sound), is(not(nullValue()))); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/StatisticsAndAchievementsTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/StatisticsAndAchievementsTest.java new file mode 100644 index 0000000..0a6c277 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/StatisticsAndAchievementsTest.java @@ -0,0 +1,61 @@ +package org.bukkit; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.Collections; +import java.util.List; + +import net.minecraft.server.AchievementList; +import net.minecraft.server.StatisticList; + +import org.bukkit.craftbukkit.CraftStatistic; +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; + +import com.google.common.collect.HashMultiset; +import com.google.common.collect.Lists; + +public class StatisticsAndAchievementsTest extends AbstractTestingBase { + @Test + @SuppressWarnings("unchecked") + public void verifyAchievementMapping() throws Throwable { + List achievements = Lists.newArrayList(Achievement.values()); + for (net.minecraft.server.Achievement achievement : (List) AchievementList.e) { + String name = achievement.name; + + String message = String.format("org.bukkit.Achievement is missing: '%s'", name); + + Achievement subject = CraftStatistic.getBukkitAchievement(achievement); + assertThat(message, subject, is(not(nullValue()))); + + assertThat(name, achievements.remove(subject), is(true)); + } + + assertThat("org.bukkit.Achievement has too many achievements", achievements, is(empty())); + } + + @Test + @SuppressWarnings("unchecked") + public void verifyStatisticMapping() throws Throwable { + HashMultiset statistics = HashMultiset.create(); + for (net.minecraft.server.Statistic statistic : (List) StatisticList.stats) { + if (statistic instanceof net.minecraft.server.Achievement) { + continue; + } + String name = statistic.name; + + String message = String.format("org.bukkit.Statistic is missing: '%s'", name); + + Statistic subject = CraftStatistic.getBukkitStatistic(statistic); + assertThat(message, subject, is(not(nullValue()))); + + statistics.add(subject); + } + + for (Statistic statistic : Statistic.values()) { + String message = String.format("org.bukkit.Statistic.%s does not have a corresponding minecraft statistic", statistic.name()); + assertThat(message, statistics.remove(statistic, statistics.count(statistic)), is(greaterThan(0))); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/WorldTypeTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/WorldTypeTest.java new file mode 100644 index 0000000..4d35a10 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/WorldTypeTest.java @@ -0,0 +1,19 @@ +package org.bukkit; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import net.minecraft.server.WorldType; +import org.junit.Test; + +public class WorldTypeTest { + @Test + public void testTypes() { + for (WorldType type : WorldType.types) { + if (type == null) continue; + if (type == WorldType.DEBUG_ALL_BLOCK_STATES) continue; // Doesn't work anyway + + assertThat(type.name() + " has no Bukkit world", org.bukkit.WorldType.getByName(type.name()), is(not(nullValue()))); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/CompositeSerialization.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/CompositeSerialization.java new file mode 100644 index 0000000..1349a7f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/CompositeSerialization.java @@ -0,0 +1,61 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; + + +public class CompositeSerialization extends AbstractTestingBase { + + public YamlConfiguration getConfig() { + return new YamlConfiguration(); + } + + @Test + public void testSaveRestoreCompositeList() throws InvalidConfigurationException { + YamlConfiguration out = getConfig(); + + List stacks = new ArrayList(); + stacks.add(new ItemStack(1)); + stacks.add(new ItemStack(2)); + stacks.add(new ItemStack(3)); + stacks.add(new ItemStack(4, 17)); + stacks.add(new ItemStack(5, 63)); + stacks.add(new ItemStack(6, 1, (short) 1)); + stacks.add(new ItemStack(18, 32, (short) 2)); + + ItemStack item7 = new ItemStack(256); + item7.addUnsafeEnchantment(Enchantment.getById(1), 1); + stacks.add(item7); + + ItemStack item8 = new ItemStack(257); + item8.addUnsafeEnchantment(Enchantment.getById(2), 2); + item8.addUnsafeEnchantment(Enchantment.getById(3), 1); + item8.addUnsafeEnchantment(Enchantment.getById(4), 5); + item8.addUnsafeEnchantment(Enchantment.getById(5), 4); + stacks.add(item8); + + out.set("composite-list.abc.def", stacks); + String yaml = out.saveToString(); + + YamlConfiguration in = new YamlConfiguration(); + in.loadFromString(yaml); + List raw = in.getList("composite-list.abc.def"); + + assertThat(stacks, hasSize(raw.size())); + + for (int i = 0; i < 9; i++) { + assertThat(String.valueOf(i), (Object) stacks.get(i), is((Object) raw.get(i))); + } + } +} + diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/FactoryItemMaterialTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/FactoryItemMaterialTest.java new file mode 100644 index 0000000..1e5c3ef --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/FactoryItemMaterialTest.java @@ -0,0 +1,156 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang.ArrayUtils; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class FactoryItemMaterialTest extends AbstractTestingBase { + static final ItemFactory factory = CraftItemFactory.instance(); + static final StringBuilder buffer = new StringBuilder(); + static final Material[] materials; + + static { + Material[] local_materials = Material.values(); + List list = new ArrayList(local_materials.length); + for (Material material : local_materials) { + if (INVALIDATED_MATERIALS.contains(material)) { + continue; + } + + list.add(material); + } + materials = list.toArray(new Material[list.size()]); + } + + static String name(Enum from, Enum to) { + if (from.getClass() == to.getClass()) { + return buffer.delete(0, Integer.MAX_VALUE).append(from.getClass().getName()).append(' ').append(from.name()).append(" to ").append(to.name()).toString(); + } + return buffer.delete(0, Integer.MAX_VALUE).append(from.getClass().getName()).append('(').append(from.name()).append(") to ").append(to.getClass().getName()).append('(').append(to.name()).append(')').toString(); + } + + @Parameters(name="Material[{index}]:{0}") + public static List data() { + List list = new ArrayList(); + for (Material material : materials) { + list.add(new Object[] {material}); + } + return list; + } + + @Parameter(0) public Material material; + + @Test + public void itemStack() { + ItemStack bukkitStack = new ItemStack(material); + CraftItemStack craftStack = CraftItemStack.asCraftCopy(bukkitStack); + ItemMeta meta = factory.getItemMeta(material); + if (meta == null) { + assertThat(material, is(Material.AIR)); + } else { + assertTrue(factory.isApplicable(meta, bukkitStack)); + assertTrue(factory.isApplicable(meta, craftStack)); + } + } + + @Test + public void generalCase() { + CraftMetaItem meta = (CraftMetaItem) factory.getItemMeta(material); + if (meta == null) { + assertThat(material, is(Material.AIR)); + } else { + assertTrue(factory.isApplicable(meta, material)); + assertTrue(meta.applicableTo(material)); + + meta = meta.clone(); + assertTrue(factory.isApplicable(meta, material)); + assertTrue(meta.applicableTo(material)); + } + } + + @Test + public void asMetaFor() { + final CraftMetaItem baseMeta = (CraftMetaItem) factory.getItemMeta(material); + if (baseMeta == null) { + assertThat(material, is(Material.AIR)); + return; + } + + for (Material other : materials) { + final ItemStack bukkitStack = new ItemStack(other); + final CraftItemStack craftStack = CraftItemStack.asCraftCopy(bukkitStack); + final CraftMetaItem otherMeta = (CraftMetaItem) factory.asMetaFor(baseMeta, other); + + final String testName = name(material, other); + + if (otherMeta == null) { + assertThat(testName, other, is(Material.AIR)); + continue; + } + + assertTrue(testName, factory.isApplicable(otherMeta, craftStack)); + assertTrue(testName, factory.isApplicable(otherMeta, bukkitStack)); + assertTrue(testName, factory.isApplicable(otherMeta, other)); + assertTrue(testName, otherMeta.applicableTo(other)); + } + } + + @Test + public void blankEqualities() { + if (material == Material.AIR) { + return; + } + final CraftMetaItem baseMeta = (CraftMetaItem) factory.getItemMeta(material); + final CraftMetaItem baseMetaClone = baseMeta.clone(); + + final ItemStack baseMetaStack = new ItemStack(material); + baseMetaStack.setItemMeta(baseMeta); + + assertThat(baseMeta, is(not(sameInstance(baseMetaStack.getItemMeta())))); + + assertTrue(factory.equals(baseMeta, null)); + assertTrue(factory.equals(null, baseMeta)); + + assertTrue(factory.equals(baseMeta, baseMetaClone)); + assertTrue(factory.equals(baseMetaClone, baseMeta)); + + assertThat(baseMeta, is(not(sameInstance(baseMetaClone)))); + + assertThat(baseMeta, is(baseMetaClone)); + assertThat(baseMetaClone, is(baseMeta)); + + for (Material other : materials) { + final String testName = name(material, other); + + final CraftMetaItem otherMeta = (CraftMetaItem) factory.asMetaFor(baseMetaClone, other); + + if (otherMeta == null) { + assertThat(testName, other, is(Material.AIR)); + continue; + } + + assertTrue(testName, factory.equals(baseMeta, otherMeta)); + assertTrue(testName, factory.equals(otherMeta, baseMeta)); + + assertThat(testName, baseMeta, is(otherMeta)); + assertThat(testName, otherMeta, is(baseMeta)); + + assertThat(testName, baseMeta.hashCode(), is(otherMeta.hashCode())); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemFactoryTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemFactoryTest.java new file mode 100644 index 0000000..f5bcbdb --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemFactoryTest.java @@ -0,0 +1,47 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.HashSet; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import net.minecraft.server.CommandAbstract; +import net.minecraft.server.IAttribute; + +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; + +public class ItemFactoryTest extends AbstractTestingBase { + + @Test + public void testKnownAttributes() throws Throwable { + final ZipInputStream nmsZipStream = new ZipInputStream(CommandAbstract.class/* Magic class that isn't imported! */.getProtectionDomain().getCodeSource().getLocation().openStream()); + final Collection names = new HashSet(); + for (ZipEntry clazzEntry; (clazzEntry = nmsZipStream.getNextEntry()) != null; ) { + final String entryName = clazzEntry.getName(); + if (!(entryName.endsWith(".class") && entryName.startsWith("net/minecraft/server/"))) { + continue; + } + + final Class clazz = Class.forName(entryName.substring(0, entryName.length() - ".class".length()).replace('/', '.')); + assertThat(entryName, clazz, is(not(nullValue()))); + for (final Field field : clazz.getDeclaredFields()) { + if (IAttribute.class.isAssignableFrom(field.getType()) && Modifier.isStatic(field.getModifiers())) { + field.setAccessible(true); + final String attributeName = ((IAttribute) field.get(null)).getName(); + assertThat("Logical error: duplicate name `" + attributeName + "' in " + clazz.getName(), names.add(attributeName), is(true)); + assertThat(clazz.getName(), CraftItemFactory.KNOWN_NBT_ATTRIBUTE_NAMES, hasItem(attributeName)); + } + } + } + + nmsZipStream.close(); + + assertThat("Extra values detected", CraftItemFactory.KNOWN_NBT_ATTRIBUTE_NAMES, is(names)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaImplementationOverrideTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaImplementationOverrideTest.java new file mode 100644 index 0000000..f1b4ec0 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaImplementationOverrideTest.java @@ -0,0 +1,80 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; + +import org.bukkit.Material; +import org.bukkit.configuration.serialization.DelegateDeserialization; +import org.bukkit.craftbukkit.Overridden; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class ItemMetaImplementationOverrideTest { + static final Class parent = CraftMetaItem.class; + + @Parameters(name="[{index}]:{1}") + public static List data() { + final List testData = new ArrayList(); + List> classes = new ArrayList>(); + + for (Material material : ItemStackTest.COMPOUND_MATERIALS) { + Class clazz = CraftItemFactory.instance().getItemMeta(material).getClass().asSubclass(parent); + if (clazz != parent) { + classes.add(clazz); + } + } + + List list = new ArrayList(); + + for (Method method: parent.getDeclaredMethods()) { + if (method.isAnnotationPresent(Overridden.class)) { + list.add(method); + } + } + + for (final Class clazz : classes) { + for (final Method method : list) { + testData.add( + new Object[] { + new Callable() { + public Method call() throws Exception { + return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes()); + } + }, + clazz.getSimpleName() + " contains " + method.getName() + } + ); + } + + testData.add( + new Object[] { + new Callable() { + public DelegateDeserialization call() throws Exception { + return clazz.getAnnotation(DelegateDeserialization.class); + } + }, + clazz.getSimpleName() + " contains annotation " + DelegateDeserialization.class + } + ); + } + + return testData; + } + + @Parameter(0) public Callable test; + @Parameter(1) public String name; + + @Test + public void testClass() throws Throwable { + assertThat(name, test.call(), is(not(nullValue()))); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java new file mode 100644 index 0000000..71a3457 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java @@ -0,0 +1,250 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Color; +import org.bukkit.DyeColor; +import org.bukkit.FireworkEffect; +import org.bukkit.Material; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.block.banner.Pattern; +import org.bukkit.block.banner.PatternType; +import org.bukkit.craftbukkit.inventory.ItemStackTest.StackProvider; +import org.bukkit.craftbukkit.inventory.ItemStackTest.StackWrapper; +import org.bukkit.craftbukkit.inventory.ItemStackTest.BukkitWrapper; +import org.bukkit.craftbukkit.inventory.ItemStackTest.CraftWrapper; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BannerMeta; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.bukkit.inventory.meta.FireworkEffectMeta; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.inventory.meta.MapMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; + +public class ItemMetaTest extends AbstractTestingBase { + + static final int MAX_FIREWORK_POWER = 127; // Please update ItemStackFireworkTest if/when this gets changed. + + @Test(expected=IllegalArgumentException.class) + public void testPowerLimitExact() { + newFireworkMeta().setPower(MAX_FIREWORK_POWER + 1); + } + + @Test(expected=IllegalArgumentException.class) + public void testPowerLimitMax() { + newFireworkMeta().setPower(Integer.MAX_VALUE); + } + + @Test(expected=IllegalArgumentException.class) + public void testPowerLimitMin() { + newFireworkMeta().setPower(Integer.MIN_VALUE); + } + + @Test(expected=IllegalArgumentException.class) + public void testPowerLimitNegative() { + newFireworkMeta().setPower(-1); + } + + @Test + public void testPowers() { + for (int i = 0; i <= MAX_FIREWORK_POWER; i++) { + FireworkMeta firework = newFireworkMeta(); + firework.setPower(i); + assertThat(String.valueOf(i), firework.getPower(), is(i)); + } + } + + @Test + public void testConflictingEnchantment() { + ItemMeta itemMeta = Bukkit.getItemFactory().getItemMeta(Material.DIAMOND_PICKAXE); + assertThat(itemMeta.hasConflictingEnchant(Enchantment.DURABILITY), is(false)); + + itemMeta.addEnchant(Enchantment.SILK_TOUCH, 1, false); + assertThat(itemMeta.hasConflictingEnchant(Enchantment.DURABILITY), is(false)); + assertThat(itemMeta.hasConflictingEnchant(Enchantment.LOOT_BONUS_BLOCKS), is(true)); + assertThat(itemMeta.hasConflictingEnchant(null), is(false)); + } + + @Test + public void testConflictingStoredEnchantment() { + EnchantmentStorageMeta itemMeta = (EnchantmentStorageMeta) Bukkit.getItemFactory().getItemMeta(Material.ENCHANTED_BOOK); + assertThat(itemMeta.hasConflictingStoredEnchant(Enchantment.DURABILITY), is(false)); + + itemMeta.addStoredEnchant(Enchantment.SILK_TOUCH, 1, false); + assertThat(itemMeta.hasConflictingStoredEnchant(Enchantment.DURABILITY), is(false)); + assertThat(itemMeta.hasConflictingStoredEnchant(Enchantment.LOOT_BONUS_BLOCKS), is(true)); + assertThat(itemMeta.hasConflictingStoredEnchant(null), is(false)); + } + + @Test + public void testConflictingEnchantments() { + ItemMeta itemMeta = Bukkit.getItemFactory().getItemMeta(Material.DIAMOND_PICKAXE); + itemMeta.addEnchant(Enchantment.DURABILITY, 6, true); + itemMeta.addEnchant(Enchantment.DIG_SPEED, 6, true); + assertThat(itemMeta.hasConflictingEnchant(Enchantment.LOOT_BONUS_BLOCKS), is(false)); + + itemMeta.addEnchant(Enchantment.SILK_TOUCH, 1, false); + assertThat(itemMeta.hasConflictingEnchant(Enchantment.LOOT_BONUS_BLOCKS), is(true)); + assertThat(itemMeta.hasConflictingEnchant(null), is(false)); + } + + @Test + public void testConflictingStoredEnchantments() { + EnchantmentStorageMeta itemMeta = (EnchantmentStorageMeta) Bukkit.getItemFactory().getItemMeta(Material.ENCHANTED_BOOK); + itemMeta.addStoredEnchant(Enchantment.DURABILITY, 6, true); + itemMeta.addStoredEnchant(Enchantment.DIG_SPEED, 6, true); + assertThat(itemMeta.hasConflictingStoredEnchant(Enchantment.LOOT_BONUS_BLOCKS), is(false)); + + itemMeta.addStoredEnchant(Enchantment.SILK_TOUCH, 1, false); + assertThat(itemMeta.hasConflictingStoredEnchant(Enchantment.LOOT_BONUS_BLOCKS), is(true)); + assertThat(itemMeta.hasConflictingStoredEnchant(null), is(false)); + } + + private static FireworkMeta newFireworkMeta() { + return ((FireworkMeta) Bukkit.getItemFactory().getItemMeta(Material.FIREWORK)); + } + + @Test + public void testCrazyEquality() { + CraftItemStack craft = CraftItemStack.asCraftCopy(new ItemStack(1)); + craft.setItemMeta(craft.getItemMeta()); + ItemStack bukkit = new ItemStack(craft); + assertThat(craft, is(bukkit)); + assertThat(bukkit, is((ItemStack) craft)); + } + + @Test + public void testEachExtraData() { + final List providers = Arrays.asList( + new StackProvider(Material.BOOK_AND_QUILL) { + @Override ItemStack operate(final ItemStack cleanStack) { + final BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setAuthor("Some author"); + meta.setPages("Page 1", "Page 2"); + meta.setTitle("A title"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new StackProvider(Material.WRITTEN_BOOK) { + @Override ItemStack operate(final ItemStack cleanStack) { + final BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setAuthor("Some author"); + meta.setPages("Page 1", "Page 2"); + meta.setTitle("A title"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + /* Skulls rely on a running server instance + new StackProvider(Material.SKULL_ITEM) { + @Override ItemStack operate(final ItemStack cleanStack) { + final SkullMeta meta = (SkullMeta) cleanStack.getItemMeta(); + meta.setOwner("Notch"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + */ + new StackProvider(Material.MAP) { + @Override ItemStack operate(final ItemStack cleanStack) { + final MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + meta.setScaling(true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new StackProvider(Material.LEATHER_BOOTS) { + @Override ItemStack operate(final ItemStack cleanStack) { + final LeatherArmorMeta meta = (LeatherArmorMeta) cleanStack.getItemMeta(); + meta.setColor(Color.FUCHSIA); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new StackProvider(Material.POTION) { + @Override ItemStack operate(final ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.CONFUSION.createEffect(1, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new StackProvider(Material.FIREWORK) { + @Override ItemStack operate(final ItemStack cleanStack) { + final FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.GREEN).withFade(Color.OLIVE).with(Type.BALL_LARGE).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new StackProvider(Material.ENCHANTED_BOOK) { + @Override ItemStack operate(final ItemStack cleanStack) { + final EnchantmentStorageMeta meta = (EnchantmentStorageMeta) cleanStack.getItemMeta(); + meta.addStoredEnchant(Enchantment.ARROW_FIRE, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new StackProvider(Material.FIREWORK_CHARGE) { + @Override ItemStack operate(final ItemStack cleanStack) { + final FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.MAROON, Color.BLACK).with(Type.CREEPER).withFlicker().build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new StackProvider(Material.BANNER) { + @Override ItemStack operate(ItemStack cleanStack) { + final BannerMeta meta = (BannerMeta) cleanStack.getItemMeta(); + meta.setBaseColor(DyeColor.CYAN); + meta.addPattern(new Pattern(DyeColor.WHITE, PatternType.BRICKS)); + cleanStack.setItemMeta(meta); + return cleanStack; + } + } + ); + + assertThat("Forgotten test?", providers, hasSize(ItemStackTest.COMPOUND_MATERIALS.length - 3/* Normal item meta, skulls and tile entities */)); + + for (final StackProvider provider : providers) { + downCastTest(new BukkitWrapper(provider)); + downCastTest(new CraftWrapper(provider)); + } + } + + private void downCastTest(final StackWrapper provider) { + final String name = provider.toString(); + final ItemStack blank = new ItemStack(1); + final ItemStack craftBlank = CraftItemStack.asCraftCopy(blank); + + downCastTest(name, provider.stack(), blank); + blank.setItemMeta(blank.getItemMeta()); + downCastTest(name, provider.stack(), blank); + + downCastTest(name, provider.stack(), craftBlank); + craftBlank.setItemMeta(craftBlank.getItemMeta()); + downCastTest(name, provider.stack(), craftBlank); + } + + private void downCastTest(final String name, final ItemStack stack, final ItemStack blank) { + assertThat(name, stack, is(not(blank))); + assertThat(name, stack.getItemMeta(), is(not(blank.getItemMeta()))); + + stack.setTypeId(1); + + assertThat(name, stack, is(blank)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackBookTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackBookTest.java new file mode 100644 index 0000000..a7edc04 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackBookTest.java @@ -0,0 +1,213 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackBookTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, Material.WRITTEN_BOOK, Material.BOOK_AND_QUILL); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + Long.parseLong("1110", 2), + ItemStackLoreEnchantmentTest.operators(), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.addPage("Page 1", "Page 2"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Pages vs. Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.addPage("Page 1", "Page 2"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + cleanStack.setItemMeta(cleanStack.getItemMeta()); + return cleanStack; + } + }, + "Pages vs. blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.addPage("Page 1", "Page 2"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.addPage("Page 2", "Page 1"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Pages switched" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.addPage("Page 1", "Page 2"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.addPage("Page 1"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Pages short" + } + ), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setAuthor("AnAuthor"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Author vs. Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setAuthor("AnAuthor"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + cleanStack.setItemMeta(cleanStack.getItemMeta()); + return cleanStack; + } + }, + "Author vs. blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setAuthor("AnAuthor"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setAuthor("AnotherAuthor"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Authors" + } + ), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setTitle("Some title"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Title vs. Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setTitle("Some title"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + cleanStack.setItemMeta(cleanStack.getItemMeta()); + return cleanStack; + } + }, + "title vs. blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setTitle("Some title"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + BookMeta meta = (BookMeta) cleanStack.getItemMeta(); + meta.setTitle("Different title"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Titles" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackEnchantStorageTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackEnchantStorageTest.java new file mode 100644 index 0000000..a0499b8 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackEnchantStorageTest.java @@ -0,0 +1,108 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.EnchantmentStorageMeta; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackEnchantStorageTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, Material.ENCHANTED_BOOK); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + Long.parseLong("10", 2), + ItemStackLoreEnchantmentTest.operators(), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) cleanStack.getItemMeta(); + meta.addStoredEnchant(Enchantment.DURABILITY, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Enchantable vs Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) cleanStack.getItemMeta(); + meta.addStoredEnchant(Enchantment.KNOCKBACK, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Enchantable vs Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) cleanStack.getItemMeta(); + meta.addStoredEnchant(Enchantment.DAMAGE_UNDEAD, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) cleanStack.getItemMeta(); + meta.addStoredEnchant(Enchantment.DAMAGE_UNDEAD, 1, true); + meta.addStoredEnchant(Enchantment.FIRE_ASPECT, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Enchantable vs More" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) cleanStack.getItemMeta(); + meta.addStoredEnchant(Enchantment.PROTECTION_FIRE, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + EnchantmentStorageMeta meta = (EnchantmentStorageMeta) cleanStack.getItemMeta(); + meta.addEnchant(Enchantment.PROTECTION_FIRE, 2, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Enchantable vs Other" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackFireworkChargeTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackFireworkChargeTest.java new file mode 100644 index 0000000..cb38cd2 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackFireworkChargeTest.java @@ -0,0 +1,128 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkEffectMeta; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackFireworkChargeTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, Material.FIREWORK_CHARGE); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + Long.parseLong("10", 2), + ItemStackLoreEnchantmentTest.operators(), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.WHITE).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.BLACK).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Effect Color 1 vs. Effect Color 2" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.WHITE).with(Type.CREEPER).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.WHITE).with(Type.BURST).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Effect type 1 vs. Effect type 2" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.WHITE).withFade(Color.BLUE).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.WHITE).withFade(Color.RED).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Effect fade 1 vs. Effect fade 2" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.WHITE).withFlicker().build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Effect vs. Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkEffectMeta meta = (FireworkEffectMeta) cleanStack.getItemMeta(); + meta.setEffect(FireworkEffect.builder().withColor(Color.WHITE).withTrail().build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Effect vs. None" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackFireworkTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackFireworkTest.java new file mode 100644 index 0000000..40b1d19 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackFireworkTest.java @@ -0,0 +1,184 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.Material; +import org.bukkit.FireworkEffect.Type; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkMeta; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackFireworkTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, Material.FIREWORK); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + Long.parseLong("110", 2), + ItemStackLoreEnchantmentTest.operators(), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.WHITE).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.BLACK).build()); + meta.addEffect(FireworkEffect.builder().withColor(Color.GREEN).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Effect Color 1 vs. Effect Color 2" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.WHITE).with(Type.CREEPER).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.WHITE).with(Type.BURST).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Effect type 1 vs. Effect type 2" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.WHITE).withFade(Color.BLUE).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.WHITE).withFade(Color.RED).build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Effect fade 1 vs. Effect fade 2" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.WHITE).withFlicker().build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Effect vs. Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.addEffect(FireworkEffect.builder().withColor(Color.WHITE).withTrail().build()); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Effect vs. None" + } + ), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.setPower(127); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.setPower(100); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Height vs. Other" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.setPower(42); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Height vs. Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + FireworkMeta meta = (FireworkMeta) cleanStack.getItemMeta(); + meta.setPower(10); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Height vs. None" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackLeatherTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackLeatherTest.java new file mode 100644 index 0000000..6d68e1f --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackLeatherTest.java @@ -0,0 +1,89 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Color; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; + +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackLeatherTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, Material.LEATHER_BOOTS, Material.LEATHER_CHESTPLATE, Material.LEATHER_HELMET, Material.LEATHER_LEGGINGS); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + Long.parseLong("10", 2), + ItemStackLoreEnchantmentTest.operators(), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + LeatherArmorMeta meta = (LeatherArmorMeta) cleanStack.getItemMeta(); + meta.setColor(Color.FUCHSIA); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Color vs Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + LeatherArmorMeta meta = (LeatherArmorMeta) cleanStack.getItemMeta(); + meta.setColor(Color.GRAY); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + LeatherArmorMeta meta = (LeatherArmorMeta) cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Color vs Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + LeatherArmorMeta meta = (LeatherArmorMeta) cleanStack.getItemMeta(); + meta.setColor(Color.MAROON); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + LeatherArmorMeta meta = (LeatherArmorMeta) cleanStack.getItemMeta(); + meta.setColor(Color.ORANGE); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Color vs Other" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackLoreEnchantmentTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackLoreEnchantmentTest.java new file mode 100644 index 0000000..32a9184 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackLoreEnchantmentTest.java @@ -0,0 +1,297 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.Repairable; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackLoreEnchantmentTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, ItemStackTest.COMPOUND_MATERIALS); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + ~0l, + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.setLore(Arrays.asList("First Lore", "Second Lore")); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Lore vs Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.setLore(Arrays.asList("Some lore")); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Lore vs Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.setLore(Arrays.asList("Some more lore", "Another lore")); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.setLore(Arrays.asList("Some more lore")); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Lore vs Other" + } + ), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.setDisplayName("TestItemName"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Name vs Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.setDisplayName("AnotherItemName"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Name vs Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.setDisplayName("The original ItemName"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.setDisplayName("The other name"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Name vs Other" + } + ), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + cleanStack.addUnsafeEnchantment(Enchantment.DIG_SPEED, 2); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "EnchantStack vs Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + cleanStack.addUnsafeEnchantment(Enchantment.OXYGEN, 1); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "EnchantStack vs Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + cleanStack.addUnsafeEnchantment(Enchantment.ARROW_DAMAGE, 1); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + cleanStack.addUnsafeEnchantment(Enchantment.ARROW_FIRE, 1); + return cleanStack; + } + }, + "EnchantStack vs OtherEnchantStack" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.addEnchant(Enchantment.DURABILITY, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Enchant vs Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.addEnchant(Enchantment.KNOCKBACK, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Enchant vs Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.addEnchant(Enchantment.PROTECTION_FIRE, 1, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + meta.addEnchant(Enchantment.PROTECTION_FIRE, 2, true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Enchant vs Other" + } + ), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + ((Repairable) meta).setRepairCost(42); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Repair vs Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + ((Repairable) meta).setRepairCost(36); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Repair vs Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + ((Repairable) meta).setRepairCost(89); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + ItemMeta meta = cleanStack.getItemMeta(); + ((Repairable) meta).setRepairCost(88); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Repair vs Other" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackMapTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackMapTest.java new file mode 100644 index 0000000..9c49985 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackMapTest.java @@ -0,0 +1,121 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.MapMeta; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackMapTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, Material.MAP); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + Long.parseLong("10", 2), + ItemStackLoreEnchantmentTest.operators(), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + meta.setScaling(true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + meta.setScaling(false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Scale vs. Unscale" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + meta.setScaling(true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Scale vs. Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + meta.setScaling(false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Unscale vs. Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + meta.setScaling(true); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Scale vs. None" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + MapMeta meta = (MapMeta) cleanStack.getItemMeta(); + meta.setScaling(false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Unscale vs. None" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackPotionsTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackPotionsTest.java new file mode 100644 index 0000000..c1f9fb7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackPotionsTest.java @@ -0,0 +1,146 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffectType; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackPotionsTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, Material.POTION); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + Long.parseLong("10", 2), + ItemStackLoreEnchantmentTest.operators(), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.CONFUSION.createEffect(1, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Potion vs Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.HARM.createEffect(2, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Potion vs Blank" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.SLOW_DIGGING.createEffect(1, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.FAST_DIGGING.createEffect(1, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Potion vs Harder" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.JUMP.createEffect(1, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.JUMP.createEffect(1, 1), false); + meta.addCustomEffect(PotionEffectType.REGENERATION.createEffect(1, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Potion vs Better" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.SPEED.createEffect(10, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.SPEED.createEffect(5, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Potion vs Faster" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.INCREASE_DAMAGE.createEffect(1, 1), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + final PotionMeta meta = (PotionMeta) cleanStack.getItemMeta(); + meta.addCustomEffect(PotionEffectType.INCREASE_DAMAGE.createEffect(1, 2), false); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Potion vs Stronger" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackSkullTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackSkullTest.java new file mode 100644 index 0000000..a79d443 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackSkullTest.java @@ -0,0 +1,88 @@ +package org.bukkit.craftbukkit.inventory; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import com.google.common.base.Joiner; + +@RunWith(Parameterized.class) +public class ItemStackSkullTest extends ItemStackTest { + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return StackProvider.compound(operators(), "%s %s", NAME_PARAMETER, Material.SKULL_ITEM); + } + + @SuppressWarnings("unchecked") + static List operators() { + return CompoundOperator.compound( + Joiner.on('+'), + NAME_PARAMETER, + Long.parseLong("10", 2), + ItemStackLoreEnchantmentTest.operators(), + Arrays.asList( + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + SkullMeta meta = (SkullMeta) cleanStack.getItemMeta(); + meta.setOwner("Notch"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + SkullMeta meta = (SkullMeta) cleanStack.getItemMeta(); + meta.setOwner("Dinnerbone"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Name 1 vs. Name 2" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + SkullMeta meta = (SkullMeta) cleanStack.getItemMeta(); + meta.setOwner("Notch"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + SkullMeta meta = (SkullMeta) cleanStack.getItemMeta(); + meta.setOwner(null); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + "Name vs. Null" + }, + new Object[] { + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + SkullMeta meta = (SkullMeta) cleanStack.getItemMeta(); + meta.setOwner("Notch"); + cleanStack.setItemMeta(meta); + return cleanStack; + } + }, + new Operator() { + public ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + }, + "Name vs. None" + } + ) + ); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackTest.java new file mode 100644 index 0000000..6140ede --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/ItemStackTest.java @@ -0,0 +1,493 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.bukkit.support.Matchers.sameHash; +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemFactory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.support.AbstractTestingBase; +import org.bukkit.util.io.BukkitObjectInputStream; +import org.bukkit.util.io.BukkitObjectOutputStream; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; + +@RunWith(Parameterized.class) +public class ItemStackTest extends AbstractTestingBase { + static abstract class StackProvider { + final Material material; + + StackProvider(Material material) { + this.material = material; + } + + ItemStack bukkit() { + return operate(cleanStack(material, false)); + } + + ItemStack craft() { + return operate(cleanStack(material, true)); + } + + abstract ItemStack operate(ItemStack cleanStack); + + static ItemStack cleanStack(Material material, boolean craft) { + final ItemStack stack = new ItemStack(material); + return craft ? CraftItemStack.asCraftCopy(stack) : stack; + } + + @Override + public String toString() { + return material.toString(); + } + + /** + * For each item in parameterList, it will apply nameFormat at nameIndex. + * For each item in parameterList for each item in materials, it will create a stack provider at each array index that contains an Operator. + * + * @param parameterList + * @param nameFormat + * @param nameIndex + * @param materials + * @return + */ + static List compound(final List parameterList, final String nameFormat, final int nameIndex, final Material...materials) { + final List out = new ArrayList(); + for (Object[] params : parameterList) { + final int len = params.length; + for (final Material material : materials) { + final Object[] paramsOut = params.clone(); + for (int i = 0; i < len; i++) { + final Object param = paramsOut[i]; + if (param instanceof Operator) { + final Operator operator = (Operator) param; + paramsOut[i] = new StackProvider(material) { + @Override + ItemStack operate(ItemStack cleanStack) { + return operator.operate(cleanStack); + } + }; + } + } + paramsOut[nameIndex] = String.format(nameFormat, paramsOut[nameIndex], material); + out.add(paramsOut); + } + } + return out; + } + } + + interface Operator { + ItemStack operate(ItemStack cleanStack); + } + + static class CompoundOperator implements Operator { + static class RecursiveContainer { + final Joiner joiner; + final Object[] strings; + final int nameParameter; + final List stack; + final List out; + final List[] lists; + + RecursiveContainer(Joiner joiner, Object[] strings, int nameParameter, List stack, List out, List[] lists) { + this.joiner = joiner; + this.strings = strings; + this.nameParameter = nameParameter; + this.stack = stack; + this.out = out; + this.lists = lists; + } + } + final Operator[] operators; + + CompoundOperator(Operator...operators) { + this.operators = operators; + } + + public ItemStack operate(ItemStack cleanStack) { + for (Operator operator : operators) { + operator.operate(cleanStack); + } + return cleanStack; + } + + @Override + public String toString() { + return Arrays.toString(operators); + } + + + /** + * This combines different tests into one large collection, combining no two tests from the same list. + * @param joiner used to join names + * @param nameParameter index of the name parameter + * @param singletonBitmask a list of bits representing the 'singletons' located in your originalLists. Lowest order bits represent the first items in originalLists. + * Singletons are exponentially linked with each other, such that, + * the output will contain every unique subset of only items from the singletons, + * as well as every unique subset that contains at least one item from each non-singleton. + * @param originalLists + * @return + */ + static List compound(final Joiner joiner, final int nameParameter, final long singletonBitmask, final List...originalLists) { + + final List out = new ArrayList(); + final List> singletons = new ArrayList>(); + final List> notSingletons = new ArrayList>(); + + { // Separate and prime the 'singletons' + int i = 0; + for (List list : originalLists) { + (((singletonBitmask >>> i++) & 0x1) == 0x1 ? singletons : notSingletons).add(list); + } + } + + for (final List primarySingleton : singletons) { + // Iterate over our singletons, to multiply the 'out' each time + for (final Object[] entry : out.toArray(EMPTY_ARRAY)) { + // Iterate over a snapshot of 'out' to prevent CMEs / infinite iteration + final int len = entry.length; + for (final Object[] singleton : primarySingleton) { + // Iterate over each item in our singleton for the current 'out' entry + final Object[] toOut = entry.clone(); + for (int i = 0; i < len; i++) { + // Iterate over each parameter + if (i == nameParameter) { + toOut[i] = joiner.join(toOut[i], singleton[i]); + } else if (toOut[i] instanceof Operator) { + final Operator op1 = (Operator) toOut[i]; + final Operator op2 = (Operator) singleton[i]; + toOut[i] = new Operator() { + public ItemStack operate(final ItemStack cleanStack) { + return op2.operate(op1.operate(cleanStack)); + } + }; + } + } + out.add(toOut); + } + } + out.addAll(primarySingleton); + } + + @SuppressWarnings("unchecked") + final List[] lists = new List[notSingletons.size() + 1]; + notSingletons.toArray(lists); + lists[lists.length - 1] = out; + + final RecursiveContainer methodParams = new RecursiveContainer(joiner, new Object[lists.length], nameParameter, new ArrayList(lists.length), new ArrayList(), lists); + + recursivelyCompound(methodParams, 0); + methodParams.out.addAll(out); + + return methodParams.out; + } + + private static void recursivelyCompound(final RecursiveContainer methodParams, final int level) { + final List stack = methodParams.stack; + + if (level == methodParams.lists.length) { + final Object[] firstParams = stack.get(0); + final int len = firstParams.length; + final int stackSize = stack.size(); + final Object[] params = new Object[len]; + + for (int i = 0; i < len; i++) { + final Object firstParam = firstParams[i]; + + if (firstParam instanceof Operator) { + final Operator[] operators = new Operator[stackSize]; + for (int j = 0; j < stackSize; j++) { + operators[j] = (Operator) stack.get(j)[i]; + } + + params[i] = new CompoundOperator(operators); + } else if (i == methodParams.nameParameter) { + final Object[] strings = methodParams.strings; + for (int j = 0; j < stackSize; j++) { + strings[j] = stack.get(j)[i]; + } + + params[i] = methodParams.joiner.join(strings); + } else { + params[i] = firstParam; + } + } + + methodParams.out.add(params); + } else { + final int marker = stack.size(); + + for (final Object[] params : methodParams.lists[level]) { + stack.add(params); + recursivelyCompound(methodParams, level + 1); + stack.remove(marker); + } + } + } + } + + interface StackWrapper { + ItemStack stack(); + } + + static class CraftWrapper implements StackWrapper { + final StackProvider provider; + + CraftWrapper(StackProvider provider) { + this.provider = provider; + } + + public ItemStack stack() { + return provider.craft(); + } + + @Override + public String toString() { + return "Craft " + provider; + } + } + + static class BukkitWrapper implements StackWrapper { + final StackProvider provider; + + BukkitWrapper(StackProvider provider) { + this.provider = provider; + } + + public ItemStack stack() { + return provider.bukkit(); + } + + @Override + public String toString() { + return "Bukkit " + provider; + } + } + + static class NoOpProvider extends StackProvider { + + NoOpProvider(Material material) { + super(material); + } + + @Override + ItemStack operate(ItemStack cleanStack) { + return cleanStack; + } + + @Override + public String toString() { + return "NoOp " + super.toString(); + } + } + + @Parameters(name="[{index}]:{" + NAME_PARAMETER + "}") + public static List data() { + return ImmutableList.of(); // TODO, test basic durability issues + } + + static final Object[][] EMPTY_ARRAY = new Object[0][]; + /** + * Materials that generate unique item meta types. + */ + static final Material[] COMPOUND_MATERIALS; + static final int NAME_PARAMETER = 2; + static { + final ItemFactory factory = CraftItemFactory.instance(); + final Map, Material> possibleMaterials = new HashMap, Material>(); + ItemMeta meta; + for (final Material material : Material.values()) { + meta = factory.getItemMeta(material); + if (meta == null || possibleMaterials.containsKey(meta.getClass())) + continue; + possibleMaterials.put(meta.getClass(), material); + + } + COMPOUND_MATERIALS = possibleMaterials.values().toArray(new Material[possibleMaterials.size()]); + } + + @Parameter(0) public StackProvider provider; + @Parameter(1) public StackProvider unequalProvider; + @Parameter(NAME_PARAMETER) public String name; + + @Test + public void testBukkitInequality() { + final StackWrapper bukkitWrapper = new CraftWrapper(provider); + testInequality(bukkitWrapper, new BukkitWrapper(unequalProvider)); + testInequality(bukkitWrapper, new BukkitWrapper(new NoOpProvider(provider.material))); + } + + @Test + public void testCraftInequality() { + final StackWrapper craftWrapper = new CraftWrapper(provider); + testInequality(craftWrapper, new CraftWrapper(unequalProvider)); + testInequality(craftWrapper, new CraftWrapper(new NoOpProvider(provider.material))); + } + + @Test + public void testMixedInequality() { + final StackWrapper craftWrapper = new CraftWrapper(provider); + testInequality(craftWrapper, new BukkitWrapper(unequalProvider)); + testInequality(craftWrapper, new BukkitWrapper(new NoOpProvider(provider.material))); + + final StackWrapper bukkitWrapper = new CraftWrapper(provider); + testInequality(bukkitWrapper, new CraftWrapper(unequalProvider)); + testInequality(bukkitWrapper, new CraftWrapper(new NoOpProvider(provider.material))); + } + + static void testInequality(StackWrapper provider, StackWrapper unequalProvider) { + final ItemStack stack = provider.stack(); + final ItemStack stack2 = provider.stack(); + assertThat(stack, allOf(equalTo(stack), sameHash(stack))); + assertThat(stack, is(not(sameInstance(stack2)))); + assertThat(stack, allOf(equalTo(stack2), sameHash(stack2))); + + final ItemStack unequalStack = unequalProvider.stack(); + final ItemStack unequalStack2 = unequalProvider.stack(); + assertThat(unequalStack, allOf(equalTo(unequalStack), sameHash(unequalStack))); + assertThat(unequalStack, is(not(sameInstance(unequalStack2)))); + assertThat(unequalStack, allOf(equalTo(unequalStack2), sameHash(unequalStack2))); + + assertThat(stack, is(not(unequalStack))); + assertThat(unequalStack, is(not(stack))); + + final ItemStack newStack = new ItemStack(stack2); + assertThat(newStack, allOf(equalTo(stack), sameHash(stack))); + assertThat(newStack, is(not(unequalStack))); + assertThat(newStack.getItemMeta(), allOf(equalTo(stack.getItemMeta()), sameHash(stack.getItemMeta()))); + assertThat(newStack.getItemMeta(), is(not(unequalStack.getItemMeta()))); + + final ItemStack craftStack = CraftItemStack.asCraftCopy(stack2); + assertThat(craftStack, allOf(equalTo(stack), sameHash(stack))); + assertThat(craftStack, is(not(unequalStack))); + assertThat(craftStack.getItemMeta(), allOf(equalTo(stack.getItemMeta()), sameHash(stack.getItemMeta()))); + assertThat(craftStack.getItemMeta(), is(not(unequalStack.getItemMeta()))); + + final ItemStack newUnequalStack = new ItemStack(unequalStack2); + assertThat(newUnequalStack, allOf(equalTo(unequalStack), sameHash(unequalStack))); + assertThat(newUnequalStack, is(not(stack))); + assertThat(newUnequalStack.getItemMeta(), allOf(equalTo(unequalStack.getItemMeta()), sameHash(unequalStack.getItemMeta()))); + assertThat(newUnequalStack.getItemMeta(), is(not(stack.getItemMeta()))); + + final ItemStack newUnequalCraftStack = CraftItemStack.asCraftCopy(unequalStack2); + assertThat(newUnequalCraftStack, allOf(equalTo(unequalStack), sameHash(unequalStack))); + assertThat(newUnequalCraftStack, is(not(stack))); + assertThat(newUnequalCraftStack.getItemMeta(), allOf(equalTo(unequalStack.getItemMeta()), sameHash(unequalStack.getItemMeta()))); + assertThat(newUnequalCraftStack.getItemMeta(), is(not(stack.getItemMeta()))); + } + + @Test + public void testBukkitYamlDeserialize() throws Throwable { + testYamlDeserialize(new BukkitWrapper(provider), new BukkitWrapper(unequalProvider)); + } + + @Test + public void testCraftYamlDeserialize() throws Throwable { + testYamlDeserialize(new CraftWrapper(provider), new CraftWrapper(unequalProvider)); + } + + @Test + public void testBukkitStreamDeserialize() throws Throwable { + testStreamDeserialize(new BukkitWrapper(provider), new BukkitWrapper(unequalProvider)); + } + + @Test + public void testCraftStreamDeserialize() throws Throwable { + testStreamDeserialize(new CraftWrapper(provider), new CraftWrapper(unequalProvider)); + } + + static void testStreamDeserialize(StackWrapper provider, StackWrapper unequalProvider) throws Throwable { + final ItemStack stack = provider.stack(); + final ItemStack unequalStack = unequalProvider.stack(); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream oos = null; + try { + oos = new BukkitObjectOutputStream(out); + + oos.writeObject(stack); + oos.writeObject(unequalStack); + } finally { + if (oos != null) { + try { + oos.close(); + } catch (IOException ex) { + } + } + } + + final String data = new String(Base64Coder.encode(out.toByteArray())); + + ObjectInputStream ois = null; + + final ItemStack readFirst; + final ItemStack readSecond; + + try { + ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); + ois = new BukkitObjectInputStream(in); + + readFirst = (ItemStack) ois.readObject(); + readSecond = (ItemStack) ois.readObject(); + } finally { + if (ois != null) { + try { + ois.close(); + } catch (IOException ex) { + } + } + } + + testEqualities(data, readFirst, readSecond, stack, unequalStack); + } + + static void testYamlDeserialize(StackWrapper provider, StackWrapper unequalProvider) { + final ItemStack stack = provider.stack(); + final ItemStack unequalStack = unequalProvider.stack(); + final YamlConfiguration configOut = new YamlConfiguration(); + + configOut.set("provider", stack); + configOut.set("unequal", unequalStack); + + final String out = '\n' + configOut.saveToString(); + final YamlConfiguration configIn = new YamlConfiguration(); + + try { + configIn.loadFromString(out); + } catch (InvalidConfigurationException ex) { + throw new RuntimeException(out, ex); + } + + testEqualities(out, configIn.getItemStack("provider"), configIn.getItemStack("unequal"), stack, unequalStack); + } + + static void testEqualities(String information, ItemStack primaryRead, ItemStack unequalRead, ItemStack primaryOriginal, ItemStack unequalOriginal) { + assertThat(information, primaryRead, allOf(equalTo(primaryOriginal), sameHash(primaryOriginal))); + assertThat(information, unequalRead, allOf(equalTo(unequalOriginal), sameHash(unequalOriginal))); + assertThat(information, primaryRead, is(not(unequalOriginal))); + assertThat(information, primaryRead, is(not(unequalRead))); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/NMSCraftItemStackTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/NMSCraftItemStackTest.java new file mode 100644 index 0000000..a183843 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/craftbukkit/inventory/NMSCraftItemStackTest.java @@ -0,0 +1,36 @@ +package org.bukkit.craftbukkit.inventory; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import net.minecraft.server.Enchantment; + +import org.bukkit.inventory.ItemStack; +import org.bukkit.support.AbstractTestingBase; +import org.junit.Test; + +public class NMSCraftItemStackTest extends AbstractTestingBase { + + @Test + public void testCloneEnchantedItem() throws Exception { + net.minecraft.server.ItemStack nmsItemStack = new net.minecraft.server.ItemStack(net.minecraft.server.Items.POTION); + nmsItemStack.addEnchantment(Enchantment.DAMAGE_ALL, 1); + ItemStack itemStack = CraftItemStack.asCraftMirror(nmsItemStack); + ItemStack clone = itemStack.clone(); + assertThat(clone.getType(), is(itemStack.getType())); + assertThat(clone.getAmount(), is(itemStack.getAmount())); + assertThat(clone.getDurability(), is(itemStack.getDurability())); + assertThat(clone.getEnchantments(), is(itemStack.getEnchantments())); + assertThat(clone.getTypeId(), is(itemStack.getTypeId())); + assertThat(clone.getData(), is(itemStack.getData())); + assertThat(clone, is(itemStack)); + } + + @Test + public void testCloneNullItem() throws Exception { + net.minecraft.server.ItemStack nmsItemStack = null; + ItemStack itemStack = CraftItemStack.asCraftMirror(nmsItemStack); + ItemStack clone = itemStack.clone(); + assertThat(clone, is(itemStack)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/map/MapTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/map/MapTest.java new file mode 100644 index 0000000..4cb2cf9 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/map/MapTest.java @@ -0,0 +1,62 @@ + +package org.bukkit.map; + +import java.awt.Color; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.minecraft.server.MaterialMapColor; +import org.junit.Assert; +import org.junit.Test; + +public class MapTest { + + private static final Logger logger = Logger.getLogger("MapTest"); + + private static final int[] modifiers = {180, 220, 255, 135}; + + @Test + public void testColors() { + MaterialMapColor[] nmsColors = MaterialMapColor.a; + Color[] bukkitColors = MapPalette.colors; + + boolean fail = false; + for (int i = 0; i < nmsColors.length; i++) { + if (nmsColors[i] == null) { + break; + } + int rgb = nmsColors[i].L; + + int r = (rgb >> 16) & 0xFF; + int g = (rgb >> 8) & 0xFF; + int b = rgb & 0xFF; + + if (i > bukkitColors.length/4) { + for (int modi : modifiers) { + int mr = (r * modi) / 255; + int mg = (g * modi) / 255; + int mb = (b * modi) / 255; + logger.log(Level.WARNING, "Missing color: c({0}, {1}, {2})", new Object[]{mr, mg, mb}); + } + fail = true; + } else { + for (int j = 0; j < modifiers.length; j++) { + int modi = modifiers[j]; + Color bukkit = bukkitColors[i * 4 + j]; + int mr = (r * modi) / 255; + int mg = (g * modi) / 255; + int mb = (b * modi) / 255; + + if (bukkit.getRed() != mr || bukkit.getGreen() != mg || bukkit.getBlue() != mb) { + logger.log(Level.WARNING, "Incorrect color: {6} {7} c({0}, {1}, {2}) != c({3}, {4}, {5})", new Object[]{ + bukkit.getRed(), bukkit.getGreen(), bukkit.getBlue(), + mr, mg, mb, + i, j + }); + fail = true; + } + } + } + } + Assert.assertFalse(fail); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/potion/PotionTest.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/potion/PotionTest.java new file mode 100644 index 0000000..a9df7d1 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/potion/PotionTest.java @@ -0,0 +1,45 @@ +package org.bukkit.potion; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; + +import java.util.EnumMap; +import java.util.Map; + +import org.bukkit.support.AbstractTestingBase; +import org.bukkit.support.Util; +import org.junit.Test; + +public class PotionTest extends AbstractTestingBase { + + @Test + public void getEffects() { + for (PotionType type : PotionType.values()) { + for (PotionEffect effect : new Potion(type).getEffects()) { + PotionEffectType potionType = effect.getType(); + assertThat(effect.getType(), is(sameInstance(PotionEffectType.getById(potionType.getId())))); + + assertNotNull(potionType.getName(), PotionType.getByEffect(potionType)); + } + } + } + + @Test + public void testEffectCompleteness() throws Throwable { + Map effectDurations = Util.getInternalState(net.minecraft.server.PotionBrewer.class, null, "effectDurations"); + + Map effects = new EnumMap(PotionType.class); + for (int id : effectDurations.keySet()) { + PotionEffectType type = PotionEffectType.getById(id); + assertNotNull(String.valueOf(id), PotionEffectType.getById(id)); + + PotionType enumType = PotionType.getByEffect(type); + assertNotNull(type.getName(), enumType); + + assertThat(enumType.name(), effects.put(enumType, enumType.name()), is(nullValue())); + } + + assertThat(effects.entrySet(), hasSize(effectDurations.size())); + assertThat(effectDurations.entrySet(), hasSize(PotionType.values().length - /* WATER */ 1)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/AbstractTestingBase.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/AbstractTestingBase.java new file mode 100644 index 0000000..3a362b7 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/AbstractTestingBase.java @@ -0,0 +1,77 @@ +package org.bukkit.support; + +import com.google.common.collect.ImmutableList; +import java.util.List; +import net.minecraft.server.DispenserRegistry; +import org.bukkit.Material; +import org.junit.BeforeClass; + +/** + * If you are getting: java.lang.ExceptionInInitializerError + * at net.minecraft.server.StatisticList.(SourceFile:58) + * at net.minecraft.server.Item.(SourceFile:252) + * at net.minecraft.server.Block.(Block.java:577) + * + * extend this class to solve it. + */ +public abstract class AbstractTestingBase { + public static final List INVALIDATED_MATERIALS = ImmutableList.builder() + .add( + Material.BREWING_STAND, + Material.BED_BLOCK, + Material.NETHER_WARTS, + Material.CAULDRON, + Material.FLOWER_POT, + Material.CROPS, + Material.SUGAR_CANE_BLOCK, + Material.CAKE_BLOCK, + Material.SKULL, + Material.PISTON_EXTENSION, + Material.PISTON_MOVING_PIECE, + Material.GLOWING_REDSTONE_ORE, + Material.DIODE_BLOCK_ON, + Material.PUMPKIN_STEM, + Material.SIGN_POST, + Material.REDSTONE_COMPARATOR_ON, + Material.TRIPWIRE, + Material.REDSTONE_LAMP_ON, + Material.MELON_STEM, + Material.REDSTONE_TORCH_OFF, + Material.REDSTONE_COMPARATOR_OFF, + Material.REDSTONE_WIRE, + Material.WALL_SIGN, + Material.DIODE_BLOCK_OFF, + Material.IRON_DOOR_BLOCK, + Material.WOODEN_DOOR, + Material.WATER, + Material.STATIONARY_WATER, + Material.LAVA, + Material.STATIONARY_LAVA, + Material.DOUBLE_STEP, + Material.DOUBLE_STEP, + Material.FIRE, + Material.PORTAL, + Material.ENDER_PORTAL, + Material.WOOD_DOUBLE_STEP, + Material.COCOA, + Material.CARROT, + Material.POTATO, + Material.STANDING_BANNER, + Material.WALL_BANNER, + Material.DAYLIGHT_DETECTOR_INVERTED, + Material.DOUBLE_STONE_SLAB2, + Material.SPRUCE_DOOR, + Material.BIRCH_DOOR, + Material.JUNGLE_DOOR, + Material.ACACIA_DOOR, + Material.DARK_OAK_DOOR + ).build(); + + @BeforeClass + public static void setup() { + DispenserRegistry.c(); + DummyServer.setup(); + DummyPotions.setup(); + DummyEnchantments.setup(); + } +} \ No newline at end of file diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyEnchantments.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyEnchantments.java new file mode 100644 index 0000000..ac34a43 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyEnchantments.java @@ -0,0 +1,12 @@ +package org.bukkit.support; + +import net.minecraft.server.Enchantment; + +public class DummyEnchantments { + static { + Enchantment.getEffects(); + org.bukkit.enchantments.Enchantment.stopAcceptingRegistrations(); + } + + public static void setup() {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyPotions.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyPotions.java new file mode 100644 index 0000000..30666ab --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyPotions.java @@ -0,0 +1,17 @@ +package org.bukkit.support; + +import net.minecraft.server.MobEffectList; + +import org.bukkit.craftbukkit.potion.CraftPotionBrewer; +import org.bukkit.potion.Potion; +import org.bukkit.potion.PotionEffectType; + +public class DummyPotions { + static { + Potion.setPotionBrewer(new CraftPotionBrewer()); + MobEffectList.BLINDNESS.getClass(); + PotionEffectType.stopAcceptingRegistrations(); + } + + public static void setup() {} +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyServer.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyServer.java new file mode 100644 index 0000000..05634f4 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/DummyServer.java @@ -0,0 +1,79 @@ +package org.bukkit.support; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.craftbukkit.inventory.CraftItemFactory; +import org.bukkit.craftbukkit.util.Versioning; + +public class DummyServer implements InvocationHandler { + private static interface MethodHandler { + Object handle(DummyServer server, Object[] args); + } + private static final HashMap methods = new HashMap(); + static { + try { + methods.put( + Server.class.getMethod("getItemFactory"), + new MethodHandler() { + public Object handle(DummyServer server, Object[] args) { + return CraftItemFactory.instance(); + } + } + ); + methods.put( + Server.class.getMethod("getName"), + new MethodHandler() { + public Object handle(DummyServer server, Object[] args) { + return DummyServer.class.getName(); + } + } + ); + methods.put( + Server.class.getMethod("getVersion"), + new MethodHandler() { + public Object handle(DummyServer server, Object[] args) { + return DummyServer.class.getPackage().getImplementationVersion(); + } + } + ); + methods.put( + Server.class.getMethod("getBukkitVersion"), + new MethodHandler() { + public Object handle(DummyServer server, Object[] args) { + return Versioning.getBukkitVersion(); + } + } + ); + methods.put( + Server.class.getMethod("getLogger"), + new MethodHandler() { + final Logger logger = Logger.getLogger(DummyServer.class.getCanonicalName()); + public Object handle(DummyServer server, Object[] args) { + return logger; + } + } + ); + Bukkit.setServer(Proxy.getProxyClass(Server.class.getClassLoader(), Server.class).asSubclass(Server.class).getConstructor(InvocationHandler.class).newInstance(new DummyServer())); + } catch (Throwable t) { + throw new Error(t); + } + } + + public static void setup() {} + + private DummyServer() {}; + + public Object invoke(Object proxy, Method method, Object[] args) { + MethodHandler handler = methods.get(method); + if (handler != null) { + return handler.handle(this, args); + } + throw new UnsupportedOperationException(String.valueOf(method)); + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/Matchers.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/Matchers.java new file mode 100644 index 0000000..b190c67 --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/Matchers.java @@ -0,0 +1,30 @@ +package org.bukkit.support; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.hamcrest.Matcher; + +public final class Matchers { + + private Matchers() {} + + public static Matcher sameHash(T value) { + return new SameHash(value); + } + + static class SameHash extends BaseMatcher { + private final int expected; + + SameHash(T object) { + expected = object.hashCode(); + } + + public boolean matches(Object item) { + return item.hashCode() == expected; + } + + public void describeTo(Description description) { + description.appendValue(expected); + } + } +} diff --git a/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/Util.java b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/Util.java new file mode 100644 index 0000000..2f24d9a --- /dev/null +++ b/MythicSpigot-master/TacoSpigot-Server/src/test/java/org/bukkit/support/Util.java @@ -0,0 +1,31 @@ +package org.bukkit.support; + +import java.lang.reflect.Field; + +public class Util { + /* + public static T getInternalState(Object object, String fieldName) { + return getInternalState(object.getClass(), object, fieldName); + } + */ + + @SuppressWarnings("unchecked") + public static T getInternalState(Class clazz, Object object, String fieldName) { + Field field; + try { + field = clazz.getDeclaredField(fieldName); + } catch (SecurityException e) { + throw new RuntimeException("Not allowed to access " + clazz, e); + } catch (NoSuchFieldException e) { + throw new RuntimeException("Unable to find field " + fieldName, e); + } + + field.setAccessible(true); + try { + return (T) field.get(object); + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } + throw new RuntimeException("Unable to get internal value"); + } +} diff --git a/MythicSpigot-master/parent.iml b/MythicSpigot-master/parent.iml new file mode 100644 index 0000000..88e81df --- /dev/null +++ b/MythicSpigot-master/parent.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/MythicSpigot-master/pom.xml b/MythicSpigot-master/pom.xml new file mode 100644 index 0000000..3fe22bf --- /dev/null +++ b/MythicSpigot-master/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + + org.sonatype.oss + oss-parent + 7 + + + me.levansj01.mythicspigot + parent + dev-SNAPSHOT + pom + + MythicSpigot-Parent + Parent project for all TacoSpigot modules. + https://github.com/TacoSpigot/TacoSpigot + + + TacoSpigot-API + TacoSpigot-Server + + + + UTF-8 + + + + + md_5-releases + http://repo.md-5.net/content/repositories/releases/ + + + + + + org.projectlombok + lombok + 1.18.12 + provided + + + + + + destroystokyo-releases + https://repo.destroystokyo.com/content/repositories/releases/ + + + destroystokyo-snapshots + https://repo.destroystokyo.com/content/repositories/snapshots/ + + + diff --git a/MythicUHC-master/.gitignore b/MythicUHC-master/.gitignore new file mode 100644 index 0000000..62c8935 --- /dev/null +++ b/MythicUHC-master/.gitignore @@ -0,0 +1 @@ +.idea/ \ No newline at end of file diff --git a/MythicUHC-master/MythicUHC.iml b/MythicUHC-master/MythicUHC.iml new file mode 100644 index 0000000..005dbf0 --- /dev/null +++ b/MythicUHC-master/MythicUHC.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MythicUHC-master/README.md b/MythicUHC-master/README.md new file mode 100644 index 0000000..8b9f8c0 --- /dev/null +++ b/MythicUHC-master/README.md @@ -0,0 +1,8 @@ +# MythicUHC [![Java](https://img.shields.io/badge/langauge-Java-ff69b4.svg)](https://en.wikipedia.org/wiki/Java_(programming_language)) +> A high performance UHC core exclusive to the Mythic Network + +## Main Features + * Bucket loads of scenarios + * Easy to understand utils for setting up users + * Ability to broadcast across bungee with an addon (in MythicCore) + * Automatic map resetting after games diff --git a/MythicUHC-master/pom.xml b/MythicUHC-master/pom.xml new file mode 100644 index 0000000..746be9f --- /dev/null +++ b/MythicUHC-master/pom.xml @@ -0,0 +1,128 @@ + + + 4.0.0 + + gg.mythic + MythicUHC + jar + 1.0 + + + + gg.mythic + mythicspigot + 2.0 + jar + provided + + + + + + + + + + org.projectlombok + lombok + 1.16.16 + + + gg.mythic + MythicCore + 1.0-SNAPSHOT + jar + provided + + + org.jodd + jodd-http + 5.0.13 + + + net.raauhh + worldborder + LATEST + provided + + + org.inventivetalent + hologramapi + 1.4.0 + provided + + + org.twitter4j + twitter4j-core + 4.0.7 + + + com.github.MilkBowl + VaultAPI + 1.7 + provided + + + org.ini4j + ini4j + 0.5.4 + + + + + + jitpack.io + https://jitpack.io + + + central + https://repo1.maven.org/maven2/ + + + inventive-repo + https://repo.inventivetalent.org/content/repositories/releases + + + + + UHC-${project.version} + clean install + + + src/main/resources + true + + + + + 3.6.2 + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.0.0 + + + false + false + + + + package + + shade + + + + + + + \ No newline at end of file diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/API.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/API.java new file mode 100644 index 0000000..5f1f03c --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/API.java @@ -0,0 +1,129 @@ +package gg.mythic.uhc; + +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.event.GameScheduleEvent; +import gg.mythic.uhc.manager.gamemode.Gamemode; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.Date; +import java.util.List; + +public class API { + + public List getEnabledGamemodes() { + return Gamemode.getEnabledGamemodes(); + } + + public int getGameTime() { + return UHC.getInstance().getGame().getGameTime(); + } + + public int getHealTime() { + return UHC.getInstance().getGame().getHealTime(); + } + + public int getGracePeriodTime() { + return UHC.getInstance().getGame().getPvpTime(); + } + + public int getBorderTime() { + return UHC.getInstance().getGame().getBorderTime(); + } + + public int getFirstShrink() { + return UHC.getInstance().getGame().getBorderTime(); + } + + public int getSlots() { + return UHC.getInstance().getGame().getSlots(); + } + + public int getAppleRatePercent() { + return UHC.getInstance().getGame().getAppleRatePercent(); + } + + public int getPvPTime() { + return UHC.getInstance().getGame().getPvpTime(); + } + + public boolean getNether() { + return UHC.getInstance().getGame().isNether(); + } + + public boolean getShears() { + return UHC.getInstance().getGame().isShears(); + } + + public int getCurrentBorder() { + return UHC.getInstance().getGame().getCurrentBorder(); + } + + public int getTeamSize() { + Game game = UHC.getInstance().getGame(); + return game.isTeams() ? game.getTeamSize() : 0; + } + + public int getTeamNumber(Player player) { + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + if (uhcPlayer.getUhcTeam() != null) { + return uhcPlayer.getUhcTeam().getId(); + } else { + return -1; + } + } + + public int getSpectatorsSize() { + return UHC.getInstance().getGame().getGameManager().getSpectators().size(); + } + + public int getRemainingPlayerSize() { + return UHC.getInstance().getGame().getGameManager().getAlivePlayers().size(); + } + + public int getMaxPlayers() { + return UHC.getInstance().getGame().getGameManager().getMaxPlayers(); + } + + public Date getScheduledDate() { + Game game = UHC.getInstance().getGame(); + return game.getScheduleDate(); + } + + public String getGameState() { + return UHC.getInstance().getGame().getState().name(); + } + + public void announce(Date date) { + Bukkit.getPluginManager().callEvent(new GameScheduleEvent(date)); + } + + public boolean isHost(Player player) { + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + if(uhcPlayer == null) return false; + + return UHC.getInstance().getGame().getHost().contains(uhcPlayer); + } + + public boolean isModerator(Player player) { + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + if(uhcPlayer == null) return false; + + return UHC.getInstance().getGame().getModerators().contains(uhcPlayer); + } + + public int getStars(Player player) { + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + if(uhcPlayer == null) return 1; + + return uhcPlayer.getStars(); + } + + public String getPlayerState(Player player) { + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + if (uhcPlayer == null) return null; + + return uhcPlayer.getState().name(); + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/UHC.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/UHC.java new file mode 100644 index 0000000..aa3756d --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/UHC.java @@ -0,0 +1,436 @@ +package gg.mythic.uhc; + +import com.google.common.collect.Iterables; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import gg.mythic.uhc.command.*; +import gg.mythic.uhc.listener.*; +import gg.mythic.uhc.listener.game.GameListener2; +import gg.mythic.uhc.listener.game.GameListener3; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.PremadeGame; +import gg.mythic.uhc.manager.gamemode.gamemodes.*; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.FileConfig; +import lombok.Getter; +import lombok.Setter; +import gg.mythic.uhc.listener.game.GameListener; +import gg.mythic.uhc.listener.game.GameListener1; +import gg.mythic.uhc.listener.lobby.LobbyListener; +import gg.mythic.uhc.listener.lobby.LobbyListener1; +import gg.mythic.uhc.manager.Database; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.leaderboard.LeaderboardManager; +import gg.mythic.uhc.manager.meetups.MeetupsKits; +import gg.mythic.uhc.manager.practice.Practice; +import gg.mythic.uhc.manager.twitter.TwitterManager; +import gg.mythic.uhc.manager.world.WorldManager; +import gg.mythic.uhc.nms.NMS; +import gg.mythic.uhc.nms.versions.v1_8_R3; +import gg.mythic.uhc.task.ExpireTask; +import gg.mythic.uhc.task.ScoreboardTask; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.menu.MenuListener; +import gg.mythic.uhc.util.visualise.VisualiseHandler; +import gg.mythic.uhc.util.visualise.VisualiseListener; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; + +import java.net.InetSocketAddress; +import java.time.ZoneId; +import java.util.*; + +@Getter +@Setter +public class UHC extends JavaPlugin { + + @Getter + private static UHC instance; + + protected FileConfig gameConfig, mainConfig, messagesConfig, scoreboardConfig, hotbarConfig, meetupsConfig; + private Random random = new Random(); + + private API api; + private Database db; + private Game game; + private WorldManager worldManager; + private TwitterManager twitterManager; + private VisualiseHandler visualiseHandler; + private Practice practice; + private boolean meetupsMode = false; + + private NMS nmsHandler = new v1_8_R3(); + private BukkitTask expireTask; + + private HashSet whitelist = new HashSet<>(); + private HashSet exclusive = new HashSet<>(); + private HashSet disqualified = new HashSet<>(); + + private List badList; + private List middleFiles = Arrays.asList( + "map-d", + "map-dp", + "map-ds", + "map-p", + "map-pd", + "map-ps", + "map-s", + "map-sd", + "map-sp", + "map-i"); + + @Override + public void onEnable() { + instance = this; + +// String packageName = this.getServer().getClass().getPackage().getName(); +// String version = packageName.substring(packageName.lastIndexOf('.') + 1); +// try { +// final Class clazz = Class.forName("gg.mythic.uhc.nms.versions." + version); +// if (NMS.class.isAssignableFrom(clazz)) { +// this.nmsHandler = (NMS) clazz.getConstructor().newInstance(); +// } +// this.getLogger().info("Running Version: " + version); +// } catch (final Exception e) { +// e.printStackTrace(); +// this.getLogger().severe("Could not find support for this version. Running version: " + version); +// this.setEnabled(false); +// return; +// } + +// try{ +// Wini ini = new Wini(new File("plugins/TerrainControl/worlds/uhc_world/WorldConfig.ini")); +// +// String middle = this.middleFiles.get((int)(Math.random() * 10) + 1); +// ini.put("", "ImageFile", middle + ".png"); +// ini.store(); +// this.getLogger().info("Middle set to " + middle); +// }catch(Exception e){ +// System.err.println(e.getMessage()); +// } + + if (this.nmsHandler instanceof v1_8_R3) { + badList = Arrays.asList( + Material.AIR, + Material.BEDROCK, + Material.COMMAND, + Material.COMMAND_MINECART, + Material.ENCHANTED_BOOK, + Material.WRITTEN_BOOK, + Material.ENDER_CHEST, + Material.ENDER_PORTAL_FRAME, + Material.DRAGON_EGG, + Material.ENDER_PORTAL, + Material.MOB_SPAWNER, + Material.SOIL, + Material.PORTAL, + Material.RED_ROSE, + Material.YELLOW_FLOWER, + Material.BONE, + Material.INK_SACK, + Material.BURNING_FURNACE, + Material.WATER, + Material.STATIONARY_WATER, + Material.LAVA, + Material.STATIONARY_LAVA, + Material.SKULL_ITEM, + Material.RECORD_11, + Material.CARROT_STICK, + Material.MONSTER_EGG, + Material.STORAGE_MINECART, + Material.BARRIER, + Material.SLIME_BLOCK, + Material.RABBIT_FOOT, + Material.RABBIT_HIDE, + Material.PRISMARINE_CRYSTALS, + Material.PRISMARINE_SHARD + ); + } else { + badList = Arrays.asList( + Material.AIR, + Material.BEDROCK, + Material.COMMAND, + Material.COMMAND_MINECART, + Material.ENCHANTED_BOOK, + Material.WRITTEN_BOOK, + Material.ENDER_CHEST, + Material.ENDER_PORTAL_FRAME, + Material.DRAGON_EGG, + Material.ENDER_PORTAL, + Material.MOB_SPAWNER, + Material.SOIL, + Material.PORTAL, + Material.RED_ROSE, + Material.YELLOW_FLOWER, + Material.BONE, + Material.INK_SACK, + Material.BURNING_FURNACE, + Material.WATER, + Material.STATIONARY_WATER, + Material.LAVA, + Material.STATIONARY_LAVA, + Material.SKULL_ITEM, + Material.RECORD_11, + Material.CARROT_STICK, + Material.MONSTER_EGG, + Material.STORAGE_MINECART + ); + } + + this.mainConfig = new FileConfig(this, "config.yml"); + this.gameConfig = new FileConfig(this, "configurations/default.yml"); + this.messagesConfig = new FileConfig(this, "messages.yml"); + this.hotbarConfig = new FileConfig(this, "hotbar.yml"); + this.scoreboardConfig = new FileConfig(this, "scoreboard.yml"); + this.meetupsConfig = new FileConfig(this, "meetups.yml"); + + this.registerGamemodes(); + this.registerCommands(); + this.registerListeners(); + + this.db = new Database(); + if (!this.db.isLoaded()) return; + + if (!meetupsMode) { + this.twitterManager = new TwitterManager(new FileConfig(this, "twitter.yml")); + if (!this.twitterManager.isVerified()) return; + } + + ConfigCursor configCursor = new ConfigCursor(this.mainConfig, ""); + if (configCursor.exists("timeZone")) + TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of(configCursor.getString("timeZone")))); + + this.game = new Game(new PremadeGame(this.gameConfig)); + this.worldManager = new WorldManager(); + this.visualiseHandler = new VisualiseHandler(); + this.practice = new Practice(); + this.api = new API(); + + ConfigCursor meetupsConfig = new ConfigCursor(this.meetupsConfig, ""); + if (meetupsConfig.getBoolean("enabled")) { + this.meetupsMode = true; + MeetupsKits.init(); + } + + new LeaderboardManager(); + new ScoreboardTask().runTaskTimerAsynchronously(this, 0L, 2L); + + this.expireTask = new ExpireTask().runTaskTimerAsynchronously(this, 20L * 5, 20L * 5); + + this.getServer().getMessenger().registerOutgoingPluginChannel(this, "UHC"); + this.getLogger().info("Enabled UHC for user: " + this.twitterManager.getUsers()[0].getScreenName()); + } + + public void broadcast(String message) { + String type; + if (isMeetupsMode()) { + type = "MEETUPS;"; + } else { + type = "UHC;"; + } + + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF(type + message); + + Player player = Iterables.getFirst(Common.getOnlinePlayers(), null); + if(player == null || !player.isOnline()) return; + + player.sendPluginMessage(this, "UHC", out.toByteArray()); + } + + public void registerListeners() { + PluginManager pluginManager = Bukkit.getPluginManager(); + pluginManager.registerEvents(new AssignationListener(), this); + pluginManager.registerEvents(new GameListener(), this); + pluginManager.registerEvents(new GameListener1(), this); + pluginManager.registerEvents(new GameListener2(), this); + pluginManager.registerEvents(new GameListener3(), this); + pluginManager.registerEvents(new LobbyListener(), this); + pluginManager.registerEvents(new LobbyListener1(), this); + pluginManager.registerEvents(new PlayerListener(), this); + pluginManager.registerEvents(new SpectatorListener(), this); + pluginManager.registerEvents(new WorldListener(), this); + pluginManager.registerEvents(new MenuListener(), this); + pluginManager.registerEvents(new OptimizerListener(), this); + pluginManager.registerEvents(new FreezeListener(), this); + + ConfigCursor configCursor = new ConfigCursor(this.mainConfig, "border.glass"); + if(configCursor.exists("enabled") && !configCursor.getBoolean("enabled")) return; + + pluginManager.registerEvents(new VisualiseListener(), this); + } + + private void registerCommands() { + this.getCommand("uhc").setExecutor(new UHCCommand()); + this.getCommand("respawn").setExecutor(new RespawnCommand()); + this.getCommand("helpop").setExecutor(new HelpOpCommand()); + this.getCommand("hc").setExecutor(new HCCommand()); + this.getCommand("removelogger").setExecutor(new RemoveLoggerCommand()); + this.getCommand("gamemodes").setExecutor(new GamemodesCommand()); + this.getCommand("assignation").setExecutor(new AssignationCommand()); + this.getCommand("killcount").setExecutor(new KillCountCommand()); + this.getCommand("killtop").setExecutor(new KillTopCommand()); + this.getCommand("whitelist").setExecutor(new WhitelistCommand()); + this.getCommand("exclusive").setExecutor(new ExclusiveCommand()); + this.getCommand("leaderboard").setExecutor(new LeaderboardCommand()); + this.getCommand("configuration").setExecutor(new ConfigurationCommand()); + this.getCommand("practice").setExecutor(new PracticeCommand()); + this.getCommand("freeze").setExecutor(new FreezeCommand()); + this.getCommand("statistics").setExecutor(new StatisticsCommand()); + this.getCommand("latescatter").setExecutor(new LateScatterCommand()); + this.getCommand("teleport").setExecutor(new TeleportCommand()); + this.getCommand("giveall").setExecutor(new GiveAllCommand()); + this.getCommand("give").setExecutor(new GiveCommand()); + this.getCommand("heal").setExecutor(new HealCommand()); + this.getCommand("healall").setExecutor(new HealAllCommand()); + this.getCommand("sethealth").setExecutor(new SetHealthCommand()); + this.getCommand("list").setExecutor(new ListCommand()); + this.getCommand("health").setExecutor(new HealthCommand()); + this.getCommand("togglespectatorchat").setExecutor(new ToggleSpectatorChat()); + this.getCommand("border").setExecutor(new BorderCommand()); + this.getCommand("info").setExecutor(new InfoCommand()); + this.getCommand("disqualify").setExecutor(new DisqualifyCommand()); + this.getCommand("loggers").setExecutor(new LoggersCommand()); + + this.getCommand("reroll").setExecutor(new RerollCommand()); + + this.getCommand("mlg").setExecutor(new MLGCommand()); + + this.getCommand("team").setExecutor(new TeamCommand()); + this.getCommand("teamall").setExecutor(new TeamAllCommand()); + this.getCommand("teamlist").setExecutor(new TeamListCommand()); + this.getCommand("sendcoords").setExecutor(new TeamCoordsCommand()); + this.getCommand("teamchat").setExecutor(new TeamChatCommand()); + this.getCommand("backpack").setExecutor(new BackPackCommand()); + this.getCommand("mole").setExecutor(new MoleCommand()); + this.getCommand("thankyou").setExecutor(new ThanksCommand()); + this.getCommand("jackpot").setExecutor(new JackpotCommand()); + this.getCommand("fly").setExecutor(new FlyCommand()); + } + + private void registerGamemodes() { + new CutClean(); + new TimeBomb(); + new BuildUHC(); + new Rush(); + new SafeLoot(); + new Timber(); + new NoClean(); + new BackPack(); + new Barebones(); + new BloodDiamond(); + new BloodEnchant(); + new Bowless(); + new Diamondless(); + new Fireless(); + new HasteyBoys(); + new Goldless(); + new Horseless(); + new Statless(); + new Absorptionless(); + new ColdWeapons(); + new GoldenRetriever(); + new LuckyLeaves(); + new NoFall(); + new Anonymous(); + new DoubleOres(); + new TripleOres(); + new RandomTeams(); + new SkyHigh(); + new ExtremeSkyHigh(); + new LAFS(); + new Eggs(); + new Moles(); + new EasyBook(); + new FlowerPower(); + new EnchantedFlowerPower(); + new SuperSuperheroes(); + new Superheroes(); + new AssaultAndBattery(); + new AssaultAndBatteryCycle(); + new DoubleHearts(); + new StockUp(); + new GunsNRoses(); + new GoneFishing(); + new DoNotDisturb(); + new BaldChickens(); + new BetaZombies(); + new BleedingSweets(); + new LongShot(); + new NoPearlDamage(); + new Switcheroo(); + new HypixelHeads(); + new InfiniteEnchant(); + new BenchBlitz(); + new Chicken(); + new Cripple(); + new Soup(); + new GapZap(); + new FastGetaway(); + new WebCage(); + new DoubleXP(); + new TripleXP(); + new NineSlots(); + new HasteyBoysLite(); + new ArmorEnchants(); + new SwordEnchants(); + new BowEnchants(); + new FiftyHearts(); + new SugarRush(); + new VeinMiner(); + new EnchantedDeath(); + new RedVsBlue(); + new SharedHealth(); + new Nightmare(); + new BlockRush(); + new RenoJackson(); + new Swordless(); + new Rodless(); + new SpeedDemon(); + new TeamSpeedDemon(); + new TrainingRabbits(); + new TeamTrainingRabbits(); + new PuppyPower(); + new RandomStartingItems(); + new RandomEnchantedStartingItems(); + new Ironless(); + new GoToHell(); + new Fallout(); + new Cupid(); + new PlayerSwap(); + new AirDrop(); + new Compass(); + new Krenzinator(); + new Enchantless(); + new NoDiamondArmour(); + new RushPlus(); + new Depths(); + new Broadcaster(); + new Limitation(); + new RiskyEnchants(); + new OreFrenzy(); + new DominosDeliveryGuarantee(); + new LightsOut(); + new CatEyes(); + new Bombers(); + new EveryRose(); + new WoodLife(); + new MonstersInc(); + new FastScenarioRoulette(); + new ScenarioRoulette(); + new WingedAxes(); + new Birds(); + new Pyro(); + new Jackpot(); + new PearlGiver(); + new GoldGiver(); + new SpeedUHC(); + // Randomizer + // new SlaveMarket(); https://www.youtube.com/watch?v=kM-M3GOh5ys There are 8 people chosen to be slave owners and get a set amount of diamonds. All other players will be auctioned off and the slave owners bid on them with their diamonds. The diamonds the slave owners have left after all players are bid on can be used in the game. + // new Captains(); Random or chosen players (depending on the host) are assigned as "Captains" who then choose their teammates. + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/AssignationCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/AssignationCommand.java new file mode 100644 index 0000000..f4d174f --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/AssignationCommand.java @@ -0,0 +1,214 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.assignation.Assignation; +import gg.mythic.uhc.manager.assignation.impl.FFAAssignation; +import gg.mythic.uhc.manager.assignation.impl.TeamAssignation; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import gg.mythic.uhc.manager.UHCTeam; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class AssignationCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) return true; + + final Player player = (Player) sender; + final Game game = UHC.getInstance().getGame(); + + if (game.getState() != Game.State.PLAYING) { + player.sendMessage("§cYou may only use this command when the game is running."); + return true; + } + + UHCPlayer uhcSender = UHCPlayer.getByUuid(player.getUniqueId()); + if (!(UHC.getInstance().getGame().getHost().contains(uhcSender) || UHC.getInstance().getGame().getModerators().contains(uhcSender))) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.assignation"); + + if (args.length == 0) { + player.sendMessage(Common.format(configCursor.getString("usage"))); + return true; + } + + if (args[0].equals("cancel")) { + if (args.length < 2) { + player.sendMessage("§cSyntax Error. Please use /assignation cancel "); + return true; + } + + UHCPlayer uhcPlayer = UHCPlayer.getByName(args[1]); + if (uhcPlayer == null) { + player.sendMessage("§cCouldn't find that player"); + return true; + } + + if (!uhcPlayer.isAssigned()) { + player.sendMessage("§cThat player is not assigned."); + return true; + } + + uhcPlayer.getAssignation().handleEnd(); + player.sendMessage("§cYou have cancelled " + uhcPlayer.getName() + " assignation."); + return true; + } + + if (args[0].equals("cancelall")) { + for (Assignation assignation : Assignation.getAssignations()) { + assignation.handleEnd(); + } + + Bukkit.broadcastMessage(ChatColor.GREEN + "" + ChatColor.BOLD + "Everybody has been unassigned!"); + } + + if (args[0].equals("all")) { + if (UHC.getInstance().getGame().getTeamSize() == 1) { + List uhcPlayers = UHCPlayer.getPlayers().values() + .stream() + .filter(UHCPlayer::isOnline) + .filter(uhcPlayer -> !uhcPlayer.isSpectating()) + .collect(Collectors.toList()); + + Collections.shuffle(uhcPlayers); + + if (uhcPlayers.size() < 2) { + player.sendMessage("Uh oh... Cannot find anybody to assign...."); + return true; + } + + while (!uhcPlayers.isEmpty()) { + UHCPlayer uhcPlayer1 = uhcPlayers.get(0); + if (uhcPlayers.size() < 2) { + uhcPlayer1.getPlayer().sendMessage(ChatColor.RED + "Poor you... You did not get assigned. Better luck next time!"); + break; + } + UHCPlayer uhcPlayer2 = uhcPlayers.get(1); + + final Assignation assignation = new FFAAssignation(uhcPlayer1, uhcPlayer2); + assignation.start(); + + uhcPlayers.remove(1); + uhcPlayers.remove(0); + } + + } else { + List uhcTeams = UHCTeam.getTeams() + .stream() + .filter(UHCTeam::isAlive) + .collect(Collectors.toList()); + + Collections.shuffle(uhcTeams); + + if (uhcTeams.size() < 2) { + player.sendMessage("Uh oh... Cannot find any teams to assign...."); + return true; + } + + while (!uhcTeams.isEmpty()) { + UHCTeam uhcTeam1 = uhcTeams.get(0); + if (uhcTeams.size() < 2) { + uhcTeam1.getTeamPlayers().forEach(uhcPlayer -> uhcPlayer.getPlayer().sendMessage(ChatColor.RED + "Poor you... Your team did not get assigned. Better luck next time!")); + break; + } + UHCTeam uhcTeam2 = uhcTeams.get(1); + + final Assignation assignation = new TeamAssignation(uhcTeam1, uhcTeam2); + assignation.start(); + + uhcTeams.remove(1); + uhcTeams.remove(0); + } + + } + Bukkit.broadcastMessage(ChatColor.GREEN + "" + ChatColor.BOLD + "Assigned everybody! Good luck!"); + + return true; + } + + final UHCPlayer uhcPlayer1 = UHCPlayer.getByName(args[0]), uhcPlayer2 = UHCPlayer.getByName(args[1]); + switch (args.length) { + case 2: + if ((uhcPlayer1 == null || !uhcPlayer1.isOnline()) || (uhcPlayer2 == null || !uhcPlayer1.isOnline())) { + player.sendMessage("§cCouldn't assign fight. Everyone must be online."); + return true; + } + + if (uhcPlayer1.isAssigned() || !uhcPlayer1.isAlive()) { + player.sendMessage("§cCouldn't assign fight. " + uhcPlayer1.getName() + " is already assigned or isn't alive."); + return true; + } + + if (uhcPlayer2.isAssigned() || !uhcPlayer2.isAlive()) { + player.sendMessage("§cCouldn't assign fight. " + uhcPlayer2.getName() + " is already assigned or isn't alive."); + return true; + } + + player.sendMessage(Common.format(configCursor.getString("assign"), uhcPlayer1.getName(), uhcPlayer2.getName())); + + final Assignation assignation = new FFAAssignation(uhcPlayer1, uhcPlayer2); + assignation.start(); + break; + case 3: + if ((uhcPlayer1 == null || !uhcPlayer1.isOnline()) || (uhcPlayer2 == null || !uhcPlayer1.isOnline())) { + player.sendMessage("§cCouldn't assign fight. Everyone must be online."); + return true; + } + + if (uhcPlayer1.isAssigned() || !uhcPlayer1.isAlive()) { + player.sendMessage("§cCouldn't assign fight. " + uhcPlayer1.getName() + " is already assigned or isn't alive."); + return true; + } + + if (uhcPlayer2.isAssigned() || !uhcPlayer2.isAlive()) { + player.sendMessage("§cCouldn't assign fight. " + uhcPlayer2.getName() + " is already assigned or isn't alive."); + return true; + } + + if (uhcPlayer1.getUhcTeam() == null) { + player.sendMessage(ChatColor.RED + "Player 1 does not have a team"); + return true; + } + if (uhcPlayer2.getUhcTeam() == null) { + player.sendMessage(ChatColor.RED + "Player 2 does not have a team"); + return true; + } + + final Assignation teamAssignation = new TeamAssignation(uhcPlayer1.getUhcTeam(), uhcPlayer2.getUhcTeam()); + teamAssignation.start(); + + player.sendMessage(ChatColor.GREEN + "Boom. Team assigning done!"); + + break; + default: + player.sendMessage("§7§m-----------------------------------------------"); + player.sendMessage("§cPlease use§7:"); + player.sendMessage(" §c/assign all §7- Assign all players/teams (will not take into account team amount)"); + player.sendMessage(" §c/assign cancel §7- Cancel the specified assign"); + player.sendMessage(" §c/assign cancelall §7- Cancel all assigns"); + player.sendMessage(" §c/assign §7- To make a FFA assignation."); + player.sendMessage(" §c/assign team §7- Assign 2 different player's teams to each other"); + player.sendMessage("§7§m-----------------------------------------------"); + break; + } + return true; + } + +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/BackPackCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/BackPackCommand.java new file mode 100644 index 0000000..6db272c --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/BackPackCommand.java @@ -0,0 +1,39 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.gamemode.Gamemode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class BackPackCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) return true; + + Player player = (Player) sender; + if (args.length == 1) { + if(!Gamemode.getByName("BackPack").isEnabled()){ + player.sendMessage("§cBackpacks are disabled on this match."); + return true; + } + + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + if (UHC.getInstance().getGame().getHost().contains(uhcPlayer) || UHC.getInstance().getGame().getModerators().contains(uhcPlayer)) { + UHCPlayer targetUhcPlayer = UHCPlayer.getByName(args[0]); + if (targetUhcPlayer == null || !targetUhcPlayer.isOnline()) { + player.sendMessage("§cCouldn't find a player with the name " + args[0]); + return true; + } + + player.openInventory(targetUhcPlayer.getUhcTeam().getBackPack()); + } + } else { + player.performCommand("team inventory"); + } + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/BorderCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/BorderCommand.java new file mode 100644 index 0000000..decc95f --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/BorderCommand.java @@ -0,0 +1,70 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.event.BorderShrinkEvent; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.JavaUtils; +import gg.mythic.uhc.manager.world.Shrink; +import org.apache.commons.lang.math.NumberUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class BorderCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (args.length < 1) { + sender.sendMessage("§cPlease use /border "); + return true; + } + + Game game = UHC.getInstance().getGame(); + + if (game.getState() != Game.State.PLAYING) { + sender.sendMessage("§cThe game must be running."); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcSender = UHCPlayer.getByUuid(player.getUniqueId()); + if (!(UHC.getInstance().getGame().getHost().contains(uhcSender) || UHC.getInstance().getGame().getModerators().contains(uhcSender))) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + if(!NumberUtils.isNumber(args[0])){ + sender.sendMessage("§cAmount must be a number."); + return true; + } + + int border = JavaUtils.tryParseInteger(args[0]); + + if (!game.isBorderTimeAlready()) { + sender.sendMessage("§cYou cannot change the border while there is no shrink happening."); + return true; + } + + if (game.getCurrentBorder() < border) { + sender.sendMessage("§cAmount must be smaller than current border."); + return true; + } + + Bukkit.getPluginManager().callEvent(new BorderShrinkEvent(border, game.getShrink().getCurrentBorder())); + game.setShrink(new Shrink(game.getCurrentBorder(), border)); +// int i = 0; +// for (String borderSize : game.getShrinks()) { +// if (border > Integer.parseInt(borderSize)) { +// game.getShrinks().remove(i); +// } +// } + game.setCurrentBorder(border); + + Bukkit.broadcastMessage("Border was shrunk to §b&l" + border); + + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ConfigurationCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ConfigurationCommand.java new file mode 100644 index 0000000..0ef6e74 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ConfigurationCommand.java @@ -0,0 +1,22 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.menu.ConfigMenu; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ConfigurationCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + final Player player = (Player) sender; + new ConfigMenu().open(player); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/DisqualifyCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/DisqualifyCommand.java new file mode 100644 index 0000000..a62fbc7 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/DisqualifyCommand.java @@ -0,0 +1,42 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class DisqualifyCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (args.length == 0) { + sender.sendMessage("§cSyntax Error. Please use /disqualify "); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcSender = UHCPlayer.getByUuid(player.getUniqueId()); + if (!(UHC.getInstance().getGame().getHost().contains(uhcSender) || UHC.getInstance().getGame().getModerators().contains(uhcSender))) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + UHCPlayer targetUhcPlayer = UHCPlayer.getByName(args[0]); + if (targetUhcPlayer == null) { + sender.sendMessage("§cCouldn't find that player."); + return true; + } + + if (!targetUhcPlayer.isOnline()) { + sender.sendMessage("§cCannot find that user. Please make sure they are online."); + return true; + } + + UHC.getInstance().getDisqualified().add(targetUhcPlayer.getPlayer().getAddress()); + Bukkit.broadcastMessage(sender.getName() + "§c has disqualified " + targetUhcPlayer.getName() + "!"); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ExclusiveCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ExclusiveCommand.java new file mode 100644 index 0000000..2146a25 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ExclusiveCommand.java @@ -0,0 +1,161 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ExclusiveCommand implements CommandExecutor, TabCompleter { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + Game game = UHC.getInstance().getGame(); + UHCPlayer uhcPlayer = null; + + if(game.getState() != Game.State.LOBBY) { + sender.sendMessage("§cCouldn't modify exclusive now."); + return true; + } + + if (sender instanceof Player) uhcPlayer = UHCPlayer.getByUuid(((Player) sender).getUniqueId()); + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.whitelist"); + + if (args.length == 0) { + sender.sendMessage(ChatColor.RED + "Usage: /exclusive (on, off, remove, add, list)"); + return true; + } + + switch (args[0]) { + case "true": + case "enable": + case "on": + if (game.getState() == Game.State.PLAYING) { + sender.sendMessage("§cYou may not modify exclusive list while the game is running."); + return true; + } + + if (uhcPlayer != null && !game.getHost().contains(uhcPlayer)) { + uhcPlayer.getPlayer().sendMessage("§cYou may be the Host to modify this value."); + return true; + } + + sender.sendMessage(Common.format(configCursor.getString("toggle"), true)); + game.setExclusive(true); + break; + case "false": + case "disable": + case "off": + if (game.getState() == Game.State.PLAYING) { + sender.sendMessage("§cYou may not modify exclusive list while the game is running."); + return true; + } + + if (uhcPlayer != null && !game.getHost().contains(uhcPlayer)) { + uhcPlayer.getPlayer().sendMessage("§cYou may be the Host to modify this value."); + return true; + } + + sender.sendMessage(Common.format(configCursor.getString("toggle"), false)); + game.setExclusive(false); + break; + case "list": + List whitelistedPlayers = new ArrayList<>(); + + if (UHC.getInstance().getExclusive().isEmpty()) { + sender.sendMessage("§cExclusive List is empty."); + return true; + } + + if (uhcPlayer == null) { + whitelistedPlayers.addAll(UHC.getInstance().getExclusive()); + sender.sendMessage(Common.format(configCursor.getString("list"), StringUtils.join(whitelistedPlayers, ", "))); + return true; + } + + if (game.getHost().contains(uhcPlayer)) { + whitelistedPlayers.addAll(UHC.getInstance().getExclusive()); + sender.sendMessage(Common.format(configCursor.getString("list"), StringUtils.join(whitelistedPlayers, ", "))); + } + break; + case "add": + if(args.length < 2) { + sender.sendMessage("§cPlease use /exclusive add "); + return true; + } + + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(args[1]); + + if (offlinePlayer.isOnline()) { + sender.sendMessage("§cYou may not exclusive-add an online player."); + return true; + } + + if (UHC.getInstance().getExclusive().contains(offlinePlayer.getName())) { + sender.sendMessage("§cYou may not exclusive-add a exclusive-added player."); + return true; + } + + if (game.getState() != Game.State.LOBBY && !game.getHost().contains(uhcPlayer)) { + sender.sendMessage("§cYou may not modify exclusive list while the game is running."); + return true; + } + + sender.sendMessage(Common.format(configCursor.getString("add.message"), offlinePlayer.getName())); + UHC.getInstance().getExclusive().add(offlinePlayer.getName().toLowerCase()); + break; + case "remove": + if(args.length < 2) { + sender.sendMessage("§cPlease use /exclusive remove "); + return true; + } + + offlinePlayer = Bukkit.getOfflinePlayer(args[1]); + + if (!UHC.getInstance().getExclusive().contains(offlinePlayer.getName())) { + sender.sendMessage("§cUser is not on the exclusive list"); + return true; + } + + if (game.getState() != Game.State.LOBBY && !game.getHost().contains(uhcPlayer)) { + sender.sendMessage("§cYou may not modify exclusive list while the game is running."); + return true; + } + + sender.sendMessage(Common.format(configCursor.getString("add.message"), offlinePlayer.getName())); + UHC.getInstance().getExclusive().remove(offlinePlayer.getName().toLowerCase()); + break; + } + + return true; + } + + @Override + public List onTabComplete(CommandSender commandSender, Command command, String s, String[] args) { + List completer = new ArrayList<>(); + + if (args.length == 1) { + String match = args[0].toLowerCase(); + completer.addAll(Arrays.asList("on", "off", "add", "remove", "list")); + completer.removeIf(value -> !(value.contains(match) || value.equalsIgnoreCase(match))); + } else return null; + + return completer; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/FlyCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/FlyCommand.java new file mode 100644 index 0000000..c732c53 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/FlyCommand.java @@ -0,0 +1,40 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.PlayerUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class FlyCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + + if (UHC.getInstance().getGame().getState() != Game.State.LOBBY || UHCPlayer.getByUuid(player.getUniqueId()).isInPractice()) { + sender.sendMessage("§cYou cannot do that right now"); + return true; + } + + if (player.getPlayer().getAllowFlight()) { + player.sendMessage("§cYou are no longer flying!"); + player.setAllowFlight(false); + player.setFlying(false); + } else { + player.sendMessage("§aYou are now flying!"); + player.setAllowFlight(true); + player.setFlying(true); + } + + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/FreezeCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/FreezeCommand.java new file mode 100644 index 0000000..db83bee --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/FreezeCommand.java @@ -0,0 +1,47 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class FreezeCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.freeze"); + + if (args.length == 0) { + sender.sendMessage(Common.format(configCursor.getString("usage"))); + return true; + } + + UHCPlayer uhcPlayerTarget = UHCPlayer.getByName(args[0]); + if (uhcPlayerTarget == null || !uhcPlayerTarget.isOnline()) { + sender.sendMessage("§cCouldn't find that player."); + return true; + } + + Player target = uhcPlayerTarget.getPlayer(); + + if (uhcPlayerTarget.isFreezed()) { + uhcPlayerTarget.setFreezed(false); + sender.sendMessage(Common.format(configCursor.getString("unfreeze"), uhcPlayerTarget.getName())); + UHC.getInstance().getNmsHandler().removeVehicle(target); + } else { + uhcPlayerTarget.setFreezed(true); + + sender.sendMessage(Common.format(configCursor.getString("freeze"), uhcPlayerTarget.getName())); + target.sendMessage(Common.format(configCursor.getString("message"))); + + UHC.getInstance().getNmsHandler().addVehicle(target); + } + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GamemodesCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GamemodesCommand.java new file mode 100644 index 0000000..d043318 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GamemodesCommand.java @@ -0,0 +1,32 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.manager.gamemode.Gamemode; +import gg.mythic.uhc.menu.GamemodesMenu; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.List; + +public class GamemodesCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + final Player player = (Player) sender; + final List gamemodes = Gamemode.getEnabledGamemodes(); + + if (gamemodes.isEmpty()) { + player.sendMessage("§cThere are no currently enabled gamemodes."); + return true; + } + + new GamemodesMenu().open(player); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GiveAllCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GiveAllCommand.java new file mode 100644 index 0000000..9d83ea9 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GiveAllCommand.java @@ -0,0 +1,94 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.util.ItemCreator; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.JavaUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class GiveAllCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (args.length < 1) { + sender.sendMessage("§cPlease use /giveall :[data] [amount]"); + return true; + } + + if (sender instanceof Player) { + Player player = (Player) sender; + UHCPlayer uhcSender = UHCPlayer.getByUuid(player.getUniqueId()); + if (!(UHC.getInstance().getGame().getHost().contains(uhcSender) || UHC.getInstance().getGame().getModerators().contains(uhcSender))) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + } + + int amount = 1; + if (args.length == 2) { + if(!NumberUtils.isNumber(args[1])){ + sender.sendMessage("§cAmount must be a number."); + return true; + } + + amount = JavaUtils.tryParseInteger(args[1]); + } + + ItemStack itemStack; + if (args[0].contains(":")) { + String[] item = args[0].split(":"); + + if(!NumberUtils.isNumber(item[0]) || !NumberUtils.isNumber(item[1])){ + sender.sendMessage("§cItem id or item damage must be a number."); + return true; + } + + int id = JavaUtils.tryParseInteger(item[0]); + int damage = JavaUtils.tryParseInteger(item[1]); + + if (id == 0) { + sender.sendMessage("§cThere was an error while parsing item id."); + return true; + } + + Material material = Material.getMaterial(id); + if (material == null) { + sender.sendMessage("§cCouldn't find item."); + return true; + } + + itemStack = new ItemCreator(material, amount, damage).get(); + } else { + if(!NumberUtils.isNumber(args[0])){ + sender.sendMessage("§cItem id or item damage must be a number."); + return true; + } + + int id = JavaUtils.tryParseInteger(args[0]); + + Material material = Material.getMaterial(id); + if (material == null) { + sender.sendMessage("§cCouldn't find item."); + return true; + } + + itemStack = new ItemCreator(material, amount, 0).get(); + } + + final Game game = UHC.getInstance().getGame(); + + game.getGameManager().getAlivePlayers().forEach(uhcPlayer -> { + if(uhcPlayer.isOnline()) uhcPlayer.getPlayer().getInventory().addItem(itemStack); + }); + + sender.sendMessage("§eYou gived §f" + amount + " §eof §f" + itemStack.getType().name() + " §eto all alive players."); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GiveCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GiveCommand.java new file mode 100644 index 0000000..b19d577 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/GiveCommand.java @@ -0,0 +1,95 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.util.ItemCreator; +import gg.mythic.uhc.util.JavaUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class GiveCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (args.length < 2) { + sender.sendMessage("§cPlease use /give :[data] [amount] "); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcSender = UHCPlayer.getByUuid(player.getUniqueId()); + if (!UHC.getInstance().getGame().getGameManager().getStaff().contains(uhcSender)) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + int amount = 1; + if (args.length == 3) { + if(!NumberUtils.isNumber(args[1])){ + sender.sendMessage("§cAmount must be a number."); + return true; + } + + amount = JavaUtils.tryParseInteger(args[1]); + } + + ItemStack itemStack; + if (args[0].contains(":")) { + String[] item = args[0].split(":"); + + if(!NumberUtils.isNumber(args[0]) || !NumberUtils.isNumber(args[1])){ + sender.sendMessage("§cItem id or item damage must be a number."); + return true; + } + + int id = JavaUtils.tryParseInteger(item[0]); + int damage = JavaUtils.tryParseInteger(item[1]); + + if (id == 0) { + sender.sendMessage("§cThere was an error while parsing item id."); + return true; + } + + Material material = Material.getMaterial(id); + if (material == null) { + sender.sendMessage("§cCouldn't find item."); + return true; + } + + itemStack = new ItemCreator(material, amount, damage).get(); + } else { + if(!NumberUtils.isNumber(args[0])){ + sender.sendMessage("§cItem id or item damage must be a number."); + return true; + } + + int id = JavaUtils.tryParseInteger(args[0]); + + Material material = Material.getMaterial(id); + if (material == null) { + sender.sendMessage("§cCouldn't find item."); + return true; + } + + itemStack = new ItemCreator(material, amount, 0).get(); + } + + UHCPlayer uhcPlayerTarget = UHCPlayer.getByName(args[2]); + if (uhcPlayerTarget == null || !uhcPlayerTarget.isOnline()) { + sender.sendMessage("§cCouldn't find that player."); + return true; + } + + Player target = uhcPlayerTarget.getPlayer(); + + target.getInventory().addItem(itemStack); + + sender.sendMessage("§eYou gave §f" + amount + " §eof §f" + itemStack.getType().name() + " §eto " + target.getName()); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HCCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HCCommand.java new file mode 100644 index 0000000..92530d3 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HCCommand.java @@ -0,0 +1,51 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class HCCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + final Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + final Game game = UHC.getInstance().getGame(); + + if (!game.getHost().contains(uhcPlayer) && !game.getModerators().contains(uhcPlayer)) { + sender.sendMessage("§cError. You must be a mod or host to execute this command"); + return true; + } + + if (args.length < 1) { + player.sendMessage("§cSyntax Error. Please use /hc "); + return true; + } + + StringBuilder stringBuilder = new StringBuilder(); + for (String string : args) { + stringBuilder.append(string); + stringBuilder.append(" "); + } + + Bukkit.getConsoleSender().sendMessage(player.getName() + ": §b" + stringBuilder); + + UHCPlayer.getPlayers().values().forEach(target -> { + if (target.isOnline() && (game.getHost().contains(target) || game.getModerators().contains(target))) { + target.getPlayer().sendMessage("§7§l[§b§lUHC§7§l] §5" + player.getName() + "§d: " + stringBuilder); + } + }); + + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealAllCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealAllCommand.java new file mode 100644 index 0000000..9b87882 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealAllCommand.java @@ -0,0 +1,46 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class HealAllCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcSender = UHCPlayer.getByUuid(player.getUniqueId()); + if (!(UHC.getInstance().getGame().getHost().contains(uhcSender) || UHC.getInstance().getGame().getModerators().contains(uhcSender))) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.heal"); + + Game game = UHC.getInstance().getGame(); + game.getGameManager().getAlivePlayers().forEach(uhcPlayerLoop -> { + if(uhcPlayerLoop.isOnline()) { + uhcPlayerLoop.getPlayer().setHealth(uhcPlayerLoop.getPlayer().getMaxHealth()); + uhcPlayerLoop.getPlayer().setFireTicks(0); + uhcPlayerLoop.getPlayer().setFoodLevel(20); + uhcPlayerLoop.getPlayer().sendMessage(Common.format(configCursor.getString("you"), uhcPlayerLoop.getName())); + } + }); + sender.sendMessage("§eYou have healed all alive players!"); + + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealCommand.java new file mode 100644 index 0000000..26a91ea --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealCommand.java @@ -0,0 +1,60 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class HealCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + + UHCPlayer uhcSender = UHCPlayer.getByUuid(player.getUniqueId()); + final Game game = UHC.getInstance().getGame(); + + if (!(UHC.getInstance().getGame().getHost().contains(uhcSender) || UHC.getInstance().getGame().getModerators().contains(uhcSender))) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.heal"); + + if(args.length == 0){ + player.setHealth(player.getMaxHealth()); + player.setFireTicks(0); + player.setFoodLevel(20); + + player.sendMessage(Common.format(configCursor.getString("you"), player.getName())); + return true; + } + + UHCPlayer uhcPlayerTarget = UHCPlayer.getByName(args[0]); + if (uhcPlayerTarget == null || !uhcPlayerTarget.isOnline()) { + sender.sendMessage("§cCouldn't find that player."); + return true; + } + + Player target = uhcPlayerTarget.getPlayer(); + + target.setHealth(target.getMaxHealth()); + target.setFireTicks(0); + target.setFoodLevel(20); + + player.sendMessage(Common.format(configCursor.getString("other"), target.getName())); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealthCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealthCommand.java new file mode 100644 index 0000000..42e12e7 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HealthCommand.java @@ -0,0 +1,64 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.text.DecimalFormat; + +public class HealthCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + Game game = UHC.getInstance().getGame(); + + if (game.getState() != Game.State.PLAYING) { + player.sendMessage("§cThe game must be running to execute this command"); + return true; + } + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.health"); + + if (args.length == 0) { + if (!uhcPlayer.isAlive()) { + player.sendMessage("§cThat player is not alive"); + return true; + } + + String health = new DecimalFormat("#.#").format(Math.round((player.getHealth() / 2) * 2.0D) / 2.0D); + player.sendMessage(Common.format(configCursor.getString("you"), health)); + return true; + } + + UHCPlayer uhcPlayerTarget = UHCPlayer.getByName(args[0]); + if (uhcPlayerTarget == null || !uhcPlayerTarget.isOnline()) { + player.sendMessage("§cCouldn't find that player, may be offline."); + return true; + } + + if (!uhcPlayerTarget.isAlive()) { + player.sendMessage("§cThat player is not alive"); + return true; + } + + String health = new DecimalFormat("#.#").format(Math.round((uhcPlayerTarget.getPlayer().getHealth() / 2) * 2.0D) / 2.0D); + player.sendMessage(Common.format(configCursor.getString("other"), uhcPlayerTarget.getName(), health)); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HelpOpCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HelpOpCommand.java new file mode 100644 index 0000000..64dad81 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/HelpOpCommand.java @@ -0,0 +1,62 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.*; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class HelpOpCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + final Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + final Game game = UHC.getInstance().getGame(); + + if (args.length < 1) { + player.sendMessage("§cSyntax Error. Please use /helpop "); + return true; + } + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.helpop"); + + if (!uhcPlayer.getHelpopCooldown().hasExpired()) { + final String time = TimeUtil.millisToSeconds(uhcPlayer.getHelpopCooldown().getRemaining()); + final String context = "second" + ((uhcPlayer.getHelpopCooldown().getRemaining() / 1000) > 1 ? "s" : ""); + + player.sendMessage(Common.format(configCursor.getString("cooldown"), time, context)); + return true; + } + + uhcPlayer.setHelpopCooldown(new Cooldown(16_000)); + + StringBuilder stringBuilder = new StringBuilder(); + for (String string : args) { + stringBuilder.append(string); + stringBuilder.append(" "); + } + + + Bukkit.getConsoleSender().sendMessage(Common.format(configCursor.getString("format"), player.getDisplayName(), stringBuilder.toString())); + + UHCPlayer.getPlayers().values().forEach(target -> { + if (target.isOnline() && (game.getHost().contains(target) || game.getModerators().contains(target))) { + target.getPlayer().sendMessage(Common.format(configCursor.getString("format"), player.getDisplayName(), stringBuilder.toString())); + } + }); + + player.sendMessage(Common.format(configCursor.getString("sent"), stringBuilder.toString())); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/InfoCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/InfoCommand.java new file mode 100644 index 0000000..e3beaf6 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/InfoCommand.java @@ -0,0 +1,42 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.gamemode.Gamemode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class InfoCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + final Player player = (Player) sender; + Game game = UHC.getInstance().getGame(); + player.sendMessage("§7§m-----------------------"); + if (game.isTeams()) { + player.sendMessage("§5§lTo" + game.getTeamSize()); + } else { + player.sendMessage("§5§lFFA"); + } + for (Gamemode scenario : Gamemode.getEnabledGamemodes()) { + player.sendMessage("§7- §f" + scenario.getName()); + } + player.sendMessage(""); + player.sendMessage("§5Current Border:§f " + game.getCurrentBorder()); + player.sendMessage("§5Final Heal:§f " + game.getHealTime()/60); + player.sendMessage("§5Grace Period:§f " + game.getPvpTime()/60); + player.sendMessage("§5First Shrink:§f " + game.getBorderTime()/60); + player.sendMessage("§5Apple Rate:§f " + game.getAppleRatePercent()); + player.sendMessage("§5Nether:§f " + game.isNether()); + player.sendMessage("§5Shears:§f " + game.isShears()); + player.sendMessage("§7§m-----------------------"); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/JackpotCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/JackpotCommand.java new file mode 100644 index 0000000..9a2da8c --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/JackpotCommand.java @@ -0,0 +1,46 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.gamemode.Gamemode; +import gg.mythic.uhc.manager.gamemode.gamemodes.Moles; +import gg.mythic.uhc.menu.MoleKitMenu; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.stream.Collectors; + +public class JackpotCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) return true; + + Player player = (Player) sender; + + Game game = UHC.getInstance().getGame(); + if (game.getState() != Game.State.PLAYING) { + player.sendMessage("§cThe game must be running to execute this command."); + return true; + } + + if (!Gamemode.getByName("Jackpot").isEnabled()) { + player.sendMessage("§cJackpot gamemode must be enabled to execute this command."); + return true; + } + + player.sendMessage("" + game.getDiamondJackpot()); + player.sendMessage("§5&lJackpot Contents"); + player.sendMessage("§bDiamonds: §f" + game.getDiamondJackpot()); + player.sendMessage("§6Gold: §f" + game.getGoldJackpot()); + player.sendMessage("" + game.getDiamondJackpot()); + + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/KillCountCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/KillCountCommand.java new file mode 100644 index 0000000..6f62ff1 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/KillCountCommand.java @@ -0,0 +1,45 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class KillCountCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + + Game game = UHC.getInstance().getGame(); + if (game.getState() != Game.State.PLAYING) { + player.sendMessage("§cYou may only use this command when the game is running."); + return true; + } + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.killcount"); + + if (args.length < 1) { + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + player.sendMessage(Common.format(configCursor.getString("yours"), uhcPlayer.getKills().getAmount())); + return true; + } + + UHCPlayer uhcPlayer = UHCPlayer.getByName(args[0]); + if (uhcPlayer != null) player.sendMessage(Common.format(configCursor.getString("others"), uhcPlayer.getName(), uhcPlayer.getKills().getAmount())); + else player.sendMessage("§c" + args[0] + " hasn't played the game."); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/KillTopCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/KillTopCommand.java new file mode 100644 index 0000000..9627436 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/KillTopCommand.java @@ -0,0 +1,69 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import org.apache.commons.lang.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.*; + +public class KillTopCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + Game game = UHC.getInstance().getGame(); + + if (game.getState() != Game.State.PLAYING) { + player.sendMessage("§cYou may only use this command when the game is running."); + return true; + } + + Map kills = new HashMap<>(); + UHCPlayer.getPlayers().values().forEach(uhcPlayer -> { + if (uhcPlayer.getKills().getAmount() != 0) kills.put(uhcPlayer.getName(), uhcPlayer.getKills().getAmount()); + }); + + if (kills.keySet().isEmpty()) { + player.sendMessage("§cNobody has killed anyone in this game."); + return true; + } + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.killtop"); + + Map orderedKills = this.order(kills); + int current = 0; + + List names = new ArrayList<>(); + for (String name : orderedKills.keySet()) { + if (++current == 11) break; + UHCPlayer uhcPlayer = UHCPlayer.getByName(name); + if (uhcPlayer.isAlive()) names.add(Common.format(configCursor.getString("format"), current, "&a", name, orderedKills.get(name))); + else names.add(Common.format(configCursor.getString("format"), current, "&c", name, orderedKills.get(name))); + } + + player.sendMessage(Common.format(configCursor.getString("message"), StringUtils.join(names, "\n"))); + return true; + } + + private > Map order(Map map) { + LinkedList> list = new LinkedList<>(map.entrySet()); + list.sort((o1, o2) -> (o2.getValue()).compareTo(o1.getValue())); + LinkedHashMap result = new LinkedHashMap<>(); + list.forEach(kvEntry -> result.put(kvEntry.getKey(), kvEntry.getValue())); + return result; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LateScatterCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LateScatterCommand.java new file mode 100644 index 0000000..6494b4f --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LateScatterCommand.java @@ -0,0 +1,62 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class LateScatterCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + ConfigCursor cursor = new ConfigCursor(UHC.getInstance().getMessagesConfig(), "commands.latescatter"); + + if(args.length == 0){ + sender.sendMessage(Common.format(cursor.getString("usage"))); + return true; + } + + Game game = UHC.getInstance().getGame(); + if(game.getState() != Game.State.PLAYING){ + sender.sendMessage("§cYou cannot respawn players until the game start."); + return true; + } + + if(game.isPvpTimeAlready()){ + sender.sendMessage("§cGrace period ended, so nobody can get late-scattered."); + return true; + } + + UHCPlayer targetUhcPlayer = UHCPlayer.getByName(args[0]); + if (targetUhcPlayer == null) { + sender.sendMessage("§cCouldn't find that player. The player must try to join."); + return true; + } + + if(targetUhcPlayer.getState() != UHCPlayer.State.WAITING){ + sender.sendMessage("§cCouldn't late-scatter that player."); + return true; + } + + sender.sendMessage(Common.format(cursor.getString("message"), targetUhcPlayer.getName())); + targetUhcPlayer.setLateScattered(true); + + if (targetUhcPlayer.isOnline()) { + for (UHCPlayer spectator : game.getGameManager().getSpectators()) { + if (!spectator.isOnline()) continue; + + Player target = spectator.getPlayer(); + target.showPlayer(targetUhcPlayer.getPlayer()); + targetUhcPlayer.getPlayer().hidePlayer(target); + } + } + + return true; + } + +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LeaderboardCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LeaderboardCommand.java new file mode 100644 index 0000000..143afe1 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LeaderboardCommand.java @@ -0,0 +1,23 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.menu.LeaderboardMenu; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class LeaderboardCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + new LeaderboardMenu().open(UHCPlayer.getByUuid(player.getUniqueId())); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ListCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ListCommand.java new file mode 100644 index 0000000..6ab3cec --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ListCommand.java @@ -0,0 +1,58 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.game.GameManager; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import org.apache.commons.lang.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.stream.Collectors; + +public class ListCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Game game = UHC.getInstance().getGame(); + GameManager gameManager = game.getGameManager(); + + Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + if (gameManager.getStaff().contains(uhcPlayer) && UHC.getInstance().getGame().getState() == Game.State.PLAYING) { + StringBuilder players = new StringBuilder("§6§lPlayers: §f"); + + for (UHCPlayer uhcPlayer1 : UHCPlayer.getPlayers().values()) { + if (uhcPlayer1.getState() == UHCPlayer.State.PLAYING) { + players.append("§a").append(uhcPlayer1.getName()).append("§f, "); + } else if (uhcPlayer1.getState() == UHCPlayer.State.DEAD) { + players.append("§c").append(uhcPlayer1.getName()).append("§f, "); + } + } + player.sendMessage(players.toString()); + + return true; + } + + ConfigCursor cursor = new ConfigCursor(UHC.getInstance().getMessagesConfig(), "commands"); + + player.sendMessage(Common.format(cursor.getString("list"), + game.getHost().isEmpty() ? "None" : StringUtils.join(game.getHost().stream().map(UHCPlayer::getName).collect(Collectors.toList()), ", "), + game.getModerators().isEmpty() ? "None" : StringUtils.join(game.getModerators().stream().map(UHCPlayer::getName).collect(Collectors.toList()), ", "), + UHCPlayer.getPlayers().values().size(), + Common.getOnlinePlayers().size(), game.getSlots(), + gameManager.getAlivePlayers().size(), gameManager.getMaxPlayers() + )); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LoggersCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LoggersCommand.java new file mode 100644 index 0000000..722c3f4 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/LoggersCommand.java @@ -0,0 +1,32 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.UHCTeam; +import gg.mythic.uhc.menu.LoggersMenu; +import gg.mythic.uhc.menu.MoleKitMenu; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class LoggersCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + if (UHC.getInstance().getGame().getHost().contains(uhcPlayer) || UHC.getInstance().getGame().getModerators().contains(uhcPlayer)) { + new LoggersMenu(1).open(player); + } + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/MLGCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/MLGCommand.java new file mode 100644 index 0000000..32bfccd --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/MLGCommand.java @@ -0,0 +1,50 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class MLGCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Game game = UHC.getInstance().getGame(); + + if (!game.isEnded()) { + sender.sendMessage("§cYou cannot do this right now..."); + return true; + } + + if (game.getMlgMode() != 0) { + sender.sendMessage("§cYou cannot do this right now..."); + return true; + } + + UHCPlayer player = UHCPlayer.getByUuid(((Player) sender).getUniqueId()); + + if (player.getState() != UHCPlayer.State.PLAYING) { + sender.sendMessage("§cYou cannot do this right now..."); + return true; + } + + if (game.getMlgList().contains(player)) { + sender.sendMessage("§cYou are already entered into the MLG..."); + return true; + } + + Bukkit.broadcastMessage("§7[§9MLG§7] §a" + player.getName() + " has joined the MLG challenge."); + game.getMlgList().add(player); + + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/MoleCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/MoleCommand.java new file mode 100644 index 0000000..099773a --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/MoleCommand.java @@ -0,0 +1,121 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.gamemode.Gamemode; +import gg.mythic.uhc.manager.gamemode.gamemodes.Moles; +import gg.mythic.uhc.menu.MoleKitMenu; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.stream.Collectors; + +public class MoleCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) return true; + + Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + if (args.length < 1) { + player.sendMessage("§cSyntax Error. Please use /mole "); + return true; + } + + Game game = UHC.getInstance().getGame(); + if (game.getState() != Game.State.PLAYING) { + player.sendMessage("§cThe game must be running to execute this command."); + return true; + } + + Moles moles = (Moles) Gamemode.getByName("Moles"); + if (!moles.isEnabled()) { + player.sendMessage("§cMoles gamemode must be enabled to execute this command."); + return true; + } + + String format; + switch (args[0]) { + case "kit": + if (!uhcPlayer.isMole()) { + player.sendMessage("§cYou must be a mole to execute this command"); + return true; + } + + if (!uhcPlayer.isAlive()) { + player.sendMessage("§cYou must be alive to share your coordinates"); + return true; + } + + new MoleKitMenu().open(player); + break; + case "list": + if(!(game.getHost().contains(uhcPlayer) || game.getModerators().contains(uhcPlayer) || uhcPlayer.isMole())) { + player.sendMessage("§cYou must be a mole to execute this command"); + return true; + } + + if (moles.getMolesTeam().isEmpty()) { + player.sendMessage("§cThere are no moles yet."); + return true; + } + + player.sendMessage("§6Mole Team's Players§7: " + StringUtils.join(moles.getMolesTeam().stream().map(target -> (target.isAlive() ? "§a" : "§c") + target.getName()).collect(Collectors.toList()), "§7, ")); + break; + case "coords": + case "coordinates": + if (!uhcPlayer.isMole()) { + player.sendMessage("§cYou must be a mole to execute this command"); + return true; + } + + if (!uhcPlayer.isAlive()) { + player.sendMessage("§cYou must be alive to share your coordinates"); + return true; + } + + Location location = player.getLocation(); + format = "§7[§6§lMole Chat§7] " + player.getDisplayName() + "§7:§f " + location.getBlockX() + " " + location.getBlockY() + " " + location.getBlockZ(); + moles.getMolesTeam().stream().filter(UHCPlayer::isOnline).forEach(target -> target.getPlayer().sendMessage(format)); + break; + case "chat": + if(!(game.getHost().contains(uhcPlayer) || game.getModerators().contains(uhcPlayer) || uhcPlayer.isMole())) { + player.sendMessage("§cYou must be a mole to execute this command"); + return true; + } + + if (args.length < 2) { + player.sendMessage("§cSyntax Error. Please use /mole chat "); + return true; + } + + StringBuilder stringBuilder = new StringBuilder(); + List words = new ArrayList<>(Arrays.asList(args)); + words.remove(0); + words.forEach(string -> { + stringBuilder.append(string); + stringBuilder.append(" "); + }); + + format = "§7[§6§lMole Chat§7] " + player.getDisplayName() + "§7:§f " + stringBuilder.toString(); + + Set players = new HashSet<>(); + players.addAll(moles.getMolesTeam()); + players.addAll(game.getHost()); + players.addAll(game.getModerators()); + + players.stream().filter(UHCPlayer::isOnline).forEach(target -> target.getPlayer().sendMessage(format)); + break; + } + + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/PracticeCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/PracticeCommand.java new file mode 100644 index 0000000..a270642 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/PracticeCommand.java @@ -0,0 +1,79 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.practice.Practice; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class PracticeCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + Game game = UHC.getInstance().getGame(); + Practice practice = UHC.getInstance().getPractice(); + + if(game.getState() != Game.State.LOBBY){ + player.sendMessage("§cPractice isn't joinable now."); + return true; + } + + if(game.getHost().contains(uhcPlayer) || game.getModerators().contains(uhcPlayer)){ + if(args.length == 0) { + player.sendMessage("§cYou must disable your Host/Moderator mode to join practice arena."); + return true; + } + + if(!player.hasPermission("uhc.command.practice.toggle")) { + player.sendMessage("§cYou do not have permissions to execute this command."); + return true; + } + + if(!args[0].equalsIgnoreCase("toggle")){ + player.sendMessage("§cPlease use /practice toggle"); + return true; + } + + practice.setJoinable(!practice.isJoinable()); + player.sendMessage("§eYou have set §7'§aPractice Arena§7' §eto§7:§f " + practice.isJoinable()); + + if(!practice.isJoinable()){ + UHCPlayer.getPlayers().values().forEach(target -> { + if(target.isInPractice()) practice.leave(target); + }); + } + return true; + } + + if(!practice.isJoinable()){ + player.sendMessage("§cPractice isn't joinable now."); + return true; + } + + if(uhcPlayer.isInPractice()){ + practice.leave(uhcPlayer); + player.sendMessage("§cYou have left the practice arena."); + return true; + } + + practice.join(uhcPlayer); + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "game"); + player.sendMessage(Common.format(configCursor.getString("practice.join"))); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RemoveLoggerCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RemoveLoggerCommand.java new file mode 100644 index 0000000..f1f2dc8 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RemoveLoggerCommand.java @@ -0,0 +1,50 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.logger.Logger; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class RemoveLoggerCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (args.length == 0) { + sender.sendMessage("§cSyntax Error. Please use /removelogger "); + return true; + } + + Player playerSender = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(playerSender.getUniqueId()); + if (!(UHC.getInstance().getGame().getHost().contains(uhcPlayer) || UHC.getInstance().getGame().getModerators().contains(uhcPlayer))) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + Game game = UHC.getInstance().getGame(); + if(game.getState() != Game.State.PLAYING){ + sender.sendMessage("§cYou cannot remove loggers until the game start."); + return true; + } + + UHCPlayer targetUhcPlayer = UHCPlayer.getByName(args[0]); + if (targetUhcPlayer == null) { + sender.sendMessage("§cCouldn't find that player."); + return true; + } + + if (targetUhcPlayer.isOnline()) { + sender.sendMessage("§cCannot remove an online player's combat logger."); + return true; + } + + Logger logger = targetUhcPlayer.getLogger(); + logger.remove(); + sender.sendMessage("§cRemoved " + targetUhcPlayer.getName() + "'s combat logger!"); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RerollCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RerollCommand.java new file mode 100644 index 0000000..5ffaf82 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RerollCommand.java @@ -0,0 +1,46 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.PlayerUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class RerollCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + if (!UHC.getInstance().isMeetupsMode()) { + return true; + } + + Game game = UHC.getInstance().getGame(); + + if (game.getState() != Game.State.SCATTERING) { + sender.sendMessage("§cYou cannot reroll right now..."); + return true; + } + + UHCPlayer player = UHCPlayer.getByUuid(((Player) sender).getUniqueId()); + + if (player.getRerollAmount() > 0) { + player.setRerollAmount(player.getRerollAmount() - 1); + + PlayerUtil.prepareGame(player); + + sender.sendMessage("§aReroll complete. You can reroll " + player.getRerollAmount() + " more times"); + } else { + sender.sendMessage("§cYou have run out of rerolls"); + } + + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RespawnCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RespawnCommand.java new file mode 100644 index 0000000..d44ec69 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/RespawnCommand.java @@ -0,0 +1,80 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.UHCTeam; +import gg.mythic.uhc.util.RespawnUtil; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class RespawnCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + if (args.length == 0) { + sender.sendMessage("§cSyntax Error. Please use /respawn "); + return true; + } + + Game game = UHC.getInstance().getGame(); + if(game.getState() != Game.State.PLAYING){ + sender.sendMessage("§cYou cannot respawn players until the game start."); + return true; + } + + Player playerSender = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(playerSender.getUniqueId()); + if (!(UHC.getInstance().getGame().getHost().contains(uhcPlayer) || UHC.getInstance().getGame().getModerators().contains(uhcPlayer))) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + UHCPlayer targetUhcPlayer = UHCPlayer.getByName(args[0]); + if (targetUhcPlayer == null) { + sender.sendMessage("§cCouldn't find that player."); + return true; + } + + if (targetUhcPlayer.isAlive()) { + sender.sendMessage("§cCouldn't respawn an alive player."); + return true; + } + + if(targetUhcPlayer.isRespawned()){ + sender.sendMessage("§cCouldn't respawn a respawned player."); + return true; + } + + if (game.isTeams() && targetUhcPlayer.getUhcTeam() == null) new UHCTeam(targetUhcPlayer); + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.respawn"); + + game.getHost().remove(targetUhcPlayer); + game.getModerators().remove(targetUhcPlayer); + + if(targetUhcPlayer.isOnline()) { + RespawnUtil.respawn(targetUhcPlayer); + + targetUhcPlayer.getPlayer().sendMessage(Common.format(configCursor.getString("respawned"))); + } else { + targetUhcPlayer.setRespawned(true); + } + + targetUhcPlayer.setWasRespawned(true); + + sender.sendMessage(Common.format(configCursor.getString("respawn"), targetUhcPlayer.getName())); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/SetHealthCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/SetHealthCommand.java new file mode 100644 index 0000000..d5ac63e --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/SetHealthCommand.java @@ -0,0 +1,51 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.util.JavaUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class SetHealthCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (args.length < 2) { + sender.sendMessage("§cPlease use /sethealth "); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcSender = UHCPlayer.getByUuid(player.getUniqueId()); + if (!UHC.getInstance().getGame().getGameManager().getStaff().contains(uhcSender)) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + UHCPlayer uhcPlayerTarget = UHCPlayer.getByName(args[0]); + if (uhcPlayerTarget == null || !uhcPlayerTarget.isOnline()) { + sender.sendMessage("§cCouldn't find that player."); + return true; + } + + int amount = 0; + if (args.length == 2) { + if(!NumberUtils.isNumber(args[1])){ + sender.sendMessage("§cAmount must be a number."); + return true; + } + + amount = JavaUtils.tryParseInteger(args[1]); + } + + uhcPlayerTarget.getPlayer().setHealth(amount); + + sender.sendMessage("§eYou set the health of §f" + uhcPlayerTarget.getPlayer().getName() + " §eto §f" + amount); + Bukkit.broadcastMessage("§e" + sender.getName() + " set the health of §f" + uhcPlayerTarget.getPlayer().getName() + " §eto §f" + amount); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/StatisticsCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/StatisticsCommand.java new file mode 100644 index 0000000..9c10de9 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/StatisticsCommand.java @@ -0,0 +1,34 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.menu.StatisticsMenu; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class StatisticsCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) return true; + + Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + if(args.length == 0){ + new StatisticsMenu(uhcPlayer).open(player); + return true; + } + + uhcPlayer = UHCPlayer.getByName(args[0]); + if(uhcPlayer == null){ + player.sendMessage("§cCouldn't find that player"); + return true; + } + + new StatisticsMenu(uhcPlayer).open(player); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamAllCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamAllCommand.java new file mode 100644 index 0000000..c3928b3 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamAllCommand.java @@ -0,0 +1,37 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.manager.UHCTeam; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class TeamAllCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + + player.sendMessage(""); + player.sendMessage(ChatColor.BOLD + "UHC Teams"); + + for (UHCTeam team : UHCTeam.getTeams()) { + player.sendMessage(team.getPrefix() + " - " + team.getLeader().getName() + " §7[" + team.getAliveUHCPlayers().size() + "/" + team.getTeamPlayers().size() + "]"); + team.getTeamPlayers().forEach(uhcPlayer -> { + if (uhcPlayer.isAlive()) { + player.sendMessage("§a" + uhcPlayer.getName()); + } else { + player.sendMessage("§c" + uhcPlayer.getName()); + } + }); + } + player.sendMessage(""); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamChatCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamChatCommand.java new file mode 100644 index 0000000..6a363ab --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamChatCommand.java @@ -0,0 +1,38 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.manager.UHCPlayer; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class TeamChatCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + if (uhcPlayer.getUhcTeam() == null) { + player.sendMessage("§cYou do not have a team."); + return true; + } + + if (args.length == 0)player.performCommand("team chat"); + else { + StringBuilder stringBuilder = new StringBuilder(); + for (String string : args) { + stringBuilder.append(string); + stringBuilder.append(" "); + } + + player.performCommand("team chat " + stringBuilder.toString()); + } + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamCommand.java new file mode 100644 index 0000000..4bfd157 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamCommand.java @@ -0,0 +1,372 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.FileConfig; +import gg.mythic.uhc.manager.UHCTeam; +import gg.mythic.uhc.manager.gamemode.Gamemode; +import org.apache.commons.lang.StringUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class TeamCommand implements CommandExecutor, TabCompleter { + + private void usage(Player player) { + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.team"); + + player.sendMessage(Common.format(configCursor.getString("usage"))); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + Game game = UHC.getInstance().getGame(); + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.team"); + + if (!game.isTeams()) { + player.sendMessage("§cTeams are disabled on this match."); + return true; + } + + if (args.length == 0) { + this.usage(player); + return true; + } + + final boolean lobby = game.getState() == Game.State.LOBBY; + + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + UHCTeam uhcTeam = uhcPlayer.getUhcTeam(); + + Gamemode gamemode = Gamemode.getByName("Random Teams"); + Gamemode lafs = Gamemode.getByName("Love At First Sight"); + Gamemode redvsblue = Gamemode.getByName("Red Vs Blue"); + + switch (args[0]) { + case "create": + if (!lobby) { + player.sendMessage("§cCouldn't modify your team while the game is running."); + return true; + } + + if(gamemode.isEnabled() || lafs.isEnabled() || redvsblue.isEnabled()){ + player.sendMessage("§cYou cannot create teams this game..."); + return true; + } + + if (uhcTeam != null) { + player.sendMessage(Common.format(configCursor.getString("already"))); + return true; + } + + new UHCTeam(uhcPlayer); + UHC.getInstance().getGame().getGameManager().colorize(uhcPlayer); + + player.sendMessage(Common.format(configCursor.getString("create"))); + break; + case "disband": + if (!lobby) { + player.sendMessage("§cCouldn't modify your team while the game is running."); + return true; + } + + if (uhcTeam == null) { + player.sendMessage(Common.format(configCursor.getString("noteam"))); + return true; + } + + if (!uhcTeam.getLeader().equals(uhcPlayer)) { + player.sendMessage(Common.format(configCursor.getString("leader"))); + return true; + } + + uhcTeam.disband(); + break; + case "leave": + if (!lobby) { + player.sendMessage("§cCouldn't modify your team while the game is running."); + return true; + } + + if(gamemode.isEnabled() || lafs.isEnabled() || redvsblue.isEnabled()){ + player.sendMessage("§cYou cannot leave from teams this game..."); + return true; + } + + if (uhcTeam == null) { + player.sendMessage(Common.format(configCursor.getString("noteam"))); + return true; + } + + if (uhcTeam.getLeader().equals(uhcPlayer)) { + uhcTeam.disband(); + return true; + } + + uhcTeam.leave(uhcPlayer, false); + + player.sendMessage(Common.format(configCursor.getString("leave.message"))); + break; + case "kick": + if (!lobby) { + player.sendMessage("§cCouldn't modify your team while the game is running."); + return true; + } + + if(gamemode.isEnabled() || lafs.isEnabled() || redvsblue.isEnabled()){ + player.sendMessage("§cYou cannot kick players from team this game..."); + return true; + } + + if (args.length < 2) { + player.sendMessage(Common.format(configCursor.getString("kick.usage"))); + return true; + } + + if (uhcTeam == null) { + player.sendMessage(Common.format(configCursor.getString("noteam"))); + return true; + } + + if (!uhcTeam.getLeader().equals(uhcPlayer)) { + player.sendMessage(Common.format(configCursor.getString("leader"))); + return true; + } + + UHCPlayer uhcPlayerTarget = UHCPlayer.getByName(args[1]); + if (uhcPlayerTarget == null) { + player.sendMessage("§cCouldn't find that player."); + return true; + } + + if(uhcPlayerTarget.getUhcTeam() == null){ + player.sendMessage("§cThat player don't have a team."); + return true; + } + + if (uhcPlayer.equals(uhcPlayerTarget)) { + player.sendMessage("§cYou may not kick yourself from team."); + return true; + } + + if(!uhcTeam.getTeamPlayers().contains(uhcPlayerTarget)){ + player.sendMessage("§cThat player is not in your team."); + return true; + } + + uhcTeam.leave(uhcPlayerTarget, true); + if (uhcPlayerTarget.isOnline()) uhcPlayerTarget.getPlayer().sendMessage(Common.format(configCursor.getString("kick.message"))); + break; + case "invite": + if (!lobby) { + player.sendMessage("§cCouldn't modify your team while the game is running."); + return true; + } + + if(gamemode.isEnabled() || lafs.isEnabled() || redvsblue.isEnabled()){ + player.sendMessage("§cYou cannot invite players to team this game..."); + return true; + } + + if (args.length < 2) { + player.sendMessage(Common.format(configCursor.getString("invite.usage"))); + return true; + } + + if (uhcTeam == null) { + uhcTeam = new UHCTeam(uhcPlayer); + UHC.getInstance().getGame().getGameManager().colorize(uhcPlayer); + + player.sendMessage(Common.format(configCursor.getString("create"))); + } + + if (!uhcTeam.getLeader().equals(uhcPlayer)) { + player.sendMessage(Common.format(configCursor.getString("leader"))); + return true; + } + + uhcPlayerTarget = UHCPlayer.getByName(args[1]); + if (uhcPlayerTarget == null || !uhcPlayerTarget.isOnline()) { + player.sendMessage("§cCouldn't find that player, may be offline."); + return true; + } + + if(uhcPlayerTarget.getUhcTeam() != null){ + player.sendMessage("§cThat player is already on a team."); + return true; + } + + uhcTeam.invite(uhcPlayerTarget); + break; + case "accept": + if (!lobby) { + player.sendMessage("§cCouldn't modify your team while the game is running."); + return true; + } + + if (args.length < 2) { + player.sendMessage(Common.format(configCursor.getString("accept.usage"))); + return true; + } + + if (uhcTeam != null) { + player.sendMessage(Common.format(configCursor.getString("already"))); + return true; + } + + uhcPlayerTarget = UHCPlayer.getByName(args[1]); + if (uhcPlayerTarget == null || !uhcPlayerTarget.isOnline()) { + player.sendMessage("§cCouldn't find that player, may be offline."); + return true; + } + + UHCTeam targetUhcTeam = uhcPlayerTarget.getUhcTeam(); + if (targetUhcTeam == null) { + player.sendMessage("§cCouldn't find " + uhcPlayerTarget.getName() + "'s team."); + return true; + } + + if (!targetUhcTeam.isInvited(uhcPlayer)) { + player.sendMessage(Common.format(configCursor.getString("accept.noinvitation"))); + return true; + } + + if (targetUhcTeam.getTeamPlayers().size() >= game.getTeamSize()) { + player.sendMessage(Common.format(configCursor.getString("accept.full"))); + return true; + } + + targetUhcTeam.join(uhcPlayer); + break; + case "list": + if (args.length < 2) { + uhcPlayerTarget = uhcPlayer; + } else { + uhcPlayerTarget = UHCPlayer.getByName(args[1]); + if (uhcPlayerTarget == null || !uhcPlayerTarget.isOnline()) { + player.sendMessage("§cCouldn't find that player, may be offline."); + return true; + } + uhcTeam = uhcPlayerTarget.getUhcTeam(); + } + + if (uhcTeam == null) { + if (uhcPlayer.equals(uhcPlayerTarget)) player.sendMessage(Common.format(configCursor.getString("noteam"))); + else player.sendMessage(Common.format(configCursor.getString("targetnoteam"))); + return true; + } + + List players = new ArrayList<>(); + uhcTeam.getTeamPlayers().forEach(target -> { + if (!uhcPlayerTarget.getUhcTeam().getLeader().equals(target)) { + players.add(this.color(target)); + } + }); + + player.sendMessage(Common.format(configCursor.getString("list"), uhcTeam.getId(), this.color(uhcTeam.getLeader()), (players.isEmpty() ? "No players found." : StringUtils.join(players, "§7,§f ")))); + break; + case "coords": + if (uhcTeam == null) { + player.sendMessage(Common.format(configCursor.getString("noteam"))); + return true; + } + + if (lobby) { + player.sendMessage("§cCouldn't share your coordinates until the game starts."); + return true; + } + + uhcTeam.shareCoordinates(uhcPlayer); + break; + case "chat": + if (uhcTeam == null) { + player.sendMessage(Common.format(configCursor.getString("noteam"))); + return true; + } + + if (args.length < 2) { + uhcPlayer.setTeamChat(!uhcPlayer.isTeamChat()); + player.sendMessage(Common.format((uhcPlayer.isTeamChat() ? configCursor.getString("chat.toggle") : configCursor.getString("chat.untoggle")))); + return true; + } + + StringBuilder stringBuilder = new StringBuilder(); + + List words = new ArrayList<>(Arrays.asList(args)); + words.remove(0); + words.forEach(string -> { + stringBuilder.append(string); + stringBuilder.append(" "); + }); + + uhcTeam.broadcast(Common.format(configCursor.getString("chat.format"), configCursor.getString("chat.prefix"), uhcTeam.getPrefix(), player.getDisplayName(), stringBuilder.toString())); + break; + case "inventory": + gamemode = Gamemode.getByName("BackPack"); + if(!gamemode.isEnabled()){ + player.sendMessage("§cBackpacks are disabled on this match."); + return true; + } + + if(!uhcPlayer.isAlive()){ + player.sendMessage("§cYou must be alive to open your backpack."); + return true; + } + + uhcTeam = uhcPlayer.getUhcTeam(); + if(uhcTeam == null){ + player.sendMessage("§cYou must be in a team to open your backpack."); + return true; + } + + if(uhcPlayer.isFreezed()){ + player.sendMessage("§cYou cannot open your backpack while frozen."); + return true; + } + + player.openInventory(uhcTeam.getBackPack()); + break; + default: + this.usage(player); + break; + } + return true; + } + + private String color(UHCPlayer uhcPlayer) { + double health = (uhcPlayer.isOnline() ? Math.ceil(uhcPlayer.getPlayer().getHealth()/ 2.0D) : 0.0); + return ((uhcPlayer.isOnline() && uhcPlayer.isAlive()) ? "§a" : "§c") + uhcPlayer.getName() + (uhcPlayer.isOnline() && uhcPlayer.isAlive() ? " §7(§c" + (health > 0 ? health : "0") + " §4❤§7)" : ""); + } + + @Override + public List onTabComplete(CommandSender commandSender, Command command, String s, String[] args) { + List completer = new ArrayList<>(); + + if (args.length == 1) { + String match = args[0].toLowerCase(); + + completer.addAll(Arrays.asList("create", "disband", "leave", "coords", "chat", "invite", "accept", "kick")); + completer.removeIf(value -> !(value.contains(match) || value.equalsIgnoreCase(match))); + } else return null; + + return completer; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamCoordsCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamCoordsCommand.java new file mode 100644 index 0000000..a3c06b4 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamCoordsCommand.java @@ -0,0 +1,21 @@ +package gg.mythic.uhc.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class TeamCoordsCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + player.performCommand("team coords"); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamListCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamListCommand.java new file mode 100644 index 0000000..f07e249 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeamListCommand.java @@ -0,0 +1,23 @@ +package gg.mythic.uhc.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class TeamListCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + + if (args.length == 0) player.performCommand("team list"); + else player.performCommand("team list " + args[0]); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeleportCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeleportCommand.java new file mode 100644 index 0000000..1fad309 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/TeleportCommand.java @@ -0,0 +1,157 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import gg.mythic.uhc.util.JavaUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerTeleportEvent; + +import java.util.Collections; +import java.util.List; + +public class TeleportCommand implements CommandExecutor, TabCompleter { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) return true; + + ConfigCursor configCursor = new ConfigCursor(UHC.getInstance().getMessagesConfig(), "commands.teleport"); + + Player playerSender = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(playerSender.getUniqueId()); + + Game game = UHC.getInstance().getGame(); + if (!this.isStaff(uhcPlayer) && uhcPlayer.getState() != UHCPlayer.State.SPECTATING) { + sender.sendMessage("§cYou cannot use this command now"); + return true; + } + + if (args.length < 1) { + sender.sendMessage(Common.format(configCursor.getString("usage"))); + return true; + } + + Player player; + if (args.length != 1 && args.length != 3) { + if (!sender.hasPermission("uhc.command.host")) { + sender.sendMessage("§cYou do not have permissions to teleport others."); + return true; + } + + player = Bukkit.getPlayer(args[0]); + } else player = (Player) sender; + + if (player == null) { + sender.sendMessage("§cPlayer with name '" + args[0] + "' could not be found."); + } else { + if (args.length < 3) { + Player target = Bukkit.getPlayer(args[args.length - 1]); + if (target == null) { + sender.sendMessage("§cPlayer with name '" + args[args.length - 1] + "' could not be found."); + return true; + } + + if (target.equals(player)) { + sender.sendMessage("§cThe teleportee and teleported are the same player."); + return true; + } + + if(!this.isStaff(uhcPlayer) && !game.getGameManager().canTeleport(uhcPlayer, target)){ + sender.sendMessage("§cThat player is out your spectator limits."); + return true; + } + + if (player.teleport(target, PlayerTeleportEvent.TeleportCause.COMMAND)) { + if (player.equals(sender)) sender.sendMessage(Common.format(configCursor.getString("you"), target.getName())); + else sender.sendMessage(Common.format(configCursor.getString("other"), player.getName(), (target.equals(sender) ? "you" : target.getName()))); + } else { + sender.sendMessage("§cFailed to teleport" + (player.equals(sender) ? "" : ' ' + player.getName()) + " to " + (target.equals(sender) ? "you" : player.getName()) + "."); + } + } else { + if(!this.isStaff(uhcPlayer)){ + sender.sendMessage("§cYou cannot teleport to coordinates."); + return true; + } + + Location location = player.getLocation(); + double x = this.getCoordinate(location.getX(), args[args.length - 3]); + double y = this.getCoordinate(location.getY(), args[args.length - 2], 0, 0); + double z = this.getCoordinate(location.getZ(), args[args.length - 1]); + + if (x == -3.0000001E7D || y == -3.0000001E7D || z == -3.0000001E7D) { + sender.sendMessage(ChatColor.RED + "Provided coordinates are not a valid location."); + return true; + } + + location.setX(x); + location.setY(y); + location.setZ(z); + + if (player.teleport(location.add(0.0D, 0.5D, 0.0D), PlayerTeleportEvent.TeleportCause.COMMAND)) { + if (player.equals(sender)) sender.sendMessage(Common.format(configCursor.getString("you"), x + "§7, §f" + y + "§7, §f" + z)); + else sender.sendMessage(Common.format(configCursor.getString("other"), player.getName(), x + "§7, §f" + y + "§7, §f" + z)); + } else { + sender.sendMessage(ChatColor.RED + "Failed to teleport" + (player.equals(sender) ? "" : ' ' + player.getName()) + " to " + x + ", " + y + ", " + z + '.'); + } + } + } + return true; + } + + + private boolean isStaff(UHCPlayer uhcPlayer) { + return UHC.getInstance().getGame().getHost().contains(uhcPlayer) || UHC.getInstance().getGame().getModerators().contains(uhcPlayer); + } + + private double getCoordinate(double current, String input) { + return this.getCoordinate(current, input, -30000000, 30000000); + } + + private double getCoordinate(double current, String input, int min, int max) { + boolean relative = input.startsWith("~"); + double result = relative ? current : 0.0D; + if (!relative || input.length() > 1) { + boolean exact = input.contains("."); + if (relative) { + input = input.substring(1); + } + + Double testResult = JavaUtils.tryParseDouble(input); + if (testResult == null || testResult == -3.0000001E7D) { + return -3.0000001E7D; + } + + result += testResult; + if (!exact && !relative) { + result += 0.5D; + } + } + + if (min != 0 || max != 0) { + if (result < (double) min) { + result = -3.0000001E7D; + } + + if (result > (double) max) { + result = -3.0000001E7D; + } + } + + return result; + } + + @Override + public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) { + return strings.length > 2 ? Collections.emptyList() : null; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ThanksCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ThanksCommand.java new file mode 100644 index 0000000..e66667b --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ThanksCommand.java @@ -0,0 +1,41 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.game.GameManager; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.stream.Collectors; + +public class ThanksCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + if (UHC.getInstance().getGame().getState() != Game.State.PLAYING) return true; + + + + Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + if (uhcPlayer.isThanked()) return true; + + uhcPlayer.setThanked(true); + Bukkit.broadcastMessage(player.getName() + ChatColor.WHITE + " just wanted to say thanks for hosting!"); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ToggleSpectatorChat.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ToggleSpectatorChat.java new file mode 100644 index 0000000..ad2c8d9 --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/ToggleSpectatorChat.java @@ -0,0 +1,27 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.util.Common; +import gg.mythic.uhc.util.ConfigCursor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class ToggleSpectatorChat implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) return true; + + ConfigCursor configCursor = new ConfigCursor(UHC.getInstance().getMessagesConfig(), "commands.togglespectatorchat"); + + Player player = (Player) sender; + Game game = UHC.getInstance().getGame(); + + game.setSpectatorChat(!game.isSpectatorChat()); + player.sendMessage(Common.format(configCursor.getString("message"), game.isSpectatorChat() ? "enabled" : "disabled")); + return true; + } +} diff --git a/MythicUHC-master/src/main/java/gg/mythic/uhc/command/UHCCommand.java b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/UHCCommand.java new file mode 100644 index 0000000..323cafe --- /dev/null +++ b/MythicUHC-master/src/main/java/gg/mythic/uhc/command/UHCCommand.java @@ -0,0 +1,458 @@ +package gg.mythic.uhc.command; + +import gg.mythic.uhc.UHC; +import gg.mythic.uhc.manager.UHCPlayer; +import gg.mythic.uhc.manager.event.BorderShrinkEvent; +import gg.mythic.uhc.manager.game.Game; +import gg.mythic.uhc.manager.leaderboard.Leaderboard; +import gg.mythic.uhc.manager.leaderboard.LeaderboardManager; +import gg.mythic.uhc.util.*; +import gg.mythic.uhc.listener.DeathmatchListener; +import gg.mythic.uhc.manager.UHCTeam; +import gg.mythic.uhc.manager.event.DeathMatchStartEvent; +import gg.mythic.uhc.manager.event.GamePreStartEvent; +import gg.mythic.uhc.manager.gamemode.Gamemode; +import gg.mythic.uhc.manager.meetups.MeetupsKits; +import gg.mythic.uhc.manager.practice.Practice; +import gg.mythic.uhc.manager.world.Shrink; +import gg.mythic.uhc.menu.ConfiguratorMenu; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class UHCCommand implements CommandExecutor, TabCompleter { + + @Override + public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("§cError. You must be a player to execute this command"); + return true; + } + + Player player = (Player) sender; + UHCPlayer uhcPlayer = UHCPlayer.getByUuid(player.getUniqueId()); + + Game game = UHC.getInstance().getGame(); + + FileConfig fileConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor configCursor = new ConfigCursor(fileConfig, "commands.uhc"); + + if (args.length < 1) { + player.sendMessage("§cSyntax Error. Please use /uhc "); + return true; + } + + if (game.getState() == Game.State.GENERATING) { + player.sendMessage("§cWorld must be generated to use this command."); + return true; + } + + switch (args[0]) { + case "spy": + if (UHC.getInstance().getGame().getGameManager().getStaff().contains(uhcPlayer)) { + uhcPlayer.setSpy(!uhcPlayer.isSpy()); + if (uhcPlayer.isSpy()) { + uhcPlayer.getPlayer().sendMessage(ChatColor.GREEN + "You toggled social spy on"); + } else { + uhcPlayer.getPlayer().sendMessage(ChatColor.RED + "You toggled social spy off"); + } + } + break; + case "jointeam": + if (args.length < 3) { + player.sendMessage("§cPlease use /uhc jointeam "); + return true; + } + + if (!game.isTeams()) { + player.sendMessage("§cMust be a Team game to use this command."); + return true; + } + + UHCPlayer targetUhcPlayer = UHCPlayer.getByName(args[1]); + if (targetUhcPlayer == null || !targetUhcPlayer.isOnline()) { + player.sendMessage("§cCouldn't find a player with the name " + args[1]); + return true; + } + + UHCPlayer leaderUhcPlayer = UHCPlayer.getByName(args[2]); + if (leaderUhcPlayer == null || !leaderUhcPlayer.isOnline()) { + player.sendMessage("§cCouldn't find a player with the name " + args[2]); + return true; + } + + UHCTeam leaderTeam = leaderUhcPlayer.getUhcTeam(); + if (leaderTeam == null) { + player.sendMessage("§cCouldn't find " + leaderUhcPlayer.getName() + "'s Team."); + return true; + } + + if (targetUhcPlayer.getUhcTeam() != null) { + if (targetUhcPlayer.getUhcTeam().getTeamPlayers().size() == 1) { + targetUhcPlayer.getUhcTeam().disband(); + } else { + targetUhcPlayer.getUhcTeam().leave(targetUhcPlayer, true); + } + } + + leaderTeam.join(targetUhcPlayer); + + break; + case "start": + if (game.getState() != Game.State.LOBBY) { + player.sendMessage("§cThe game has already started."); + return true; + } + + player.sendMessage(Common.format(configCursor.getString("start"))); + Bukkit.getPluginManager().callEvent(new GamePreStartEvent()); + break; + case "forcedeathmatch": + if (game.getState() != Game.State.PLAYING) { + player.sendMessage("§cThe game must be running."); + return true; + } + + if (game.isDeathmatchRunning()) { + player.sendMessage("§cDeathmatch is already running."); + return true; + } + + FileConfig messagesConfig = UHC.getInstance().getMessagesConfig(); + ConfigCursor cursor = new ConfigCursor(messagesConfig, "game"); + + game.setDeathmatchRunning(true); + Bukkit.broadcastMessage(Common.format(cursor.getString("deathmatch"))); + Bukkit.getPluginManager().registerEvents(new DeathmatchListener(), UHC.getInstance()); + Bukkit.getPluginManager().callEvent(new DeathMatchStartEvent(UHC.getInstance().getWorldManager())); + break; + case "config": + if (!game.getHost().contains(uhcPlayer)) { + player.sendMessage("§cYou must be a host to do this"); + return true; + } + new ConfiguratorMenu().open(player); + break; + case "moderator": + case "mod": + if (game.getHost().contains(uhcPlayer)) { + player.sendMessage("§cYou may disable your Host mode first."); + return true; + } + + if (game.getState() == Game.State.SCATTERING) { + player.sendMessage("§cWait till the game starts."); + return true; + } + + if (game.getModerators().contains(uhcPlayer)) { + game.getModerators().remove(uhcPlayer); + player.sendMessage(Common.format(configCursor.getString("mod"), "&cdisabled")); + + if (game.getState() == Game.State.PLAYING) { + if (game.isPvpTimeAlready()) { + PlayerUtil.prepareSpectator(uhcPlayer); + player.sendMessage("§aCouldn't late-scatter you because grace period ends."); + } else { + if (game.isTeams() && uhcPlayer.getUhcTeam() == null) + new UHCTeam(uhcPlayer); + + PlayerUtil.prepareGame(uhcPlayer); + uhcPlayer.setState(UHCPlayer.State.PLAYING); + uhcPlayer.setHasPlayed(true); + + player.teleport(game.getScatterLocations().remove(0)); + player.sendMessage("§aYou have been late-scattered."); + + if (player.isOnline()) { + for (UHCPlayer spectator : game.getGameManager().getSpectators()) { + if (!spectator.isOnline()) continue; + + Player target = spectator.getPlayer(); + target.showPlayer(player); + player.hidePlayer(target); + } + } + } + } else { + PlayerUtil.prepareLobby(uhcPlayer); + uhcPlayer.setState(UHCPlayer.State.WAITING); + } + } else { + if (uhcPlayer.getUhcTeam() != null) { + uhcPlayer.getUhcTeam().leave(uhcPlayer, true); + } + + game.getModerators().add(uhcPlayer); + player.setRecieveCosmetics(false); + player.sendMessage(Common.format(configCursor.getString("mod"), "&aenabled")); + + if (game.getState() == Game.State.LOBBY) uhcPlayer.setState(UHCPlayer.State.SPECTATING); + else PlayerUtil.prepareSpectator(uhcPlayer); + } + UHC.getInstance().getGame().getGameManager().colorize(uhcPlayer); + break; + case "host": + if (game.getModerators().contains(uhcPlayer)) { + player.sendMessage("§cYou may disable your Moderator mode first."); + return true; + } + + if (game.getState() == Game.State.SCATTERING) { + player.sendMessage("§cWait till the game starts."); + return true; + } + + if (game.getHost().contains(uhcPlayer)) { + game.getHost().remove(uhcPlayer); + player.sendMessage(Common.format(configCursor.getString("host"), "&cdisabled")); + + if (game.getState() == Game.State.PLAYING) { + if (game.isPvpTimeAlready()) { + PlayerUtil.prepareSpectator(uhcPlayer); + player.sendMessage("§aCouldn't late-scatter you because grace period ends."); + } else { + if (game.isTeams() && uhcPlayer.getUhcTeam() == null) + new UHCTeam(uhcPlayer); + + PlayerUtil.prepareGame(uhcPlayer); + uhcPlayer.setState(UHCPlayer.State.PLAYING); + uhcPlayer.setHasPlayed(true); + + player.teleport(game.getScatterLocations().remove(0)); + player.sendMessage("§aYou have been late-scattered."); + if (player.isOnline()) { + for (UHCPlayer spectator : game.getGameManager().getSpectators()) { + if (!spectator.isOnline()) continue; + + Player target = spectator.getPlayer(); + target.showPlayer(player); + player.hidePlayer(target); + } + } + } + } else { + PlayerUtil.prepareLobby(uhcPlayer); + uhcPlayer.setState(UHCPlayer.State.WAITING); + } + } else { + if (uhcPlayer.getUhcTeam() != null) { + uhcPlayer.getUhcTeam().leave(uhcPlayer, true); + } + + game.getHost().add(uhcPlayer); + player.setRecieveCosmetics(false); + player.sendMessage(Common.format(configCursor.getString("host"), "&aenabled")); + + if (game.getState() == Game.State.LOBBY) uhcPlayer.setState(UHCPlayer.State.SPECTATING); + else PlayerUtil.prepareSpectator(uhcPlayer); + } + + UHC.getInstance().getGame().getGameManager().colorize(uhcPlayer); + break; + case "savekit": + if (!player.hasPermission("uhc.command.uhc.savekit")) { + player.sendMessage("§cYou don't have permissions."); + return true; + } + + Practice practice = UHC.getInstance().getPractice(); + practice.setInventory(player.getInventory().getContents()); + practice.setArmor(player.getInventory().getArmorContents()); + + ConfigCursor practiceCursor = new ConfigCursor(UHC.getInstance().getMainConfig(), "practice"); + practiceCursor.set("inventory", InventoryUtil.serializeInventory(practice.getInventory())); + practiceCursor.set("armor", InventoryUtil.serializeInventory(practice.getArmor())); + practiceCursor.save(); + + PlayerUtil.prepareLobby(uhcPlayer); + player.sendMessage("§aYou have set pratice kit successful."); + break; + case "loadkit": + if (!player.hasPermission("uhc.command.uhc.loadkit")) { + player.sendMessage("§cYou don't have permissions."); + return true; + } + + PlayerUtil.reset(uhcPlayer); + + practice = UHC.getInstance().getPractice(); + player.getInventory().setContents(practice.getInventory()); + player.getInventory().setArmorContents(practice.getArmor()); + player.updateInventory(); + + player.sendMessage("§aYou have been given practice kit."); + break; + case "savemeetupskit": + if (!player.hasPermission("uhc.command.uhc.savekit")) { + player.sendMessage("§cYou don't have permissions."); + return true; + } + + if (args.length < 2) { + player.sendMessage("§cSyntax Error. Please use /uhc savemeetupskit "); + return true; + } + + MeetupsKits kit; + + if (MeetupsKits.getByName(args[1]) == null) { + kit = new MeetupsKits(args[1]); + } else { + kit = MeetupsKits.getByName(args[1]); + } + kit.setInventory(player.getInventory().getContents()); + kit.setArmor(player.getInventory().getArmorContents()); + + ConfigCursor meetupsCursor = new ConfigCursor(UHC.getInstance().getMeetupsConfig(), "kits." + args[1]); + meetupsCursor.set("inventory", InventoryUtil.serializeInventory(kit.getInventory())); + meetupsCursor.set("armor", InventoryUtil.serializeInventory(kit.getArmor())); + meetupsCursor.save(); + + PlayerUtil.prepareLobby(uhcPlayer); + player.sendMessage("§aMeetups kit" + args[1] + "was saved!"); + break; + case "loadmeetupskit": + if (!player.hasPermission("uhc.command.uhc.loadkit")) { + player.sendMessage("§cYou don't have permissions."); + return true; + } + + if (args.length < 2) { + player.sendMessage("§cSyntax Error. Please use /uhc loadmeetupskit "); + return true; + } + + if (MeetupsKits.getByName(args[1]) == null) { + player.sendMessage("§cKit does not exist..."); + return true; + } else { + PlayerUtil.reset(uhcPlayer); + MeetupsKits getKit = MeetupsKits.getByName(args[1]); + player.getInventory().setContents(getKit.getInventory()); + player.getInventory().setArmorContents(getKit.getArmor()); + player.updateInventory(); + } + + player.sendMessage("§aYou have been given meetups kit " + args[1]); + break; + case "sethologram": + if (!player.hasPermission("uhc.command.uhc.sethologram")) { + player.sendMessage("§cYou don't have permissions."); + return true; + } + + if (args.length < 2) { + player.sendMessage("§cSyntax Error. Please use /uhc sethologram "); + return true; + } + + try { + LeaderboardManager.Values value = LeaderboardManager.Values.valueOf(args[1].toUpperCase()); + + configCursor = new ConfigCursor(UHC.getInstance().getMainConfig(), "hologram"); + configCursor.set(value.name().toLowerCase() + ".location", LocationUtil.serialize(player.getLocation())); + configCursor.save(); + + Leaderboard leaderboard = LeaderboardManager.getByName(value.name()); + leaderboard.removeHologram(); + leaderboard.createHologram(); + + player.sendMessage("§aYou have set " + value.getName() + "'s hologram to your location."); + } catch (IllegalArgumentException ex) { + player.sendMessage("§cSyntax Error. Please use /leaderboard sethologram "); + } + break; + case "removehologram": + if (!player.hasPermission("uhc.uhc.command.uhc.removehologram")) { + player.sendMessage("§cYou don't have permissions."); + return true; + } + + if (args.length < 2) { + player.sendMessage("§cSyntax Error. Please use /uhc removehologram "); + return true; + } + + try { + LeaderboardManager.Values value = LeaderboardManager.Values.valueOf(args[1].toUpperCase()); + + configCursor = new ConfigCursor(UHC.getInstance().getMainConfig(), "hologram"); + configCursor.set(value.name().toLowerCase() + ".location", null); + configCursor.save(); + + LeaderboardManager.getByName(value.name()).removeHologram(); + + player.sendMessage("§cYou have removed " + value.getName() + "'s hologram."); + } catch (IllegalArgumentException ex) { + player.sendMessage("§cSyntax Error. Please use /leaderboard removehologram "); + } + break; + case "forceshrink": + if (!player.hasPermission("uhc.command.host")) { + player.sendMessage("§cYou don't have permissions."); + return true; + } + + if (game.getState() != Game.State.PLAYING) { + player.sendMessage("§cThe game must be running."); + return true; + } + + if (game.isBorderTimeAlready() && game.getShrink() != null) { + Gamemode skyHigh = Gamemode.getByName("Sky High"); + Gamemode extremeSkyHigh = Gamemode.getByName("Extreme Sky High"); + Gamemode goToHell = Gamemode.getByName("Go To Hell"); + Gamemode fallout = Gamemode.getByName("Fallout"); + // Common.getCounter(game.getGameTime(), game.getShrink().getTime(), Common.format(configCursor.getString("borderCounter"), game.getShrink().getNewBorder(), "